From 4f0dac764549bbd97551ae186beffa79c205fa89 Mon Sep 17 00:00:00 2001 From: Till Wegmueller Date: Sun, 8 Feb 2026 20:30:52 +0100 Subject: [PATCH] Fix formatting Signed-off-by: Till Wegmueller --- src/authz/condition.rs | 40 ++++++++++------------ src/authz/engine.rs | 75 ++++++++++++++++++++++++++---------------- src/authz/errors.rs | 4 ++- src/authz/loader.rs | 25 +++++++------- src/authz/policy.rs | 26 ++++++--------- src/authz/web.rs | 8 ++++- 6 files changed, 95 insertions(+), 83 deletions(-) diff --git a/src/authz/condition.rs b/src/authz/condition.rs index f49f57d..be8b589 100644 --- a/src/authz/condition.rs +++ b/src/authz/condition.rs @@ -67,16 +67,16 @@ enum Token { Dot, LParen, RParen, - Eq, // == - Ne, // != - Gt, // > - Lt, // < - Ge, // >= - Le, // <= - And, // && - Or, // || - Not, // ! - In, // in + Eq, // == + Ne, // != + Gt, // > + Lt, // < + Ge, // >= + Le, // <= + And, // && + Or, // || + Not, // ! + In, // in } fn tokenize(input: &str) -> Result, AuthzError> { @@ -476,7 +476,10 @@ fn eval_value(expr: &Expr, context: &Value) -> Result { )), } } - Expr::In { element, collection } => { + Expr::In { + element, + collection, + } => { let elem = eval_value(element, context)?; let coll = eval_value(collection, context)?; match coll { @@ -491,17 +494,13 @@ fn eval_value(expr: &Expr, context: &Value) -> Result { let r = eval_value(right, context)?; match op { BinOp::And => match (&l, &r) { - (EvalResult::Bool(a), EvalResult::Bool(b)) => { - Ok(EvalResult::Bool(*a && *b)) - } + (EvalResult::Bool(a), EvalResult::Bool(b)) => Ok(EvalResult::Bool(*a && *b)), _ => Err(AuthzError::InvalidCondition( "`&&` requires boolean operands".into(), )), }, BinOp::Or => match (&l, &r) { - (EvalResult::Bool(a), EvalResult::Bool(b)) => { - Ok(EvalResult::Bool(*a || *b)) - } + (EvalResult::Bool(a), EvalResult::Bool(b)) => Ok(EvalResult::Bool(*a || *b)), _ => Err(AuthzError::InvalidCondition( "`||` requires boolean operands".into(), )), @@ -591,9 +590,7 @@ mod tests { fn test_parse_boolean_and() { let expr = parse_condition("a > 1 && b < 2").unwrap(); match expr { - Expr::BinOp { - op: BinOp::And, .. - } => {} + Expr::BinOp { op: BinOp::And, .. } => {} _ => panic!("expected And"), } } @@ -657,8 +654,7 @@ mod tests { #[test] fn test_evaluate_boolean_and() { - let expr = - parse_condition("request.time.hour >= 9 && request.time.hour < 17").unwrap(); + let expr = parse_condition("request.time.hour >= 9 && request.time.hour < 17").unwrap(); let ctx = json!({ "request": { "time": { "hour": 14 } } }); assert!(evaluate(&expr, &ctx).unwrap()); diff --git a/src/authz/engine.rs b/src/authz/engine.rs index d101afe..29722d8 100644 --- a/src/authz/engine.rs +++ b/src/authz/engine.rs @@ -92,7 +92,10 @@ fn check_abac_rules( // Check if the principal matches any of the rule's principal patterns let principal_match = rule.principals.is_empty() - || rule.principals.iter().any(|p| matches_principal(principal, p, state)); + || rule + .principals + .iter() + .any(|p| matches_principal(principal, p, state)); if !principal_match { continue; @@ -323,9 +326,14 @@ mod tests { fn test_check_inherited_permission() { let state = make_vm_state(); // alice has vm_admin which includes vm_viewer -> vm:view_console - assert!( - check(&state, "user/alice", "vm:view_console", "vm/vm-123", &json!({})).unwrap() - ); + assert!(check( + &state, + "user/alice", + "vm:view_console", + "vm/vm-123", + &json!({}) + ) + .unwrap()); } #[test] @@ -341,9 +349,14 @@ mod tests { fn test_check_userset_membership() { let state = make_vm_state(); // bob is member of group/engineers, which has vm_viewer on vm/vm-456 - assert!( - check(&state, "user/bob", "vm:view_console", "vm/vm-456", &json!({})).unwrap() - ); + assert!(check( + &state, + "user/bob", + "vm:view_console", + "vm/vm-456", + &json!({}) + ) + .unwrap()); // but bob can't start vm-456 (only viewer) assert!(!check(&state, "user/bob", "vm:start", "vm/vm-456", &json!({})).unwrap()); } @@ -351,9 +364,7 @@ mod tests { #[test] fn test_check_unknown_permission() { let state = make_vm_state(); - assert!( - !check(&state, "user/alice", "vm:delete", "vm/vm-123", &json!({})).unwrap() - ); + assert!(!check(&state, "user/alice", "vm:delete", "vm/vm-123", &json!({})).unwrap()); } #[test] @@ -384,20 +395,16 @@ mod tests { effect: "allow".into(), permissions: vec!["invoice:view".into()], principals: vec!["group:finance".into()], - condition: Some( - "request.time.hour >= 9 && request.time.hour < 17".into(), - ), + condition: Some("request.time.hour >= 9 && request.time.hour < 17".into()), + }], + grants: vec![GrantTuple { + relation: "member".into(), + object_type: "group".into(), + object_id: "finance".into(), + subject_type: "user".into(), + subject_id: "carol".into(), + subject_relation: None, }], - grants: vec![ - GrantTuple { - relation: "member".into(), - object_type: "group".into(), - object_id: "finance".into(), - subject_type: "user".into(), - subject_id: "carol".into(), - subject_relation: None, - }, - ], }; let state = compile_policies(vec![parsed]).unwrap(); @@ -407,15 +414,25 @@ mod tests { // Carol is in finance, outside business hours -> denied let ctx_late = json!({ "request": { "time": { "hour": 22 } } }); - assert!( - !check(&state, "user/carol", "invoice:view", "invoice/inv-1", &ctx_late).unwrap() - ); + assert!(!check( + &state, + "user/carol", + "invoice:view", + "invoice/inv-1", + &ctx_late + ) + .unwrap()); // Dave is NOT in finance -> denied even during business hours let ctx_hours = json!({ "request": { "time": { "hour": 14 } } }); - assert!( - !check(&state, "user/dave", "invoice:view", "invoice/inv-1", &ctx_hours).unwrap() - ); + assert!(!check( + &state, + "user/dave", + "invoice:view", + "invoice/inv-1", + &ctx_hours + ) + .unwrap()); } #[test] diff --git a/src/authz/errors.rs b/src/authz/errors.rs index 91b678f..fe6961f 100644 --- a/src/authz/errors.rs +++ b/src/authz/errors.rs @@ -21,7 +21,9 @@ pub enum AuthzError { #[error("Invalid policy: {0}")] #[diagnostic( code(barycenter::authz::invalid_policy), - help("Each policy file must contain valid `resource`, `role`, `rule`, or `grant` KDL nodes") + help( + "Each policy file must contain valid `resource`, `role`, `rule`, or `grant` KDL nodes" + ) )] InvalidPolicy(String), diff --git a/src/authz/loader.rs b/src/authz/loader.rs index c541b19..4ea965a 100644 --- a/src/authz/loader.rs +++ b/src/authz/loader.rs @@ -32,12 +32,11 @@ pub fn load_policies(dir: &Path) -> Result { for entry in entries { let path = entry.path(); - let contents = std::fs::read_to_string(&path).map_err(|source| { - AuthzError::PolicyLoadError { + let contents = + std::fs::read_to_string(&path).map_err(|source| AuthzError::PolicyLoadError { path: path.display().to_string(), source, - } - })?; + })?; let parsed = parse_kdl_document(&contents)?; all_parsed.push(parsed); file_count += 1; @@ -214,16 +213,14 @@ mod tests { }, ], rules: vec![], - grants: vec![ - GrantTuple { - relation: "vm_admin".into(), - object_type: "vm".into(), - object_id: "vm-123".into(), - subject_type: "user".into(), - subject_id: "alice".into(), - subject_relation: None, - }, - ], + grants: vec![GrantTuple { + relation: "vm_admin".into(), + object_type: "vm".into(), + object_id: "vm-123".into(), + subject_type: "user".into(), + subject_id: "alice".into(), + subject_relation: None, + }], } } diff --git a/src/authz/policy.rs b/src/authz/policy.rs index d5c7ba2..4b9ba7c 100644 --- a/src/authz/policy.rs +++ b/src/authz/policy.rs @@ -135,23 +135,17 @@ pub fn parse_kdl_document(source: &str) -> Result { ) })?; - let on = node - .get("on") - .and_then(|v| v.as_string()) - .ok_or_else(|| { - AuthzError::InvalidGrant(format!( - "grant `{relation}` missing `on` property (e.g. on=\"vm/vm-123\")" - )) - })?; + let on = node.get("on").and_then(|v| v.as_string()).ok_or_else(|| { + AuthzError::InvalidGrant(format!( + "grant `{relation}` missing `on` property (e.g. on=\"vm/vm-123\")" + )) + })?; - let to = node - .get("to") - .and_then(|v| v.as_string()) - .ok_or_else(|| { - AuthzError::InvalidGrant(format!( - "grant `{relation}` missing `to` property (e.g. to=\"user/alice\")" - )) - })?; + let to = node.get("to").and_then(|v| v.as_string()).ok_or_else(|| { + AuthzError::InvalidGrant(format!( + "grant `{relation}` missing `to` property (e.g. to=\"user/alice\")" + )) + })?; let obj = ObjectRef::parse(on).ok_or_else(|| { AuthzError::InvalidGrant(format!( diff --git a/src/authz/web.rs b/src/authz/web.rs index dee9cff..88898bd 100644 --- a/src/authz/web.rs +++ b/src/authz/web.rs @@ -22,7 +22,13 @@ async fn handle_check( State(state): State>, Json(req): Json, ) -> impl IntoResponse { - match engine::check(&state, &req.principal, &req.permission, &req.resource, &req.context) { + match engine::check( + &state, + &req.principal, + &req.permission, + &req.resource, + &req.context, + ) { Ok(allowed) => Json(CheckResponse { allowed }).into_response(), Err(e) => e.into_response(), }