Can clear 2FA login history from edit_user page

This commit is contained in:
2022-11-12 11:16:55 +01:00
parent 7a3eaa944e
commit 7e1cbb184d
6 changed files with 226 additions and 10 deletions

View File

@ -60,6 +60,7 @@ pub struct UpdateUserQuery {
grant_type: String,
granted_clients: String,
two_factor: String,
clear_2fa_history: Option<String>,
}
pub async fn users_route(
@ -114,10 +115,15 @@ pub async fn users_route(
let temp_pass = rand_str(TEMPORARY_PASSWORDS_LEN);
user.password = hash_password(&temp_pass).expect("Failed to hash password");
user.need_reset_password = true;
user.last_successful_2fa = Default::default();
Some(temp_pass)
}
};
if update.0.clear_2fa_history.is_some() {
user.last_successful_2fa = Default::default();
}
let res = users
.send(users_actor::UpdateUserRequest(user.clone()))
.await

View File

@ -1,3 +1,6 @@
use std::collections::HashMap;
use std::net::IpAddr;
use crate::constants::SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN;
use crate::data::client::ClientID;
use crate::data::entity_manager::EntityManager;
@ -5,9 +8,7 @@ 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;
use crate::utils::time::{fmt_time, time};
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct UserID(pub String);
@ -64,6 +65,19 @@ impl TwoFactor {
}
}
#[derive(Debug)]
pub struct Successful2FALogin {
pub ip: IpAddr,
pub time: u64,
pub can_bypass_2fa: bool,
}
impl Successful2FALogin {
pub fn fmt_time(&self) -> String {
fmt_time(self.time)
}
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct User {
pub uid: UserID,
@ -175,6 +189,17 @@ impl User {
})
.collect::<Vec<_>>()
}
pub fn get_formatted_2fa_successful_logins(&self) -> Vec<Successful2FALogin> {
self.last_successful_2fa
.iter()
.map(|(ip, time)| Successful2FALogin {
ip: *ip,
time: *time,
can_bypass_2fa: self.can_bypass_two_factors_for_ip(*ip),
})
.collect::<Vec<_>>()
}
}
impl PartialEq for User {
@ -268,6 +293,7 @@ impl EntityManager<User> {
self.update_user(id, |mut user| {
user.password = new_hash;
user.need_reset_password = temporary;
user.two_factor_exemption_after_successful_login = Default::default();
user
})
}

View File

@ -1,3 +1,4 @@
use chrono::{DateTime, NaiveDateTime, Utc};
use std::time::{SystemTime, UNIX_EPOCH};
/// Get the current time since epoch
@ -7,3 +8,16 @@ pub fn time() -> u64 {
.unwrap()
.as_secs()
}
/// Format unix timestamp to a human-readable string
pub fn fmt_time(timestamp: u64) -> String {
// Create a NaiveDateTime from the timestamp
let naive =
NaiveDateTime::from_timestamp_opt(timestamp as i64, 0).expect("Failed to parse timestamp!");
// Create a normal DateTime from the NaiveDateTime
let datetime: DateTime<Utc> = DateTime::from_utc(naive, Utc);
// Format the datetime how you want
datetime.format("%Y-%m-%d %H:%M:%S").to_string()
}