mirror of
https://github.com/CloudNebulaProject/barycenter.git
synced 2026-04-10 13:10:42 +00:00
Fix formatting
Signed-off-by: Till Wegmueller <toasterson@gmail.com>
This commit is contained in:
parent
df57dda960
commit
4f0dac7645
6 changed files with 95 additions and 83 deletions
|
|
@ -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<Vec<Token>, AuthzError> {
|
||||
|
|
@ -476,7 +476,10 @@ fn eval_value(expr: &Expr, context: &Value) -> Result<EvalResult, AuthzError> {
|
|||
)),
|
||||
}
|
||||
}
|
||||
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<EvalResult, AuthzError> {
|
|||
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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,11 @@ pub fn load_policies(dir: &Path) -> Result<AuthzState, AuthzError> {
|
|||
|
||||
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,
|
||||
}],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,23 +135,17 @@ pub fn parse_kdl_document(source: &str) -> Result<ParsedPolicy, AuthzError> {
|
|||
)
|
||||
})?;
|
||||
|
||||
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!(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,13 @@ async fn handle_check(
|
|||
State(state): State<Arc<AuthzState>>,
|
||||
Json(req): Json<CheckRequest>,
|
||||
) -> 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(),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue