text/x-rust
•
1.26 KB
•
45 lines
use std::sync::Arc;
use axum::{
extract::{FromRef, FromRequestParts},
http::{StatusCode, header, request::Parts},
};
use rubhub_auth_store::RunnerToken;
use crate::GlobalState;
/// Extractor that validates runner authentication via Bearer token
pub struct RunnerAuth(pub Arc<RunnerToken>);
impl<S> FromRequestParts<S> for RunnerAuth
where
S: Send + Sync,
GlobalState: FromRef<S>,
{
type Rejection = (StatusCode, &'static str);
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let state = GlobalState::from_ref(state);
// Get Authorization header
let auth_header = parts
.headers
.get(header::AUTHORIZATION)
.and_then(|v| v.to_str().ok())
.ok_or((StatusCode::UNAUTHORIZED, "Missing Authorization header"))?;
// Extract Bearer token
let token = auth_header.strip_prefix("Bearer ").ok_or((
StatusCode::UNAUTHORIZED,
"Invalid Authorization header format",
))?;
// Validate token
let runner_token = state
.auth
.validate_runner_token(token)
.ok_or((StatusCode::UNAUTHORIZED, "Invalid runner token"))?;
Ok(RunnerAuth(runner_token))
}
}