1use std::collections::BTreeMap;
2use std::fmt;
3use std::sync::Arc;
4
5use http::Request;
6use time::Duration;
7
8use super::model_schema::ModelSchemaOptions;
9use crate::db::{DbFieldType, DbValue, User};
10use crate::error::RustAuthError;
11
12#[derive(Debug, Clone, Default)]
14pub struct UserOptions {
15 pub schema: ModelSchemaOptions,
16 pub change_email: ChangeEmailOptions,
17 pub delete_user: DeleteUserOptions,
18 pub additional_fields: BTreeMap<String, UserAdditionalField>,
19}
20
21impl UserOptions {
22 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn builder() -> Self {
27 Self::new()
28 }
29
30 #[must_use]
31 pub fn schema(mut self, schema: ModelSchemaOptions) -> Self {
32 self.schema = schema;
33 self
34 }
35
36 #[must_use]
37 pub fn change_email(mut self, change_email: ChangeEmailOptions) -> Self {
38 self.change_email = change_email;
39 self
40 }
41
42 #[must_use]
43 pub fn delete_user(mut self, delete_user: DeleteUserOptions) -> Self {
44 self.delete_user = delete_user;
45 self
46 }
47
48 #[must_use]
49 pub fn additional_field(mut self, name: impl Into<String>, field: UserAdditionalField) -> Self {
50 self.additional_fields.insert(name.into(), field);
51 self
52 }
53}
54
55#[derive(Debug, Clone, PartialEq)]
57pub struct UserAdditionalField {
58 pub field_type: DbFieldType,
59 pub required: bool,
60 pub input: bool,
61 pub returned: bool,
62 pub default_value: Option<DbValue>,
63 pub db_name: Option<String>,
64}
65
66impl UserAdditionalField {
67 pub fn new(field_type: DbFieldType) -> Self {
68 Self {
69 field_type,
70 required: true,
71 input: true,
72 returned: true,
73 default_value: None,
74 db_name: None,
75 }
76 }
77
78 #[must_use]
79 pub fn optional(mut self) -> Self {
80 self.required = false;
81 self
82 }
83
84 #[must_use]
85 pub fn generated(mut self) -> Self {
86 self.input = false;
87 self
88 }
89
90 #[must_use]
91 pub fn hidden(mut self) -> Self {
92 self.returned = false;
93 self
94 }
95
96 #[must_use]
97 pub fn default_value(mut self, value: DbValue) -> Self {
98 self.default_value = Some(value);
99 self
100 }
101
102 #[must_use]
103 pub fn db_name(mut self, db_name: impl Into<String>) -> Self {
104 self.db_name = Some(db_name.into());
105 self
106 }
107}
108
109#[derive(Clone, Default)]
111pub struct ChangeEmailOptions {
112 pub enabled: bool,
113 pub update_email_without_verification: bool,
114 pub send_change_email_confirmation: Option<Arc<dyn SendChangeEmailConfirmation>>,
115}
116
117impl fmt::Debug for ChangeEmailOptions {
118 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
119 formatter
120 .debug_struct("ChangeEmailOptions")
121 .field("enabled", &self.enabled)
122 .field(
123 "update_email_without_verification",
124 &self.update_email_without_verification,
125 )
126 .field(
127 "send_change_email_confirmation",
128 &self
129 .send_change_email_confirmation
130 .as_ref()
131 .map(|_| "<send-change-email-confirmation>"),
132 )
133 .finish()
134 }
135}
136
137impl ChangeEmailOptions {
138 pub fn new() -> Self {
139 Self::default()
140 }
141
142 pub fn builder() -> Self {
143 Self::new()
144 }
145
146 #[must_use]
147 pub fn enabled(mut self, enabled: bool) -> Self {
148 self.enabled = enabled;
149 self
150 }
151
152 #[must_use]
153 pub fn update_email_without_verification(mut self, enabled: bool) -> Self {
154 self.update_email_without_verification = enabled;
155 self
156 }
157
158 #[must_use]
159 pub fn send_change_email_confirmation<S>(mut self, sender: S) -> Self
160 where
161 S: SendChangeEmailConfirmation,
162 {
163 self.send_change_email_confirmation = Some(Arc::new(sender));
164 self
165 }
166}
167
168#[derive(Debug, Clone, PartialEq, Eq)]
170pub struct ChangeEmailConfirmation {
171 pub user: User,
172 pub new_email: String,
173 pub url: String,
174 pub token: String,
175}
176
177pub trait SendChangeEmailConfirmation: Send + Sync + 'static {
179 fn send_change_email_confirmation(
180 &self,
181 payload: ChangeEmailConfirmation,
182 request: Option<&Request<Vec<u8>>>,
183 ) -> Result<(), RustAuthError>;
184}
185
186impl<F> SendChangeEmailConfirmation for F
187where
188 F: for<'a> Fn(
189 ChangeEmailConfirmation,
190 Option<&'a Request<Vec<u8>>>,
191 ) -> Result<(), RustAuthError>
192 + Send
193 + Sync
194 + 'static,
195{
196 fn send_change_email_confirmation(
197 &self,
198 payload: ChangeEmailConfirmation,
199 request: Option<&Request<Vec<u8>>>,
200 ) -> Result<(), RustAuthError> {
201 self(payload, request)
202 }
203}
204
205#[derive(Clone, Default)]
207pub struct DeleteUserOptions {
208 pub enabled: bool,
209 pub send_delete_account_verification: Option<Arc<dyn SendDeleteAccountVerification>>,
210 pub before_delete: Option<Arc<dyn BeforeDeleteUser>>,
211 pub after_delete: Option<Arc<dyn AfterDeleteUser>>,
212 pub delete_token_expires_in: Option<Duration>,
213}
214
215impl fmt::Debug for DeleteUserOptions {
216 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
217 formatter
218 .debug_struct("DeleteUserOptions")
219 .field("enabled", &self.enabled)
220 .field(
221 "send_delete_account_verification",
222 &self
223 .send_delete_account_verification
224 .as_ref()
225 .map(|_| "<send-delete-account-verification>"),
226 )
227 .field(
228 "before_delete",
229 &self.before_delete.as_ref().map(|_| "<before-delete>"),
230 )
231 .field(
232 "after_delete",
233 &self.after_delete.as_ref().map(|_| "<after-delete>"),
234 )
235 .field("delete_token_expires_in", &self.delete_token_expires_in)
236 .finish()
237 }
238}
239
240impl DeleteUserOptions {
241 pub fn new() -> Self {
242 Self::default()
243 }
244
245 pub fn builder() -> Self {
246 Self::new()
247 }
248
249 #[must_use]
250 pub fn enabled(mut self, enabled: bool) -> Self {
251 self.enabled = enabled;
252 self
253 }
254
255 #[must_use]
256 pub fn send_delete_account_verification<S>(mut self, sender: S) -> Self
257 where
258 S: SendDeleteAccountVerification,
259 {
260 self.send_delete_account_verification = Some(Arc::new(sender));
261 self
262 }
263
264 #[must_use]
265 pub fn before_delete<B>(mut self, hook: B) -> Self
266 where
267 B: BeforeDeleteUser,
268 {
269 self.before_delete = Some(Arc::new(hook));
270 self
271 }
272
273 #[must_use]
274 pub fn after_delete<A>(mut self, hook: A) -> Self
275 where
276 A: AfterDeleteUser,
277 {
278 self.after_delete = Some(Arc::new(hook));
279 self
280 }
281
282 #[must_use]
283 pub fn delete_token_expires_in(mut self, expires_in: Duration) -> Self {
284 self.delete_token_expires_in = Some(expires_in);
285 self
286 }
287}
288
289#[derive(Debug, Clone, PartialEq, Eq)]
291pub struct DeleteAccountVerificationEmail {
292 pub user: User,
293 pub url: String,
294 pub token: String,
295}
296
297pub trait SendDeleteAccountVerification: Send + Sync + 'static {
299 fn send_delete_account_verification(
300 &self,
301 payload: DeleteAccountVerificationEmail,
302 request: Option<&Request<Vec<u8>>>,
303 ) -> Result<(), RustAuthError>;
304}
305
306impl<F> SendDeleteAccountVerification for F
307where
308 F: for<'a> Fn(
309 DeleteAccountVerificationEmail,
310 Option<&'a Request<Vec<u8>>>,
311 ) -> Result<(), RustAuthError>
312 + Send
313 + Sync
314 + 'static,
315{
316 fn send_delete_account_verification(
317 &self,
318 payload: DeleteAccountVerificationEmail,
319 request: Option<&Request<Vec<u8>>>,
320 ) -> Result<(), RustAuthError> {
321 self(payload, request)
322 }
323}
324
325pub trait BeforeDeleteUser: Send + Sync + 'static {
327 fn before_delete(
328 &self,
329 user: &User,
330 request: Option<&Request<Vec<u8>>>,
331 ) -> Result<(), RustAuthError>;
332}
333
334impl<F> BeforeDeleteUser for F
335where
336 F: for<'a> Fn(&User, Option<&'a Request<Vec<u8>>>) -> Result<(), RustAuthError>
337 + Send
338 + Sync
339 + 'static,
340{
341 fn before_delete(
342 &self,
343 user: &User,
344 request: Option<&Request<Vec<u8>>>,
345 ) -> Result<(), RustAuthError> {
346 self(user, request)
347 }
348}
349
350pub trait AfterDeleteUser: Send + Sync + 'static {
352 fn after_delete(
353 &self,
354 user: &User,
355 request: Option<&Request<Vec<u8>>>,
356 ) -> Result<(), RustAuthError>;
357}
358
359impl<F> AfterDeleteUser for F
360where
361 F: for<'a> Fn(&User, Option<&'a Request<Vec<u8>>>) -> Result<(), RustAuthError>
362 + Send
363 + Sync
364 + 'static,
365{
366 fn after_delete(
367 &self,
368 user: &User,
369 request: Option<&Request<Vec<u8>>>,
370 ) -> Result<(), RustAuthError> {
371 self(user, request)
372 }
373}