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<User, Box<dyn Error>> {
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::<User>("users")
.find_one(doc! {"_id": token.id}, None)
.await?;
if let Some(user) = user {
Ok(user)
} else {
Err("user not found".into())
}
}