1use std::fmt;
2use std::sync::Arc;
3
4#[cfg(feature = "oauth")]
5use openauth_oauth::oauth2::SocialOAuthProvider;
6
7use super::storage::SecondaryStorage;
8use crate::crypto::SecretEntry;
9use crate::plugin::AuthPlugin;
10
11use super::account::AccountOptions;
12use super::advanced::AdvancedOptions;
13use super::email_password::EmailPasswordOptions;
14use super::email_verification::EmailVerificationOptions;
15use super::origins::TrustedOriginOptions;
16use super::password::PasswordOptions;
17use super::rate_limit::RateLimitOptions;
18use super::session::SessionOptions;
19use super::user::UserOptions;
20
21#[derive(Debug, Clone, PartialEq, Eq, Default)]
23pub struct TelemetryOptions {
24 pub enabled: Option<bool>,
26 pub debug: bool,
27}
28
29impl TelemetryOptions {
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 #[must_use]
35 pub fn enabled(mut self, enabled: bool) -> Self {
36 self.enabled = Some(enabled);
37 self
38 }
39
40 #[must_use]
41 pub fn debug(mut self, debug: bool) -> Self {
42 self.debug = debug;
43 self
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Default)]
49pub struct ExperimentalOptions {
50 pub joins: bool,
51}
52
53impl ExperimentalOptions {
54 pub fn new() -> Self {
55 Self::default()
56 }
57
58 #[must_use]
59 pub fn joins(mut self, enabled: bool) -> Self {
60 self.joins = enabled;
61 self
62 }
63}
64
65#[derive(Clone, Default)]
67pub struct OpenAuthOptions {
68 pub base_url: Option<String>,
69 pub base_path: Option<String>,
70 pub secret: Option<String>,
71 pub secrets: Vec<SecretEntry>,
72 pub trusted_origins: TrustedOriginOptions,
73 pub disabled_paths: Vec<String>,
74 pub session: SessionOptions,
75 pub user: UserOptions,
76 pub email_password: EmailPasswordOptions,
77 pub email_verification: EmailVerificationOptions,
78 pub password: PasswordOptions,
79 pub account: AccountOptions,
80 pub advanced: AdvancedOptions,
81 pub rate_limit: RateLimitOptions,
82 pub secondary_storage: Option<Arc<dyn SecondaryStorage>>,
83 pub plugins: Vec<AuthPlugin>,
84 #[cfg(feature = "oauth")]
85 pub social_providers: Vec<Arc<dyn SocialOAuthProvider>>,
86 pub production: bool,
87 pub telemetry: TelemetryOptions,
88 pub experimental: ExperimentalOptions,
89}
90
91impl OpenAuthOptions {
92 pub fn new() -> Self {
93 Self::default()
94 }
95
96 pub fn builder() -> Self {
97 Self::new()
98 }
99
100 #[must_use]
101 pub fn base_url(mut self, base_url: impl Into<String>) -> Self {
102 self.base_url = Some(base_url.into());
103 self
104 }
105
106 #[must_use]
107 pub fn base_path(mut self, base_path: impl Into<String>) -> Self {
108 self.base_path = Some(base_path.into());
109 self
110 }
111
112 #[must_use]
113 pub fn secret(mut self, secret: impl Into<String>) -> Self {
114 self.secret = Some(secret.into());
115 self
116 }
117
118 #[must_use]
119 pub fn secrets(mut self, secrets: Vec<SecretEntry>) -> Self {
120 self.secrets = secrets;
121 self
122 }
123
124 #[must_use]
125 pub fn trusted_origins(mut self, trusted_origins: TrustedOriginOptions) -> Self {
126 self.trusted_origins = trusted_origins;
127 self
128 }
129
130 #[must_use]
131 pub fn disabled_path(mut self, path: impl Into<String>) -> Self {
132 self.disabled_paths.push(path.into());
133 self
134 }
135
136 #[must_use]
137 pub fn disabled_paths<I, S>(mut self, paths: I) -> Self
138 where
139 I: IntoIterator<Item = S>,
140 S: Into<String>,
141 {
142 self.disabled_paths = paths.into_iter().map(Into::into).collect();
143 self
144 }
145
146 #[must_use]
147 pub fn session(mut self, session: SessionOptions) -> Self {
148 self.session = session;
149 self
150 }
151
152 #[must_use]
153 pub fn user(mut self, user: UserOptions) -> Self {
154 self.user = user;
155 self
156 }
157
158 #[must_use]
159 pub fn email_password(mut self, email_password: EmailPasswordOptions) -> Self {
160 self.email_password = email_password;
161 self
162 }
163
164 #[must_use]
165 pub fn email_verification(mut self, email_verification: EmailVerificationOptions) -> Self {
166 self.email_verification = email_verification;
167 self
168 }
169
170 #[must_use]
171 pub fn password(mut self, password: PasswordOptions) -> Self {
172 self.password = password;
173 self
174 }
175
176 #[must_use]
177 pub fn account(mut self, account: AccountOptions) -> Self {
178 self.account = account;
179 self
180 }
181
182 #[must_use]
183 pub fn advanced(mut self, advanced: AdvancedOptions) -> Self {
184 self.advanced = advanced;
185 self
186 }
187
188 #[must_use]
189 pub fn rate_limit(mut self, rate_limit: RateLimitOptions) -> Self {
190 self.rate_limit = rate_limit;
191 self
192 }
193
194 #[must_use]
195 pub fn secondary_storage(mut self, storage: Arc<dyn SecondaryStorage>) -> Self {
196 self.secondary_storage = Some(storage);
197 self
198 }
199
200 #[must_use]
201 pub fn plugin(mut self, plugin: AuthPlugin) -> Self {
202 self.plugins.push(plugin);
203 self
204 }
205
206 #[must_use]
207 pub fn plugins(mut self, plugins: Vec<AuthPlugin>) -> Self {
208 self.plugins = plugins;
209 self
210 }
211
212 #[cfg(feature = "oauth")]
213 #[must_use]
214 pub fn social_provider<P>(mut self, provider: P) -> Self
215 where
216 P: SocialOAuthProvider,
217 {
218 self.social_providers.push(Arc::new(provider));
219 self
220 }
221
222 #[cfg(feature = "oauth")]
223 #[must_use]
224 pub fn social_provider_arc(mut self, provider: Arc<dyn SocialOAuthProvider>) -> Self {
225 self.social_providers.push(provider);
226 self
227 }
228
229 #[must_use]
230 pub fn production(mut self, production: bool) -> Self {
231 self.production = production;
232 self
233 }
234
235 #[must_use]
236 pub fn telemetry(mut self, telemetry: TelemetryOptions) -> Self {
237 self.telemetry = telemetry;
238 self
239 }
240
241 #[must_use]
242 pub fn experimental(mut self, experimental: ExperimentalOptions) -> Self {
243 self.experimental = experimental;
244 self
245 }
246}
247
248impl fmt::Debug for OpenAuthOptions {
249 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
250 formatter
251 .debug_struct("OpenAuthOptions")
252 .field("base_url", &self.base_url)
253 .field("base_path", &self.base_path)
254 .field("secret", &self.secret.as_ref().map(|_| "<redacted>"))
255 .field(
256 "secrets",
257 &format_args!("{} secret(s) redacted", self.secrets.len()),
258 )
259 .field("trusted_origins", &self.trusted_origins)
260 .field("disabled_paths", &self.disabled_paths)
261 .field("session", &self.session)
262 .field("user", &self.user)
263 .field("email_password", &self.email_password)
264 .field("email_verification", &self.email_verification)
265 .field("password", &self.password)
266 .field("account", &self.account)
267 .field("advanced", &self.advanced)
268 .field("rate_limit", &self.rate_limit)
269 .field(
270 "secondary_storage",
271 &self
272 .secondary_storage
273 .as_ref()
274 .map(|_| "<secondary-storage>"),
275 )
276 .field("plugins", &self.plugins)
277 .field("social_providers", &debug_social_providers(self))
278 .field("production", &self.production)
279 .field("telemetry", &self.telemetry)
280 .field("experimental", &self.experimental)
281 .finish()
282 }
283}
284
285#[cfg(feature = "oauth")]
286fn debug_social_providers(options: &OpenAuthOptions) -> Vec<&str> {
287 options
288 .social_providers
289 .iter()
290 .map(|provider| provider.id())
291 .collect()
292}
293
294#[cfg(not(feature = "oauth"))]
295fn debug_social_providers(_options: &OpenAuthOptions) -> Vec<&'static str> {
296 Vec::new()
297}