use rand::{distributions::Alphanumeric, Rng}; use serde::Serialize; use tracing::instrument; use crate::database::Database; use crate::types::http::{ResponseCode, Result}; #[derive(Serialize)] pub struct Session { pub user_id: u64, pub token: String, } impl Session { #[instrument(skip(db))] pub fn from_token(db: &Database, token: &str) -> Result { let Ok(Some(session)) = db.get_session(token) else { return Err(ResponseCode::BadRequest.text("Invalid auth token")); }; Ok(session) } #[instrument(skip(db))] pub fn reterieve_all(db: &Database) -> Result> { let Ok(sessions) = db.get_all_sessions() else { return Err(ResponseCode::InternalServerError.text("Failed to fetch sessions")) }; Ok(sessions) } #[instrument(skip(db))] pub fn new(db: &Database, user_id: u64) -> Result { let token: String = rand::thread_rng() .sample_iter(&Alphanumeric) .take(32) .map(char::from) .collect(); match db.set_session(user_id, &token) { Err(_) => Err(ResponseCode::BadRequest.text("Failed to create session")), Ok(_) => Ok(Self { user_id, token }), } } #[instrument(skip(db))] pub fn delete(db: &Database, user_id: u64) -> Result<()> { if db.delete_session(user_id).is_err() { tracing::error!("Failed to logout user"); return Err(ResponseCode::InternalServerError.text("Failed to logout")); }; Ok(()) } }