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