surrealdb_core/iam/policies/
mod.rs1use cedar_policy::{Authorizer, Context, Decision, Entities, Entity, EntityUid, Request, Response};
2
3mod policy_set;
4
5use policy_set::*;
6
7use crate::iam::{Action, Actor, Resource};
8
9pub fn is_allowed(
11 actor: &Actor,
12 action: &Action,
13 resource: &Resource,
14 context: Context,
15) -> (bool, Response) {
16 _is_allowed(
17 Some(actor.into()),
18 Some(action.into()),
19 Some(resource.into()),
20 Entities::from_entities(_get_entities(Some(actor), Some(resource))).unwrap(),
21 context,
22 )
23}
24
25fn _get_entities(actor: Option<&Actor>, resource: Option<&Resource>) -> Vec<Entity> {
26 let mut entities = Vec::new();
27 if let Some(actor) = actor {
28 entities.extend(actor.cedar_entities());
29 }
30 if let Some(resource) = resource {
31 entities.extend(resource.cedar_entities());
32 }
33 entities
34}
35
36fn _is_allowed(
37 actor: Option<EntityUid>,
38 action: Option<EntityUid>,
39 resource: Option<EntityUid>,
40 entities: Entities,
41 context: Context,
42) -> (bool, Response) {
43 let policy_set = POLICY_SET.to_owned();
44
45 let authorizer = Authorizer::new();
46
47 let req = Request::new(actor, action, resource, context);
48
49 let res = authorizer.is_authorized(&req, &policy_set, &entities);
50
51 (res.decision() == Decision::Allow, res)
52}
53
54#[cfg(test)]
55mod tests {
56 use cedar_policy::{ValidationMode, ValidationResult, Validator};
57
58 use crate::iam::{default_schema, entities::Level, ResourceKind, Role};
59
60 use super::*;
61
62 #[test]
63 fn validate_policy_set() {
64 let validator = Validator::new(default_schema());
65 let result = Validator::validate(&validator, &POLICY_SET, ValidationMode::default());
66
67 if !ValidationResult::validation_passed(&result) {
68 let e = ValidationResult::validation_errors(&result);
69 for err in e {
70 println!("{}", err);
71 }
72 panic!("Policy set validation failed");
73 }
74 }
75
76 #[test]
77 fn test_is_allowed() {
78 let actor = Actor::new("test".into(), vec![Role::Viewer], Level::Root);
80 let res = ResourceKind::Namespace.on_root();
81
82 let (allowed, _) = is_allowed(&actor, &Action::View, &res, Context::empty());
83 assert!(allowed);
84
85 let actor = Actor::new(
87 "test".into(),
88 vec![Role::Viewer],
89 Level::Database("test".into(), "test".into()),
90 );
91 let res = ResourceKind::Namespace.on_root();
92
93 let (allowed, _) = is_allowed(&actor, &Action::View, &res, Context::empty());
94 assert!(!allowed);
95 }
96}