1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use std::collections::{HashMap, HashSet};
use cedar_policy::{Context, Entity, EntityUid, RestrictedExpression};
use crate::error::PolicyError;
/// Anything that can become a Cedar‐typed atom, e.g. `User::"alice"`,
/// `Action::"foo"`, `Group::"devs"`.
///
/// Types implementing this trait can produce their Cedar identity (`cedar_id`),
/// attributes, parent relationships, and context for evaluation.
pub trait CedarAtom {
/// The Cedar typename (“User”, “Action”, “Group”, etc)
fn cedar_type() -> &'static str;
/// Build a Cedar parent list for this atom, default is no parents.
#[allow(dead_code)]
fn cedar_parents(&self) -> HashSet<EntityUid> {
// Default: no parent type
HashSet::new()
}
/// Build an entity for this Cedar atom, e.g. `User::"alice"` or `Host::"flappa.example.com"`.
///
/// Public API: may be used by external consumers or future refactorings.
#[allow(dead_code)]
fn cedar_entity(&self) -> Result<Entity, PolicyError> {
let entity_uid = self.cedar_entity_uid()?;
let attrs = self.cedar_attr()?;
Ok(Entity::new(entity_uid, attrs, self.cedar_parents())?)
}
/// Build the attributes for this Cedar atom.
fn cedar_attr(&self) -> Result<HashMap<String, RestrictedExpression>, PolicyError> {
let res: HashMap<String, RestrictedExpression> = HashMap::new();
Ok(res)
}
/// Build an EntityUid for atomic principal / action / resource slots.
fn cedar_entity_uid(&self) -> Result<EntityUid, PolicyError> {
self.cedar_id()
.parse::<EntityUid>()
.map_err(|e| PolicyError::ParseError(e.to_string()))
}
/// Build the context for this Cedar atom, empty by default.
fn cedar_ctx(&self) -> Result<Context, PolicyError> {
Ok(Context::empty())
}
/// The ID string, fully qualified (e.g. `User::"alice"` or `DNS::Action::"create_host"`).
fn cedar_id(&self) -> String;
}