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

update for RFC 34 (cedar#430) #156

Merged
merged 6 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cedar
Submodule cedar updated 476 files
35 changes: 2 additions & 33 deletions cedar-drt/fuzz/fuzz_targets/abac-type-directed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ struct FuzzTargetInput {
/// generated entity slice
#[serde(skip)]
pub entities: Entities,
/// Should we pre-evaluate entity attributes
#[serde(skip)]
pub should_cache_entities: bool,
/// generated policy
pub policy: ABACPolicy,
/// the requests to try for this hierarchy and policy. We try 8 requests per
Expand Down Expand Up @@ -86,11 +83,9 @@ impl<'a> Arbitrary<'a> for FuzzTargetInput {
];
let all_entities = Entities::try_from(hierarchy).map_err(|_| Error::NotEnoughData)?;
let entities = drop_some_entities(all_entities, u)?;
let should_cache_entities = bool::arbitrary(u)?;
Ok(Self {
schema,
entities,
should_cache_entities,
policy,
requests,
})
Expand Down Expand Up @@ -148,36 +143,10 @@ fuzz_target!(|input: FuzzTargetInput| {
debug!("Schema: {}\n", input.schema.schemafile_string());
debug!("Policies: {policyset}\n");
debug!("Entities: {}\n", input.entities);
let original_entities = input.entities.clone();
let cached_entities = if input.should_cache_entities {
Some(input.entities.evaluate())
} else {
None
};
for request in input.requests.into_iter().map(Into::into) {
debug!("Request : {request}");
let (rust_res, total_dur) = time_function(|| {
run_auth_test(&java_def_engine, &request, &policyset, &original_entities)
});

if let Some(ref entities) = cached_entities {
match entities {
Ok(entities) => {
let (cached_rust_res, _total_dur) = time_function(|| {
run_auth_test(&java_def_engine, &request, &policyset, entities)
});
assert_eq!(rust_res, cached_rust_res);
}
Err(eval_er) => match &rust_res.diagnostics.errors[0] {
authorizer::AuthorizationError::AttributeEvaluationError(e) => {
assert_eq!(eval_er, e)
}
authorizer::AuthorizationError::PolicyEvaluationError { id, error } => {
panic!("Wrong error! Got policy eval error {id} {error}")
}
},
}
}
let (rust_res, total_dur) =
time_function(|| run_auth_test(&java_def_engine, request, &policyset, &input.entities));

info!("{}{}", TOTAL_MSG, total_dur.as_nanos());

Expand Down
2 changes: 1 addition & 1 deletion cedar-drt/fuzz/fuzz_targets/abac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ fuzz_target!(|input: FuzzTargetInput| {
.map(Into::into)
.collect::<Vec<_>>();
let mut responses = Vec::with_capacity(requests.len());
for request in &requests {
for request in requests.iter().cloned() {
debug!("Request: {request}");
let (ans, total_dur) =
time_function(|| run_auth_test(&java_def_engine, request, &policyset, &entities));
Expand Down
2 changes: 1 addition & 1 deletion cedar-drt/fuzz/fuzz_targets/eval-type-directed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ fuzz_target!(|input: FuzzTargetInput| {
debug!("Entities: {}\n", input.entities);
run_eval_test(
&java_def_engine,
&input.request.into(),
input.request.into(),
&input.expression,
&input.entities,
SETTINGS.enable_extensions,
Expand Down
10 changes: 5 additions & 5 deletions cedar-drt/fuzz/fuzz_targets/partial-eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ fuzz_target!(|input: FuzzTargetInput| {
return; // Don't waste time testing a policy w/ no unknowns
}

for q in input.requests.into_iter().map(Into::into) {
for q in input.requests.into_iter().map(ast::Request::from) {
let auth = Authorizer::new();
let ans = auth.is_authorized_core(&q, &policyset, &input.entities);
let ans = auth.is_authorized_core(q.clone(), &policyset, &input.entities);

match ans {
ResponseKind::FullyEvaluated(ans) => {
// Concrete evaluation should also succeed w/out any substitutions
let concrete_res = auth.is_authorized(&q, &policyset, &input.entities);
let concrete_res = auth.is_authorized(q, &policyset, &input.entities);
assert!(responses_equiv(ans, concrete_res));
}
ResponseKind::Partial(residual_set) => {
Expand All @@ -185,7 +185,7 @@ fuzz_target!(|input: FuzzTargetInput| {
}) {
subst_set.add(policy).unwrap();
}
let final_res = auth.is_authorized(&q, &subst_set, &input.entities);
let final_res = auth.is_authorized(q.clone(), &subst_set, &input.entities);

let mut concrete_set = PolicySet::new();
for policy in policyset.policies().map(|p: &Policy| {
Expand All @@ -194,7 +194,7 @@ fuzz_target!(|input: FuzzTargetInput| {
}) {
concrete_set.add(policy).unwrap();
}
let concrete_res = auth.is_authorized(&q, &concrete_set, &input.entities);
let concrete_res = auth.is_authorized(q, &concrete_set, &input.entities);
assert!(responses_equiv(concrete_res, final_res));
}
};
Expand Down
2 changes: 1 addition & 1 deletion cedar-drt/fuzz/fuzz_targets/rbac-authorizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fuzz_target!(|input: AuthorizerInputAbstractEvaluator| {
// the result of the call to is_authorized.
let java_def_engine =
JavaDefinitionalEngine::new().expect("failed to create definitional engine");
let res = run_auth_test(&java_def_engine, &request, &policyset, &entities);
let res = run_auth_test(&java_def_engine, request, &policyset, &entities);

// Check the following property: there should be an error reported iff we
// had either PermitError or ForbidError
Expand Down
4 changes: 3 additions & 1 deletion cedar-drt/fuzz/fuzz_targets/rbac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use cedar_drt::*;
use cedar_drt_inner::*;
use cedar_policy_core::ast;
use cedar_policy_core::entities::Entities;
use cedar_policy_core::extensions::Extensions;
use cedar_policy_generators::err::Result;
use cedar_policy_generators::hierarchy::{
AttributesMode, EntityUIDGenMode, HierarchyGenerator, HierarchyGeneratorMode,
Expand Down Expand Up @@ -140,6 +141,7 @@ impl<'a> Arbitrary<'a> for FuzzTargetInput {
0..=4,
),
u,
extensions: Extensions::all_available(),
}
.generate()?,
);
Expand Down Expand Up @@ -203,7 +205,7 @@ fuzz_target!(|input: FuzzTargetInput| {
for rbac_request in input.requests.into_iter() {
let request = ast::Request::from(rbac_request);
let (_, dur) =
time_function(|| run_auth_test(&java_def_engine, &request, &policyset, &entities));
time_function(|| run_auth_test(&java_def_engine, request, &policyset, &entities));
info!("{}{}", TOTAL_MSG, dur.as_nanos());
}
}
Expand Down
3 changes: 1 addition & 2 deletions cedar-drt/fuzz/fuzz_targets/validation-pbt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,10 @@ fuzz_target!(|input: FuzzTargetInput| {
for r in input.requests.into_iter() {
let q = ast::Request::from(r);
debug!("Request: {q}");
let ans = authorizer.is_authorized(&q, &policyset, &entities);
let ans = authorizer.is_authorized(q.clone(), &policyset, &entities);

let unexpected_errs = ans.diagnostics.errors.iter().filter_map(|error|
match error {
cedar_policy::AuthorizationError::AttributeEvaluationError(_) => None,
cedar_policy::AuthorizationError::PolicyEvaluationError { error, .. } => match error.error_kind() {
// Evaluation errors the validator should prevent.
cedar_policy::EvaluationErrorKind::UnspecifiedEntityAccess(_) |
Expand Down
24 changes: 18 additions & 6 deletions cedar-drt/fuzz/src/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
* limitations under the License.
*/

use cedar_policy_core::ast::{EntityUIDEntry, PolicyID, PolicySet, Request};
use cedar_policy_core::ast::{EntityUIDEntry, PolicyID, PolicySet, Request, RestrictedExpr};
use cedar_policy_core::authorizer::{Decision, Response};
use cedar_policy_core::entities::Entities;
use cedar_policy_generators::collections::HashMap;
use cedar_policy_validator::SchemaFragment;
use serde::Serialize;
use smol_str::SmolStr;
use std::io::Write;
use std::path::Path;

Expand Down Expand Up @@ -101,10 +102,21 @@ pub fn dump<'a>(
resource: dump_request_var(q.resource()),
context: q
.context()
.map(|ctxt| {
ctxt.iter()
.map(|(k, expr)| (k.to_string(), expr.to_natural_json().unwrap()))
.collect::<HashMap<_, _>>()
.map(|ctx| {
ctx.iter()
.map(|it| {
it.map(|(k, pval)| {
(
k.clone(),
RestrictedExpr::try_from(pval)
.unwrap()
.to_natural_json()
.unwrap(),
)
})
.collect::<HashMap<_, _>>()
})
.unwrap_or_default() // for purely-unknown Context, use empty map
})
.unwrap_or_default(),
decision: a.decision,
Expand Down Expand Up @@ -165,7 +177,7 @@ struct IntegrationRequest<'a> {
/// Resource
resource: Option<String>,
/// Context
context: HashMap<String, serde_json::Value>,
context: HashMap<SmolStr, serde_json::Value>,
/// Decision
decision: Decision,
/// Reasons
Expand Down
55 changes: 27 additions & 28 deletions cedar-drt/fuzz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ pub use prt::*;

use cedar_drt::{time_function, CedarTestImplementation, RUST_AUTH_MSG, RUST_VALIDATION_MSG};
use cedar_policy::frontend::is_authorized::InterfaceResponse;
use cedar_policy_core::ast::PolicySet;
use cedar_policy_core::ast::{self, Expr};
use cedar_policy_core::ast;
use cedar_policy_core::authorizer::{Authorizer, Diagnostics, Response};
use cedar_policy_core::entities::Entities;
use cedar_policy_core::evaluator::{EvaluationErrorKind, Evaluator};
Expand All @@ -36,8 +35,8 @@ use log::info;
/// evaluate and `request` and `entities` are used to populate the evaluator.
pub fn run_eval_test(
custom_impl: &impl CedarTestImplementation,
request: &ast::Request,
expr: &Expr,
request: ast::Request,
expr: &ast::Expr,
entities: &Entities,
enable_extensions: bool,
) {
Expand All @@ -46,10 +45,7 @@ pub fn run_eval_test(
} else {
Extensions::none()
};
let eval = match Evaluator::new(request, entities, &exts) {
Ok(e) => e,
Err(_) => return, // FOR NOW just ignore errors in the restricted exprs
};
let eval = Evaluator::new(request.clone(), entities, &exts);
let expected = match eval.interpret(expr, &std::collections::HashMap::default()) {
Ok(v) => Some(v),
Err(e) if matches!(e.error_kind(), EvaluationErrorKind::IntegerOverflow(_)) => {
Expand All @@ -68,13 +64,13 @@ pub fn run_eval_test(
/// the two agree on.
pub fn run_auth_test(
custom_impl: &impl CedarTestImplementation,
request: &ast::Request,
policies: &PolicySet,
request: ast::Request,
policies: &ast::PolicySet,
entities: &Entities,
) -> Response {
let authorizer = Authorizer::new();
let (rust_res, rust_auth_dur) =
time_function(|| authorizer.is_authorized(request, policies, entities));
time_function(|| authorizer.is_authorized(request.clone(), policies, entities));
info!("{}{}", RUST_AUTH_MSG, rust_auth_dur.as_nanos());

// For now, we ignore tests where cedar-policy returns an integer
Expand All @@ -92,14 +88,14 @@ pub fn run_auth_test(
// in case the caller wants to expect those.
let ret = rust_res.clone();

let definitional_res = custom_impl.is_authorized(request, policies, entities);
let definitional_res = custom_impl.is_authorized(request.clone(), policies, entities);
// For now, we expect never to receive errors from the definitional engine,
// and we otherwise ignore errors in the comparison.
assert_eq!(
definitional_res
.diagnostics()
.errors()
.map(|e| e.to_string())
.map(ToString::to_string)
.collect::<Vec<String>>(),
Vec::<String>::new()
);
Expand Down Expand Up @@ -127,7 +123,7 @@ pub fn run_auth_test(
pub fn run_val_test(
custom_impl: &impl CedarTestImplementation,
schema: ValidatorSchema,
policies: &PolicySet,
policies: &ast::PolicySet,
mode: ValidationMode,
) {
let validator = Validator::new(schema.clone());
Expand Down Expand Up @@ -177,7 +173,7 @@ pub fn run_val_test(
#[test]
fn test_run_auth_test() {
use cedar_drt::JavaDefinitionalEngine;
use cedar_policy_core::ast::{Entity, EntityUID, RestrictedExpr};
use cedar_policy_core::ast::{Entity, EntityUID, RequestSchemaAllPass, RestrictedExpr};
use cedar_policy_core::entities::{NoEntitiesSchema, TCComputation};
use smol_str::SmolStr;

Expand All @@ -197,8 +193,11 @@ fn test_run_auth_test() {
action,
resource,
Some(cedar_policy_core::ast::Context::empty()),
);
let mut policies = PolicySet::new();
None::<&RequestSchemaAllPass>,
Extensions::all_available(),
)
.unwrap();
let mut policies = ast::PolicySet::new();

let policy_string = r#"
permit(principal,action,resource) when
Expand All @@ -217,24 +216,24 @@ fn test_run_auth_test() {
.add(static_policy)
.expect("Adding static policy in Policy form should succeed");

let mut alice_attributes: std::collections::HashMap<SmolStr, RestrictedExpr> =
std::collections::HashMap::new();
alice_attributes.insert(
"foo".into(),
RestrictedExpr::val(cedar_policy_core::ast::Literal::Bool(true)),
);
let alice_attributes: std::collections::HashMap<SmolStr, RestrictedExpr> =
std::collections::HashMap::from_iter([(
"foo".into(),
RestrictedExpr::val(cedar_policy_core::ast::Literal::Bool(true)),
)]);
let entity_alice = Entity::new(
EntityUID::with_eid_and_type("User", "alice").unwrap(),
alice_attributes,
std::collections::HashSet::new(),
);

let entity_view = Entity::new(
&Extensions::all_available(),
)
.unwrap();
let entity_view = Entity::new_with_attr_partial_value(
EntityUID::with_eid_and_type("Action", "view").unwrap(),
std::collections::HashMap::new(),
std::collections::HashSet::new(),
);
let entity_vacation = Entity::new(
let entity_vacation = Entity::new_with_attr_partial_value(
EntityUID::with_eid_and_type("Photo", "vacation").unwrap(),
std::collections::HashMap::new(),
std::collections::HashSet::new(),
Expand All @@ -246,5 +245,5 @@ fn test_run_auth_test() {
Extensions::all_available(),
)
.unwrap();
run_auth_test(&java_def_engine, &query, &policies, &entities);
run_auth_test(&java_def_engine, query, &policies, &entities);
}
4 changes: 2 additions & 2 deletions cedar-drt/src/cedar_test_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub trait CedarTestImplementation {
/// Custom authorizer entry point.
fn is_authorized(
&self,
request: &Request,
request: Request,
policies: &PolicySet,
entities: &Entities,
) -> InterfaceResponse;
Expand All @@ -41,7 +41,7 @@ pub trait CedarTestImplementation {
/// expected due to errors.
fn interpret(
&self,
request: &Request,
request: Request,
entities: &Entities,
expr: &Expr,
expected: Option<Value>,
Expand Down
8 changes: 4 additions & 4 deletions cedar-drt/src/dafny_java_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,21 +396,21 @@ impl<'j> JavaDefinitionalEngine<'j> {
impl<'j> CedarTestImplementation for JavaDefinitionalEngine<'j> {
fn is_authorized(
&self,
request: &ast::Request,
request: ast::Request,
policies: &ast::PolicySet,
entities: &Entities,
) -> InterfaceResponse {
self.is_authorized(request, policies, entities)
self.is_authorized(&request, policies, entities)
}

fn interpret(
&self,
request: &ast::Request,
request: ast::Request,
entities: &Entities,
expr: &Expr,
expected: Option<Value>,
) -> bool {
self.eval(request, entities, expr, expected)
self.eval(&request, entities, expr, expected)
}

fn validate(
Expand Down
Loading