tuwunel_api_oidc/
auth_metadata.rs1use axum::{Json, extract::State, response::IntoResponse};
2use serde::{Deserialize, Serialize};
3use tuwunel_core::Result;
4
5use super::ACCOUNT_MANAGEMENT_ACTIONS_SUPPORTED;
6
7#[derive(Debug, Serialize, Deserialize)]
8struct ProviderMetadata {
9 issuer: String,
10 authorization_endpoint: String,
11 token_endpoint: String,
12 device_authorization_endpoint: Option<String>,
13 registration_endpoint: Option<String>,
14 revocation_endpoint: Option<String>,
15 jwks_uri: String,
16 userinfo_endpoint: Option<String>,
17 account_management_uri: Option<String>,
18 account_management_actions_supported: Option<Vec<String>>,
19 response_types_supported: Vec<String>,
20 response_modes_supported: Option<Vec<String>>,
21 grant_types_supported: Option<Vec<String>>,
22 code_challenge_methods_supported: Option<Vec<String>>,
23 token_endpoint_auth_methods_supported: Option<Vec<String>>,
24 scopes_supported: Option<Vec<String>>,
25 subject_types_supported: Option<Vec<String>>,
26 id_token_signing_alg_values_supported: Option<Vec<String>>,
27 prompt_values_supported: Option<Vec<String>>,
28 claim_types_supported: Option<Vec<String>>,
29 claims_supported: Option<Vec<String>>,
30}
31
32pub(crate) async fn openid_configuration_route(
33 State(services): State<crate::State>,
34) -> Result<impl IntoResponse> {
35 let issuer = services.oauth.get_server()?.issuer_url()?;
36 let base = issuer.trim_end_matches('/').to_owned();
37
38 let native_registration = services.config.authentication.oidc.native_auth
41 && services.config.allows_password_registration();
42
43 let prompt_values: Vec<String> = native_registration
44 .then(|| "create".to_owned())
45 .into_iter()
46 .collect();
47
48 Ok(Json(ProviderMetadata {
49 issuer,
50
51 authorization_endpoint: format!("{base}/_tuwunel/oidc/authorize"),
52
53 registration_endpoint: Some(format!("{base}/_tuwunel/oidc/registration")),
54
55 userinfo_endpoint: Some(format!("{base}/_tuwunel/oidc/userinfo")),
56
57 token_endpoint: format!("{base}/_tuwunel/oidc/token"),
58
59 device_authorization_endpoint: Some(format!("{base}/_tuwunel/oidc/device_authorization")),
60
61 jwks_uri: format!("{base}/_tuwunel/oidc/jwks"),
62
63 account_management_uri: Some(format!("{base}/_tuwunel/oidc/account")),
64
65 revocation_endpoint: Some(format!("{base}/_tuwunel/oidc/revoke")),
66
67 response_modes_supported: Some(vec!["query".to_owned(), "fragment".to_owned()]),
68
69 response_types_supported: vec!["code".to_owned()],
70
71 code_challenge_methods_supported: Some(vec!["S256".to_owned()]),
72
73 id_token_signing_alg_values_supported: Some(vec!["ES256".to_owned()]),
74
75 prompt_values_supported: Some(prompt_values),
76
77 subject_types_supported: Some(vec!["public".to_owned()]),
78
79 claim_types_supported: Some(vec!["normal".to_owned()]),
80
81 grant_types_supported: Some(vec![
82 "authorization_code".to_owned(),
83 "refresh_token".to_owned(),
84 "urn:ietf:params:oauth:grant-type:device_code".to_owned(),
85 ]),
86
87 token_endpoint_auth_methods_supported: Some(vec![
88 "none".to_owned(),
89 "client_secret_basic".to_owned(),
90 "client_secret_post".to_owned(),
91 ]),
92
93 scopes_supported: Some(vec![
94 "openid".to_owned(),
95 "urn:matrix:client:api:*".to_owned(),
96 "urn:matrix:org.matrix.msc2967.client:api:*".to_owned(),
97 "urn:matrix:client:device:*".to_owned(),
98 "urn:matrix:org.matrix.msc2967.client:device:*".to_owned(),
99 ]),
100
101 account_management_actions_supported: Some(
102 ACCOUNT_MANAGEMENT_ACTIONS_SUPPORTED
103 .iter()
104 .map(ToString::to_string)
105 .collect(),
106 ),
107
108 claims_supported: Some(vec![
109 "iss".to_owned(),
110 "sub".to_owned(),
111 "aud".to_owned(),
112 "exp".to_owned(),
113 "iat".to_owned(),
114 "nonce".to_owned(),
115 ]),
116 }))
117}