openauth_core/options/
password.rs1use std::fmt;
2use std::sync::Arc;
3
4use http::Request;
5
6use crate::db::User;
7use crate::error::OpenAuthError;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct PasswordResetPayload {
12 pub user: User,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct PasswordResetEmail {
18 pub user: User,
19 pub url: String,
20 pub token: String,
21}
22
23pub trait SendResetPassword: Send + Sync + 'static {
25 fn send_reset_password(
26 &self,
27 payload: PasswordResetEmail,
28 request: Option<&Request<Vec<u8>>>,
29 ) -> Result<(), OpenAuthError>;
30}
31
32impl<F> SendResetPassword for F
33where
34 F: for<'a> Fn(PasswordResetEmail, Option<&'a Request<Vec<u8>>>) -> Result<(), OpenAuthError>
35 + Send
36 + Sync
37 + 'static,
38{
39 fn send_reset_password(
40 &self,
41 payload: PasswordResetEmail,
42 request: Option<&Request<Vec<u8>>>,
43 ) -> Result<(), OpenAuthError> {
44 self(payload, request)
45 }
46}
47
48pub trait OnPasswordReset: Send + Sync + 'static {
50 fn on_password_reset(
51 &self,
52 payload: PasswordResetPayload,
53 request: Option<&Request<Vec<u8>>>,
54 ) -> Result<(), OpenAuthError>;
55}
56
57impl<F> OnPasswordReset for F
58where
59 F: for<'a> Fn(PasswordResetPayload, Option<&'a Request<Vec<u8>>>) -> Result<(), OpenAuthError>
60 + Send
61 + Sync
62 + 'static,
63{
64 fn on_password_reset(
65 &self,
66 payload: PasswordResetPayload,
67 request: Option<&Request<Vec<u8>>>,
68 ) -> Result<(), OpenAuthError> {
69 self(payload, request)
70 }
71}
72
73#[derive(Clone)]
75pub struct PasswordOptions {
76 pub min_password_length: usize,
77 pub max_password_length: usize,
78 pub send_reset_password: Option<Arc<dyn SendResetPassword>>,
79 pub reset_password_token_expires_in: Option<u64>,
80 pub on_password_reset: Option<Arc<dyn OnPasswordReset>>,
81 pub revoke_sessions_on_password_reset: bool,
82}
83
84impl Default for PasswordOptions {
85 fn default() -> Self {
86 Self {
87 min_password_length: 8,
88 max_password_length: 128,
89 send_reset_password: None,
90 reset_password_token_expires_in: None,
91 on_password_reset: None,
92 revoke_sessions_on_password_reset: false,
93 }
94 }
95}
96
97impl PasswordOptions {
98 pub fn new() -> Self {
99 Self::default()
100 }
101
102 pub fn builder() -> Self {
103 Self::new()
104 }
105
106 #[must_use]
107 pub fn min_password_length(mut self, length: usize) -> Self {
108 self.min_password_length = length;
109 self
110 }
111
112 #[must_use]
113 pub fn max_password_length(mut self, length: usize) -> Self {
114 self.max_password_length = length;
115 self
116 }
117
118 #[must_use]
119 pub fn send_reset_password<S>(mut self, sender: S) -> Self
120 where
121 S: SendResetPassword,
122 {
123 self.send_reset_password = Some(Arc::new(sender));
124 self
125 }
126
127 #[must_use]
128 pub fn reset_password_token_expires_in(mut self, seconds: u64) -> Self {
129 self.reset_password_token_expires_in = Some(seconds);
130 self
131 }
132
133 #[must_use]
134 pub fn on_password_reset<P>(mut self, handler: P) -> Self
135 where
136 P: OnPasswordReset,
137 {
138 self.on_password_reset = Some(Arc::new(handler));
139 self
140 }
141
142 #[must_use]
143 pub fn revoke_sessions_on_password_reset(mut self, enabled: bool) -> Self {
144 self.revoke_sessions_on_password_reset = enabled;
145 self
146 }
147}
148
149impl fmt::Debug for PasswordOptions {
150 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
151 formatter
152 .debug_struct("PasswordOptions")
153 .field("min_password_length", &self.min_password_length)
154 .field("max_password_length", &self.max_password_length)
155 .field(
156 "send_reset_password",
157 &self
158 .send_reset_password
159 .as_ref()
160 .map(|_| "<send-reset-password>"),
161 )
162 .field(
163 "reset_password_token_expires_in",
164 &self.reset_password_token_expires_in,
165 )
166 .field(
167 "on_password_reset",
168 &self
169 .on_password_reset
170 .as_ref()
171 .map(|_| "<on-password-reset>"),
172 )
173 .field(
174 "revoke_sessions_on_password_reset",
175 &self.revoke_sessions_on_password_reset,
176 )
177 .finish()
178 }
179}