use axum::extract::{FromRequestParts, Request};
use axum::http::request::Parts;
use axum::middleware::Next;
use axum::response::Response;
use super::{HEADER_NAME, TrustTask};
use crate::error::AppError;
pub struct TrustTaskHeader(pub TrustTask);
impl<S> FromRequestParts<S> for TrustTaskHeader
where
S: Send + Sync,
{
type Rejection = AppError;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let raw = parts
.headers
.get(HEADER_NAME)
.ok_or(AppError::TrustTaskMissing)?;
let s = raw
.to_str()
.map_err(|_| AppError::Validation("Trust-Task header is not valid UTF-8".into()))?;
let task = TrustTask::new(s)?;
Ok(Self(task))
}
}
pub(crate) async fn validate_header(
expected: &TrustTask,
request: Request,
next: Next,
) -> Result<Response, AppError> {
let raw = request
.headers()
.get(HEADER_NAME)
.ok_or(AppError::TrustTaskMissing)?;
let received = raw
.to_str()
.map_err(|_| AppError::Validation("Trust-Task header is not valid UTF-8".into()))?;
if received != expected.as_str() {
return Err(AppError::TrustTaskMismatch {
expected: expected.as_str().to_string(),
received: Some(received.to_string()),
});
}
Ok(next.run(request).await)
}