use axum::{
extract::FromRequestParts,
http::{
StatusCode,
header::{AUTHORIZATION, HeaderValue},
},
};
pub struct ApiToken;
impl ApiToken {
fn header_matches(value: &HeaderValue) -> bool {
let Some(token) = option_env!("AXVM_HTTP_TOKEN") else {
return false;
};
value.to_str().ok().is_some_and(|value| {
value
.strip_prefix("Bearer ")
.is_some_and(|rest| rest == token)
})
}
}
impl<S: Sync> FromRequestParts<S> for ApiToken {
type Rejection = StatusCode;
async fn from_request_parts(
parts: &mut axum::http::request::Parts,
_state: &S,
) -> Result<Self, Self::Rejection> {
let authorized = parts
.headers
.get(AUTHORIZATION)
.is_some_and(Self::header_matches);
if authorized {
Ok(ApiToken)
} else {
Err(StatusCode::UNAUTHORIZED)
}
}
}