You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

75 lines
2.0 KiB

pub mod auth;
pub mod dictionary;
pub mod info;
pub mod major;
use crate::state::AppState;
use axum::{
Json, Router,
extract::Request,
extract::State,
http::StatusCode,
middleware::Next,
response::{IntoResponse, Response},
};
use serde::Serialize;
use std::sync::Arc;
#[derive(Debug, Serialize)]
struct ErrorResponseBody {
error: String,
}
pub fn routes(state: Arc<AppState>) -> Router<Arc<AppState>> {
Router::new()
.nest("/info", info::routes())
.nest("/auth", auth::routes())
.nest("/dicts", dictionary::routes())
.nest("/major", major::routes())
.route_layer(axum::middleware::from_fn_with_state(
state,
|state: State<Arc<AppState>>, request: Request, next: Next| async move {
auth_middleware_inner(state, request, next).await
},
))
}
async fn auth_middleware_inner(
state: State<Arc<AppState>>,
mut request: Request,
next: Next,
) -> Response {
let auth_header = request
.headers()
.get("Authorization")
.and_then(|h| h.to_str().ok());
let api_key_header = request
.headers()
.get("X-API-Key")
.and_then(|h| h.to_str().ok());
let token = if let Some(header) = auth_header {
header.to_string()
} else if let Some(key) = api_key_header {
key.to_string()
} else {
let error = ErrorResponseBody {
error: "Missing authorization header or API key".to_string(),
};
return (StatusCode::UNAUTHORIZED, Json(error)).into_response();
};
match state.0.dependencies.auth_service.authenticate(&token).await {
Ok(claims) => {
request.extensions_mut().insert(claims);
next.run(request).await
}
Err(_) => {
let error = ErrorResponseBody {
error: "Unauthorized".to_string(),
};
(StatusCode::UNAUTHORIZED, Json(error)).into_response()
}
}
}