Files
libertas/libertas_api/src/middleware/auth.rs
2025-11-02 09:31:01 +01:00

50 lines
1.5 KiB
Rust

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<AppState> for UserId {
type Rejection = Response;
async fn from_request_parts(
parts: &mut Parts,
state: &AppState,
) -> Result<Self, Self::Rejection> {
let tokenizer: Arc<dyn TokenGenerator> = state.token_generator.clone();
let result = (async || -> CoreResult<Uuid> {
let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>()
.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())
}
}
}
}