openidconnect_lax/
discovery.rs

1use std::fmt::Debug;
2use std::future::Future;
3use std::marker::PhantomData;
4
5use http::header::{HeaderValue, ACCEPT};
6use http::method::Method;
7use http::status::StatusCode;
8use oauth2::{AuthUrl, Scope, TokenUrl};
9use serde::de::DeserializeOwned;
10use serde::Serialize;
11use serde_with::{serde_as, skip_serializing_none, VecSkipError};
12use thiserror::Error;
13
14use super::http_utils::{check_content_type, MIME_TYPE_JSON};
15use super::types::{
16    AuthDisplay, AuthenticationContextClass, ClaimName, ClaimType, ClientAuthMethod, GrantType,
17    IssuerUrl, JsonWebKey, JsonWebKeySet, JsonWebKeySetUrl, JsonWebKeyType, JsonWebKeyUse,
18    JweContentEncryptionAlgorithm, JweKeyManagementAlgorithm, JwsSigningAlgorithm, LanguageTag,
19    OpPolicyUrl, OpTosUrl, RegistrationUrl, ResponseMode, ResponseType, ResponseTypes,
20    ServiceDocUrl, SubjectIdentifierType,
21};
22use super::{HttpRequest, HttpResponse, UserInfoUrl, CONFIG_URL_SUFFIX};
23
24///
25/// Trait for adding extra fields to [`ProviderMetadata`].
26///
27pub trait AdditionalProviderMetadata: Clone + Debug + DeserializeOwned + Serialize {}
28
29// In order to support serde flatten, this must be an empty struct rather than an empty
30// tuple struct.
31///
32/// Empty (default) extra [`ProviderMetadata`] fields.
33///
34#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
35pub struct EmptyAdditionalProviderMetadata {}
36impl AdditionalProviderMetadata for EmptyAdditionalProviderMetadata {}
37
38///
39/// Provider metadata returned by [OpenID Connect Discovery](
40/// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata).
41///
42#[serde_as]
43#[skip_serializing_none]
44#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
45#[allow(clippy::type_complexity)]
46pub struct ProviderMetadata<A, AD, CA, CN, CT, G, JE, JK, JS, JT, JU, K, RM, RT, S>
47where
48    A: AdditionalProviderMetadata,
49    AD: AuthDisplay,
50    CA: ClientAuthMethod,
51    CN: ClaimName,
52    CT: ClaimType,
53    G: GrantType,
54    JE: JweContentEncryptionAlgorithm<JT>,
55    JK: JweKeyManagementAlgorithm,
56    JS: JwsSigningAlgorithm<JT>,
57    JT: JsonWebKeyType,
58    JU: JsonWebKeyUse,
59    K: JsonWebKey<JS, JT, JU>,
60    RM: ResponseMode,
61    RT: ResponseType,
62    S: SubjectIdentifierType,
63{
64    issuer: IssuerUrl,
65    authorization_endpoint: AuthUrl,
66    token_endpoint: Option<TokenUrl>,
67    userinfo_endpoint: Option<UserInfoUrl>,
68    jwks_uri: JsonWebKeySetUrl,
69    #[serde(default = "JsonWebKeySet::default", skip)]
70    jwks: JsonWebKeySet<JS, JT, JU, K>,
71    registration_endpoint: Option<RegistrationUrl>,
72    scopes_supported: Option<Vec<Scope>>,
73    #[serde(bound(deserialize = "RT: ResponseType"))]
74    response_types_supported: Vec<ResponseTypes<RT>>,
75    #[serde(bound(deserialize = "RM: ResponseMode"))]
76    response_modes_supported: Option<Vec<RM>>,
77    #[serde(bound(deserialize = "G: GrantType"))]
78    grant_types_supported: Option<Vec<G>>,
79    acr_values_supported: Option<Vec<AuthenticationContextClass>>,
80    #[serde(bound(deserialize = "S: SubjectIdentifierType"))]
81    subject_types_supported: Vec<S>,
82    #[serde(bound(deserialize = "JS: JwsSigningAlgorithm<JT>"))]
83    #[serde_as(as = "VecSkipError<_>")]
84    id_token_signing_alg_values_supported: Vec<JS>,
85    #[serde(
86        bound(deserialize = "JK: JweKeyManagementAlgorithm"),
87        default = "Option::default"
88    )]
89    #[serde_as(as = "Option<VecSkipError<_>>")]
90    id_token_encryption_alg_values_supported: Option<Vec<JK>>,
91    #[serde(
92        bound(deserialize = "JE: JweContentEncryptionAlgorithm<JT>"),
93        default = "Option::default"
94    )]
95    #[serde_as(as = "Option<VecSkipError<_>>")]
96    id_token_encryption_enc_values_supported: Option<Vec<JE>>,
97    #[serde(
98        bound(deserialize = "JS: JwsSigningAlgorithm<JT>"),
99        default = "Option::default"
100    )]
101    #[serde_as(as = "Option<VecSkipError<_>>")]
102    userinfo_signing_alg_values_supported: Option<Vec<JS>>,
103    #[serde(
104        bound(deserialize = "JK: JweKeyManagementAlgorithm"),
105        default = "Option::default"
106    )]
107    #[serde_as(as = "Option<VecSkipError<_>>")]
108    userinfo_encryption_alg_values_supported: Option<Vec<JK>>,
109    #[serde(
110        bound(deserialize = "JE: JweContentEncryptionAlgorithm<JT>"),
111        default = "Option::default"
112    )]
113    #[serde_as(as = "Option<VecSkipError<_>>")]
114    userinfo_encryption_enc_values_supported: Option<Vec<JE>>,
115    #[serde(
116        bound(deserialize = "JS: JwsSigningAlgorithm<JT>"),
117        default = "Option::default"
118    )]
119    #[serde_as(as = "Option<VecSkipError<_>>")]
120    request_object_signing_alg_values_supported: Option<Vec<JS>>,
121    #[serde(
122        bound(deserialize = "JK: JweKeyManagementAlgorithm"),
123        default = "Option::default"
124    )]
125    #[serde_as(as = "Option<VecSkipError<_>>")]
126    request_object_encryption_alg_values_supported: Option<Vec<JK>>,
127    #[serde(
128        bound(deserialize = "JE: JweContentEncryptionAlgorithm<JT>"),
129        default = "Option::default"
130    )]
131    #[serde_as(as = "Option<VecSkipError<_>>")]
132    request_object_encryption_enc_values_supported: Option<Vec<JE>>,
133    #[serde(bound(deserialize = "CA: ClientAuthMethod"))]
134    token_endpoint_auth_methods_supported: Option<Vec<CA>>,
135    #[serde(
136        bound(deserialize = "JS: JwsSigningAlgorithm<JT>"),
137        default = "Option::default"
138    )]
139    #[serde_as(as = "Option<VecSkipError<_>>")]
140    token_endpoint_auth_signing_alg_values_supported: Option<Vec<JS>>,
141    #[serde(bound(deserialize = "AD: AuthDisplay"))]
142    display_values_supported: Option<Vec<AD>>,
143    #[serde(bound(deserialize = "CT: ClaimType"))]
144    claim_types_supported: Option<Vec<CT>>,
145    #[serde(bound(deserialize = "CN: ClaimName"))]
146    claims_supported: Option<Vec<CN>>,
147    service_documentation: Option<ServiceDocUrl>,
148    claims_locales_supported: Option<Vec<LanguageTag>>,
149    ui_locales_supported: Option<Vec<LanguageTag>>,
150    claims_parameter_supported: Option<bool>,
151    request_parameter_supported: Option<bool>,
152    request_uri_parameter_supported: Option<bool>,
153    require_request_uri_registration: Option<bool>,
154    op_policy_uri: Option<OpPolicyUrl>,
155    op_tos_uri: Option<OpTosUrl>,
156
157    #[serde(bound(deserialize = "A: AdditionalProviderMetadata"), flatten)]
158    additional_metadata: A,
159
160    #[serde(skip)]
161    _phantom_jt: PhantomData<JT>,
162}
163impl<A, AD, CA, CN, CT, G, JE, JK, JS, JT, JU, K, RM, RT, S>
164    ProviderMetadata<A, AD, CA, CN, CT, G, JE, JK, JS, JT, JU, K, RM, RT, S>
165where
166    A: AdditionalProviderMetadata,
167    AD: AuthDisplay,
168    CA: ClientAuthMethod,
169    CN: ClaimName,
170    CT: ClaimType,
171    G: GrantType,
172    JE: JweContentEncryptionAlgorithm<JT>,
173    JK: JweKeyManagementAlgorithm,
174    JS: JwsSigningAlgorithm<JT>,
175    JT: JsonWebKeyType,
176    JU: JsonWebKeyUse,
177    K: JsonWebKey<JS, JT, JU>,
178    RM: ResponseMode,
179    RT: ResponseType,
180    S: SubjectIdentifierType,
181{
182    ///
183    /// Instantiates new provider metadata.
184    ///
185    pub fn new(
186        issuer: IssuerUrl,
187        authorization_endpoint: AuthUrl,
188        jwks_uri: JsonWebKeySetUrl,
189        response_types_supported: Vec<ResponseTypes<RT>>,
190        subject_types_supported: Vec<S>,
191        id_token_signing_alg_values_supported: Vec<JS>,
192        additional_metadata: A,
193    ) -> Self {
194        Self {
195            issuer,
196            authorization_endpoint,
197            token_endpoint: None,
198            userinfo_endpoint: None,
199            jwks_uri,
200            jwks: JsonWebKeySet::new(Vec::new()),
201            registration_endpoint: None,
202            scopes_supported: None,
203            response_types_supported,
204            response_modes_supported: None,
205            grant_types_supported: None,
206            acr_values_supported: None,
207            subject_types_supported,
208            id_token_signing_alg_values_supported,
209            id_token_encryption_alg_values_supported: None,
210            id_token_encryption_enc_values_supported: None,
211            userinfo_signing_alg_values_supported: None,
212            userinfo_encryption_alg_values_supported: None,
213            userinfo_encryption_enc_values_supported: None,
214            request_object_signing_alg_values_supported: None,
215            request_object_encryption_alg_values_supported: None,
216            request_object_encryption_enc_values_supported: None,
217            token_endpoint_auth_methods_supported: None,
218            token_endpoint_auth_signing_alg_values_supported: None,
219            display_values_supported: None,
220            claim_types_supported: None,
221            claims_supported: None,
222            service_documentation: None,
223            claims_locales_supported: None,
224            ui_locales_supported: None,
225            claims_parameter_supported: None,
226            request_parameter_supported: None,
227            request_uri_parameter_supported: None,
228            require_request_uri_registration: None,
229            op_policy_uri: None,
230            op_tos_uri: None,
231            additional_metadata,
232            _phantom_jt: PhantomData,
233        }
234    }
235
236    field_getters_setters![
237        pub self [self] ["provider metadata value"] {
238            set_issuer -> issuer[IssuerUrl],
239            set_authorization_endpoint -> authorization_endpoint[AuthUrl],
240            set_token_endpoint -> token_endpoint[Option<TokenUrl>],
241            set_userinfo_endpoint -> userinfo_endpoint[Option<UserInfoUrl>],
242            set_jwks_uri -> jwks_uri[JsonWebKeySetUrl],
243            set_jwks -> jwks[JsonWebKeySet<JS, JT, JU, K>],
244            set_registration_endpoint -> registration_endpoint[Option<RegistrationUrl>],
245            set_scopes_supported -> scopes_supported[Option<Vec<Scope>>],
246            set_response_types_supported -> response_types_supported[Vec<ResponseTypes<RT>>],
247            set_response_modes_supported -> response_modes_supported[Option<Vec<RM>>],
248            set_grant_types_supported -> grant_types_supported[Option<Vec<G>>],
249            set_acr_values_supported
250                -> acr_values_supported[Option<Vec<AuthenticationContextClass>>],
251            set_subject_types_supported -> subject_types_supported[Vec<S>],
252            set_id_token_signing_alg_values_supported
253                -> id_token_signing_alg_values_supported[Vec<JS>],
254            set_id_token_encryption_alg_values_supported
255                -> id_token_encryption_alg_values_supported[Option<Vec<JK>>],
256            set_id_token_encryption_enc_values_supported
257                -> id_token_encryption_enc_values_supported[Option<Vec<JE>>],
258            set_userinfo_signing_alg_values_supported
259                -> userinfo_signing_alg_values_supported[Option<Vec<JS>>],
260            set_userinfo_encryption_alg_values_supported
261                -> userinfo_encryption_alg_values_supported[Option<Vec<JK>>],
262            set_userinfo_encryption_enc_values_supported
263                -> userinfo_encryption_enc_values_supported[Option<Vec<JE>>],
264            set_request_object_signing_alg_values_supported
265                -> request_object_signing_alg_values_supported[Option<Vec<JS>>],
266            set_request_object_encryption_alg_values_supported
267                -> request_object_encryption_alg_values_supported[Option<Vec<JK>>],
268            set_request_object_encryption_enc_values_supported
269                -> request_object_encryption_enc_values_supported[Option<Vec<JE>>],
270            set_token_endpoint_auth_methods_supported
271                -> token_endpoint_auth_methods_supported[Option<Vec<CA>>],
272            set_token_endpoint_auth_signing_alg_values_supported
273                -> token_endpoint_auth_signing_alg_values_supported[Option<Vec<JS>>],
274            set_display_values_supported -> display_values_supported[Option<Vec<AD>>],
275            set_claim_types_supported -> claim_types_supported[Option<Vec<CT>>],
276            set_claims_supported -> claims_supported[Option<Vec<CN>>],
277            set_service_documentation -> service_documentation[Option<ServiceDocUrl>],
278            set_claims_locales_supported -> claims_locales_supported[Option<Vec<LanguageTag>>],
279            set_ui_locales_supported -> ui_locales_supported[Option<Vec<LanguageTag>>],
280            set_claims_parameter_supported -> claims_parameter_supported[Option<bool>],
281            set_request_parameter_supported -> request_parameter_supported[Option<bool>],
282            set_request_uri_parameter_supported -> request_uri_parameter_supported[Option<bool>],
283            set_require_request_uri_registration -> require_request_uri_registration[Option<bool>],
284            set_op_policy_uri -> op_policy_uri[Option<OpPolicyUrl>],
285            set_op_tos_uri -> op_tos_uri[Option<OpTosUrl>],
286        }
287    ];
288
289    ///
290    /// Fetches the OpenID Connect Discovery document and associated JSON Web Key Set from the
291    /// OpenID Connect Provider.
292    ///
293    pub fn discover<HC, RE>(
294        issuer_url: &IssuerUrl,
295        http_client: HC,
296    ) -> Result<Self, DiscoveryError<RE>>
297    where
298        HC: Fn(HttpRequest) -> Result<HttpResponse, RE>,
299        RE: std::error::Error + 'static,
300    {
301        let discovery_url = issuer_url
302            .join(CONFIG_URL_SUFFIX)
303            .map_err(DiscoveryError::UrlParse)?;
304
305        http_client(Self::discovery_request(discovery_url))
306            .map_err(DiscoveryError::Request)
307            .and_then(|http_response| Self::discovery_response(issuer_url, http_response))
308            .and_then(|provider_metadata| {
309                JsonWebKeySet::fetch(provider_metadata.jwks_uri(), http_client).map(|jwks| Self {
310                    jwks,
311                    ..provider_metadata
312                })
313            })
314    }
315
316    ///
317    /// Asynchronously fetches the OpenID Connect Discovery document and associated JSON Web Key Set
318    /// from the OpenID Connect Provider.
319    ///
320    pub async fn discover_async<F, HC, RE>(
321        issuer_url: IssuerUrl,
322        http_client: HC,
323    ) -> Result<Self, DiscoveryError<RE>>
324    where
325        F: Future<Output = Result<HttpResponse, RE>>,
326        HC: Fn(HttpRequest) -> F,
327        RE: std::error::Error + 'static,
328    {
329        let discovery_url = issuer_url
330            .join(CONFIG_URL_SUFFIX)
331            .map_err(DiscoveryError::UrlParse)?;
332
333        let provider_metadata = http_client(Self::discovery_request(discovery_url))
334            .await
335            .map_err(DiscoveryError::Request)
336            .and_then(|http_response| Self::discovery_response(&issuer_url, http_response))?;
337
338        JsonWebKeySet::fetch_async(provider_metadata.jwks_uri(), http_client)
339            .await
340            .map(|jwks| Self {
341                jwks,
342                ..provider_metadata
343            })
344    }
345
346    fn discovery_request(discovery_url: url::Url) -> HttpRequest {
347        HttpRequest {
348            url: discovery_url,
349            method: Method::GET,
350            headers: vec![(ACCEPT, HeaderValue::from_static(MIME_TYPE_JSON))]
351                .into_iter()
352                .collect(),
353            body: Vec::new(),
354        }
355    }
356
357    fn discovery_response<RE>(
358        issuer_url: &IssuerUrl,
359        discovery_response: HttpResponse,
360    ) -> Result<Self, DiscoveryError<RE>>
361    where
362        RE: std::error::Error + 'static,
363    {
364        if discovery_response.status_code != StatusCode::OK {
365            return Err(DiscoveryError::Response(
366                discovery_response.status_code,
367                discovery_response.body,
368                format!("HTTP status code {}", discovery_response.status_code),
369            ));
370        }
371
372        check_content_type(&discovery_response.headers, MIME_TYPE_JSON).map_err(|err_msg| {
373            DiscoveryError::Response(
374                discovery_response.status_code,
375                discovery_response.body.clone(),
376                err_msg,
377            )
378        })?;
379
380        let provider_metadata = serde_path_to_error::deserialize::<_, Self>(
381            &mut serde_json::Deserializer::from_slice(&discovery_response.body),
382        )
383        .map_err(DiscoveryError::Parse)?;
384
385        if provider_metadata.issuer() != issuer_url {
386            Err(DiscoveryError::Validation(format!(
387                "unexpected issuer URI `{}` (expected `{}`)",
388                provider_metadata.issuer().as_str(),
389                issuer_url.as_str()
390            )))
391        } else {
392            Ok(provider_metadata)
393        }
394    }
395
396    ///
397    /// Returns additional provider metadata fields.
398    ///
399    pub fn additional_metadata(&self) -> &A {
400        &self.additional_metadata
401    }
402    ///
403    /// Returns mutable additional provider metadata fields.
404    ///
405    pub fn additional_metadata_mut(&mut self) -> &mut A {
406        &mut self.additional_metadata
407    }
408}
409
410///
411/// Error retrieving provider metadata.
412///
413#[derive(Debug, Error)]
414#[non_exhaustive]
415pub enum DiscoveryError<RE>
416where
417    RE: std::error::Error + 'static,
418{
419    ///
420    /// An unexpected error occurred.
421    ///
422    #[error("Other error: {0}")]
423    Other(String),
424    ///
425    /// Failed to parse server response.
426    ///
427    #[error("Failed to parse server response")]
428    Parse(#[source] serde_path_to_error::Error<serde_json::Error>),
429    ///
430    /// An error occurred while sending the request or receiving the response (e.g., network
431    /// connectivity failed).
432    ///
433    #[error("Request failed")]
434    Request(#[source] RE),
435    ///
436    /// Server returned an invalid response.
437    ///
438    #[error("Server returned invalid response: {2}")]
439    Response(StatusCode, Vec<u8>, String),
440    ///
441    /// Failed to parse discovery URL from issuer URL.
442    ///
443    #[error("Failed to parse URL")]
444    UrlParse(#[source] url::ParseError),
445    ///
446    /// Failed to validate provider metadata.
447    ///
448    #[error("Validation error: {0}")]
449    Validation(String),
450}
451
452#[cfg(test)]
453mod tests {
454    use oauth2::{AuthUrl, Scope, TokenUrl};
455
456    use crate::core::{
457        CoreAuthDisplay, CoreClaimName, CoreClaimType, CoreClientAuthMethod, CoreGrantType,
458        CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm, CoreJwsSigningAlgorithm,
459        CoreProviderMetadata, CoreResponseMode, CoreResponseType, CoreSubjectIdentifierType,
460    };
461
462    use super::{
463        AuthenticationContextClass, IssuerUrl, JsonWebKeySetUrl, LanguageTag, OpPolicyUrl,
464        OpTosUrl, RegistrationUrl, ResponseTypes, ServiceDocUrl, UserInfoUrl,
465    };
466
467    #[test]
468    fn test_discovery_deserialization() {
469        // Fetched from: https://rp.certification.openid.net:8080/openidconnect-rs/
470        //     rp-response_type-code/.well-known/openid-configuration
471        let json_response_standard = "\
472            \"issuer\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\",\
473            \"authorization_endpoint\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/authorization\",\
474            \"token_endpoint\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/token\",\
475            \"userinfo_endpoint\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/userinfo\",\
476            \"jwks_uri\":\"https://rp.certification.openid.net:8080/static/jwks_3INbZl52IrrPCp2j.json\",\
477            \"registration_endpoint\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/registration\",\
478            \"scopes_supported\":[\
479               \"email\",\
480               \"phone\",\
481               \"profile\",\
482               \"openid\",\
483               \"address\",\
484               \"offline_access\",\
485               \"openid\"\
486            ],\
487            \"response_types_supported\":[\
488               \"code\"\
489            ],\
490            \"response_modes_supported\":[\
491               \"query\",\
492               \"fragment\",\
493               \"form_post\"\
494            ],\
495            \"grant_types_supported\":[\
496               \"authorization_code\",\
497               \"implicit\",\
498               \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\
499               \"refresh_token\"\
500            ],\
501            \"acr_values_supported\":[\
502               \"PASSWORD\"\
503            ],\
504            \"subject_types_supported\":[\
505               \"public\",\
506               \"pairwise\"\
507            ],\
508            \"id_token_signing_alg_values_supported\":[\
509               \"RS256\",\
510               \"RS384\",\
511               \"RS512\",\
512               \"ES256\",\
513               \"ES384\",\
514               \"ES512\",\
515               \"HS256\",\
516               \"HS384\",\
517               \"HS512\",\
518               \"PS256\",\
519               \"PS384\",\
520               \"PS512\",\
521               \"none\"\
522            ],\
523            \"id_token_encryption_alg_values_supported\":[\
524               \"RSA1_5\",\
525               \"RSA-OAEP\",\
526               \"RSA-OAEP-256\",\
527               \"A128KW\",\
528               \"A192KW\",\
529               \"A256KW\",\
530               \"ECDH-ES\",\
531               \"ECDH-ES+A128KW\",\
532               \"ECDH-ES+A192KW\",\
533               \"ECDH-ES+A256KW\"\
534            ],\
535            \"id_token_encryption_enc_values_supported\":[\
536               \"A128CBC-HS256\",\
537               \"A192CBC-HS384\",\
538               \"A256CBC-HS512\",\
539               \"A128GCM\",\
540               \"A192GCM\",\
541               \"A256GCM\"\
542            ],\
543            \"userinfo_signing_alg_values_supported\":[\
544               \"RS256\",\
545               \"RS384\",\
546               \"RS512\",\
547               \"ES256\",\
548               \"ES384\",\
549               \"ES512\",\
550               \"HS256\",\
551               \"HS384\",\
552               \"HS512\",\
553               \"PS256\",\
554               \"PS384\",\
555               \"PS512\",\
556               \"none\"\
557            ],\
558            \"userinfo_encryption_alg_values_supported\":[\
559               \"RSA1_5\",\
560               \"RSA-OAEP\",\
561               \"RSA-OAEP-256\",\
562               \"A128KW\",\
563               \"A192KW\",\
564               \"A256KW\",\
565               \"ECDH-ES\",\
566               \"ECDH-ES+A128KW\",\
567               \"ECDH-ES+A192KW\",\
568               \"ECDH-ES+A256KW\"\
569            ],\
570            \"userinfo_encryption_enc_values_supported\":[\
571               \"A128CBC-HS256\",\
572               \"A192CBC-HS384\",\
573               \"A256CBC-HS512\",\
574               \"A128GCM\",\
575               \"A192GCM\",\
576               \"A256GCM\"\
577            ],\
578            \"request_object_signing_alg_values_supported\":[\
579               \"RS256\",\
580               \"RS384\",\
581               \"RS512\",\
582               \"ES256\",\
583               \"ES384\",\
584               \"ES512\",\
585               \"HS256\",\
586               \"HS384\",\
587               \"HS512\",\
588               \"PS256\",\
589               \"PS384\",\
590               \"PS512\",\
591               \"none\"\
592            ],\
593            \"request_object_encryption_alg_values_supported\":[\
594               \"RSA1_5\",\
595               \"RSA-OAEP\",\
596               \"RSA-OAEP-256\",\
597               \"A128KW\",\
598               \"A192KW\",\
599               \"A256KW\",\
600               \"ECDH-ES\",\
601               \"ECDH-ES+A128KW\",\
602               \"ECDH-ES+A192KW\",\
603               \"ECDH-ES+A256KW\"\
604            ],\
605            \"request_object_encryption_enc_values_supported\":[\
606               \"A128CBC-HS256\",\
607               \"A192CBC-HS384\",\
608               \"A256CBC-HS512\",\
609               \"A128GCM\",\
610               \"A192GCM\",\
611               \"A256GCM\"\
612            ],\
613            \"token_endpoint_auth_methods_supported\":[\
614               \"client_secret_post\",\
615               \"client_secret_basic\",\
616               \"client_secret_jwt\",\
617               \"private_key_jwt\"\
618            ],\
619            \"token_endpoint_auth_signing_alg_values_supported\":[\
620               \"RS256\",\
621               \"RS384\",\
622               \"RS512\",\
623               \"ES256\",\
624               \"ES384\",\
625               \"ES512\",\
626               \"HS256\",\
627               \"HS384\",\
628               \"HS512\",\
629               \"PS256\",\
630               \"PS384\",\
631               \"PS512\"\
632            ],\
633            \"claim_types_supported\":[\
634               \"normal\",\
635               \"aggregated\",\
636               \"distributed\"\
637            ],\
638            \"claims_supported\":[\
639               \"name\",\
640               \"given_name\",\
641               \"middle_name\",\
642               \"picture\",\
643               \"email_verified\",\
644               \"birthdate\",\
645               \"sub\",\
646               \"address\",\
647               \"zoneinfo\",\
648               \"email\",\
649               \"gender\",\
650               \"preferred_username\",\
651               \"family_name\",\
652               \"website\",\
653               \"profile\",\
654               \"phone_number_verified\",\
655               \"nickname\",\
656               \"updated_at\",\
657               \"phone_number\",\
658               \"locale\"\
659            ],\
660            \"claims_parameter_supported\":true,\
661            \"request_parameter_supported\":true,\
662            \"request_uri_parameter_supported\":true,\
663            \"require_request_uri_registration\":true";
664
665        let json_response = format!(
666            "{{{},{}}}",
667            json_response_standard,
668            "\"end_session_endpoint\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/end_session\",\
669            \"version\":\"3.0\""
670        );
671
672        let all_signing_algs = vec![
673            CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
674            CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384,
675            CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512,
676            CoreJwsSigningAlgorithm::EcdsaP256Sha256,
677            CoreJwsSigningAlgorithm::EcdsaP384Sha384,
678            CoreJwsSigningAlgorithm::EcdsaP521Sha512,
679            CoreJwsSigningAlgorithm::HmacSha256,
680            CoreJwsSigningAlgorithm::HmacSha384,
681            CoreJwsSigningAlgorithm::HmacSha512,
682            CoreJwsSigningAlgorithm::RsaSsaPssSha256,
683            CoreJwsSigningAlgorithm::RsaSsaPssSha384,
684            CoreJwsSigningAlgorithm::RsaSsaPssSha512,
685            CoreJwsSigningAlgorithm::None,
686        ];
687        let all_encryption_algs = vec![
688            CoreJweKeyManagementAlgorithm::RsaPkcs1V15,
689            CoreJweKeyManagementAlgorithm::RsaOaep,
690            CoreJweKeyManagementAlgorithm::RsaOaepSha256,
691            CoreJweKeyManagementAlgorithm::AesKeyWrap128,
692            CoreJweKeyManagementAlgorithm::AesKeyWrap192,
693            CoreJweKeyManagementAlgorithm::AesKeyWrap256,
694            CoreJweKeyManagementAlgorithm::EcdhEs,
695            CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap128,
696            CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap192,
697            CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap256,
698        ];
699        let new_provider_metadata = CoreProviderMetadata::new(
700            IssuerUrl::new(
701                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code"
702                    .to_string(),
703            )
704            .unwrap(),
705            AuthUrl::new(
706                "https://rp.certification.openid.net:8080/openidconnect-rs/\
707                 rp-response_type-code/authorization"
708                    .to_string(),
709            )
710            .unwrap(),
711            JsonWebKeySetUrl::new(
712                "https://rp.certification.openid.net:8080/static/jwks_3INbZl52IrrPCp2j.json"
713                    .to_string(),
714            )
715            .unwrap(),
716            vec![ResponseTypes::new(vec![CoreResponseType::Code])],
717            vec![
718                CoreSubjectIdentifierType::Public,
719                CoreSubjectIdentifierType::Pairwise,
720            ],
721            all_signing_algs.clone(),
722            Default::default(),
723        )
724        .set_request_object_signing_alg_values_supported(Some(all_signing_algs.clone()))
725        .set_token_endpoint_auth_signing_alg_values_supported(Some(vec![
726            CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
727            CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384,
728            CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512,
729            CoreJwsSigningAlgorithm::EcdsaP256Sha256,
730            CoreJwsSigningAlgorithm::EcdsaP384Sha384,
731            CoreJwsSigningAlgorithm::EcdsaP521Sha512,
732            CoreJwsSigningAlgorithm::HmacSha256,
733            CoreJwsSigningAlgorithm::HmacSha384,
734            CoreJwsSigningAlgorithm::HmacSha512,
735            CoreJwsSigningAlgorithm::RsaSsaPssSha256,
736            CoreJwsSigningAlgorithm::RsaSsaPssSha384,
737            CoreJwsSigningAlgorithm::RsaSsaPssSha512,
738        ]))
739        .set_scopes_supported(Some(vec![
740            Scope::new("email".to_string()),
741            Scope::new("phone".to_string()),
742            Scope::new("profile".to_string()),
743            Scope::new("openid".to_string()),
744            Scope::new("address".to_string()),
745            Scope::new("offline_access".to_string()),
746            Scope::new("openid".to_string()),
747        ]))
748        .set_userinfo_signing_alg_values_supported(Some(all_signing_algs))
749        .set_id_token_encryption_enc_values_supported(Some(vec![
750            CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256,
751            CoreJweContentEncryptionAlgorithm::Aes192CbcHmacSha384,
752            CoreJweContentEncryptionAlgorithm::Aes256CbcHmacSha512,
753            CoreJweContentEncryptionAlgorithm::Aes128Gcm,
754            CoreJweContentEncryptionAlgorithm::Aes192Gcm,
755            CoreJweContentEncryptionAlgorithm::Aes256Gcm,
756        ]))
757        .set_grant_types_supported(Some(vec![
758            CoreGrantType::AuthorizationCode,
759            CoreGrantType::Implicit,
760            CoreGrantType::JwtBearer,
761            CoreGrantType::RefreshToken,
762        ]))
763        .set_response_modes_supported(Some(vec![
764            CoreResponseMode::Query,
765            CoreResponseMode::Fragment,
766            CoreResponseMode::FormPost,
767        ]))
768        .set_require_request_uri_registration(Some(true))
769        .set_registration_endpoint(Some(
770            RegistrationUrl::new(
771                "https://rp.certification.openid.net:8080/openidconnect-rs/\
772                 rp-response_type-code/registration"
773                    .to_string(),
774            )
775            .unwrap(),
776        ))
777        .set_claims_parameter_supported(Some(true))
778        .set_request_object_encryption_enc_values_supported(Some(vec![
779            CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256,
780            CoreJweContentEncryptionAlgorithm::Aes192CbcHmacSha384,
781            CoreJweContentEncryptionAlgorithm::Aes256CbcHmacSha512,
782            CoreJweContentEncryptionAlgorithm::Aes128Gcm,
783            CoreJweContentEncryptionAlgorithm::Aes192Gcm,
784            CoreJweContentEncryptionAlgorithm::Aes256Gcm,
785        ]))
786        .set_userinfo_endpoint(Some(
787            UserInfoUrl::new(
788                "https://rp.certification.openid.net:8080/openidconnect-rs/\
789                 rp-response_type-code/userinfo"
790                    .to_string(),
791            )
792            .unwrap(),
793        ))
794        .set_token_endpoint_auth_methods_supported(Some(vec![
795            CoreClientAuthMethod::ClientSecretPost,
796            CoreClientAuthMethod::ClientSecretBasic,
797            CoreClientAuthMethod::ClientSecretJwt,
798            CoreClientAuthMethod::PrivateKeyJwt,
799        ]))
800        .set_claims_supported(Some(
801            vec![
802                "name",
803                "given_name",
804                "middle_name",
805                "picture",
806                "email_verified",
807                "birthdate",
808                "sub",
809                "address",
810                "zoneinfo",
811                "email",
812                "gender",
813                "preferred_username",
814                "family_name",
815                "website",
816                "profile",
817                "phone_number_verified",
818                "nickname",
819                "updated_at",
820                "phone_number",
821                "locale",
822            ]
823            .iter()
824            .map(|claim| CoreClaimName::new((*claim).to_string()))
825            .collect(),
826        ))
827        .set_request_object_encryption_alg_values_supported(Some(all_encryption_algs.clone()))
828        .set_claim_types_supported(Some(vec![
829            CoreClaimType::Normal,
830            CoreClaimType::Aggregated,
831            CoreClaimType::Distributed,
832        ]))
833        .set_request_uri_parameter_supported(Some(true))
834        .set_request_parameter_supported(Some(true))
835        .set_token_endpoint(Some(
836            TokenUrl::new(
837                "https://rp.certification.openid.net:8080/openidconnect-rs/\
838                 rp-response_type-code/token"
839                    .to_string(),
840            )
841            .unwrap(),
842        ))
843        .set_id_token_encryption_alg_values_supported(Some(all_encryption_algs.clone()))
844        .set_userinfo_encryption_alg_values_supported(Some(all_encryption_algs))
845        .set_userinfo_encryption_enc_values_supported(Some(vec![
846            CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256,
847            CoreJweContentEncryptionAlgorithm::Aes192CbcHmacSha384,
848            CoreJweContentEncryptionAlgorithm::Aes256CbcHmacSha512,
849            CoreJweContentEncryptionAlgorithm::Aes128Gcm,
850            CoreJweContentEncryptionAlgorithm::Aes192Gcm,
851            CoreJweContentEncryptionAlgorithm::Aes256Gcm,
852        ]))
853        .set_acr_values_supported(Some(vec![AuthenticationContextClass::new(
854            "PASSWORD".to_string(),
855        )]));
856
857        let provider_metadata: CoreProviderMetadata = serde_json::from_str(&json_response).unwrap();
858        assert_eq!(provider_metadata, new_provider_metadata);
859
860        let serialized = serde_json::to_string(&provider_metadata).unwrap();
861        assert_eq!(serialized, format!("{{{}}}", json_response_standard));
862
863        assert_eq!(
864            IssuerUrl::new(
865                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code"
866                    .to_string()
867            )
868            .unwrap(),
869            *provider_metadata.issuer()
870        );
871        assert_eq!(
872            AuthUrl::new(
873                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\
874                 /authorization"
875                    .to_string()
876            )
877            .unwrap(),
878            *provider_metadata.authorization_endpoint()
879        );
880        assert_eq!(
881            Some(
882                &TokenUrl::new(
883                    "https://rp.certification.openid.net:8080/openidconnect-rs\
884                     /rp-response_type-code/token"
885                        .to_string()
886                )
887                .unwrap()
888            ),
889            provider_metadata.token_endpoint()
890        );
891        assert_eq!(
892            Some(
893                &UserInfoUrl::new(
894                    "https://rp.certification.openid.net:8080/openidconnect-rs\
895                     /rp-response_type-code/userinfo"
896                        .to_string()
897                )
898                .unwrap()
899            ),
900            provider_metadata.userinfo_endpoint()
901        );
902        assert_eq!(
903            &JsonWebKeySetUrl::new(
904                "https://rp.certification.openid.net:8080/static/jwks_3INbZl52IrrPCp2j.json"
905                    .to_string()
906            )
907            .unwrap(),
908            provider_metadata.jwks_uri()
909        );
910        assert_eq!(
911            Some(
912                &RegistrationUrl::new(
913                    "https://rp.certification.openid.net:8080/openidconnect-rs\
914                     /rp-response_type-code/registration"
915                        .to_string()
916                )
917                .unwrap()
918            ),
919            provider_metadata.registration_endpoint()
920        );
921        assert_eq!(
922            Some(
923                &vec![
924                    "email",
925                    "phone",
926                    "profile",
927                    "openid",
928                    "address",
929                    "offline_access",
930                    "openid",
931                ]
932                .iter()
933                .map(|s| (*s).to_string())
934                .map(Scope::new)
935                .collect::<Vec<_>>()
936            ),
937            provider_metadata.scopes_supported()
938        );
939        assert_eq!(
940            vec![ResponseTypes::new(vec![CoreResponseType::Code])],
941            *provider_metadata.response_types_supported()
942        );
943        assert_eq!(
944            Some(&vec![
945                CoreResponseMode::Query,
946                CoreResponseMode::Fragment,
947                CoreResponseMode::FormPost,
948            ]),
949            provider_metadata.response_modes_supported()
950        );
951        assert_eq!(
952            Some(
953                &vec![
954                    CoreGrantType::AuthorizationCode,
955                    CoreGrantType::Implicit,
956                    CoreGrantType::JwtBearer,
957                    CoreGrantType::RefreshToken,
958                ]
959                .into_iter()
960                .collect::<Vec<_>>()
961            ),
962            provider_metadata.grant_types_supported()
963        );
964        assert_eq!(
965            Some(&vec![AuthenticationContextClass::new(
966                "PASSWORD".to_string(),
967            )]),
968            provider_metadata.acr_values_supported()
969        );
970        assert_eq!(
971            vec![
972                CoreSubjectIdentifierType::Public,
973                CoreSubjectIdentifierType::Pairwise,
974            ],
975            *provider_metadata.subject_types_supported()
976        );
977        assert_eq!(
978            vec![
979                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
980                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384,
981                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512,
982                CoreJwsSigningAlgorithm::EcdsaP256Sha256,
983                CoreJwsSigningAlgorithm::EcdsaP384Sha384,
984                CoreJwsSigningAlgorithm::EcdsaP521Sha512,
985                CoreJwsSigningAlgorithm::HmacSha256,
986                CoreJwsSigningAlgorithm::HmacSha384,
987                CoreJwsSigningAlgorithm::HmacSha512,
988                CoreJwsSigningAlgorithm::RsaSsaPssSha256,
989                CoreJwsSigningAlgorithm::RsaSsaPssSha384,
990                CoreJwsSigningAlgorithm::RsaSsaPssSha512,
991                CoreJwsSigningAlgorithm::None,
992            ],
993            *provider_metadata.id_token_signing_alg_values_supported()
994        );
995        assert_eq!(
996            Some(&vec![
997                CoreJweKeyManagementAlgorithm::RsaPkcs1V15,
998                CoreJweKeyManagementAlgorithm::RsaOaep,
999                CoreJweKeyManagementAlgorithm::RsaOaepSha256,
1000                CoreJweKeyManagementAlgorithm::AesKeyWrap128,
1001                CoreJweKeyManagementAlgorithm::AesKeyWrap192,
1002                CoreJweKeyManagementAlgorithm::AesKeyWrap256,
1003                CoreJweKeyManagementAlgorithm::EcdhEs,
1004                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap128,
1005                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap192,
1006                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap256,
1007            ]),
1008            provider_metadata.id_token_encryption_alg_values_supported()
1009        );
1010        assert_eq!(
1011            Some(&vec![
1012                CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256,
1013                CoreJweContentEncryptionAlgorithm::Aes192CbcHmacSha384,
1014                CoreJweContentEncryptionAlgorithm::Aes256CbcHmacSha512,
1015                CoreJweContentEncryptionAlgorithm::Aes128Gcm,
1016                CoreJweContentEncryptionAlgorithm::Aes192Gcm,
1017                CoreJweContentEncryptionAlgorithm::Aes256Gcm,
1018            ]),
1019            provider_metadata.id_token_encryption_enc_values_supported()
1020        );
1021        assert_eq!(
1022            Some(&vec![
1023                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1024                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384,
1025                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512,
1026                CoreJwsSigningAlgorithm::EcdsaP256Sha256,
1027                CoreJwsSigningAlgorithm::EcdsaP384Sha384,
1028                CoreJwsSigningAlgorithm::EcdsaP521Sha512,
1029                CoreJwsSigningAlgorithm::HmacSha256,
1030                CoreJwsSigningAlgorithm::HmacSha384,
1031                CoreJwsSigningAlgorithm::HmacSha512,
1032                CoreJwsSigningAlgorithm::RsaSsaPssSha256,
1033                CoreJwsSigningAlgorithm::RsaSsaPssSha384,
1034                CoreJwsSigningAlgorithm::RsaSsaPssSha512,
1035                CoreJwsSigningAlgorithm::None,
1036            ]),
1037            provider_metadata.userinfo_signing_alg_values_supported()
1038        );
1039        assert_eq!(
1040            Some(&vec![
1041                CoreJweKeyManagementAlgorithm::RsaPkcs1V15,
1042                CoreJweKeyManagementAlgorithm::RsaOaep,
1043                CoreJweKeyManagementAlgorithm::RsaOaepSha256,
1044                CoreJweKeyManagementAlgorithm::AesKeyWrap128,
1045                CoreJweKeyManagementAlgorithm::AesKeyWrap192,
1046                CoreJweKeyManagementAlgorithm::AesKeyWrap256,
1047                CoreJweKeyManagementAlgorithm::EcdhEs,
1048                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap128,
1049                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap192,
1050                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap256,
1051            ]),
1052            provider_metadata.userinfo_encryption_alg_values_supported()
1053        );
1054        assert_eq!(
1055            Some(&vec![
1056                CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256,
1057                CoreJweContentEncryptionAlgorithm::Aes192CbcHmacSha384,
1058                CoreJweContentEncryptionAlgorithm::Aes256CbcHmacSha512,
1059                CoreJweContentEncryptionAlgorithm::Aes128Gcm,
1060                CoreJweContentEncryptionAlgorithm::Aes192Gcm,
1061                CoreJweContentEncryptionAlgorithm::Aes256Gcm,
1062            ]),
1063            provider_metadata.userinfo_encryption_enc_values_supported()
1064        );
1065        assert_eq!(
1066            Some(&vec![
1067                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1068                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384,
1069                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512,
1070                CoreJwsSigningAlgorithm::EcdsaP256Sha256,
1071                CoreJwsSigningAlgorithm::EcdsaP384Sha384,
1072                CoreJwsSigningAlgorithm::EcdsaP521Sha512,
1073                CoreJwsSigningAlgorithm::HmacSha256,
1074                CoreJwsSigningAlgorithm::HmacSha384,
1075                CoreJwsSigningAlgorithm::HmacSha512,
1076                CoreJwsSigningAlgorithm::RsaSsaPssSha256,
1077                CoreJwsSigningAlgorithm::RsaSsaPssSha384,
1078                CoreJwsSigningAlgorithm::RsaSsaPssSha512,
1079                CoreJwsSigningAlgorithm::None,
1080            ]),
1081            provider_metadata.request_object_signing_alg_values_supported()
1082        );
1083        assert_eq!(
1084            Some(&vec![
1085                CoreJweKeyManagementAlgorithm::RsaPkcs1V15,
1086                CoreJweKeyManagementAlgorithm::RsaOaep,
1087                CoreJweKeyManagementAlgorithm::RsaOaepSha256,
1088                CoreJweKeyManagementAlgorithm::AesKeyWrap128,
1089                CoreJweKeyManagementAlgorithm::AesKeyWrap192,
1090                CoreJweKeyManagementAlgorithm::AesKeyWrap256,
1091                CoreJweKeyManagementAlgorithm::EcdhEs,
1092                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap128,
1093                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap192,
1094                CoreJweKeyManagementAlgorithm::EcdhEsAesKeyWrap256,
1095            ]),
1096            provider_metadata.request_object_encryption_alg_values_supported()
1097        );
1098        assert_eq!(
1099            Some(&vec![
1100                CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256,
1101                CoreJweContentEncryptionAlgorithm::Aes192CbcHmacSha384,
1102                CoreJweContentEncryptionAlgorithm::Aes256CbcHmacSha512,
1103                CoreJweContentEncryptionAlgorithm::Aes128Gcm,
1104                CoreJweContentEncryptionAlgorithm::Aes192Gcm,
1105                CoreJweContentEncryptionAlgorithm::Aes256Gcm,
1106            ]),
1107            provider_metadata.request_object_encryption_enc_values_supported()
1108        );
1109        assert_eq!(
1110            Some(&vec![
1111                CoreClientAuthMethod::ClientSecretPost,
1112                CoreClientAuthMethod::ClientSecretBasic,
1113                CoreClientAuthMethod::ClientSecretJwt,
1114                CoreClientAuthMethod::PrivateKeyJwt,
1115            ]),
1116            provider_metadata.token_endpoint_auth_methods_supported()
1117        );
1118        assert_eq!(
1119            Some(&vec![
1120                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1121                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384,
1122                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512,
1123                CoreJwsSigningAlgorithm::EcdsaP256Sha256,
1124                CoreJwsSigningAlgorithm::EcdsaP384Sha384,
1125                CoreJwsSigningAlgorithm::EcdsaP521Sha512,
1126                CoreJwsSigningAlgorithm::HmacSha256,
1127                CoreJwsSigningAlgorithm::HmacSha384,
1128                CoreJwsSigningAlgorithm::HmacSha512,
1129                CoreJwsSigningAlgorithm::RsaSsaPssSha256,
1130                CoreJwsSigningAlgorithm::RsaSsaPssSha384,
1131                CoreJwsSigningAlgorithm::RsaSsaPssSha512,
1132            ]),
1133            provider_metadata.token_endpoint_auth_signing_alg_values_supported()
1134        );
1135        assert_eq!(None, provider_metadata.display_values_supported());
1136        assert_eq!(
1137            Some(&vec![
1138                CoreClaimType::Normal,
1139                CoreClaimType::Aggregated,
1140                CoreClaimType::Distributed,
1141            ]),
1142            provider_metadata.claim_types_supported()
1143        );
1144        assert_eq!(
1145            Some(&vec![
1146                CoreClaimName::new("name".to_string()),
1147                CoreClaimName::new("given_name".to_string()),
1148                CoreClaimName::new("middle_name".to_string()),
1149                CoreClaimName::new("picture".to_string()),
1150                CoreClaimName::new("email_verified".to_string()),
1151                CoreClaimName::new("birthdate".to_string()),
1152                CoreClaimName::new("sub".to_string()),
1153                CoreClaimName::new("address".to_string()),
1154                CoreClaimName::new("zoneinfo".to_string()),
1155                CoreClaimName::new("email".to_string()),
1156                CoreClaimName::new("gender".to_string()),
1157                CoreClaimName::new("preferred_username".to_string()),
1158                CoreClaimName::new("family_name".to_string()),
1159                CoreClaimName::new("website".to_string()),
1160                CoreClaimName::new("profile".to_string()),
1161                CoreClaimName::new("phone_number_verified".to_string()),
1162                CoreClaimName::new("nickname".to_string()),
1163                CoreClaimName::new("updated_at".to_string()),
1164                CoreClaimName::new("phone_number".to_string()),
1165                CoreClaimName::new("locale".to_string()),
1166            ]),
1167            provider_metadata.claims_supported()
1168        );
1169        assert_eq!(None, provider_metadata.service_documentation());
1170        assert_eq!(None, provider_metadata.claims_locales_supported());
1171        assert_eq!(None, provider_metadata.ui_locales_supported());
1172        assert_eq!(Some(true), provider_metadata.claims_parameter_supported());
1173        assert_eq!(Some(true), provider_metadata.request_parameter_supported());
1174        assert_eq!(
1175            Some(true),
1176            provider_metadata.request_uri_parameter_supported()
1177        );
1178        assert_eq!(
1179            Some(true),
1180            provider_metadata.require_request_uri_registration()
1181        );
1182        assert_eq!(None, provider_metadata.op_policy_uri());
1183        assert_eq!(None, provider_metadata.op_tos_uri());
1184
1185        // Note: the following fields provided by the response above are not part of the OpenID
1186        // Connect Discovery 1.0 spec:
1187        // - end_session_endpoint
1188        // - version
1189
1190        let serialized_json = serde_json::to_string(&provider_metadata).unwrap();
1191
1192        let redeserialized_metadata: CoreProviderMetadata =
1193            serde_json::from_str(&serialized_json).unwrap();
1194        assert_eq!(provider_metadata, redeserialized_metadata);
1195    }
1196
1197    // Tests the fields missing from the example response in test_discovery_deserialization().
1198    #[test]
1199    fn test_discovery_deserialization_other_fields() {
1200        let json_response = "{
1201        \"issuer\" : \"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\",
1202        \"authorization_endpoint\" : \"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/authorization\",
1203        \"jwks_uri\" : \"https://rp.certification.openid.net:8080/static/jwks_oMXD5waO08Q1GEnv.json\",
1204        \"response_types_supported\" : [
1205           \"code\",
1206           \"code token\",
1207           \"code id_token\",
1208           \"id_token token\",
1209           \"code id_token token\",
1210           \"token id_token\",
1211           \"token id_token code\",
1212           \"id_token\",
1213           \"token\"
1214        ],
1215        \"subject_types_supported\" : [
1216           \"public\",
1217           \"pairwise\"
1218        ],
1219        \"id_token_signing_alg_values_supported\" : [
1220           \"HS256\",
1221           \"HS384\",
1222           \"HS512\"
1223        ],
1224        \"display_values_supported\" : [
1225           \"page\",
1226           \"popup\",
1227           \"touch\",
1228           \"wap\"
1229        ],
1230        \"service_documentation\" : \"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/documentation\",
1231        \"claims_locales_supported\" : [
1232           \"de\",
1233           \"fr\",
1234           \"de-CH-1901\"
1235        ],
1236        \"ui_locales_supported\" : [
1237           \"ja\",
1238           \"sr-Latn\",
1239           \"yue-HK\"
1240        ],
1241        \"op_policy_uri\" : \"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/op_policy\",
1242        \"op_tos_uri\" : \"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/op_tos\"
1243    }";
1244
1245        let provider_metadata: CoreProviderMetadata = serde_json::from_str(json_response).unwrap();
1246
1247        assert_eq!(
1248            IssuerUrl::new(
1249                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code"
1250                    .to_string()
1251            )
1252            .unwrap(),
1253            *provider_metadata.issuer()
1254        );
1255        assert_eq!(
1256            AuthUrl::new(
1257                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\
1258                 /authorization"
1259                    .to_string()
1260            )
1261            .unwrap(),
1262            *provider_metadata.authorization_endpoint()
1263        );
1264        assert_eq!(None, provider_metadata.token_endpoint());
1265        assert_eq!(None, provider_metadata.userinfo_endpoint());
1266        assert_eq!(
1267            JsonWebKeySetUrl::new(
1268                "https://rp.certification.openid.net:8080/static/jwks_oMXD5waO08Q1GEnv.json"
1269                    .to_string()
1270            )
1271            .unwrap(),
1272            *provider_metadata.jwks_uri()
1273        );
1274        assert_eq!(None, provider_metadata.registration_endpoint());
1275        assert_eq!(None, provider_metadata.scopes_supported());
1276        assert_eq!(
1277            vec![
1278                ResponseTypes::new(vec![CoreResponseType::Code]),
1279                ResponseTypes::new(vec![CoreResponseType::Code, CoreResponseType::Token]),
1280                ResponseTypes::new(vec![CoreResponseType::Code, CoreResponseType::IdToken]),
1281                ResponseTypes::new(vec![CoreResponseType::IdToken, CoreResponseType::Token]),
1282                ResponseTypes::new(vec![
1283                    CoreResponseType::Code,
1284                    CoreResponseType::IdToken,
1285                    CoreResponseType::Token,
1286                ]),
1287                ResponseTypes::new(vec![CoreResponseType::Token, CoreResponseType::IdToken]),
1288                ResponseTypes::new(vec![
1289                    CoreResponseType::Token,
1290                    CoreResponseType::IdToken,
1291                    CoreResponseType::Code,
1292                ]),
1293                ResponseTypes::new(vec![CoreResponseType::IdToken]),
1294                ResponseTypes::new(vec![CoreResponseType::Token]),
1295            ],
1296            *provider_metadata.response_types_supported()
1297        );
1298        assert_eq!(None, provider_metadata.response_modes_supported());
1299        assert_eq!(None, provider_metadata.grant_types_supported());
1300        assert_eq!(None, provider_metadata.acr_values_supported());
1301        assert_eq!(
1302            vec![
1303                CoreSubjectIdentifierType::Public,
1304                CoreSubjectIdentifierType::Pairwise,
1305            ],
1306            *provider_metadata.subject_types_supported()
1307        );
1308        assert_eq!(
1309            vec![
1310                CoreJwsSigningAlgorithm::HmacSha256,
1311                CoreJwsSigningAlgorithm::HmacSha384,
1312                CoreJwsSigningAlgorithm::HmacSha512,
1313            ],
1314            *provider_metadata.id_token_signing_alg_values_supported()
1315        );
1316        assert_eq!(
1317            None,
1318            provider_metadata.id_token_encryption_alg_values_supported()
1319        );
1320        assert_eq!(
1321            None,
1322            provider_metadata.id_token_encryption_enc_values_supported()
1323        );
1324        assert_eq!(
1325            None,
1326            provider_metadata.userinfo_signing_alg_values_supported()
1327        );
1328        assert_eq!(
1329            None,
1330            provider_metadata.userinfo_encryption_alg_values_supported()
1331        );
1332        assert_eq!(
1333            None,
1334            provider_metadata.userinfo_encryption_enc_values_supported()
1335        );
1336        assert_eq!(
1337            None,
1338            provider_metadata.request_object_signing_alg_values_supported()
1339        );
1340        assert_eq!(
1341            None,
1342            provider_metadata.request_object_encryption_alg_values_supported()
1343        );
1344        assert_eq!(
1345            None,
1346            provider_metadata.request_object_encryption_enc_values_supported()
1347        );
1348        assert_eq!(
1349            None,
1350            provider_metadata.token_endpoint_auth_methods_supported()
1351        );
1352        assert_eq!(
1353            None,
1354            provider_metadata.token_endpoint_auth_signing_alg_values_supported()
1355        );
1356        assert_eq!(
1357            Some(&vec![
1358                CoreAuthDisplay::Page,
1359                CoreAuthDisplay::Popup,
1360                CoreAuthDisplay::Touch,
1361                CoreAuthDisplay::Wap,
1362            ]),
1363            provider_metadata.display_values_supported()
1364        );
1365        assert_eq!(None, provider_metadata.claim_types_supported());
1366        assert_eq!(None, provider_metadata.claims_supported());
1367
1368        assert_eq!(
1369            Some(
1370                &ServiceDocUrl::new(
1371                    "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\
1372                 /documentation"
1373                        .to_string()
1374                )
1375                    .unwrap()
1376            ),
1377            provider_metadata.service_documentation()
1378        );
1379        assert_eq!(
1380            Some(&vec![
1381                LanguageTag::new("de".to_string()),
1382                LanguageTag::new("fr".to_string()),
1383                LanguageTag::new("de-CH-1901".to_string()),
1384            ]),
1385            provider_metadata.claims_locales_supported()
1386        );
1387        assert_eq!(
1388            Some(&vec![
1389                LanguageTag::new("ja".to_string()),
1390                LanguageTag::new("sr-Latn".to_string()),
1391                LanguageTag::new("yue-HK".to_string()),
1392            ]),
1393            provider_metadata.ui_locales_supported()
1394        );
1395        assert_eq!(None, provider_metadata.claims_parameter_supported());
1396        assert_eq!(None, provider_metadata.request_parameter_supported());
1397        assert_eq!(None, provider_metadata.request_uri_parameter_supported());
1398        assert_eq!(None, provider_metadata.require_request_uri_registration());
1399        assert_eq!(
1400            Some(
1401                &OpPolicyUrl::new(
1402                    "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\
1403                 /op_policy"
1404                        .to_string()
1405                )
1406                    .unwrap()
1407            ),
1408            provider_metadata.op_policy_uri()
1409        );
1410        assert_eq!(
1411            Some(
1412                &OpTosUrl::new(
1413                    "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\
1414                 /op_tos"
1415                        .to_string()
1416                )
1417                    .unwrap()
1418            ),
1419            provider_metadata.op_tos_uri()
1420        );
1421
1422        let serialized_json = serde_json::to_string(&provider_metadata).unwrap();
1423
1424        let redeserialized_metadata: CoreProviderMetadata =
1425            serde_json::from_str(&serialized_json).unwrap();
1426        assert_eq!(provider_metadata, redeserialized_metadata);
1427    }
1428
1429    // Tests that we ignore enum values that the OIDC provider supports but that the client does
1430    // not (which trigger serde deserialization errors while parsing the provider metadata).
1431    #[test]
1432    fn test_unsupported_enum_values() {
1433        let json_response = "{\
1434            \"issuer\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\",\
1435            \"authorization_endpoint\":\"https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code/authorization\",\
1436            \"jwks_uri\":\"https://rp.certification.openid.net:8080/static/jwks_3INbZl52IrrPCp2j.json\",\
1437            \"response_types_supported\":[\
1438               \"code\"\
1439            ],\
1440            \"subject_types_supported\":[\
1441               \"public\",\
1442               \"pairwise\"\
1443            ],\
1444            \"id_token_signing_alg_values_supported\":[\
1445               \"RS256\",\
1446               \"MAGIC\",\
1447               \"none\"\
1448            ],\
1449            \"id_token_encryption_alg_values_supported\":[\
1450               \"RSA1_5\",\
1451               \"MAGIC\"\
1452            ],\
1453            \"id_token_encryption_enc_values_supported\":[\
1454               \"A128CBC-HS256\",\
1455               \"MAGIC\"\
1456            ],\
1457            \"userinfo_signing_alg_values_supported\":[\
1458               \"RS256\",\
1459               \"MAGIC\",\
1460               \"none\"\
1461            ],\
1462            \"userinfo_encryption_alg_values_supported\":[\
1463               \"RSA1_5\",\
1464               \"MAGIC\"\
1465            ],\
1466            \"userinfo_encryption_enc_values_supported\":[\
1467               \"A128CBC-HS256\",\
1468               \"MAGIC\"\
1469            ],\
1470            \"request_object_signing_alg_values_supported\":[\
1471               \"RS256\",\
1472               \"MAGIC\",\
1473               \"none\"\
1474            ],\
1475            \"request_object_encryption_alg_values_supported\":[\
1476               \"RSA1_5\",\
1477               \"MAGIC\"\
1478            ],\
1479            \"request_object_encryption_enc_values_supported\":[\
1480               \"A128CBC-HS256\",\
1481               \"MAGIC\"\
1482            ],\
1483            \"token_endpoint_auth_signing_alg_values_supported\":[\
1484               \"RS256\",\
1485               \"MAGIC\",\
1486               \"none\"\
1487            ]\
1488        }";
1489
1490        let provider_metadata: CoreProviderMetadata = serde_json::from_str(json_response).unwrap();
1491
1492        assert_eq!(
1493            IssuerUrl::new(
1494                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code"
1495                    .to_string()
1496            )
1497            .unwrap(),
1498            *provider_metadata.issuer()
1499        );
1500        assert_eq!(
1501            AuthUrl::new(
1502                "https://rp.certification.openid.net:8080/openidconnect-rs/rp-response_type-code\
1503                 /authorization"
1504                    .to_string()
1505            )
1506            .unwrap(),
1507            *provider_metadata.authorization_endpoint()
1508        );
1509        assert_eq!(None, provider_metadata.token_endpoint());
1510        assert_eq!(None, provider_metadata.userinfo_endpoint());
1511        assert_eq!(
1512            JsonWebKeySetUrl::new(
1513                "https://rp.certification.openid.net:8080/static/jwks_3INbZl52IrrPCp2j.json"
1514                    .to_string()
1515            )
1516            .unwrap(),
1517            *provider_metadata.jwks_uri()
1518        );
1519        assert_eq!(None, provider_metadata.registration_endpoint());
1520        assert_eq!(None, provider_metadata.scopes_supported());
1521        assert_eq!(
1522            vec![ResponseTypes::new(vec![CoreResponseType::Code])],
1523            *provider_metadata.response_types_supported()
1524        );
1525        assert_eq!(None, provider_metadata.response_modes_supported());
1526        assert_eq!(None, provider_metadata.grant_types_supported());
1527        assert_eq!(None, provider_metadata.acr_values_supported());
1528        assert_eq!(
1529            vec![
1530                CoreSubjectIdentifierType::Public,
1531                CoreSubjectIdentifierType::Pairwise,
1532            ],
1533            *provider_metadata.subject_types_supported()
1534        );
1535        assert_eq!(
1536            vec![
1537                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1538                CoreJwsSigningAlgorithm::None,
1539            ],
1540            *provider_metadata.id_token_signing_alg_values_supported()
1541        );
1542        assert_eq!(
1543            Some(&vec![CoreJweKeyManagementAlgorithm::RsaPkcs1V15]),
1544            provider_metadata.id_token_encryption_alg_values_supported()
1545        );
1546        assert_eq!(
1547            Some(&vec![
1548                CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256
1549            ]),
1550            provider_metadata.id_token_encryption_enc_values_supported()
1551        );
1552        assert_eq!(
1553            Some(&vec![
1554                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1555                CoreJwsSigningAlgorithm::None,
1556            ]),
1557            provider_metadata.userinfo_signing_alg_values_supported()
1558        );
1559        assert_eq!(
1560            Some(&vec![CoreJweKeyManagementAlgorithm::RsaPkcs1V15]),
1561            provider_metadata.userinfo_encryption_alg_values_supported()
1562        );
1563        assert_eq!(
1564            Some(&vec![
1565                CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256
1566            ]),
1567            provider_metadata.userinfo_encryption_enc_values_supported()
1568        );
1569        assert_eq!(
1570            Some(&vec![
1571                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1572                CoreJwsSigningAlgorithm::None,
1573            ]),
1574            provider_metadata.request_object_signing_alg_values_supported()
1575        );
1576        assert_eq!(
1577            Some(&vec![CoreJweKeyManagementAlgorithm::RsaPkcs1V15]),
1578            provider_metadata.request_object_encryption_alg_values_supported()
1579        );
1580        assert_eq!(
1581            Some(&vec![
1582                CoreJweContentEncryptionAlgorithm::Aes128CbcHmacSha256
1583            ]),
1584            provider_metadata.request_object_encryption_enc_values_supported()
1585        );
1586        assert_eq!(
1587            None,
1588            provider_metadata.token_endpoint_auth_methods_supported()
1589        );
1590        assert_eq!(
1591            Some(&vec![
1592                CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256,
1593                CoreJwsSigningAlgorithm::None,
1594            ]),
1595            provider_metadata.token_endpoint_auth_signing_alg_values_supported()
1596        );
1597        assert_eq!(None, provider_metadata.display_values_supported());
1598        assert_eq!(None, provider_metadata.claim_types_supported());
1599        assert_eq!(None, provider_metadata.claims_supported());
1600
1601        assert_eq!(None, provider_metadata.service_documentation());
1602        assert_eq!(None, provider_metadata.claims_locales_supported());
1603        assert_eq!(None, provider_metadata.ui_locales_supported());
1604        assert_eq!(None, provider_metadata.claims_parameter_supported());
1605        assert_eq!(None, provider_metadata.request_parameter_supported());
1606        assert_eq!(None, provider_metadata.request_uri_parameter_supported());
1607        assert_eq!(None, provider_metadata.require_request_uri_registration());
1608        assert_eq!(None, provider_metadata.op_policy_uri());
1609        assert_eq!(None, provider_metadata.op_tos_uri());
1610
1611        let serialized_json = serde_json::to_string(&provider_metadata).unwrap();
1612
1613        let redeserialized_metadata: CoreProviderMetadata =
1614            serde_json::from_str(&serialized_json).unwrap();
1615        assert_eq!(provider_metadata, redeserialized_metadata);
1616    }
1617}