From 5536104ca1e2a10a887bf4d56bfe22602cb40571 Mon Sep 17 00:00:00 2001 From: fernando Date: Wed, 14 Feb 2024 10:34:38 -0500 Subject: [PATCH] Delete expired sessions. Update session duration on access --- src/auth/mod.rs | 1 - src/auth/session.rs | 56 +++++++++++++++++++++++++++++++++++------ src/controller/login.rs | 5 +--- src/main.rs | 8 +++--- src/view/mod.rs | 1 - 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/auth/mod.rs b/src/auth/mod.rs index 95c2152..c41a5ba 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -1,4 +1,3 @@ -use rocket::response::Redirect; use rocket::State; use rocket::{ http::Status, diff --git a/src/auth/session.rs b/src/auth/session.rs index 7dac4cf..f539f41 100644 --- a/src/auth/session.rs +++ b/src/auth/session.rs @@ -1,6 +1,6 @@ -use std::{collections::HashMap, sync::{Arc, Mutex}}; - use serde::{Deserialize, Serialize}; +use std::time::{SystemTime, UNIX_EPOCH}; +use std::{collections::HashMap, sync::Mutex}; pub struct Sessions { sessions: Mutex>, @@ -19,22 +19,64 @@ impl Sessions { } pub fn get(&self, session_id: &str) -> Option { - let map = self.sessions.lock().unwrap(); + let mut map = self.sessions.lock().unwrap(); - match map.get(session_id) { - Some(s) => Some(s.clone()), - None => None, + // Remove expired sessions + + // current unix time in seconds + let current_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_secs(); + + let keys = map.keys().cloned().collect::>(); + + for key in keys { + if map.get(&key).unwrap().expires_at < current_time { + map.remove(&key); + } } + + // Get the session & extend its duration + let new_session = match map.get(session_id) { + Some(s) => s.extend_duration(current_time), + None => return None, + }; + + let returned_session = new_session.clone(); + + // Update the session in the map + map.insert(session_id.to_string(), new_session); + + Some(returned_session) } } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SessionData { user_id: i32, + expires_at: u64, } impl SessionData { + // Create a new session with a duration set to 1 hour pub fn new(user_id: i32) -> Self { - SessionData { user_id } + let expires_at = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_secs() + + 3600; + + SessionData { + user_id, + expires_at, + } + } + + pub fn extend_duration(&self, current_time: u64) -> Self { + SessionData { + user_id: self.user_id, + expires_at: current_time + 3600, + } } } diff --git a/src/controller/login.rs b/src/controller/login.rs index 17b42c2..de46ef7 100644 --- a/src/controller/login.rs +++ b/src/controller/login.rs @@ -11,10 +11,7 @@ pub struct LoginData { #[get("/login")] pub fn login(sessions: &State) -> &'static str { - sessions.insert( - "123456".into(), - SessionData::new(1), - ); + sessions.insert("123456".into(), SessionData::new(1)); ":D" } diff --git a/src/main.rs b/src/main.rs index e0c567b..b287062 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,9 +14,9 @@ fn rocket() -> _ { .manage(auth::session::Sessions::new()) .register("/", catchers![view::not_authorized]) .mount("/", routes![controller::index,]) - .mount("/f", routes![ - controller::user::create_user, - controller::login::login, - ]) + .mount( + "/f", + routes![controller::user::create_user, controller::login::login,], + ) .mount("/static", FileServer::from("static")) } diff --git a/src/view/mod.rs b/src/view/mod.rs index 2b1467e..9477f4d 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -25,7 +25,6 @@ pub fn default_skeleton(content: Markup) -> Markup { } } - #[catch(401)] pub fn not_authorized() -> Markup { html! {