scuffle_cedar_policy/
traits.rs

1use crate::entity_type_name::EntityTypeName;
2use crate::{CedarActionRequestError, Entity, EntityUid};
3
4/// A type which can be used as a CedarId
5pub trait CedarId {
6    /// Convert self into a [smol_str::SmolStr]
7    fn into_smol_string(self) -> smol_str::SmolStr;
8}
9
10impl CedarId for smol_str::SmolStr {
11    fn into_smol_string(self) -> smol_str::SmolStr {
12        self
13    }
14}
15
16impl CedarId for String {
17    fn into_smol_string(self) -> smol_str::SmolStr {
18        self.into()
19    }
20}
21
22/// A trait defining an entity.
23pub trait CedarEntity {
24    /// Entities can have tags attached to them.
25    /// Not all entities have tags and if your entity does not have tag you should use the [crate::NoTag] type.
26    type TagType: serde::Serialize;
27    /// The id type for this entity.
28    type Id: CedarId;
29    /// The attributes for this entity. Normally this is [`Self`].
30    type Attrs: serde::Serialize;
31
32    /// The full qualified cedar name of this entity type.
33    const TYPE_NAME: EntityTypeName;
34
35    /// The parsed type name for this entity.
36    fn entity_type_name() -> &'static cedar_policy::EntityTypeName;
37}
38
39/// A special trait for enum style entities.
40pub trait CedarEnumEntity: CedarEntity<Id = Self, Attrs = crate::NoAttributes> {
41    /// Convert an enum variant into an entity.
42    fn into_entity(self) -> Entity<Self>
43    where
44        Self: Sized;
45}
46
47/// A trait defining a relationship between a cedar action its principal and resource.
48pub trait CedarAction<Principal, Resource>: CedarActionEntity {
49    /// The context used by this action.
50    /// Not all actions have contexts and if your action does not have a context you should use the [crate::EmptyContext] type.
51    type Context: serde::Serialize;
52
53    /// Construct a [cedar_policy::Request] from this action.
54    fn request(
55        principal: EntityUid<Principal>,
56        resource: EntityUid<Resource>,
57        ctx: &Self::Context,
58        schema: Option<&cedar_policy::Schema>,
59    ) -> Result<cedar_policy::Request, CedarActionRequestError>
60    where
61        Principal: CedarEntity,
62        Resource: CedarEntity,
63    {
64        let ctx_json = serde_json::to_value(ctx)?;
65        let a_euid = Self::action_entity_uid();
66        let context = cedar_policy::Context::from_json_value(ctx_json, schema.map(|s| (s, a_euid)))?;
67        Ok(cedar_policy::Request::new(
68            principal.into(),
69            a_euid.clone(),
70            resource.into(),
71            context,
72            schema,
73        )?)
74    }
75}
76
77/// A trait which defines a action entity for a specific type.
78pub trait CedarActionEntity {
79    /// The entity uid for this action.
80    fn action_entity_uid() -> &'static cedar_policy::EntityUid;
81}
82
83/// A trait defining a relationship between two cedar entities or two cedar actions.
84/// This is used to construct entity parents or action groups.
85pub trait CedarChild<Parent> {}