-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmod.rs
More file actions
109 lines (93 loc) · 3.46 KB
/
mod.rs
File metadata and controls
109 lines (93 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
pub mod admin;
pub mod api;
pub mod attestation;
pub mod oauth;
pub mod users;
use axum::{middleware::from_fn_with_state, routing::get, Json, Router};
use serde::Serialize;
use tower_http::cors::{Any, CorsLayer};
use utoipa::ToSchema;
use crate::{middleware::AuthState, state::AppState, static_files};
#[derive(Serialize, ToSchema)]
pub struct HealthResponse {
/// Service status
pub status: &'static str,
/// API version
pub version: &'static str,
}
/// Health check endpoint
///
/// Returns the health status of the API service. This endpoint is typically used by
/// load balancers, monitoring systems, and orchestration tools to verify service availability.
#[utoipa::path(
get,
path = "/health",
tag = "Health",
responses(
(status = 200, description = "Service is healthy", body = HealthResponse)
)
)]
async fn health_check() -> Json<HealthResponse> {
Json(HealthResponse {
status: "ok",
version: env!("CARGO_PKG_VERSION"),
})
}
/// Create the main API router with all routes
pub fn create_router(app_state: AppState) -> Router {
create_router_with_cors(app_state, vec![])
}
/// Create the main API router with CORS configuration
pub fn create_router_with_cors(app_state: AppState, allowed_origins: Vec<String>) -> Router {
// Create auth state for middleware
let auth_state = AuthState {
session_repository: app_state.session_repository.clone(),
user_service: app_state.user_service.clone(),
admin_domains: app_state.admin_domains.clone(),
};
// OAuth routes (public, no auth required)
let auth_routes = oauth::create_oauth_router();
// Logout route (requires authentication)
let logout_route = Router::new()
.route("/logout", axum::routing::post(oauth::logout))
.layer(from_fn_with_state(
auth_state.clone(),
crate::middleware::auth_middleware,
));
// Attestation routes (public, no auth required)
let attestation_routes = attestation::create_attestation_router();
// Admin routes (requires admin authentication)
let admin_routes = admin::create_admin_router().layer(from_fn_with_state(
auth_state.clone(),
crate::middleware::admin_auth_middleware,
));
// User routes (requires authentication)
let user_routes = users::create_user_router().layer(from_fn_with_state(
auth_state.clone(),
crate::middleware::auth_middleware,
));
// API proxy routes (requires authentication)
let api_routes = api::create_api_router().layer(from_fn_with_state(
auth_state,
crate::middleware::auth_middleware,
));
// Build the base router
let router = Router::new()
.route("/health", get(health_check))
.nest("/v1/auth", auth_routes)
.nest("/v1/auth", logout_route) // Logout route with auth middleware
.nest("/v1/users", user_routes)
.nest("/v1/admin", admin_routes)
.merge(api_routes) // Merge instead of nest since api routes already have /v1 prefix
.merge(attestation_routes) // Merge attestation routes (already have /v1 prefix)
.with_state(app_state)
// Add static file serving as fallback (must be last)
.fallback(static_files::static_handler);
tracing::info!("CORS enabled for origins: {:?}", allowed_origins);
let cors = CorsLayer::new()
.allow_origin(Any)
.allow_methods(Any)
.allow_headers(Any)
.expose_headers(Any);
router.layer(cors)
}