alibi_api/plugins/two_factor/
config.rs1use super::*;
2#[async_trait]
4pub trait SendTwoFactorOtp: Send + Sync {
5 async fn send(&self, user: &UserView, otp: &str) -> AuthResult<()>;
7}
8
9#[derive(Debug, Clone)]
11pub struct AccountLockoutConfig {
12 pub enabled: bool,
13 pub max_failed_attempts: f64,
14 pub duration_seconds: f64,
15}
16
17impl Default for AccountLockoutConfig {
18 fn default() -> Self {
19 Self {
20 enabled: true,
21 max_failed_attempts: 10.0,
22 duration_seconds: 900.0,
23 }
24 }
25}
26
27#[derive(Clone, alibi_core::PluginConfig)]
29#[plugin(name = "TwoFactorPlugin")]
30pub struct TwoFactorConfig {
31 #[config(default = false)]
33 pub allow_passwordless: bool,
34 #[config(default = None)]
36 pub totp_allow_passwordless: Option<bool>,
37 #[config(default = None)]
39 pub backup_allow_passwordless: Option<bool>,
40 #[config(default = 10.0)]
42 pub backup_code_amount: f64,
43 #[config(default = 10.0)]
45 pub backup_code_length: f64,
46 #[config(default = None, skip)]
48 pub custom_backup_codes_generate:
49 Option<Arc<dyn Fn() -> AuthResult<Vec<String>> + Send + Sync>>,
50 #[config(default = TwoFactorBackupStorage::default(), skip)]
51 pub backup_storage: TwoFactorBackupStorage,
52 #[config(default = AccountLockoutConfig::default())]
53 pub account_lockout: AccountLockoutConfig,
54 #[config(default = None)]
56 pub issuer: Option<String>,
57 #[config(default = false)]
59 pub skip_verification_on_enable: bool,
60 #[config(default = DEFAULT_TWO_FACTOR_COOKIE_MAX_AGE_SECS)]
62 pub two_factor_cookie_max_age: f64,
63 #[config(default = DEFAULT_TRUST_DEVICE_MAX_AGE_SECS)]
65 pub trust_device_max_age: f64,
66 #[config(default = DEFAULT_TOTP_PERIOD_SECS)]
68 pub totp_period: f64,
69 #[config(default = DEFAULT_TOTP_DIGITS)]
71 pub totp_digits: f64,
72 #[config(default = None)]
74 pub totp_issuer: Option<String>,
75 #[config(default = false)]
77 pub totp_disabled: bool,
78 #[config(default = None, skip)]
80 pub send_otp: Option<Arc<dyn SendTwoFactorOtp>>,
81 #[config(default = 6.0)]
83 pub otp_digits: f64,
84 #[config(default = 3.0)]
86 pub otp_period_minutes: f64,
87 #[config(default = 5.0)]
89 pub otp_allowed_attempts: f64,
90 #[config(default = TwoFactorOtpStorage::default(), skip)]
91 pub otp_storage: TwoFactorOtpStorage,
92}
93
94impl std::fmt::Debug for TwoFactorConfig {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 f.debug_struct("TwoFactorConfig")
97 .field("allow_passwordless", &self.allow_passwordless)
98 .field("totp_allow_passwordless", &self.totp_allow_passwordless)
99 .field("backup_allow_passwordless", &self.backup_allow_passwordless)
100 .field("backup_code_amount", &self.backup_code_amount)
101 .field("backup_code_length", &self.backup_code_length)
102 .field(
103 "custom_backup_codes_generate",
104 &self.custom_backup_codes_generate.is_some(),
105 )
106 .field("backup_storage", &self.backup_storage)
107 .field("account_lockout", &self.account_lockout)
108 .field("issuer", &self.issuer)
109 .field(
110 "skip_verification_on_enable",
111 &self.skip_verification_on_enable,
112 )
113 .field("two_factor_cookie_max_age", &self.two_factor_cookie_max_age)
114 .field("trust_device_max_age", &self.trust_device_max_age)
115 .field("totp_period", &self.totp_period)
116 .field("totp_digits", &self.totp_digits)
117 .field("totp_issuer", &self.totp_issuer)
118 .field("totp_disabled", &self.totp_disabled)
119 .field("send_otp", &self.send_otp.as_ref().map(|_| "custom"))
120 .field("otp_digits", &self.otp_digits)
121 .field("otp_period_minutes", &self.otp_period_minutes)
122 .field("otp_allowed_attempts", &self.otp_allowed_attempts)
123 .field("otp_storage", &self.otp_storage)
124 .finish()
125 }
126}