openauth_plugins/organization/
options.rs1use openauth_core::db::TableOptions;
2use serde_json::{json, Value};
3
4use super::hooks::OrganizationHooks;
5use super::{Invitation, Member, Organization};
6use std::sync::Arc;
7
8pub type SendInvitationEmailHook =
9 Arc<dyn Fn(&InvitationEmail) -> Result<(), openauth_core::error::OpenAuthError> + Send + Sync>;
10
11#[derive(Clone)]
12pub struct OrganizationOptions {
13 pub allow_user_to_create_organization: bool,
14 pub organization_limit: Option<usize>,
15 pub creator_role: String,
16 pub membership_limit: usize,
17 pub invitation_expires_in: i64,
18 pub invitation_limit: usize,
19 pub cancel_pending_invitations_on_re_invite: bool,
20 pub require_email_verification_on_invitation: bool,
21 pub disable_organization_deletion: bool,
22 pub hooks: OrganizationHooks,
23 pub send_invitation_email: Option<SendInvitationEmailHook>,
24 pub teams: TeamOptions,
25 pub dynamic_access_control: DynamicAccessControlOptions,
26 pub custom_roles: std::collections::BTreeMap<String, serde_json::Value>,
27 pub schema: OrganizationSchemaOptions,
28}
29
30#[derive(Clone, Debug, PartialEq, Eq)]
31pub struct TeamOptions {
32 pub enabled: bool,
33 pub create_default_team: bool,
34 pub maximum_teams: Option<usize>,
35 pub maximum_members_per_team: Option<usize>,
36 pub allow_removing_all_teams: bool,
37}
38
39#[derive(Clone, Debug, Default, PartialEq, Eq)]
40pub struct DynamicAccessControlOptions {
41 pub enabled: bool,
42 pub maximum_roles_per_organization: Option<usize>,
43}
44
45#[derive(Clone, Debug, Default, PartialEq, Eq)]
46pub struct OrganizationSchemaOptions {
47 pub organization: TableOptions,
48 pub member: TableOptions,
49 pub invitation: TableOptions,
50 pub team: TableOptions,
51 pub team_member: TableOptions,
52 pub organization_role: TableOptions,
53}
54
55#[derive(Debug, Clone)]
56pub struct InvitationEmail {
57 pub id: String,
58 pub role: String,
59 pub email: String,
60 pub organization: Organization,
61 pub invitation: Invitation,
62 pub inviter: Member,
63}
64
65impl Default for OrganizationOptions {
66 fn default() -> Self {
67 Self {
68 allow_user_to_create_organization: true,
69 organization_limit: None,
70 creator_role: "owner".to_owned(),
71 membership_limit: 100,
72 invitation_expires_in: 60 * 60 * 48,
73 invitation_limit: 100,
74 cancel_pending_invitations_on_re_invite: false,
75 require_email_verification_on_invitation: false,
76 disable_organization_deletion: false,
77 hooks: OrganizationHooks::default(),
78 send_invitation_email: None,
79 teams: TeamOptions::default(),
80 dynamic_access_control: DynamicAccessControlOptions::default(),
81 custom_roles: std::collections::BTreeMap::new(),
82 schema: OrganizationSchemaOptions::default(),
83 }
84 }
85}
86
87impl Default for TeamOptions {
88 fn default() -> Self {
89 Self {
90 enabled: false,
91 create_default_team: true,
92 maximum_teams: None,
93 maximum_members_per_team: None,
94 allow_removing_all_teams: false,
95 }
96 }
97}
98
99impl OrganizationOptions {
100 pub fn builder() -> OrganizationOptionsBuilder {
101 OrganizationOptionsBuilder::default()
102 }
103
104 pub(crate) fn to_metadata(&self) -> Value {
105 json!({
106 "allowUserToCreateOrganization": self.allow_user_to_create_organization,
107 "organizationLimit": self.organization_limit,
108 "creatorRole": self.creator_role,
109 "membershipLimit": self.membership_limit,
110 "invitationExpiresIn": self.invitation_expires_in,
111 "invitationLimit": self.invitation_limit,
112 "cancelPendingInvitationsOnReInvite": self.cancel_pending_invitations_on_re_invite,
113 "requireEmailVerificationOnInvitation": self.require_email_verification_on_invitation,
114 "disableOrganizationDeletion": self.disable_organization_deletion,
115 "teams": {
116 "enabled": self.teams.enabled,
117 "defaultTeam": { "enabled": self.teams.create_default_team },
118 "maximumTeams": self.teams.maximum_teams,
119 "maximumMembersPerTeam": self.teams.maximum_members_per_team,
120 "allowRemovingAllTeams": self.teams.allow_removing_all_teams,
121 },
122 "dynamicAccessControl": {
123 "enabled": self.dynamic_access_control.enabled,
124 "maximumRolesPerOrganization": self.dynamic_access_control.maximum_roles_per_organization,
125 },
126 "customRoles": self.custom_roles,
127 })
128 }
129}
130
131#[derive(Clone, Default)]
132pub struct OrganizationOptionsBuilder {
133 options: OrganizationOptions,
134}
135
136impl OrganizationOptionsBuilder {
137 pub fn allow_user_to_create_organization(mut self, allow: bool) -> Self {
138 self.options.allow_user_to_create_organization = allow;
139 self
140 }
141
142 pub fn organization_limit(mut self, limit: usize) -> Self {
143 self.options.organization_limit = Some(limit);
144 self
145 }
146
147 pub fn creator_role(mut self, role: impl Into<String>) -> Self {
148 self.options.creator_role = role.into();
149 self
150 }
151
152 pub fn membership_limit(mut self, limit: usize) -> Self {
153 self.options.membership_limit = limit;
154 self
155 }
156
157 pub fn invitation_expires_in(mut self, seconds: i64) -> Self {
158 self.options.invitation_expires_in = seconds;
159 self
160 }
161
162 pub fn invitation_limit(mut self, limit: usize) -> Self {
163 self.options.invitation_limit = limit;
164 self
165 }
166
167 pub fn cancel_pending_invitations_on_re_invite(mut self, cancel: bool) -> Self {
168 self.options.cancel_pending_invitations_on_re_invite = cancel;
169 self
170 }
171
172 pub fn require_email_verification_on_invitation(mut self, require: bool) -> Self {
173 self.options.require_email_verification_on_invitation = require;
174 self
175 }
176
177 pub fn disable_organization_deletion(mut self, disable: bool) -> Self {
178 self.options.disable_organization_deletion = disable;
179 self
180 }
181
182 pub fn hooks(mut self, hooks: OrganizationHooks) -> Self {
183 self.options.hooks = hooks;
184 self
185 }
186
187 pub fn send_invitation_email(mut self, hook: SendInvitationEmailHook) -> Self {
188 self.options.send_invitation_email = Some(hook);
189 self
190 }
191
192 pub fn teams(mut self, teams: TeamOptions) -> Self {
193 self.options.teams = teams;
194 self
195 }
196
197 pub fn dynamic_access_control(mut self, options: DynamicAccessControlOptions) -> Self {
198 self.options.dynamic_access_control = options;
199 self
200 }
201
202 pub fn custom_role(mut self, role: impl Into<String>, permissions: serde_json::Value) -> Self {
203 self.options.custom_roles.insert(role.into(), permissions);
204 self
205 }
206
207 pub fn schema(mut self, schema: OrganizationSchemaOptions) -> Self {
208 self.options.schema = schema;
209 self
210 }
211
212 pub fn build(self) -> OrganizationOptions {
213 self.options
214 }
215}