use std::sync::Arc;
use axum::extract::{Request, State};
use axum::http::StatusCode;
use axum::middleware::Next;
use axum::response::{IntoResponse, Response};
use crate::state::AppState;
const SKIP_AUTH_PATHS: &[&str] = &["/api/v1/health", "/api/v1/webhooks/github"];
pub async fn auth_middleware(
State(state): State<Arc<AppState>>,
request: Request,
next: Next,
) -> Response {
let tokens = &state.api_tokens;
if tokens.is_empty() {
return next.run(request).await;
}
let path = request.uri().path();
if SKIP_AUTH_PATHS.contains(&path) {
return next.run(request).await;
}
let auth_header = request
.headers()
.get("authorization")
.and_then(|v| v.to_str().ok());
match auth_header {
Some(header) if header.starts_with("Bearer ") => {
let token = &header[7..];
if tokens.iter().any(|t| t == token) {
next.run(request).await
} else {
(StatusCode::UNAUTHORIZED, "invalid bearer token").into_response()
}
}
_ => (StatusCode::UNAUTHORIZED, "missing bearer token").into_response(),
}
}