alibi_plugins/organization/hooks/
organization.rs1use crate::organization::types::CreatedOrganizationResponse;
2use alibi_core::AuthResult;
3use alibi_core::CreateMember;
4use alibi_core::CreateOrganization;
5use alibi_core::Member;
6use alibi_core::Organization;
7use alibi_core::UpdateOrganization;
8use alibi_core::utils::json::JsValue;
9use alibi_core::wire::UserView;
10use async_trait::async_trait;
11use indexmap::IndexMap;
12use serde_json::Map;
13use serde_json::Value;
14
15#[derive(Debug, Clone)]
17pub struct OrganizationDraftContext {
18 pub organization: CreateOrganization,
19 pub user: UserView,
20}
21
22#[derive(Debug, Clone)]
24pub struct OrganizationMemberDraftContext {
25 pub organization: Organization,
26 pub member: CreateMember,
27 pub user: UserView,
28}
29
30#[derive(Debug, Clone)]
33pub struct OrganizationCreatedContext {
34 pub organization: Organization,
35 pub member: Member,
36 pub user: UserView,
37}
38
39#[derive(Debug, Clone, Default)]
41pub struct OrganizationCreatePatch {
42 pub id: Option<String>,
43 pub name: Option<String>,
44 pub slug: Option<String>,
45 pub logo: Option<Option<String>>,
47 pub metadata: Option<Option<Map<String, Value>>>,
51}
52impl OrganizationCreatePatch {
53 pub(crate) fn apply(self, data: &mut CreateOrganization) {
54 if let Some(id) = self.id {
55 data.id = Some(id);
56 }
57 if let Some(name) = self.name {
58 data.name = name;
59 }
60 if let Some(slug) = self.slug {
61 data.slug = slug;
62 }
63 if let Some(logo) = self.logo {
64 data.logo = logo;
65 }
66 if let Some(metadata) = self.metadata {
67 data.metadata = metadata.map(Value::Object);
68 }
69 }
70}
71
72#[derive(Debug, Clone, Default)]
74pub struct OrganizationMemberCreatePatch {
75 pub organization_id: Option<String>,
76 pub user_id: Option<String>,
77 pub role: Option<String>,
78}
79impl OrganizationMemberCreatePatch {
80 pub(crate) fn apply(self, data: &mut CreateMember) {
81 if let Some(id) = self.organization_id {
82 data.organization_id = id;
83 }
84 if let Some(id) = self.user_id {
85 data.user_id = id;
86 }
87 if let Some(role) = self.role {
88 data.role = role;
89 }
90 }
91}
92
93#[async_trait]
101pub trait OrganizationCreationHooks: std::fmt::Debug + Send + Sync {
102 async fn before_create(
103 &self,
104 _context: &OrganizationDraftContext,
105 ) -> AuthResult<Option<OrganizationCreatePatch>> {
106 Ok(None)
107 }
108 async fn before_add_member(
109 &self,
110 _context: &OrganizationMemberDraftContext,
111 ) -> AuthResult<Option<OrganizationMemberCreatePatch>> {
112 Ok(None)
113 }
114 async fn after_add_member(&self, _context: &OrganizationCreatedContext) -> AuthResult<()> {
115 Ok(())
116 }
117 async fn after_create(&self, _context: &OrganizationCreatedContext) -> AuthResult<()> {
118 Ok(())
119 }
120}
121
122#[derive(Debug, Clone)]
127pub struct OrganizationDeleteContext {
128 pub organization: crate::organization::types::OrganizationResponse,
129 pub user: UserView,
130 pub session: alibi_core::wire::SessionView,
131 pub headers: std::collections::HashMap<String, String>,
133 pub request: Option<alibi_core::AuthRequest>,
136}
137
138pub(crate) struct DeleteInvocation<'a> {
139 pub headers: &'a std::collections::HashMap<String, String>,
140 pub request: Option<&'a alibi_core::AuthRequest>,
141}
142
143#[async_trait]
150pub trait OrganizationDeletionHooks: std::fmt::Debug + Send + Sync {
151 async fn before_delete(&self, _context: &OrganizationDeleteContext) -> AuthResult<()> {
152 Ok(())
153 }
154 async fn after_delete(&self, _context: &OrganizationDeleteContext) -> AuthResult<()> {
155 Ok(())
156 }
157}
158
159#[derive(Debug, Clone)]
161pub struct OrganizationUpdateInput {
162 pub name: Option<String>,
163 pub slug: Option<String>,
164 pub logo: Option<Option<String>>,
165 pub metadata: Option<IndexMap<String, JsValue>>,
167}
168
169#[derive(Debug, Clone)]
171pub struct OrganizationUpdateContext {
172 pub organization: OrganizationUpdateInput,
173 pub user: UserView,
174 pub member: Member,
175}
176
177#[derive(Debug, Clone)]
180pub struct OrganizationUpdatedContext {
181 pub organization: Option<CreatedOrganizationResponse>,
182 pub user: UserView,
183 pub member: Member,
184}
185
186#[derive(Debug, Clone, Default)]
188pub struct OrganizationUpdatePatch {
189 pub name: Option<String>,
190 pub slug: Option<String>,
191 pub logo: Option<Option<String>>,
193 pub metadata: Option<Option<IndexMap<String, JsValue>>>,
196}
197impl OrganizationUpdatePatch {
198 pub(crate) fn apply(self, data: &mut UpdateOrganization) -> AuthResult<()> {
199 if let Some(name) = self.name {
200 data.name = Some(name);
201 }
202 if let Some(slug) = self.slug {
203 data.slug = Some(slug);
204 }
205 if let Some(logo) = self.logo {
206 data.logo = Some(logo);
207 }
208 if let Some(metadata) = self.metadata {
209 data.metadata = Some(
210 metadata
211 .map_or(JsValue::Null, JsValue::Object)
212 .to_json_value()?,
213 );
214 }
215 Ok(())
216 }
217}
218
219#[async_trait]
226pub trait OrganizationUpdateHooks: std::fmt::Debug + Send + Sync {
227 async fn before_update(
228 &self,
229 _context: &OrganizationUpdateContext,
230 ) -> AuthResult<Option<OrganizationUpdatePatch>> {
231 Ok(None)
232 }
233 async fn after_update(&self, _context: &OrganizationUpdatedContext) -> AuthResult<()> {
234 Ok(())
235 }
236}