1use std::sync::Arc;
2
3use axum::extract::{Request, State};
4use axum::http::StatusCode;
5use axum::middleware::Next;
6use axum::response::Response;
7
8use crate::state::ApiState;
9
10pub async fn require_api_key(
11 State(state): State<Arc<ApiState>>,
12 req: Request,
13 next: Next,
14) -> Result<Response, StatusCode> {
15 let Some(ref expected) = state.api_key else {
16 return Ok(next.run(req).await);
17 };
18
19 let provided = req
20 .headers()
21 .get("authorization")
22 .and_then(|v| v.to_str().ok())
23 .and_then(|v| v.strip_prefix("Bearer "))
24 .or_else(|| req.headers().get("x-api-key").and_then(|v| v.to_str().ok()));
25
26 match provided {
27 Some(key) if key == expected => Ok(next.run(req).await),
28 _ => Err(StatusCode::UNAUTHORIZED),
29 }
30}