scufflecloud_core_cedar/models/
organization.rs

1use core_db_types::models::{
2    Organization, OrganizationInvitation, OrganizationMember, Policy, Project, Role, ServiceAccount, ServiceAccountToken,
3};
4use core_traits::OptionExt;
5
6use crate::macros::{cedar_entity, cedar_entity_id};
7use crate::{CedarIdentifiable, EntityTypeName, JsonEntityUid, entity_type_name};
8
9cedar_entity!(Organization);
10
11cedar_entity!(Project);
12
13cedar_entity!(Policy);
14
15cedar_entity!(Role);
16
17impl crate::CedarIdentifiable for OrganizationMember {
18    const ENTITY_TYPE: EntityTypeName = entity_type_name!("OrganizationMember");
19
20    fn entity_id(&self) -> cedar_policy::EntityId {
21        cedar_policy::EntityId::new(format!(
22            "{}:{}",
23            self.organization_id.to_string_unprefixed(),
24            self.user_id.to_string_unprefixed()
25        ))
26    }
27}
28
29impl crate::CedarEntity for OrganizationMember {
30    async fn parents(&self, _: &impl core_traits::Global) -> Result<impl IntoIterator<Item = JsonEntityUid>, tonic::Status> {
31        Ok(std::iter::once(self.organization_id.entity_uid()))
32    }
33}
34
35cedar_entity_id!(ServiceAccount);
36
37impl crate::CedarEntity for ServiceAccount {
38    async fn parents(&self, _: &impl core_traits::Global) -> Result<impl IntoIterator<Item = JsonEntityUid>, tonic::Status> {
39        Ok(std::iter::once(self.organization_id.entity_uid()).chain(self.project_id.map(|id| id.entity_uid())))
40    }
41}
42
43cedar_entity!(ServiceAccountToken);
44
45cedar_entity_id!(OrganizationInvitation);
46
47impl crate::CedarEntity for OrganizationInvitation {
48    async fn additional_attributes(
49        &self,
50        global: &impl core_traits::Global,
51    ) -> Result<impl serde::Serialize, tonic::Status> {
52        #[derive(serde_derive::Serialize)]
53        struct AdditionalAttrs {
54            organization: Organization,
55        }
56
57        Ok(AdditionalAttrs {
58            organization: global
59                .organization_loader()
60                .load(self.organization_id)
61                .await
62                .ok()
63                .into_tonic_internal_err("failed to query organization")?
64                .into_tonic_not_found("organization not found")?,
65        })
66    }
67}