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
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() |
|
} |
|
} |
|
}
|
|
|