use axum::{ RequestPartsExt, extract::FromRequestParts, http::{StatusCode, request::Parts}, response::{IntoResponse, Response}, }; use axum_extra::TypedHeader; use axum_extra::headers::{Authorization, authorization::Bearer}; use libertas_core::error::{CoreError, CoreResult}; use uuid::Uuid; use crate::{security::TokenGenerator, state::AppState}; use std::sync::Arc; pub struct UserId(pub Uuid); impl FromRequestParts for UserId { type Rejection = Response; async fn from_request_parts( parts: &mut Parts, state: &AppState, ) -> Result { let tokenizer: Arc = state.token_generator.clone(); let result = (async || -> CoreResult { let TypedHeader(Authorization(bearer)) = parts .extract::>>() .await .map_err(|_| CoreError::Auth("Missing Authorization header".to_string()))?; let user_id = tokenizer.verify_token(bearer.token())?; Ok(user_id) })() .await; match result { Ok(user_id) => Ok(Self(user_id)), Err(e) => { let status = match e { CoreError::Auth(_) => StatusCode::UNAUTHORIZED, _ => StatusCode::INTERNAL_SERVER_ERROR, }; Err((status, e.to_string()).into_response()) } } } }