use async_trait::async_trait;
use axum_core::extract::{FromRequest, RequestParts};
use http::{header::AUTHORIZATION, StatusCode};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct AuthBearer(pub String);
#[async_trait]
impl<B> FromRequest<B> for AuthBearer
where
B: Send,
{
type Rejection = (StatusCode, &'static str);
async fn from_request(req: &mut RequestParts<B>) -> std::result::Result<Self, Self::Rejection> {
let authorisation = req
.headers()
.get(AUTHORIZATION)
.ok_or((StatusCode::BAD_REQUEST, "`Authorization` header is missing"))?
.to_str()
.map_err(|_| {
(
StatusCode::BAD_REQUEST,
"`Authorization` header contains invalid characters",
)
})?;
let split = authorisation.split_once(' ');
match split {
Some((name, contents)) if name == "Bearer" => Ok(Self(contents.to_string())),
_ => Err((
StatusCode::BAD_REQUEST,
"`Authorization` header must be a bearer token",
)),
}
}
}