use axum::{
body::Body,
extract::Request,
http::header::AUTHORIZATION,
middleware::Next,
response::{IntoResponse, Response},
};
use jsonwebtoken::{Algorithm, DecodingKey, Validation, decode};
use serde::Deserialize;
use crate::rest::{AuthConfig, RestError};
#[derive(Debug, Deserialize)]
struct Claims {
exp: usize,
}
pub async fn auth_middleware(auth: AuthConfig, request: Request<Body>, next: Next) -> Response {
if auth.is_public(request.uri().path()) {
return next.run(request).await;
}
let token = request
.headers()
.get(AUTHORIZATION)
.and_then(|value| value.to_str().ok())
.and_then(|value| value.strip_prefix("Bearer "))
.map(str::trim);
let Some(token) = token else {
return RestError::Unauthorized.into_response();
};
let mut validation = Validation::new(Algorithm::HS256);
validation.validate_exp = true;
match decode::<Claims>(
token,
&DecodingKey::from_secret(auth.secret.as_bytes()),
&validation,
) {
Ok(data) => {
let _ = data.claims.exp;
next.run(request).await
}
Err(_) => RestError::Unauthorized.into_response(),
}
}