Start to create 2FA exemption after successful 2FA login
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@ -1,9 +1,13 @@
|
||||
use crate::constants::SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN;
|
||||
use crate::data::client::ClientID;
|
||||
use crate::data::entity_manager::EntityManager;
|
||||
use crate::data::login_redirect::LoginRedirect;
|
||||
use crate::data::totp_key::TotpKey;
|
||||
use crate::data::webauthn_manager::WebauthnPubKey;
|
||||
use crate::utils::err::Res;
|
||||
use crate::utils::time::time;
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct UserID(pub String);
|
||||
@ -76,6 +80,15 @@ pub struct User {
|
||||
#[serde(default)]
|
||||
pub two_factor: Vec<TwoFactor>,
|
||||
|
||||
/// Exempt the user from validating a second factor after a previous successful authentication
|
||||
/// for a defined amount of time
|
||||
#[serde(default)]
|
||||
pub two_factor_exemption_after_successful_login: bool,
|
||||
|
||||
/// IP addresses of last successful logins
|
||||
#[serde(default)]
|
||||
pub last_successful_2fa: HashMap<IpAddr, u64>,
|
||||
|
||||
/// None = all services
|
||||
/// Some([]) = no service
|
||||
pub authorized_clients: Option<Vec<ClientID>>,
|
||||
@ -101,6 +114,13 @@ impl User {
|
||||
!self.two_factor.is_empty()
|
||||
}
|
||||
|
||||
pub fn can_bypass_two_factors_for_ip(&self, ip: IpAddr) -> bool {
|
||||
self.two_factor_exemption_after_successful_login
|
||||
&& self.last_successful_2fa.get(&ip).unwrap_or(&0)
|
||||
+ SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN
|
||||
> time()
|
||||
}
|
||||
|
||||
pub fn add_factor(&mut self, factor: TwoFactor) {
|
||||
self.two_factor.push(factor);
|
||||
}
|
||||
@ -178,6 +198,8 @@ impl Default for User {
|
||||
enabled: true,
|
||||
admin: false,
|
||||
two_factor: vec![],
|
||||
two_factor_exemption_after_successful_login: false,
|
||||
last_successful_2fa: Default::default(),
|
||||
authorized_clients: Some(Vec::new()),
|
||||
}
|
||||
}
|
||||
@ -249,4 +271,11 @@ impl EntityManager<User> {
|
||||
user
|
||||
})
|
||||
}
|
||||
|
||||
pub fn save_new_successful_2fa_authentication(&mut self, id: &UserID, ip: IpAddr) -> bool {
|
||||
self.update_user(id, |mut user| {
|
||||
user.last_successful_2fa.insert(ip, time());
|
||||
user
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user