use actix_identity::Identity; use serde::{Deserialize, Serialize}; use crate::data::user::{User, UserID}; #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] pub enum SessionStatus { Invalid, SignedIn, NeedNewPassword, NeedMFA, } impl Default for SessionStatus { fn default() -> Self { Self::Invalid } } #[derive(Debug, Serialize, Deserialize, Default)] pub struct SessionIdentityData { pub id: UserID, pub is_admin: bool, pub status: SessionStatus, } pub struct SessionIdentity<'a>(pub &'a Identity); impl<'a> SessionIdentity<'a> { fn get_session_data(&self) -> Option { Self::deserialize_session_data(self.0.identity()) } pub fn deserialize_session_data(data: Option) -> Option { let res: Option = data.as_deref() .map(serde_json::from_str) .map(|f| match f { Ok(d) => Some(d), Err(e) => { log::warn!("Failed to deserialize session data! {:?}", e); None } }) .unwrap_or(None); // Check if session is valid if let Some(sess) = &res { if sess.id.is_empty() { return None; } } res } fn set_session_data(&self, data: &SessionIdentityData) { let s = serde_json::to_string(data) .expect("Failed to serialize session data!"); self.0.remember(s); } pub fn set_user(&self, user: &User) { self.set_session_data(&SessionIdentityData { id: user.uid.clone(), is_admin: user.admin, status: SessionStatus::SignedIn, }); } 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) -> UserID { self.get_session_data() .unwrap_or_default() .id } }