haste_server/auth_n/oidc/routes/
mod.rs1use crate::{
2 auth_n::oidc::middleware::{
3 AuthSessionValidationLayer, OIDCParameterInjectLayer, ParameterConfig, project_exists,
4 },
5 services::AppState,
6};
7use axum::{Router, middleware};
8use axum_extra::routing::RouterExt;
9use haste_fhir_search::SearchEngine;
10use haste_fhir_terminology::FHIRTerminology;
11use haste_repository::Repository;
12use std::sync::{Arc, LazyLock};
13use tower::ServiceBuilder;
14
15mod authorize;
16pub mod discovery;
17pub mod federated;
18pub mod interactions;
19mod jwks;
20pub mod route_string;
21pub mod scope;
22pub mod token;
23
24static AUTHORIZE_PARAMETERS: LazyLock<Arc<ParameterConfig>> = LazyLock::new(|| {
25 Arc::new(ParameterConfig {
26 required_parameters: vec![
27 "client_id".to_string(),
28 "response_type".to_string(),
29 "state".to_string(),
30 "code_challenge".to_string(),
31 "code_challenge_method".to_string(),
32 ],
33 optional_parameters: vec!["scope".to_string(), "redirect_uri".to_string()],
34 allow_launch_parameters: true,
35 })
36});
37
38static LOGOUT_PARAMETERS: LazyLock<Arc<ParameterConfig>> = LazyLock::new(|| {
39 Arc::new(ParameterConfig {
40 required_parameters: vec!["client_id".to_string()],
41 optional_parameters: vec!["redirect_uri".to_string()],
42 allow_launch_parameters: true,
43 })
44});
45
46pub fn create_router<
47 Repo: Repository + Send + Sync,
48 Search: SearchEngine + Send + Sync,
49 Terminology: FHIRTerminology + Send + Sync,
50>(
51 state: Arc<AppState<Repo, Search, Terminology>>,
52) -> Router<Arc<AppState<Repo, Search, Terminology>>> {
53 Router::new()
54 .merge(Router::new().typed_get(jwks::jwks_get))
55 .merge(federated::federated_router())
56 .nest(
57 "/auth",
58 Router::new()
59 .merge(Router::new().typed_post(token::token))
60 .merge(
61 Router::new()
62 .merge(
63 Router::new()
64 .typed_post(authorize::authorize)
65 .typed_get(authorize::authorize)
66 .typed_post(scope::scope_post)
67 .route_layer(ServiceBuilder::new().layer(
68 OIDCParameterInjectLayer::new((*AUTHORIZE_PARAMETERS).clone()),
69 )),
70 )
71 .route_layer(
72 ServiceBuilder::new()
73 .layer(AuthSessionValidationLayer::new("interactions/login")),
74 ),
75 ),
76 )
77 .nest("/interactions", interactions::interactions_router())
78 .route_layer(
79 ServiceBuilder::new().layer(middleware::from_fn_with_state(state, project_exists)),
80 )
81}