Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema options for partially-authorize command #1416

Merged
merged 11 commits into from
Jan 9, 2025
3 changes: 3 additions & 0 deletions cedar-policy-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Changes to the Cedar language, which are likely to affect users of the CLI, are

## Unreleased

- Add schema options `schema` and `schema-format` for the `partially-authorize`
command (#1416, resolving #1332)

## 4.2.2

## 4.2.1
Expand Down
48 changes: 37 additions & 11 deletions cedar-policy-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl RequestArgs {

#[cfg(feature = "partial-eval")]
impl PartialRequestArgs {
fn get_request(&self) -> Result<Request> {
fn get_request(&self, schema: Option<&Schema>) -> Result<Request> {
let mut builder = RequestBuilder::default();
let qjson: PartialRequestJSON = match self.request_json_file.as_ref() {
Some(jsonfile) => {
Expand Down Expand Up @@ -416,15 +416,16 @@ impl PartialRequestArgs {
builder = builder.principal(principal);
}

if let Some(action) = qjson
let action = qjson
.action
.map(|s| {
s.parse()
s.parse::<EntityUid>()
.wrap_err_with(|| format!("failed to parse action {s} as entity Uid"))
})
.transpose()?
{
builder = builder.action(action);
.transpose()?;

if let Some(action_ref) = &action {
builder = builder.action(action_ref.clone());
}

if let Some(resource) = qjson
Expand All @@ -441,15 +442,25 @@ impl PartialRequestArgs {
if let Some(context) = qjson
.context
.map(|json| {
Context::from_json_value(json.clone(), None)
.wrap_err_with(|| format!("fail to convert context json {json} to Context"))
Context::from_json_value(
json.clone(),
schema.and_then(|s| Some((s, action.as_ref()?))),
)
.wrap_err_with(|| format!("fail to convert context json {json} to Context"))
})
.transpose()?
{
builder = builder.context(context);
}

Ok(builder.build())
if let Some(schema) = schema {
let builder_schema = builder.schema(schema);
builder_schema
.build()
.wrap_err_with(|| format!("failed to build request with validation"))
adpaco-aws marked this conversation as resolved.
Show resolved Hide resolved
} else {
Ok(builder.build())
}
}
}

Expand Down Expand Up @@ -573,6 +584,12 @@ pub struct PartiallyAuthorizeArgs {
/// Policies args (incorporated by reference)
#[command(flatten)]
pub policies: PoliciesArgs,
/// Schema args (incorporated by reference)
///
/// Used to populate the store with action entities and for schema-based
/// parsing of entity hierarchy, if present
#[command(flatten)]
pub schema: OptionalSchemaArgs,
/// File containing JSON representation of the Cedar entity hierarchy
#[arg(long = "entities", value_name = "FILE")]
pub entities_file: String,
Expand Down Expand Up @@ -1320,6 +1337,7 @@ pub fn partial_authorize(args: &PartiallyAuthorizeArgs) -> CedarExitCode {
&args.request,
&args.policies,
&args.entities_file,
&args.schema,
args.timing,
);
match ans {
Expand Down Expand Up @@ -1563,6 +1581,7 @@ fn execute_partial_request(
request: &PartialRequestArgs,
policies: &PoliciesArgs,
entities_filename: impl AsRef<Path>,
schema: &OptionalSchemaArgs,
compute_duration: bool,
) -> Result<PartialResponse, Vec<Report>> {
let mut errs = vec![];
Expand All @@ -1573,14 +1592,21 @@ fn execute_partial_request(
PolicySet::new()
}
};
let entities = match load_entities(entities_filename, None) {
let schema = match schema.get_schema() {
Ok(opt) => opt,
Err(e) => {
errs.push(e);
None
}
};
let entities = match load_entities(entities_filename, schema.as_ref()) {
Ok(entities) => entities,
Err(e) => {
errs.push(e);
Entities::empty()
}
};
match request.get_request() {
match request.get_request(schema.as_ref()) {
Ok(request) if errs.is_empty() => {
let authorizer = Authorizer::new();
let auth_start = Instant::now();
Expand Down
Loading