haste_server/auth_n/oidc/routes/
mod.rs

1use 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;
18mod interactions;
19mod jwks;
20pub mod route_string;
21pub mod scope;
22pub mod token;
23
24pub static AUTH_NESTED_PATH: &str = "/auth";
25
26static AUTHORIZE_PARAMETERS: LazyLock<Arc<ParameterConfig>> = LazyLock::new(|| {
27    Arc::new(ParameterConfig {
28        required_parameters: vec![
29            "client_id".to_string(),
30            "response_type".to_string(),
31            "state".to_string(),
32            "code_challenge".to_string(),
33            "code_challenge_method".to_string(),
34        ],
35        optional_parameters: vec!["scope".to_string(), "redirect_uri".to_string()],
36        allow_launch_parameters: true,
37    })
38});
39
40static LOGOUT_PARAMETERS: LazyLock<Arc<ParameterConfig>> = LazyLock::new(|| {
41    Arc::new(ParameterConfig {
42        required_parameters: vec!["client_id".to_string()],
43        optional_parameters: vec!["redirect_uri".to_string()],
44        allow_launch_parameters: true,
45    })
46});
47
48pub fn create_router<
49    Repo: Repository + Send + Sync,
50    Search: SearchEngine + Send + Sync,
51    Terminology: FHIRTerminology + Send + Sync,
52>(
53    state: Arc<AppState<Repo, Search, Terminology>>,
54) -> Router<Arc<AppState<Repo, Search, Terminology>>> {
55    Router::new()
56        .merge(Router::new().typed_get(jwks::jwks_get))
57        .merge(federated::federated_router())
58        .nest(
59            AUTH_NESTED_PATH,
60            Router::new()
61                .merge(Router::new().typed_post(token::token))
62                .merge(
63                    Router::new()
64                        .merge(
65                            Router::new()
66                                .typed_post(authorize::authorize)
67                                .typed_get(authorize::authorize)
68                                .typed_post(scope::scope_post)
69                                .route_layer(ServiceBuilder::new().layer(
70                                    OIDCParameterInjectLayer::new((*AUTHORIZE_PARAMETERS).clone()),
71                                )),
72                        )
73                        .route_layer(
74                            ServiceBuilder::new()
75                                .layer(AuthSessionValidationLayer::new("interactions/login")),
76                        ),
77                ),
78        )
79        .nest("/interactions", interactions::interactions_router())
80        .route_layer(
81            ServiceBuilder::new().layer(middleware::from_fn_with_state(state, project_exists)),
82        )
83}