alibi_core/store/contracts/
organization.rs1use super::*;
2#[derive(Debug, Clone, Default)]
4pub struct ListOrganizationMembersParams {
5 pub organization_id: String,
7 pub limit: Option<usize>,
9 pub offset: Option<usize>,
11 pub sort_by: Option<String>,
13 pub sort_direction: Option<String>,
15 pub filter_field: Option<String>,
17 pub filter_value: Option<String>,
19 pub filter_operator: Option<String>,
21}
22
23#[derive(Debug, Clone, Default)]
26pub struct MemberPageQuery {
27 pub organization_id: String,
28 pub limit: Option<f64>,
29 pub offset: Option<f64>,
30 pub sort_by: Option<String>,
31 pub sort_direction: Option<String>,
32 pub filter_field: Option<String>,
33 pub filter_value: Option<String>,
34 pub filter_operator: Option<String>,
35}
36
37#[async_trait]
38pub trait OrganizationStore: Send + Sync {
39 async fn create_organization(&self, org: CreateOrganization) -> AuthResult<Organization>;
40 async fn get_organization_by_id(&self, id: &str) -> AuthResult<Option<Organization>>;
41 async fn get_organization_by_slug(&self, slug: &str) -> AuthResult<Option<Organization>>;
42 async fn list_organizations_by_ids(&self, ids: &[String]) -> AuthResult<Vec<Organization>>;
47 async fn update_organization(
48 &self,
49 id: &str,
50 update: UpdateOrganization,
51 ) -> AuthResult<Organization>;
52 async fn patch_organization_if_present(
59 &self,
60 _id: &str,
61 _update: UpdateOrganization,
62 ) -> AuthResult<Option<Organization>> {
63 Err(AuthError::NotImplemented(
64 "Organization patches are not supported by this store".into(),
65 ))
66 }
67 async fn update_organization_if_present(
71 &self,
72 _id: &str,
73 _update: UpdateOrganization,
74 ) -> AuthResult<Option<Organization>> {
75 Err(AuthError::NotImplemented(
76 "Optional organization updates are not supported by this store".into(),
77 ))
78 }
79 async fn delete_organization(&self, id: &str) -> AuthResult<()>;
83 async fn list_user_organizations(&self, user_id: &str) -> AuthResult<Vec<Organization>>;
84}
85
86#[async_trait]
87pub trait MemberStore: Send + Sync {
88 async fn create_member(&self, member: CreateMember) -> AuthResult<Member>;
89 async fn get_member(&self, organization_id: &str, user_id: &str) -> AuthResult<Option<Member>>;
90 async fn get_member_by_id(&self, id: &str) -> AuthResult<Option<Member>>;
91 async fn update_member_role(&self, member_id: &str, role: &str) -> AuthResult<Member>;
92 async fn update_member_role_if_present(
95 &self,
96 _member_id: &str,
97 _role: &str,
98 ) -> AuthResult<Option<Member>> {
99 Err(AuthError::NotImplemented(
100 "Optional member role updates are not supported by this store".into(),
101 ))
102 }
103 async fn delete_member(&self, member_id: &str) -> AuthResult<()>;
104 async fn delete_member_with_context(
109 &self,
110 _member_id: &str,
111 _organization_id: &str,
112 _user_id: &str,
113 _remove_team_members: bool,
114 ) -> AuthResult<()> {
115 Err(AuthError::NotImplemented(
116 "Contextual member deletion is not supported by this store".into(),
117 ))
118 }
119 async fn list_organization_members_page(
122 &self,
123 _organization_id: &str,
124 _limit: usize,
125 ) -> AuthResult<Vec<Member>> {
126 Err(AuthError::NotImplemented(
127 "Unsorted member pages are not supported by this store".into(),
128 ))
129 }
130 async fn list_organization_members(&self, org_id: &str) -> AuthResult<Vec<Member>>;
131 async fn query_organization_members(
134 &self,
135 params: &ListOrganizationMembersParams,
136 ) -> AuthResult<(Vec<Member>, usize)>;
137 async fn query_organization_members_page(
139 &self,
140 _params: &MemberPageQuery,
141 ) -> AuthResult<(Vec<Member>, usize)> {
142 Err(AuthError::NotImplemented(
143 "Raw numeric member pages are not supported by this store".into(),
144 ))
145 }
146 async fn count_organization_members(&self, org_id: &str) -> AuthResult<i64>;
147 async fn count_organization_owners(&self, org_id: &str) -> AuthResult<i64>;
148}
149
150#[derive(Debug, Clone, Default, PartialEq, Eq)]
153pub struct InvitationCreateOptions {
154 pub id: Option<String>,
155 pub status: Option<InvitationStatus>,
156 pub created_at: Option<chrono::DateTime<chrono::Utc>>,
157}
158
159#[async_trait]
160pub trait InvitationStore: Send + Sync {
161 async fn create_invitation_with_options(
162 &self,
163 invitation: CreateInvitation,
164 options: InvitationCreateOptions,
165 ) -> AuthResult<Invitation> {
166 if options == InvitationCreateOptions::default() {
167 self.create_invitation(invitation).await
168 } else {
169 Err(AuthError::NotImplemented(
170 "Invitation creation overrides are not supported by this store".into(),
171 ))
172 }
173 }
174
175 async fn pending_invitation_page(
177 &self,
178 _org_id: &str,
179 _email: Option<&str>,
180 ) -> AuthResult<Vec<Invitation>> {
181 Err(AuthError::NotImplemented(
182 "Pending invitation pages are not supported by this store".into(),
183 ))
184 }
185 async fn update_invitation_expiry(
187 &self,
188 _id: &str,
189 _expires_at: chrono::DateTime<chrono::Utc>,
190 ) -> AuthResult<Invitation> {
191 Err(AuthError::NotImplemented(
192 "Invitation expiry updates are not supported by this store".into(),
193 ))
194 }
195
196 async fn create_invitation(&self, invitation: CreateInvitation) -> AuthResult<Invitation>;
197 async fn get_invitation_by_id(&self, id: &str) -> AuthResult<Option<Invitation>>;
198 async fn get_pending_invitation(
199 &self,
200 org_id: &str,
201 email: &str,
202 ) -> AuthResult<Option<Invitation>>;
203 async fn update_invitation_status(
204 &self,
205 id: &str,
206 status: InvitationStatus,
207 ) -> AuthResult<Invitation>;
208 async fn update_invitation_status_if_status(
212 &self,
213 _id: &str,
214 _expected: InvitationStatus,
215 _status: InvitationStatus,
216 ) -> AuthResult<Option<Invitation>> {
217 Err(AuthError::NotImplemented(
218 "Conditional invitation updates are not supported by this store".into(),
219 ))
220 }
221 async fn list_organization_invitations(&self, org_id: &str) -> AuthResult<Vec<Invitation>>;
222 async fn count_pending_organization_invitations(&self, org_id: &str) -> AuthResult<i64>;
224 async fn list_user_invitations(&self, email: &str) -> AuthResult<Vec<Invitation>>;
225 async fn accept_invitation_with_teams(
227 &self,
228 _invitation_id: &str,
229 _user_id: &str,
230 _session_token: &str,
231 _team_limits: &[(String, Option<f64>)],
232 _membership_limit: Option<usize>,
233 ) -> AuthResult<Option<(Invitation, Member)>> {
234 Err(AuthError::NotImplemented(
235 "Atomic invitation acceptance is not supported by this store".to_owned(),
236 ))
237 }
238 async fn update_invitation_team_ids(
239 &self,
240 _id: &str,
241 _team_ids: Option<String>,
242 ) -> AuthResult<Invitation> {
243 Err(AuthError::NotImplemented(
244 "Invitation team updates are not supported by this store".to_owned(),
245 ))
246 }
247}