use axum::{
extract::FromRequestParts,
http::{request::Parts, StatusCode},
};
use uuid::Uuid;
use crate::auth::verify_token;
#[derive(Debug, Clone)]
pub struct OptionalAuthUser(pub Option<Uuid>);
impl<S> FromRequestParts<S> for OptionalAuthUser
where
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
if let Some(user_id_str) = parts.extensions.get::<String>() {
if let Ok(user_id) = Uuid::parse_str(user_id_str) {
return Ok(OptionalAuthUser(Some(user_id)));
}
}
if let Some(auth_header) = parts.headers.get("authorization") {
if let Ok(auth_str) = auth_header.to_str() {
if auth_str.starts_with("Bearer ") {
let token = &auth_str[7..];
let secret = std::env::var("JWT_SECRET").ok();
if let Some(secret) = secret {
if let Ok(claims) = verify_token(token, &secret) {
if let Ok(user_id) = Uuid::parse_str(&claims.sub) {
return Ok(OptionalAuthUser(Some(user_id)));
}
}
}
}
}
}
Ok(OptionalAuthUser(None))
}
}