From ed6f000cac948aca821172e93e41f01ef0c037d8 Mon Sep 17 00:00:00 2001 From: Kesha Hietala Date: Tue, 4 Jun 2024 10:22:39 -0400 Subject: [PATCH] FFI nits (#837) Signed-off-by: Kesha Hietala --- cedar-policy-core/src/authorizer.rs | 1 + cedar-policy-core/src/jsonvalue.rs | 4 + cedar-policy/src/api.rs | 6 +- cedar-policy/src/ffi/is_authorized.rs | 37 ++++----- cedar-policy/src/ffi/utils.rs | 8 +- cedar-policy/src/ffi/validate.rs | 86 ++++++++++---------- cedar-testing/src/cedar_test_impl.rs | 12 +-- cedar-testing/src/integration_testing.rs | 35 ++++---- cedar-testing/tests/cedar-policy-cli/main.rs | 2 +- 9 files changed, 102 insertions(+), 89 deletions(-) diff --git a/cedar-policy-core/src/authorizer.rs b/cedar-policy-core/src/authorizer.rs index b794d5e82..82c3cb82d 100644 --- a/cedar-policy-core/src/authorizer.rs +++ b/cedar-policy-core/src/authorizer.rs @@ -652,6 +652,7 @@ impl Response { #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)] #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))] +#[serde(rename_all = "camelCase")] pub enum Decision { /// The `Authorizer` determined that the request should be allowed Allow, diff --git a/cedar-policy-core/src/jsonvalue.rs b/cedar-policy-core/src/jsonvalue.rs index 57e4709c6..d3d0bed57 100644 --- a/cedar-policy-core/src/jsonvalue.rs +++ b/cedar-policy-core/src/jsonvalue.rs @@ -22,6 +22,10 @@ use serde::{Deserialize, Serialize}; /// Wrapper around `serde_json::Value`, with a different `Deserialize` /// implementation, such that duplicate keys in JSON objects (maps/records) are /// not allowed (result in an error). +// +// CAUTION: this type is publicly exported in `cedar-policy`. +// Don't make fields `pub`, don't make breaking changes, and use caution +// when adding public methods. #[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct JsonValueWithNoDuplicateKeys(serde_json::Value); diff --git a/cedar-policy/src/api.rs b/cedar-policy/src/api.rs index 947c563cb..1f2dd1f25 100644 --- a/cedar-policy/src/api.rs +++ b/cedar-policy/src/api.rs @@ -48,6 +48,7 @@ use cedar_policy_validator::RequestValidationError; // this type is unsuitable f use itertools::{Either, Itertools}; use miette::Diagnostic; use ref_cast::RefCast; +use serde::{Deserialize, Serialize}; use smol_str::SmolStr; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::io::Read; @@ -1165,7 +1166,10 @@ impl From for Response { } /// Used to select how a policy will be validated. -#[derive(Default, Eq, PartialEq, Copy, Clone, Debug)] +#[derive(Default, Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "wasm", derive(tsify::Tsify))] +#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))] +#[serde(rename_all = "camelCase")] #[non_exhaustive] pub enum ValidationMode { /// Validate that policies do not contain any type errors, and additionally diff --git a/cedar-policy/src/ffi/is_authorized.rs b/cedar-policy/src/ffi/is_authorized.rs index 80bb388f1..135b1ca5a 100644 --- a/cedar-policy/src/ffi/is_authorized.rs +++ b/cedar-policy/src/ffi/is_authorized.rs @@ -17,17 +17,15 @@ //! This module contains the `is_authorized` entry points that other language //! FFIs can call #![allow(clippy::module_name_repetitions)] -use super::utils::{DetailedError, PolicySet, Schema, WithWarnings}; +use super::utils::{DetailedError, JsonValueWithNoDuplicateKeys, PolicySet, Schema, WithWarnings}; use crate::{ Authorizer, Context, Decision, Entities, EntityId, EntityTypeName, EntityUid, PolicyId, Request, SlotId, }; -use cedar_policy_core::jsonvalue::JsonValueWithNoDuplicateKeys; use itertools::Itertools; use miette::{miette, Diagnostic, WrapErr}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, MapPreventDuplicates}; -use smol_str::{SmolStr, ToSmolStr}; use std::collections::{HashMap, HashSet}; #[cfg(feature = "partial-eval")] use std::convert::Infallible; @@ -154,7 +152,7 @@ pub struct Response { #[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))] #[serde(rename_all = "camelCase")] pub struct Diagnostics { - /// `PolicyId`s of the policies that contributed to the decision. + /// Ids of the policies that contributed to the decision. /// If no policies applied to the request, this set will be empty. #[cfg_attr(feature = "wasm", tsify(type = "Set"))] reason: HashSet, @@ -225,7 +223,8 @@ impl Diagnostics { #[serde(rename_all = "camelCase")] pub struct AuthorizationError { /// Id of the policy where the error (or warning) occurred - pub policy_id: SmolStr, + #[cfg_attr(feature = "wasm", tsify(type = "string"))] + pub policy_id: PolicyId, /// Error (or warning). /// You can look at the `severity` field to see whether it is actually an /// error or a warning. @@ -235,14 +234,14 @@ pub struct AuthorizationError { impl AuthorizationError { /// Create an `AuthorizationError` from a policy ID and any `miette` error pub fn new( - policy_id: impl Into, + policy_id: impl Into, error: impl miette::Diagnostic + Send + Sync + 'static, ) -> Self { Self::new_from_report(policy_id, miette::Report::new(error)) } /// Create an `AuthorizationError` from a policy ID and a `miette::Report` - pub fn new_from_report(policy_id: impl Into, report: miette::Report) -> Self { + pub fn new_from_report(policy_id: impl Into, report: miette::Report) -> Self { Self { policy_id: policy_id.into(), error: report.into(), @@ -254,7 +253,7 @@ impl From for AuthorizationError { fn from(e: crate::AuthorizationError) -> Self { match e { crate::AuthorizationError::PolicyEvaluationError(e) => { - Self::new(e.id().to_smolstr(), e.into_inner()) + Self::new(e.id().clone(), e.into_inner()) } } } @@ -280,7 +279,7 @@ pub struct ResidualResponse { errored: HashSet, may_be_determining: HashSet, must_be_determining: HashSet, - residuals: HashMap, + residuals: HashMap, nontrivial_residuals: HashSet, } @@ -312,22 +311,22 @@ impl ResidualResponse { } /// (Borrowed) Iterator over the set of residual policies - pub fn residuals(&self) -> impl Iterator { + pub fn residuals(&self) -> impl Iterator { self.residuals.values() } /// (Owned) Iterator over the set of residual policies - pub fn into_residuals(self) -> impl Iterator { + pub fn into_residuals(self) -> impl Iterator { self.residuals.into_values() } - /// Get the residual policy for a specified [`PolicyId`] if it exists - pub fn residual(&self, p: &PolicyId) -> Option<&serde_json::Value> { + /// Get the residual policy for a specified id if it exists + pub fn residual(&self, p: &PolicyId) -> Option<&JsonValueWithNoDuplicateKeys> { self.residuals.get(p) } /// (Borrowed) Iterator over the set of non-trivial residual policies - pub fn nontrivial_residuals(&self) -> impl Iterator { + pub fn nontrivial_residuals(&self) -> impl Iterator { self.residuals.iter().filter_map(|(id, policy)| { if self.nontrivial_residuals.contains(id) { Some(policy) @@ -369,7 +368,7 @@ impl TryFrom for ResidualResponse { .collect(), residuals: partial_response .all_residuals() - .map(|e| e.to_json().map(|json| (e.id().clone(), json))) + .map(|e| e.to_json().map(|json| (e.id().clone(), json.into()))) .collect::>()?, }) } @@ -467,7 +466,7 @@ pub struct AuthorizationCall { /// parsing of `context`, and not for request validation. /// If a schema is not provided, this option has no effect. #[serde(default = "constant_true")] - enable_request_validation: bool, + validate_request: bool, /// The slice containing entities and policies slice: RecvdSlice, } @@ -556,7 +555,7 @@ impl AuthorizationCall { action, resource, context, - if self.enable_request_validation { + if self.validate_request { schema.as_ref() } else { None @@ -625,7 +624,7 @@ impl AuthorizationCall { b = b.resource(resource); } b = b.context(context); - let request = if self.enable_request_validation { + let request = if self.validate_request { match schema.as_ref() { Some(schema_ref) => match b.schema(schema_ref).build() { Ok(req) => Some(req), @@ -1857,7 +1856,7 @@ mod test { "schema": { "human": "entity User, Photo; action view appliesTo { principal: User, resource: Photo };" }, - "enableRequestValidation": false, + "validateRequest": false, }); assert_is_authorized_json(good_call); diff --git a/cedar-policy/src/ffi/utils.rs b/cedar-policy/src/ffi/utils.rs index 0a4f29055..9e689d29f 100644 --- a/cedar-policy/src/ffi/utils.rs +++ b/cedar-policy/src/ffi/utils.rs @@ -16,11 +16,15 @@ //! Utility functions and types for JSON interface use crate::{Policy, SchemaWarning, Template}; -use cedar_policy_core::jsonvalue::JsonValueWithNoDuplicateKeys; use miette::WrapErr; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, str::FromStr}; +// Publicly expose the `JsonValueWithNoDuplicateKeys` type so that the +// `*_json_str` APIs will correctly error if the input JSON string contains +// duplicate keys. +pub use cedar_policy_core::jsonvalue::JsonValueWithNoDuplicateKeys; + #[cfg(feature = "wasm")] extern crate tsify; @@ -237,10 +241,8 @@ impl PolicySet { #[serde(rename_all = "camelCase")] pub enum Schema { /// Schema in the Cedar schema format. See - #[serde(rename = "human")] Human(String), /// Schema in Cedar's JSON schema format. See - #[serde(rename = "json")] Json(JsonValueWithNoDuplicateKeys), } diff --git a/cedar-policy/src/ffi/validate.rs b/cedar-policy/src/ffi/validate.rs index 59a306427..94bfaa0dd 100644 --- a/cedar-policy/src/ffi/validate.rs +++ b/cedar-policy/src/ffi/validate.rs @@ -18,9 +18,8 @@ //! call #![allow(clippy::module_name_repetitions)] use super::utils::{DetailedError, PolicySet, Schema, WithWarnings}; -use crate::{ValidationMode, Validator}; +use crate::{PolicyId, ValidationMode, Validator}; use serde::{Deserialize, Serialize}; -use smol_str::{SmolStr, ToSmolStr}; #[cfg(feature = "wasm")] extern crate tsify; @@ -32,22 +31,31 @@ extern crate tsify; pub fn validate(call: ValidationCall) -> ValidationAnswer { match call.get_components() { WithWarnings { - t: Ok((policies, schema)), + t: Ok((policies, schema, settings)), warnings, } => { + // if validation is not enabled, stop here + if !settings.enabled { + return ValidationAnswer::Success { + validation_errors: Vec::new(), + validation_warnings: Vec::new(), + other_warnings: warnings.into_iter().map(Into::into).collect(), + }; + } + // otherwise, call `Validator::validate` let validator = Validator::new(schema); let (validation_errors, validation_warnings) = validator - .validate(&policies, ValidationMode::default()) + .validate(&policies, settings.mode) .into_errors_and_warnings(); let validation_errors: Vec = validation_errors .map(|error| ValidationError { - policy_id: error.policy_id().to_smolstr(), + policy_id: error.policy_id().clone(), error: miette::Report::new(error).into(), }) .collect(); let validation_warnings: Vec = validation_warnings .map(|error| ValidationError { - policy_id: error.policy_id().to_smolstr(), + policy_id: error.policy_id().clone(), error: miette::Report::new(error).into(), }) .collect(); @@ -94,15 +102,17 @@ pub struct ValidationCall { #[cfg_attr(feature = "wasm", tsify(type = "Schema"))] pub schema: Schema, /// Policies to validate - pub policy_set: PolicySet, + pub policies: PolicySet, } impl ValidationCall { fn get_components( self, - ) -> WithWarnings>> { + ) -> WithWarnings< + Result<(crate::PolicySet, crate::Schema, ValidationSettings), Vec>, + > { let mut errs = vec![]; - let policies = match self.policy_set.parse(None) { + let policies = match self.policies.parse(None) { Ok(policies) => policies, Err(e) => { errs.extend(e); @@ -118,7 +128,7 @@ impl ValidationCall { }; match (errs.is_empty(), pair) { (true, Some((schema, warnings))) => WithWarnings { - t: Ok((policies, schema)), + t: Ok((policies, schema, self.validation_settings)), warnings: warnings.map(miette::Report::new).collect(), }, _ => WithWarnings { @@ -130,31 +140,24 @@ impl ValidationCall { } /// Configuration for the validation call -#[derive(Default, Serialize, Deserialize, Debug)] -#[cfg_attr(feature = "wasm", derive(tsify::Tsify))] -#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))] -#[serde(rename_all = "camelCase")] -pub struct ValidationSettings { - /// Whether validation is enabled - enabled: ValidationEnabled, -} - -/// String enum for validation mode #[derive(Serialize, Deserialize, Debug)] #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))] #[serde(rename_all = "camelCase")] -pub enum ValidationEnabled { - /// Setting for which policies will be validated against the schema - #[serde(alias = "regular")] - On, - /// Setting for which no validation will be done - Off, +pub struct ValidationSettings { + /// Whether validation is enabled. If this flag is set to `false`, then + /// only parsing is performed. The default value is `true`. + enabled: bool, + /// Used to control how a policy is validated. See comments on [`ValidationMode`]. + mode: ValidationMode, } -impl Default for ValidationEnabled { +impl Default for ValidationSettings { fn default() -> Self { - Self::On + Self { + enabled: true, + mode: ValidationMode::default(), + } } } @@ -165,7 +168,8 @@ impl Default for ValidationEnabled { #[serde(rename_all = "camelCase")] pub struct ValidationError { /// Id of the policy where the error (or warning) occurred - pub policy_id: SmolStr, + #[cfg_attr(feature = "wasm", tsify(type = "string"))] + pub policy_id: PolicyId, /// Error (or warning) itself. /// You can look at the `severity` field to see whether it is actually an /// error or a warning. @@ -253,7 +257,7 @@ mod test { let call = ValidationCall { validation_settings: ValidationSettings::default(), schema: Schema::Json(json!({}).into()), - policy_set: PolicySet::Map(HashMap::new()), + policies: PolicySet::Map(HashMap::new()), }; assert_validates_without_errors(serde_json::to_value(&call).unwrap()); @@ -261,14 +265,14 @@ mod test { let call = ValidationCall { validation_settings: ValidationSettings::default(), schema: Schema::Human(String::new()), - policy_set: PolicySet::Map(HashMap::new()), + policies: PolicySet::Map(HashMap::new()), }; assert_validates_without_errors(serde_json::to_value(&call).unwrap()); let call = json!({ "schema": { "json": {} }, - "policySet": {} + "policies": {} }); assert_validates_without_errors(call); @@ -320,7 +324,7 @@ mod test { } } }}}, - "policySet": { + "policies": { "policy0": "permit(principal in UserGroup::\"alice_friends\", action == Action::\"viewPhoto\", resource);" }}); @@ -334,7 +338,7 @@ mod test { "entityTypes": {}, "actions": {} }}}, - "policySet": { + "policies": { "policy0": "azfghbjknnhbud" } }); @@ -366,7 +370,7 @@ mod test { } } }}}, - "policySet": { + "policies": { "policy0": "permit(principal == Photo::\"photo.jpg\", action == Action::\"viewPhoto\", resource == User::\"alice\");", "policy1": "permit(principal == Photo::\"photo2.jpg\", action == Action::\"viewPhoto\", resource == User::\"alice2\");" }}); @@ -420,7 +424,7 @@ mod test { } } }}}, - "policySet": { + "policies": { "policy0": "permit(principal in UserGroup::\"alice_friends\", action == Action::\"viewPhoto\", resource);" } }); @@ -435,7 +439,7 @@ mod test { "entityTypes": {}, "actions": {} }}}, - "policySet": "azfghbjknnhbud" + "policies": "azfghbjknnhbud" }); assert_is_failure( @@ -465,7 +469,7 @@ mod test { } } }}}, - "policySet": "forbid(principal, action, resource);permit(principal == Photo::\"photo.jpg\", action == Action::\"viewPhoto\", resource == User::\"alice\");" + "policies": "forbid(principal, action, resource);permit(principal == Photo::\"photo.jpg\", action == Action::\"viewPhoto\", resource == User::\"alice\");" }); assert_validates_with_errors(json, 1); @@ -478,7 +482,7 @@ mod test { "entityTypes": {}, "actions": {} }}}, - "policySet": "permit(principal, action, resource);forbid" + "policies": "permit(principal, action, resource);forbid" }); assert_is_failure( @@ -501,7 +505,7 @@ mod test { "foo": { "entityTypes": {}, "actions": {} }, "foo": { "entityTypes": {}, "actions": {} } }}, - "policySet": "" + "policies": "" }"#; assert_matches!(validate_json_str(json), Err(e) => { @@ -513,7 +517,7 @@ mod test { fn test_validate_fails_on_duplicate_policy_id() { let json = r#"{ "schema": { "json": { "": { "entityTypes": {}, "actions": {} } } }, - "policySet": { + "policies": { "ID0": "permit(principal, action, resource);", "ID0": "permit(principal, action, resource);" } diff --git a/cedar-testing/src/cedar_test_impl.rs b/cedar-testing/src/cedar_test_impl.rs index f067b10a1..8c935d2c3 100644 --- a/cedar-testing/src/cedar_test_impl.rs +++ b/cedar-testing/src/cedar_test_impl.rs @@ -29,13 +29,13 @@ use cedar_policy_core::extensions::Extensions; use cedar_policy_validator::{ValidationMode, Validator, ValidatorSchema}; use miette::miette; use serde::{Deserialize, Serialize}; -use smol_str::ToSmolStr; use std::collections::HashMap; use std::collections::HashSet; use std::time::{Duration, Instant}; /// Return type for `CedarTestImplementation` methods #[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] pub enum TestResult { /// The request succeeded Success(T), @@ -67,11 +67,13 @@ impl TestResult { /// Simple wrapper around u128 to remind ourselves that timing info is in microseconds. #[derive(Debug, Deserialize)] +#[serde(transparent)] pub struct Micros(pub u128); /// Version of `Response` used for testing. Includes a /// `ffi::Response` and a map with timing information. #[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct TestResponse { /// Actual response pub response: ffi::Response, @@ -82,6 +84,7 @@ pub struct TestResponse { /// Version of `ValidationResult` used for testing. #[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct TestValidationResult { /// Validation errors pub errors: Vec, @@ -93,14 +96,11 @@ pub struct TestValidationResult { pub mod partial { use super::*; #[derive(Debug, Deserialize, PartialEq, Eq)] + #[serde(rename_all = "camelCase")] pub struct FlatPartialResponse { - #[serde(rename = "knownPermits")] pub known_permits: HashSet, - #[serde(rename = "knownForbids")] pub known_forbids: HashSet, - #[serde(rename = "determiningUnderApprox")] pub determining_under_approx: HashSet, - #[serde(rename = "determiningOverApprox")] pub determining_over_approx: HashSet, pub decision: Decision, } @@ -290,7 +290,7 @@ impl CedarTestImplementation for RustEngine { // `ErrorComparisonMode::PolicyIds` mode. let policy_id = e.id(); ffi::AuthorizationError::new_from_report( - policy_id.to_smolstr(), + policy_id.clone(), miette!("{policy_id}"), ) }) diff --git a/cedar-testing/src/integration_testing.rs b/cedar-testing/src/integration_testing.rs index a34f10f20..b676416c5 100644 --- a/cedar-testing/src/integration_testing.rs +++ b/cedar-testing/src/integration_testing.rs @@ -33,25 +33,24 @@ use std::{ collections::HashSet, env, path::{Path, PathBuf}, - str::FromStr, }; /// JSON representation of our integration test file format #[derive(Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] +#[serde(rename_all = "camelCase")] pub struct JsonTest { - /// Filename of the policies to use (in pure Cedar syntax) + /// Filename of the policy set (in Cedar syntax) pub policies: String, /// Filename of a JSON file representing the entity hierarchy pub entities: String, - /// Filename of a JSON file containing the schema. + /// Filename of the schema (in Cedar syntax) pub schema: String, /// Whether the given policies are expected to pass the validator with this /// schema, or not pub should_validate: bool, /// Requests to perform on that data, along with their expected results /// Alias for backwards compatibility - #[serde(alias = "queries")] pub requests: Vec, } @@ -59,9 +58,10 @@ pub struct JsonTest { /// in our integration test file format #[derive(Debug, Deserialize, Serialize, Clone)] #[serde(deny_unknown_fields)] +#[serde(rename_all = "camelCase")] pub struct JsonRequest { /// Description for the request - pub desc: String, + pub description: String, /// Principal for the request, in either explicit or implicit `__entity` form /// /// Examples: @@ -88,11 +88,10 @@ pub struct JsonRequest { pub context: JsonValueWithNoDuplicateKeys, /// Whether to enable request validation for this request #[serde(default = "constant_true")] - pub enable_request_validation: bool, + pub validate_request: bool, /// Expected decision for the request pub decision: Decision, /// Expected policies that led to the decision - #[serde(alias = "reasons")] pub reason: Vec, /// Expected policies that resulted in errors pub errors: Vec, @@ -210,7 +209,7 @@ pub fn parse_request_from_test( .map(|json| { let error_string = format!( "Failed to parse principal for request \"{}\" in {}", - json_request.desc, test_name + json_request.description, test_name ); parse_entity_uid(json, error_string) }) @@ -221,7 +220,7 @@ pub fn parse_request_from_test( .map(|json| { let error_string = format!( "Failed to parse action for request \"{}\" in {}", - json_request.desc, test_name + json_request.description, test_name ); parse_entity_uid(json, error_string) }) @@ -232,7 +231,7 @@ pub fn parse_request_from_test( .map(|json| { let error_string = format!( "Failed to parse resource for request \"{}\" in {}", - json_request.desc, test_name + json_request.description, test_name ); parse_entity_uid(json, error_string) }) @@ -241,7 +240,7 @@ pub fn parse_request_from_test( .unwrap_or_else(|| { panic!( "Unknown action {} for request \"{}\" in {}", - action, json_request.desc, test_name + action, json_request.description, test_name ) }); let context = @@ -250,7 +249,7 @@ pub fn parse_request_from_test( .unwrap_or_else(|e| { panic!( "Failed to parse context for request \"{}\" in {}: {e}", - json_request.desc, test_name + json_request.description, test_name ) }); Request::new( @@ -258,7 +257,7 @@ pub fn parse_request_from_test( (action, None), (resource, None), context, - if json_request.enable_request_validation { + if json_request.validate_request { Some(schema) } else { None @@ -268,7 +267,7 @@ pub fn parse_request_from_test( .unwrap_or_else(|e| { panic!( "error validating request \"{}\" in {}: {e}", - json_request.desc, test_name + json_request.description, test_name ) }) } @@ -320,7 +319,7 @@ pub fn perform_integration_test( response.response.decision(), json_request.decision, "test {test_name} failed for request \"{}\": unexpected decision", - &json_request.desc + &json_request.description ); // check reason let reason: HashSet = response.response.diagnostics().reason().cloned().collect(); @@ -328,7 +327,7 @@ pub fn perform_integration_test( reason, json_request.reason.into_iter().collect(), "test {test_name} failed for request \"{}\": unexpected reason", - &json_request.desc + &json_request.description ); // check errors, if applicable // for now, the integration tests only support the `PolicyIds` comparison mode @@ -340,13 +339,13 @@ pub fn perform_integration_test( .response .diagnostics() .errors() - .map(|err| PolicyId::from_str(&err.policy_id).unwrap()) + .map(|err| err.policy_id.clone()) .collect(); assert_eq!( errors, json_request.errors.into_iter().collect(), "test {test_name} failed for request \"{}\": unexpected errors", - &json_request.desc + &json_request.description ); } } diff --git a/cedar-testing/tests/cedar-policy-cli/main.rs b/cedar-testing/tests/cedar-policy-cli/main.rs index 0b1328c75..c6984a864 100644 --- a/cedar-testing/tests/cedar-policy-cli/main.rs +++ b/cedar-testing/tests/cedar-policy-cli/main.rs @@ -145,7 +145,7 @@ fn perform_integration_test_from_json(jsonfile: impl AsRef) { entity_args.push("--action".to_string()); entity_args.push(value_to_euid_string(s.into()).unwrap()); } - if !json_request.enable_request_validation { + if !json_request.validate_request { entity_args.push("--request-validation=false".to_string()); }