Skip to main content

alibi_core/store/stateless/
roles.rs

1use super::*;
2
3fn selected(
4    row: &OrganizationRole,
5    organization_id: &str,
6    selector: &OrganizationRoleSelector,
7) -> bool {
8    row.organization_id == organization_id
9        && match selector {
10            OrganizationRoleSelector::Id(id) => row.id == *id,
11            OrganizationRoleSelector::Name(name) => row.role == *name,
12        }
13}
14#[async_trait]
15impl OrganizationRoleStore for StatelessStore {
16    async fn create_organization_role(
17        &self,
18        data: CreateOrganizationRole,
19    ) -> AuthResult<OrganizationRole> {
20        let row = OrganizationRole {
21            id: uuid::Uuid::new_v4().to_string(),
22            organization_id: data.organization_id,
23            role: data.role,
24            permission: serde_json::to_string(&data.permission)?.into(),
25            created_at: Utc::now(),
26            updated_at: None,
27        };
28        drop(
29            self.organization_state()?
30                .roles
31                .insert(row.id.clone(), row.clone()),
32        );
33        Ok(row)
34    }
35    async fn get_organization_role(
36        &self,
37        org: &str,
38        selector: &OrganizationRoleSelector,
39    ) -> AuthResult<Option<OrganizationRole>> {
40        Ok(self
41            .organization_state()?
42            .roles
43            .values()
44            .find(|row| selected(row, org, selector))
45            .cloned())
46    }
47    async fn list_organization_roles(&self, org: &str) -> AuthResult<Vec<OrganizationRole>> {
48        Ok(self
49            .organization_state()?
50            .roles
51            .values()
52            .filter(|row| row.organization_id == org)
53            .take(self.find_many_limit)
54            .cloned()
55            .collect())
56    }
57    async fn count_organization_roles(&self, org: &str) -> AuthResult<usize> {
58        Ok(self
59            .organization_state()?
60            .roles
61            .values()
62            .filter(|row| row.organization_id == org)
63            .count())
64    }
65    async fn has_organization_role_members(&self, org: &str, role: &str) -> AuthResult<bool> {
66        Ok(self
67            .organization_state()?
68            .members
69            .values()
70            .filter(|row| row.organization_id == org && row.role.contains(role))
71            .take(self.find_many_limit)
72            .any(|row| row.role.split(',').map(str::trim).any(|part| part == role)))
73    }
74    async fn update_organization_role(
75        &self,
76        org: &str,
77        selector: &OrganizationRoleSelector,
78        update: UpdateOrganizationRole,
79    ) -> AuthResult<OrganizationRole> {
80        let permission = update
81            .permission
82            .map(|p| serde_json::to_string(&p))
83            .transpose()?;
84        let mut state = self.organization_state()?;
85        let mut first = None;
86        let now = Utc::now();
87        // Source update applies the literal patch to every selector match,
88        // returning the first row. Names need not be unique in a memory adapter.
89        for row in state
90            .roles
91            .values_mut()
92            .filter(|row| selected(row, org, selector))
93        {
94            if let Some(role) = &update.role {
95                row.role.clone_from(role);
96            }
97            if let Some(permission) = &permission {
98                row.permission = permission.clone().into();
99            }
100            row.updated_at = Some(now);
101            if first.is_none() {
102                first = Some(row.clone());
103            }
104        }
105        first.ok_or_else(|| AuthError::bad_request("Role not found"))
106    }
107    async fn delete_organization_role(
108        &self,
109        org: &str,
110        selector: &OrganizationRoleSelector,
111    ) -> AuthResult<bool> {
112        let mut state = self.organization_state()?;
113        let before = state.roles.len();
114        state.roles.retain(|_, row| !selected(row, org, selector));
115        Ok(before != state.roles.len())
116    }
117}