1mod claims;
4pub mod jwks;
5pub mod middleware;
6pub mod user_info;
7
8use jsonwebtoken::jwk::JwkSet;
9use log::trace;
10use serde::Deserialize;
11use tokio::sync::OnceCell;
12
13use self::jwks::fetch_keys;
14
15static CONFIG: OnceCell<Config> = OnceCell::const_new();
17
18#[derive(Debug, Clone)]
20pub struct Config {
21 pub openid_configuration: OpenIDEndpointConfiguration,
23 pub client_id: String,
25 pub jwk_set: JwkSet,
27}
28
29impl Config {
30 #[cfg(test)]
35 pub fn set(config: Self) {
36 let _ = CONFIG.set(config);
37 }
38
39 #[allow(clippy::expect_used)]
45 pub async fn init(app_config: &crate::config::app::Config) {
46 trace!("Initializing auth...");
47 let openid_config =
48 OpenIDEndpointConfiguration::fetch(app_config.auth_discovery_uri.as_ref()).await;
49
50 let config = Self {
51 client_id: app_config.client_id.clone(),
52 jwk_set: fetch_keys(&openid_config.jwks_uri).await,
53 openid_configuration: openid_config,
54 };
55
56 CONFIG.set(config).expect("Already initialized!");
57 }
58
59 #[allow(clippy::expect_used)]
64 pub fn get() -> &'static Self {
65 CONFIG.get().expect("Not yet initialized!")
66 }
67}
68
69#[derive(Debug, Clone, Default, Deserialize)]
73pub struct OpenIDEndpointConfiguration {
74 pub issuer: String,
76 pub authorization_endpoint: String,
78 pub token_endpoint: String,
80 pub jwks_uri: String,
82}
83
84impl OpenIDEndpointConfiguration {
85 #[allow(clippy::expect_used)]
90 async fn fetch(issuer_uri: &str) -> Self {
91 trace!("Fetching endpoints from discovery endpoint...");
92 reqwest::get(issuer_uri)
93 .await
94 .expect("Error fetching from auth server!")
95 .json::<Self>()
96 .await
97 .expect("Auth server returned invalid keys!")
98 }
99}