use crate::models::track::TrackId; use crate::models::user::{User, UserId}; use crate::AppState; use actix_web::HttpRequest; use bson::doc; use jwt::VerifyWithKey; use serde::{Deserialize, Serialize}; use std::error::Error; use std::time::SystemTime; #[derive(Serialize, Deserialize)] pub struct UserToken { pub id: UserId, pub expires: SystemTime, } #[derive(Serialize, Deserialize)] pub struct InviteToken { pub id: TrackId, pub expires: SystemTime, } pub async fn enforce_session(req: &HttpRequest, state: &AppState) -> Result> { let header = req .headers() .get("Authorization") .ok_or("Missing authorization header")?; let authorization = header.to_str()?; let authorization_split: Vec<&str> = authorization.split(' ').collect(); if authorization_split[0] != "Bearer" { return Err("Not a bearer token".into()); } let token_str = authorization_split[1]; let token: UserToken = token_str.verify_with_key(&state.key)?; if SystemTime::now() > token.expires { return Err("expired".into()); } // fetch the user from the db let user = state .db .database(&state.config.mongodb_database) .collection::("users") .find_one(doc! {"_id": token.id}, None) .await?; if let Some(user) = user { Ok(user) } else { Err("user not found".into()) } }