Login
4 branches 0 tags
Ben (T14/NixOS) Improved flake 41eb128 11 days ago 252 Commits
rubhub / src / extractors / runner_auth.rs
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))
    }
}