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 prompt_values: Vec<String> = (services.config.oidc_native_auth
41 && services.config.allow_registration)
42 .then(|| "create".to_owned())
43 .into_iter()
44 .collect();
45
46 Ok(Json(ProviderMetadata {
47 issuer,
48
49 authorization_endpoint: format!("{base}/_tuwunel/oidc/authorize"),
50
51 registration_endpoint: Some(format!("{base}/_tuwunel/oidc/registration")),
52
53 userinfo_endpoint: Some(format!("{base}/_tuwunel/oidc/userinfo")),
54
55 token_endpoint: format!("{base}/_tuwunel/oidc/token"),
56
57 device_authorization_endpoint: Some(format!("{base}/_tuwunel/oidc/device_authorization")),
58
59 jwks_uri: format!("{base}/_tuwunel/oidc/jwks"),
60
61 account_management_uri: Some(format!("{base}/_tuwunel/oidc/account")),
62
63 revocation_endpoint: Some(format!("{base}/_tuwunel/oidc/revoke")),
64
65 response_modes_supported: Some(vec!["query".to_owned(), "fragment".to_owned()]),
66
67 response_types_supported: vec!["code".to_owned()],
68
69 code_challenge_methods_supported: Some(vec!["S256".to_owned()]),
70
71 id_token_signing_alg_values_supported: Some(vec!["ES256".to_owned()]),
72
73 prompt_values_supported: Some(prompt_values),
74
75 subject_types_supported: Some(vec!["public".to_owned()]),
76
77 claim_types_supported: Some(vec!["normal".to_owned()]),
78
79 grant_types_supported: Some(vec![
80 "authorization_code".to_owned(),
81 "refresh_token".to_owned(),
82 "urn:ietf:params:oauth:grant-type:device_code".to_owned(),
83 ]),
84
85 token_endpoint_auth_methods_supported: Some(vec![
86 "none".to_owned(),
87 "client_secret_basic".to_owned(),
88 "client_secret_post".to_owned(),
89 ]),
90
91 scopes_supported: Some(vec![
92 "openid".to_owned(),
93 "urn:matrix:client:api:*".to_owned(),
94 "urn:matrix:org.matrix.msc2967.client:api:*".to_owned(),
95 "urn:matrix:client:device:*".to_owned(),
96 "urn:matrix:org.matrix.msc2967.client:device:*".to_owned(),
97 ]),
98
99 account_management_actions_supported: Some(
100 ACCOUNT_MANAGEMENT_ACTIONS_SUPPORTED
101 .iter()
102 .map(ToString::to_string)
103 .collect(),
104 ),
105
106 claims_supported: Some(vec![
107 "iss".to_owned(),
108 "sub".to_owned(),
109 "aud".to_owned(),
110 "exp".to_owned(),
111 "iat".to_owned(),
112 "nonce".to_owned(),
113 ]),
114 }))
115}