rustical_oidc/
lib.rs

1#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
2#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
3use crate::routes::{route_get_oidc_callback, route_post_oidc};
4use axum::{
5    Extension, Router,
6    routing::{get, post},
7};
8pub use config::OidcConfig;
9use openidconnect::{CsrfToken, Nonce, PkceCodeVerifier};
10use serde::{Deserialize, Serialize};
11pub use user_store::UserStore;
12
13mod config;
14mod error;
15mod routes;
16mod user_store;
17
18const SESSION_KEY_OIDC_STATE: &str = "oidc_state";
19
20#[derive(Debug, Deserialize, Serialize)]
21struct OidcState {
22    state: CsrfToken,
23    nonce: Nonce,
24    pkce_verifier: PkceCodeVerifier,
25    redirect_uri: Option<String>,
26}
27
28#[derive(Debug, Clone)]
29pub struct OidcServiceConfig {
30    pub default_redirect_path: &'static str,
31    pub session_key_user_id: &'static str,
32    pub callback_path: &'static str,
33}
34
35#[derive(Debug, Deserialize, Serialize)]
36struct GroupAdditionalClaims {
37    #[serde(default)]
38    groups: Option<Vec<String>>,
39}
40
41impl openidconnect::AdditionalClaims for GroupAdditionalClaims {}
42
43pub fn oidc_router<US: UserStore>(
44    config: OidcConfig,
45    service_config: OidcServiceConfig,
46    user_store: US,
47) -> Router {
48    Router::new()
49        .route("/", post(route_post_oidc))
50        .route("/callback", get(route_get_oidc_callback::<US>))
51        .layer(Extension(user_store))
52        .layer(Extension(config))
53        .layer(Extension(service_config))
54}