Can request new user password on login
This commit is contained in:
@ -46,6 +46,17 @@ impl<E> EntityManager<E> where E: serde::Serialize + serde::de::DeserializeOwned
|
||||
self.save()
|
||||
}
|
||||
|
||||
/// Replace entries in the list that matches a criteria
|
||||
pub fn replace_entries<F>(&mut self, filter: F, el: &E) -> Res where F: Fn(&E) -> bool {
|
||||
for i in 0..self.list.len() {
|
||||
if filter(&self.list[i]) {
|
||||
self.list[i] = el.clone();
|
||||
}
|
||||
}
|
||||
|
||||
self.save()
|
||||
}
|
||||
|
||||
/// Iterate over the entries of this entity manager
|
||||
pub fn iter(&self) -> Iter<'_, E> {
|
||||
self.list.iter()
|
||||
|
@ -6,18 +6,28 @@ use crate::data::user::User;
|
||||
use crate::utils::time::time;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||
enum SessionStatus {
|
||||
pub enum SessionStatus {
|
||||
Invalid,
|
||||
SignedIn,
|
||||
NeedNewPassword,
|
||||
NeedMFA,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
impl Default for SessionStatus {
|
||||
fn default() -> Self {
|
||||
Self::Invalid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
struct SessionIdentityData {
|
||||
pub id: String,
|
||||
pub is_admin: bool,
|
||||
last_access: u64,
|
||||
pub status: SessionStatus,
|
||||
|
||||
// TODO : add session max duration (1 day)
|
||||
}
|
||||
|
||||
pub struct SessionIdentity<'a>(pub &'a Identity);
|
||||
@ -39,6 +49,13 @@ impl<'a> SessionIdentity<'a> {
|
||||
.map(serde_json::from_str)
|
||||
.map(|f| f.expect("Failed to deserialize session data!"));
|
||||
|
||||
// Check if session is valid
|
||||
if let Some(sess) = &res {
|
||||
if sess.id.is_empty() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(session) = res.as_mut() {
|
||||
if session.last_access + MAX_SESSION_DURATION < time() {
|
||||
log::info!("Session is expired for {}", session.id);
|
||||
@ -63,9 +80,27 @@ impl<'a> SessionIdentity<'a> {
|
||||
self.0.remember(s);
|
||||
}
|
||||
|
||||
pub fn set_status(&self, status: SessionStatus) {
|
||||
let mut sess = self.get_session_data().unwrap_or_default();
|
||||
sess.status = status;
|
||||
self.set_session_data(&sess);
|
||||
}
|
||||
|
||||
pub fn is_authenticated(&self) -> bool {
|
||||
self.get_session_data()
|
||||
.map(|s| s.status == SessionStatus::SignedIn)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn need_new_password(&self) -> bool {
|
||||
self.get_session_data()
|
||||
.map(|s| s.status == SessionStatus::NeedNewPassword)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn user_id(&self) -> String {
|
||||
self.get_session_data()
|
||||
.unwrap_or_default()
|
||||
.id
|
||||
}
|
||||
}
|
@ -2,9 +2,11 @@ use crate::data::entity_manager::EntityManager;
|
||||
use crate::data::service::ServiceID;
|
||||
use crate::utils::err::Res;
|
||||
|
||||
pub type UserID = String;
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct User {
|
||||
pub uid: String,
|
||||
pub uid: UserID,
|
||||
pub first_name: String,
|
||||
pub last_last: String,
|
||||
pub username: String,
|
||||
@ -67,4 +69,44 @@ impl EntityManager<User> {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn find_by_user_id(&self, id: &UserID) -> Option<User> {
|
||||
for entry in self.iter() {
|
||||
if entry.uid.eq(id) {
|
||||
return Some(entry.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Update user information
|
||||
fn update_user<F>(&mut self, id: &UserID, update: F) -> bool where F: FnOnce(User) -> User {
|
||||
let user = match self.find_by_user_id(id) {
|
||||
None => return false,
|
||||
Some(user) => user
|
||||
};
|
||||
|
||||
if let Err(e) = self.replace_entries(|u| u.uid.eq(id), &update(user)) {
|
||||
log::error!("Failed to update user information! {:?}", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn change_user_password(&mut self, id: &UserID, password: &str, temporary: bool) -> bool {
|
||||
let new_hash = match hash_password(password) {
|
||||
Ok(h) => { h }
|
||||
Err(e) => {
|
||||
log::error!("Failed to hash user password! {}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
self.update_user(id, |mut user| {
|
||||
user.password = new_hash;
|
||||
user.need_reset_password = temporary;
|
||||
user
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user