use std::env;
use axum::extract::Request;
use axum::http::header::AUTHORIZATION;
use axum::middleware::Next;
use axum::response::{IntoResponse, Response};
use subtle::ConstantTimeEq;
use super::error::UhpFailure;
const API_KEY_ENV: &str = "EMBACLE_API_KEY";
pub async fn require_auth(request: Request, next: Next) -> Response {
let expected = match env::var(API_KEY_ENV) {
Ok(key) if !key.is_empty() => key,
_ => return next.run(request).await,
};
let presented = request
.headers()
.get(AUTHORIZATION)
.and_then(|v| v.to_str().ok())
.and_then(|v| v.strip_prefix("Bearer "))
.unwrap_or_default();
let matches = expected.len() == presented.len()
&& bool::from(expected.as_bytes().ct_eq(presented.as_bytes()));
if matches {
next.run(request).await
} else if presented.is_empty() {
UhpFailure::unauthorized(
"missing_credential",
"this endpoint requires a bearer token",
)
.into_response()
} else {
UhpFailure::unauthorized("invalid_credential", "the bearer token was not accepted")
.into_response()
}
}