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 })
127 }
128}
129
130#[derive(Clone, Default)]
131pub struct OrganizationOptionsBuilder {
132 options: OrganizationOptions,
133}
134
135impl OrganizationOptionsBuilder {
136 pub fn allow_user_to_create_organization(mut self, allow: bool) -> Self {
137 self.options.allow_user_to_create_organization = allow;
138 self
139 }
140
141 pub fn organization_limit(mut self, limit: usize) -> Self {
142 self.options.organization_limit = Some(limit);
143 self
144 }
145
146 pub fn creator_role(mut self, role: impl Into<String>) -> Self {
147 self.options.creator_role = role.into();
148 self
149 }
150
151 pub fn membership_limit(mut self, limit: usize) -> Self {
152 self.options.membership_limit = limit;
153 self
154 }
155
156 pub fn invitation_expires_in(mut self, seconds: i64) -> Self {
157 self.options.invitation_expires_in = seconds;
158 self
159 }
160
161 pub fn invitation_limit(mut self, limit: usize) -> Self {
162 self.options.invitation_limit = limit;
163 self
164 }
165
166 pub fn cancel_pending_invitations_on_re_invite(mut self, cancel: bool) -> Self {
167 self.options.cancel_pending_invitations_on_re_invite = cancel;
168 self
169 }
170
171 pub fn require_email_verification_on_invitation(mut self, require: bool) -> Self {
172 self.options.require_email_verification_on_invitation = require;
173 self
174 }
175
176 pub fn disable_organization_deletion(mut self, disable: bool) -> Self {
177 self.options.disable_organization_deletion = disable;
178 self
179 }
180
181 pub fn hooks(mut self, hooks: OrganizationHooks) -> Self {
182 self.options.hooks = hooks;
183 self
184 }
185
186 pub fn send_invitation_email(mut self, hook: SendInvitationEmailHook) -> Self {
187 self.options.send_invitation_email = Some(hook);
188 self
189 }
190
191 pub fn teams(mut self, teams: TeamOptions) -> Self {
192 self.options.teams = teams;
193 self
194 }
195
196 pub fn dynamic_access_control(mut self, options: DynamicAccessControlOptions) -> Self {
197 self.options.dynamic_access_control = options;
198 self
199 }
200
201 pub fn custom_role(mut self, role: impl Into<String>, permissions: serde_json::Value) -> Self {
202 self.options.custom_roles.insert(role.into(), permissions);
203 self
204 }
205
206 pub fn schema(mut self, schema: OrganizationSchemaOptions) -> Self {
207 self.options.schema = schema;
208 self
209 }
210
211 pub fn build(self) -> OrganizationOptions {
212 self.options
213 }
214}