Merge factors type for authentication

This commit is contained in:
2022-11-11 12:26:02 +01:00
parent 8d231c0b45
commit af383720b7
44 changed files with 1177 additions and 674 deletions

View File

@@ -32,14 +32,32 @@ impl TwoFactor {
}
}
pub fn description_str(&self) -> &'static str {
match self.kind {
TwoFactorType::TOTP(_) => "Login by entering an OTP code",
TwoFactorType::WEBAUTHN(_) => "Login using a security key",
}
}
pub fn type_image(&self) -> &'static str {
match self.kind {
TwoFactorType::TOTP(_) => "/assets/img/pin.svg",
TwoFactorType::WEBAUTHN(_) => "/assets/img/key.svg",
}
}
pub fn login_url(&self, redirect_uri: &LoginRedirect) -> String {
match self.kind {
TwoFactorType::TOTP(_) => format!("/2fa_otp?id={}&redirect={}",
self.id.0, redirect_uri.get_encoded()),
TwoFactorType::WEBAUTHN(_) => format!("/2fa_webauthn?id={}&redirect={}",
self.id.0, redirect_uri.get_encoded()),
TwoFactorType::TOTP(_) => format!("/2fa_otp?redirect={}", redirect_uri.get_encoded()),
TwoFactorType::WEBAUTHN(_) => {
format!("/2fa_webauthn?redirect={}", redirect_uri.get_encoded())
}
}
}
pub fn is_webauthn(&self) -> bool {
matches!(self.kind, TwoFactorType::WEBAUTHN(_))
}
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -71,7 +89,7 @@ impl User {
pub fn can_access_app(&self, id: &ClientID) -> bool {
match &self.authorized_clients {
None => true,
Some(c) => c.contains(id)
Some(c) => c.contains(id),
}
}
@@ -94,6 +112,49 @@ impl User {
pub fn find_factor(&self, factor_id: &FactorID) -> Option<&TwoFactor> {
self.two_factor.iter().find(|f| f.id.eq(factor_id))
}
pub fn has_webauthn_factor(&self) -> bool {
self.two_factor.iter().any(TwoFactor::is_webauthn)
}
/// Get all registered OTP registered passwords
pub fn get_otp_factors(&self) -> Vec<TotpKey> {
self.two_factor.iter().fold(vec![], |mut acc, factor| {
if let TwoFactorType::TOTP(key) = &factor.kind {
acc.push(key.clone())
}
acc
})
}
/// Get all registered 2FA webauthn public keys
pub fn get_webauthn_pub_keys(&self) -> Vec<WebauthnPubKey> {
self.two_factor.iter().fold(vec![], |mut acc, factor| {
if let TwoFactorType::WEBAUTHN(key) = &factor.kind {
acc.push(*key.clone())
}
acc
})
}
/// Get the first factor of each kind of factors
pub fn get_distinct_factors_types(&self) -> Vec<&TwoFactor> {
let mut urls = vec![];
self.two_factor
.iter()
.filter(|f| {
if urls.contains(&f.type_str()) {
false
} else {
urls.push(f.type_str());
true
}
})
.collect::<Vec<_>>()
}
}
impl PartialEq for User {
@@ -157,8 +218,8 @@ impl EntityManager<User> {
/// Update user information
fn update_user<F>(&mut self, id: &UserID, update: F) -> bool
where
F: FnOnce(User) -> User,
where
F: FnOnce(User) -> User,
{
let user = match self.find_by_user_id(id) {
None => return false,