use actix::{Actor, AsyncContext, Context, Handler}; use actix::Message; use crate::constants::*; use crate::data::client::ClientID; use crate::data::user::UserID; use crate::utils::time::time; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq)] pub struct SessionID(pub String); #[derive(Clone, Debug)] pub struct Session { pub session_id: SessionID, pub client: ClientID, pub user: UserID, pub redirect_uri: String, pub authorization_code: String, pub code_expire_on: u64, pub token: String, pub token_expire_at: u64, pub nonce: Option, pub code_challenge: Option<(String, String)>, } impl Session { pub fn is_expired(&self) -> bool { self.code_expire_on < time() && self.token_expire_at < time() } } #[derive(Message)] #[rtype(result = "()")] pub struct PushNewSession(pub Session); #[derive(Default)] pub struct OpenIDSessionsActor { session: Vec, } impl OpenIDSessionsActor { pub fn clean_old_sessions(&mut self) { self.session.retain(|s| !s.is_expired()); } } impl Actor for OpenIDSessionsActor { type Context = Context; fn started(&mut self, ctx: &mut Self::Context) { // Clean up at a regular interval failed attempts ctx.run_interval(OPEN_ID_SESSION_CLEANUP_INTERVAL, |act, _ctx| { log::trace!("Cleaning up old login sessions"); act.clean_old_sessions(); }); } } impl Handler for OpenIDSessionsActor { type Result = (); fn handle(&mut self, msg: PushNewSession, _ctx: &mut Self::Context) -> Self::Result { self.session.push(msg.0) } }