1 use std::fmt::{Display, Error as FormatterError, Formatter};
2 use std::ops::Deref;
3 
4 pub use oauth2::basic::{
5     BasicErrorResponseType as CoreErrorResponseType,
6     BasicRequestTokenError as CoreRequestTokenError,
7     BasicRevocationErrorResponse as CoreRevocationErrorResponse, BasicTokenType as CoreTokenType,
8 };
9 pub use oauth2::StandardRevocableToken as CoreRevocableToken;
10 use oauth2::{
11     EmptyExtraTokenFields, ErrorResponseType, ResponseType as OAuth2ResponseType,
12     StandardErrorResponse, StandardTokenIntrospectionResponse, StandardTokenResponse,
13 };
14 
15 use serde::{Deserialize, Serialize};
16 
17 use crate::registration::{
18     ClientMetadata, ClientRegistrationRequest, ClientRegistrationResponse,
19     EmptyAdditionalClientMetadata, EmptyAdditionalClientRegistrationResponse,
20     RegisterErrorResponseType,
21 };
22 use crate::{
23     ApplicationType, AuthDisplay, AuthPrompt, ClaimName, ClaimType, Client, ClientAuthMethod,
24     EmptyAdditionalClaims, EmptyAdditionalProviderMetadata, GenderClaim, GrantType, IdToken,
25     IdTokenClaims, IdTokenFields, IdTokenVerifier, JsonWebKeySet, JweContentEncryptionAlgorithm,
26     JweKeyManagementAlgorithm, JwsSigningAlgorithm, ProviderMetadata, ResponseMode, ResponseType,
27     SubjectIdentifierType, UserInfoClaims, UserInfoJsonWebToken, UserInfoVerifier,
28 };
29 
30 use super::AuthenticationFlow;
31 
32 pub use self::jwk::{
33     CoreHmacKey, CoreJsonWebKey, CoreJsonWebKeyType, CoreJsonWebKeyUse, CoreRsaPrivateSigningKey,
34 };
35 
36 mod crypto;
37 
38 // Private purely for organizational reasons; exported publicly above.
39 mod jwk;
40 
41 ///
42 /// OpenID Connect Core token introspection response.
43 ///
44 pub type CoreTokenIntrospectionResponse =
45     StandardTokenIntrospectionResponse<EmptyExtraTokenFields, CoreTokenType>;
46 
47 ///
48 /// OpenID Connect Core authentication flows.
49 ///
50 pub type CoreAuthenticationFlow = AuthenticationFlow<CoreResponseType>;
51 
52 ///
53 /// OpenID Connect Core client.
54 ///
55 pub type CoreClient = Client<
56     EmptyAdditionalClaims,
57     CoreAuthDisplay,
58     CoreGenderClaim,
59     CoreJweContentEncryptionAlgorithm,
60     CoreJwsSigningAlgorithm,
61     CoreJsonWebKeyType,
62     CoreJsonWebKeyUse,
63     CoreJsonWebKey,
64     CoreAuthPrompt,
65     StandardErrorResponse<CoreErrorResponseType>,
66     CoreTokenResponse,
67     CoreTokenType,
68     CoreTokenIntrospectionResponse,
69     CoreRevocableToken,
70     CoreRevocationErrorResponse,
71 >;
72 
73 ///
74 /// OpenID Connect Core client metadata.
75 ///
76 pub type CoreClientMetadata = ClientMetadata<
77     EmptyAdditionalClientMetadata,
78     CoreApplicationType,
79     CoreClientAuthMethod,
80     CoreGrantType,
81     CoreJweContentEncryptionAlgorithm,
82     CoreJweKeyManagementAlgorithm,
83     CoreJwsSigningAlgorithm,
84     CoreJsonWebKeyType,
85     CoreJsonWebKeyUse,
86     CoreJsonWebKey,
87     CoreResponseType,
88     CoreSubjectIdentifierType,
89 >;
90 
91 ///
92 /// OpenID Connect Core client registration request.
93 ///
94 pub type CoreClientRegistrationRequest = ClientRegistrationRequest<
95     EmptyAdditionalClientMetadata,
96     EmptyAdditionalClientRegistrationResponse,
97     CoreApplicationType,
98     CoreClientAuthMethod,
99     CoreRegisterErrorResponseType,
100     CoreGrantType,
101     CoreJweContentEncryptionAlgorithm,
102     CoreJweKeyManagementAlgorithm,
103     CoreJwsSigningAlgorithm,
104     CoreJsonWebKeyType,
105     CoreJsonWebKeyUse,
106     CoreJsonWebKey,
107     CoreResponseType,
108     CoreSubjectIdentifierType,
109 >;
110 
111 ///
112 /// OpenID Connect Core client registration response.
113 ///
114 pub type CoreClientRegistrationResponse = ClientRegistrationResponse<
115     EmptyAdditionalClientMetadata,
116     EmptyAdditionalClientRegistrationResponse,
117     CoreApplicationType,
118     CoreClientAuthMethod,
119     CoreGrantType,
120     CoreJweContentEncryptionAlgorithm,
121     CoreJweKeyManagementAlgorithm,
122     CoreJwsSigningAlgorithm,
123     CoreJsonWebKeyType,
124     CoreJsonWebKeyUse,
125     CoreJsonWebKey,
126     CoreResponseType,
127     CoreSubjectIdentifierType,
128 >;
129 
130 ///
131 /// OpenID Connect Core ID token.
132 ///
133 pub type CoreIdToken = IdToken<
134     EmptyAdditionalClaims,
135     CoreGenderClaim,
136     CoreJweContentEncryptionAlgorithm,
137     CoreJwsSigningAlgorithm,
138     CoreJsonWebKeyType,
139 >;
140 
141 ///
142 /// OpenID Connect Core ID token claims.
143 ///
144 pub type CoreIdTokenClaims = IdTokenClaims<EmptyAdditionalClaims, CoreGenderClaim>;
145 
146 ///
147 /// OpenID Connect Core ID token fields.
148 ///
149 pub type CoreIdTokenFields = IdTokenFields<
150     EmptyAdditionalClaims,
151     EmptyExtraTokenFields,
152     CoreGenderClaim,
153     CoreJweContentEncryptionAlgorithm,
154     CoreJwsSigningAlgorithm,
155     CoreJsonWebKeyType,
156 >;
157 
158 ///
159 /// OpenID Connect Core ID token verifier.
160 ///
161 pub type CoreIdTokenVerifier<'a> = IdTokenVerifier<
162     'a,
163     CoreJwsSigningAlgorithm,
164     CoreJsonWebKeyType,
165     CoreJsonWebKeyUse,
166     CoreJsonWebKey,
167 >;
168 
169 ///
170 /// OpenID Connect Core token response.
171 ///
172 pub type CoreTokenResponse = StandardTokenResponse<CoreIdTokenFields, CoreTokenType>;
173 
174 ///
175 /// OpenID Connect Core JSON Web Key Set.
176 ///
177 pub type CoreJsonWebKeySet =
178     JsonWebKeySet<CoreJwsSigningAlgorithm, CoreJsonWebKeyType, CoreJsonWebKeyUse, CoreJsonWebKey>;
179 
180 ///
181 /// OpenID Connect Core provider metadata.
182 ///
183 pub type CoreProviderMetadata = ProviderMetadata<
184     EmptyAdditionalProviderMetadata,
185     CoreAuthDisplay,
186     CoreClientAuthMethod,
187     CoreClaimName,
188     CoreClaimType,
189     CoreGrantType,
190     CoreJweContentEncryptionAlgorithm,
191     CoreJweKeyManagementAlgorithm,
192     CoreJwsSigningAlgorithm,
193     CoreJsonWebKeyType,
194     CoreJsonWebKeyUse,
195     CoreJsonWebKey,
196     CoreResponseMode,
197     CoreResponseType,
198     CoreSubjectIdentifierType,
199 >;
200 
201 ///
202 /// OpenID Connect Core user info claims.
203 ///
204 pub type CoreUserInfoClaims = UserInfoClaims<EmptyAdditionalClaims, CoreGenderClaim>;
205 
206 ///
207 /// OpenID Connect Core user info JSON Web Token.
208 ///
209 pub type CoreUserInfoJsonWebToken = UserInfoJsonWebToken<
210     EmptyAdditionalClaims,
211     CoreGenderClaim,
212     CoreJweContentEncryptionAlgorithm,
213     CoreJwsSigningAlgorithm,
214     CoreJsonWebKeyType,
215 >;
216 
217 ///
218 /// OpenID Connect Core user info verifier.
219 ///
220 pub type CoreUserInfoVerifier<'a> = UserInfoVerifier<
221     'a,
222     CoreJweContentEncryptionAlgorithm,
223     CoreJwsSigningAlgorithm,
224     CoreJsonWebKeyType,
225     CoreJsonWebKeyUse,
226     CoreJsonWebKey,
227 >;
228 
229 ///
230 /// OpenID Connect Core client application type.
231 ///
232 /// These values are defined in
233 /// [Section 2 of OpenID Connect Dynamic Client Registration 1.0](
234 ///     http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata).
235 ///
236 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
237 pub enum CoreApplicationType {
238     ///
239     /// Native Clients MUST only register `redirect_uri`s using custom URI schemes or URLs using
240     /// the `http` scheme with `localhost` as the hostname. Authorization Servers MAY place
241     /// additional constraints on Native Clients.
242     ///
243     Native,
244     ///
245     /// Web Clients using the OAuth Implicit Grant Type MUST only register URLs using the `https`
246     /// scheme as `redirect_uri`s; they MUST NOT use `localhost` as the hostname.
247     ///
248     Web,
249     ///
250     /// An extension not defined by the OpenID Connect Dynamic Client Registration spec.
251     ///
252     Extension(String),
253 }
254 // FIXME: Once https://github.com/serde-rs/serde/issues/912 is resolved, use #[serde(other)] instead
255 // of custom serializer/deserializers. Right now this isn't possible because serde(other) only
256 // supports unit variants.
257 deserialize_from_str!(CoreApplicationType);
258 serialize_as_str!(CoreApplicationType);
259 impl CoreApplicationType {
from_str(s: &str) -> Self260     fn from_str(s: &str) -> Self {
261         match s {
262             "native" => CoreApplicationType::Native,
263             "web" => CoreApplicationType::Web,
264             ext => CoreApplicationType::Extension(ext.to_string()),
265         }
266     }
267 }
268 impl AsRef<str> for CoreApplicationType {
as_ref(&self) -> &str269     fn as_ref(&self) -> &str {
270         match *self {
271             CoreApplicationType::Native => "native",
272             CoreApplicationType::Web => "web",
273             CoreApplicationType::Extension(ref ext) => ext.as_str(),
274         }
275     }
276 }
277 impl ApplicationType for CoreApplicationType {}
278 
279 ///
280 /// How the Authorization Server displays the authentication and consent user interface pages
281 /// to the End-User.
282 ///
283 /// These values are defined in
284 /// [Section 3.1.2.1](http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
285 ///
286 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
287 pub enum CoreAuthDisplay {
288     ///
289     /// The Authorization Server SHOULD display the authentication and consent UI consistent
290     /// with a full User Agent page view. If the display parameter is not specified, this is
291     /// the default display mode.
292     ///
293     Page,
294     ///
295     /// The Authorization Server SHOULD display the authentication and consent UI consistent
296     /// with a popup User Agent window. The popup User Agent window should be of an appropriate
297     /// size for a login-focused dialog and should not obscure the entire window that it is
298     /// popping up over.
299     ///
300     Popup,
301     ///
302     /// The Authorization Server SHOULD display the authentication and consent UI consistent
303     /// with a device that leverages a touch interface.
304     ///
305     Touch,
306     ///
307     /// The Authorization Server SHOULD display the authentication and consent UI consistent
308     /// with a "feature phone" type display.
309     ///
310     Wap,
311     ///
312     /// An extension not defined by the OpenID Connect Core spec.
313     ///
314     Extension(String),
315 }
316 deserialize_from_str!(CoreAuthDisplay);
317 serialize_as_str!(CoreAuthDisplay);
318 impl CoreAuthDisplay {
from_str(s: &str) -> Self319     fn from_str(s: &str) -> Self {
320         match s {
321             "page" => CoreAuthDisplay::Page,
322             "popup" => CoreAuthDisplay::Popup,
323             "touch" => CoreAuthDisplay::Touch,
324             "wap" => CoreAuthDisplay::Wap,
325             ext => CoreAuthDisplay::Extension(ext.to_string()),
326         }
327     }
328 }
329 impl AsRef<str> for CoreAuthDisplay {
as_ref(&self) -> &str330     fn as_ref(&self) -> &str {
331         match *self {
332             CoreAuthDisplay::Page => "page",
333             CoreAuthDisplay::Popup => "popup",
334             CoreAuthDisplay::Touch => "touch",
335             CoreAuthDisplay::Wap => "wap",
336             CoreAuthDisplay::Extension(ref ext) => ext.as_str(),
337         }
338     }
339 }
340 impl AuthDisplay for CoreAuthDisplay {}
341 impl Display for CoreAuthDisplay {
fmt(&self, f: &mut Formatter) -> Result<(), FormatterError>342     fn fmt(&self, f: &mut Formatter) -> Result<(), FormatterError> {
343         write!(f, "{}", self.as_ref())
344     }
345 }
346 
347 ///
348 /// Whether the Authorization Server should prompt the End-User for re-authentication and
349 /// consent.
350 ///
351 /// These values are defined in
352 /// [Section 3.1.2.1](http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
353 ///
354 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
355 pub enum CoreAuthPrompt {
356     ///
357     /// The Authorization Server MUST NOT display any authentication or consent user interface
358     /// pages. An error is returned if an End-User is not already authenticated or the Client
359     /// does not have pre-configured consent for the requested Claims or does not fulfill other
360     /// conditions for processing the request. The error code will typically be
361     /// `login_required,` `interaction_required`, or another code defined in
362     /// [Section 3.1.2.6](http://openid.net/specs/openid-connect-core-1_0.html#AuthError).
363     /// This can be used as a method to check for existing authentication and/or consent.
364     ///
365     None,
366     ///
367     /// The Authorization Server SHOULD prompt the End-User for reauthentication. If it cannot
368     /// reauthenticate the End-User, it MUST return an error, typically `login_required`.
369     ///
370     Login,
371     ///
372     /// The Authorization Server SHOULD prompt the End-User for consent before returning
373     /// information to the Client. If it cannot obtain consent, it MUST return an error,
374     /// typically `consent_required`.
375     ///
376     Consent,
377     ///
378     /// The Authorization Server SHOULD prompt the End-User to select a user account. This
379     /// enables an End-User who has multiple accounts at the Authorization Server to select
380     /// amongst the multiple accounts that they might have current sessions for. If it cannot
381     /// obtain an account selection choice made by the End-User, it MUST return an error,
382     /// typically `account_selection_required`.
383     ///
384     SelectAccount,
385     ///
386     /// An extension not defined by the OpenID Connect Core spec.
387     ///
388     Extension(String),
389 }
390 deserialize_from_str!(CoreAuthPrompt);
391 serialize_as_str!(CoreAuthPrompt);
392 impl CoreAuthPrompt {
from_str(s: &str) -> Self393     fn from_str(s: &str) -> Self {
394         match s {
395             "none" => CoreAuthPrompt::None,
396             "login" => CoreAuthPrompt::Login,
397             "consent" => CoreAuthPrompt::Consent,
398             "select_account" => CoreAuthPrompt::SelectAccount,
399             ext => CoreAuthPrompt::Extension(ext.to_string()),
400         }
401     }
402 }
403 impl AsRef<str> for CoreAuthPrompt {
as_ref(&self) -> &str404     fn as_ref(&self) -> &str {
405         match *self {
406             CoreAuthPrompt::None => "none",
407             CoreAuthPrompt::Login => "login",
408             CoreAuthPrompt::Consent => "consent",
409             CoreAuthPrompt::SelectAccount => "select_account",
410             CoreAuthPrompt::Extension(ref ext) => ext.as_str(),
411         }
412     }
413 }
414 impl AuthPrompt for CoreAuthPrompt {}
415 
416 impl Display for CoreAuthPrompt {
fmt(&self, f: &mut Formatter) -> Result<(), FormatterError>417     fn fmt(&self, f: &mut Formatter) -> Result<(), FormatterError> {
418         write!(f, "{}", self.as_ref())
419     }
420 }
421 
422 new_type![
423     ///
424     /// OpenID Connect Core claim name.
425     ///
426     #[derive(Deserialize, Eq, Hash, Ord, PartialOrd, Serialize)]
427     CoreClaimName(String)
428 ];
429 impl ClaimName for CoreClaimName {}
430 
431 ///
432 /// Representation of a Claim Value.
433 ///
434 /// See [Section 5.6](http://openid.net/specs/openid-connect-core-1_0.html#ClaimTypes) for
435 /// further information.
436 ///
437 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
438 pub enum CoreClaimType {
439     ///
440     /// Aggregated Claim Type.
441     ///
442     /// See [Section 5.6.2](
443     ///     http://openid.net/specs/openid-connect-core-1_0.html#AggregatedDistributedClaims)
444     /// for details.
445     ///
446     Aggregated,
447     ///
448     /// Distributed Claim Type.
449     ///
450     /// See [Section 5.6.2](
451     ///     http://openid.net/specs/openid-connect-core-1_0.html#AggregatedDistributedClaims)
452     /// for details.
453     ///
454     Distributed,
455     ///
456     /// Normal Claims are represented as members in a JSON object. The Claim Name is the member
457     /// name and the Claim Value is the member value.
458     ///
459     Normal,
460     ///
461     /// An extension not defined by the OpenID Connect Core spec.
462     ///
463     Extension(String),
464 }
465 deserialize_from_str!(CoreClaimType);
466 serialize_as_str!(CoreClaimType);
467 impl CoreClaimType {
from_str(s: &str) -> Self468     fn from_str(s: &str) -> Self {
469         match s {
470             "normal" => CoreClaimType::Normal,
471             "aggregated" => CoreClaimType::Aggregated,
472             "distributed" => CoreClaimType::Distributed,
473             ext => CoreClaimType::Extension(ext.to_string()),
474         }
475     }
476 }
477 impl AsRef<str> for CoreClaimType {
as_ref(&self) -> &str478     fn as_ref(&self) -> &str {
479         match *self {
480             CoreClaimType::Normal => "normal",
481             CoreClaimType::Aggregated => "aggregated",
482             CoreClaimType::Distributed => "distributed",
483             CoreClaimType::Extension(ref ext) => ext.as_str(),
484         }
485     }
486 }
487 impl ClaimType for CoreClaimType {}
488 
489 ///
490 /// OpenID Connect Core client authentication method.
491 ///
492 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
493 pub enum CoreClientAuthMethod {
494     ///
495     /// Client secret passed via the HTTP Basic authentication scheme.
496     ///
497     ClientSecretBasic,
498     ///
499     /// Client authentication using a JSON Web Token signed with the client secret used as an HMAC
500     /// key.
501     ///
502     ClientSecretJwt,
503     ///
504     /// Client secret passed via the POST request body.
505     ///
506     ClientSecretPost,
507     ///
508     /// JSON Web Token signed with a private key whose public key has been previously registered
509     /// with the OpenID Connect provider.
510     ///
511     PrivateKeyJwt,
512     ///
513     /// The Client does not authenticate itself at the Token Endpoint, either because it uses only
514     /// the Implicit Flow (and so does not use the Token Endpoint) or because it is a Public Client
515     /// with no Client Secret or other authentication mechanism.
516     ///
517     None,
518     ///
519     /// An extension not defined by the OpenID Connect Core spec.
520     ///
521     Extension(String),
522 }
523 deserialize_from_str!(CoreClientAuthMethod);
524 serialize_as_str!(CoreClientAuthMethod);
525 impl CoreClientAuthMethod {
from_str(s: &str) -> Self526     fn from_str(s: &str) -> Self {
527         match s {
528             "client_secret_basic" => CoreClientAuthMethod::ClientSecretBasic,
529             "client_secret_jwt" => CoreClientAuthMethod::ClientSecretJwt,
530             "client_secret_post" => CoreClientAuthMethod::ClientSecretPost,
531             "private_key_jwt" => CoreClientAuthMethod::PrivateKeyJwt,
532             "none" => CoreClientAuthMethod::None,
533             ext => CoreClientAuthMethod::Extension(ext.to_string()),
534         }
535     }
536 }
537 impl AsRef<str> for CoreClientAuthMethod {
as_ref(&self) -> &str538     fn as_ref(&self) -> &str {
539         match *self {
540             CoreClientAuthMethod::ClientSecretBasic => "client_secret_basic",
541             CoreClientAuthMethod::ClientSecretJwt => "client_secret_jwt",
542             CoreClientAuthMethod::ClientSecretPost => "client_secret_post",
543             CoreClientAuthMethod::PrivateKeyJwt => "private_key_jwt",
544             CoreClientAuthMethod::None => "none",
545             CoreClientAuthMethod::Extension(ref ext) => ext.as_str(),
546         }
547     }
548 }
549 impl ClientAuthMethod for CoreClientAuthMethod {}
550 
551 new_type![
552     ///
553     /// OpenID Connect Core gender claim.
554     ///
555     #[derive(Deserialize, Eq, Hash, Ord, PartialOrd, Serialize)]
556     CoreGenderClaim(String)
557 ];
558 impl GenderClaim for CoreGenderClaim {}
559 
560 ///
561 /// OpenID Connect Core grant type.
562 ///
563 // These are defined in various specs, including the Client Registration spec:
564 //   http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
565 #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
566 pub enum CoreGrantType {
567     ///
568     /// Authorization code grant.
569     ///
570     AuthorizationCode,
571     ///
572     /// Client credentials grant.
573     ///
574     ClientCredentials,
575     ///
576     /// Device Authorization Grant as described in [RFC 8628](https://tools.ietf.org/html/rfc8628).
577     ///
578     DeviceCode,
579     ///
580     /// Implicit grant.
581     ///
582     Implicit,
583     ///
584     /// JWT-based authentication as described in [RFC 7523](https://tools.ietf.org/html/rfc7523).
585     ///
586     JwtBearer,
587     ///
588     /// End user password grant.
589     ///
590     Password,
591     ///
592     /// Refresh token grant.
593     ///
594     RefreshToken,
595     ///
596     /// An extension not defined by any of the supported specifications.
597     ///
598     Extension(String),
599 }
600 deserialize_from_str!(CoreGrantType);
601 serialize_as_str!(CoreGrantType);
602 impl CoreGrantType {
from_str(s: &str) -> Self603     fn from_str(s: &str) -> Self {
604         match s {
605             "authorization_code" => CoreGrantType::AuthorizationCode,
606             "client_credentials" => CoreGrantType::ClientCredentials,
607             "urn:ietf:params:oauth:grant-type:device_code" => CoreGrantType::DeviceCode,
608             "implicit" => CoreGrantType::Implicit,
609             "urn:ietf:params:oauth:grant-type:jwt-bearer" => CoreGrantType::JwtBearer,
610             "password" => CoreGrantType::Password,
611             "refresh_token" => CoreGrantType::RefreshToken,
612             ext => CoreGrantType::Extension(ext.to_string()),
613         }
614     }
615 }
616 impl AsRef<str> for CoreGrantType {
as_ref(&self) -> &str617     fn as_ref(&self) -> &str {
618         match *self {
619             CoreGrantType::AuthorizationCode => "authorization_code",
620             CoreGrantType::ClientCredentials => "client_credentials",
621             CoreGrantType::DeviceCode => "urn:ietf:params:oauth:grant-type:device_code",
622             CoreGrantType::Implicit => "implicit",
623             CoreGrantType::JwtBearer => "urn:ietf:params:oauth:grant-type:jwt-bearer",
624             CoreGrantType::Password => "password",
625             CoreGrantType::RefreshToken => "refresh_token",
626             CoreGrantType::Extension(ref ext) => ext.as_str(),
627         }
628     }
629 }
630 impl GrantType for CoreGrantType {}
631 
632 ///
633 /// OpenID Connect Core JWE encryption algorithms.
634 ///
635 /// These algorithms represent the `enc` header parameter values for JSON Web Encryption.
636 /// The values are described in
637 /// [Section 5.1 of RFC 7518](https://tools.ietf.org/html/rfc7518#section-5.1).
638 ///
639 #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
640 #[non_exhaustive]
641 pub enum CoreJweContentEncryptionAlgorithm {
642     ///
643     /// AES-128 CBC HMAC SHA-256 authenticated encryption.
644     ///
645     #[serde(rename = "A128CBC-HS256")]
646     Aes128CbcHmacSha256,
647     ///
648     /// AES-192 CBC HMAC SHA-384 authenticated encryption.
649     ///
650     #[serde(rename = "A192CBC-HS384")]
651     Aes192CbcHmacSha384,
652     ///
653     /// AES-256 CBC HMAC SHA-512 authenticated encryption.
654     ///
655     #[serde(rename = "A256CBC-HS512")]
656     Aes256CbcHmacSha512,
657     ///
658     /// AES-128 GCM.
659     ///
660     #[serde(rename = "A128GCM")]
661     Aes128Gcm,
662     ///
663     /// AES-192 GCM.
664     ///
665     #[serde(rename = "A192GCM")]
666     Aes192Gcm,
667     ///
668     /// AES-256 GCM.
669     ///
670     #[serde(rename = "A256GCM")]
671     Aes256Gcm,
672 }
673 impl JweContentEncryptionAlgorithm<CoreJsonWebKeyType> for CoreJweContentEncryptionAlgorithm {
key_type(&self) -> Result<CoreJsonWebKeyType, String>674     fn key_type(&self) -> Result<CoreJsonWebKeyType, String> {
675         Ok(CoreJsonWebKeyType::Symmetric)
676     }
677 }
678 
679 ///
680 /// OpenID Connect Core JWE key management algorithms.
681 ///
682 /// These algorithms represent the `alg` header parameter values for JSON Web Encryption.
683 /// They are used to encrypt the Content Encryption Key (CEK) to produce the JWE Encrypted Key, or
684 /// to use key agreement to agree upon the CEK. The values are described in
685 /// [Section 4.1 of RFC 7518](https://tools.ietf.org/html/rfc7518#section-4.1).
686 ///
687 #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
688 #[non_exhaustive]
689 pub enum CoreJweKeyManagementAlgorithm {
690     ///
691     /// RSAES-PKCS1-V1_5.
692     ///
693     #[serde(rename = "RSA1_5")]
694     RsaPkcs1V15,
695     ///
696     /// RSAES OAEP using default parameters.
697     ///
698     #[serde(rename = "RSA-OAEP")]
699     RsaOaep,
700     ///
701     /// RSAES OAEP using SHA-256 and MGF1 with SHA-256.
702     ///
703     #[serde(rename = "RSA-OAEP-256")]
704     RsaOaepSha256,
705     ///
706     /// AES-128 Key Wrap.
707     ///
708     #[serde(rename = "A128KW")]
709     AesKeyWrap128,
710     ///
711     /// AES-192 Key Wrap.
712     ///
713     #[serde(rename = "A192KW")]
714     AesKeyWrap192,
715     ///
716     /// AES-256 Key Wrap.
717     ///
718     #[serde(rename = "A256KW")]
719     AesKeyWrap256,
720     ///
721     /// Direct use of a shared symmetric key as the Content Encryption Key (CEK).
722     ///
723     #[serde(rename = "dir")]
724     Direct,
725     ///
726     /// Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF.
727     ///
728     #[serde(rename = "ECDH-ES")]
729     EcdhEs,
730     ///
731     /// ECDH-ES using Concat KDF and CEK wrapped with AES-128 Key Wrap.
732     ///
733     #[serde(rename = "ECDH-ES+A128KW")]
734     EcdhEsAesKeyWrap128,
735     ///
736     /// ECDH-ES using Concat KDF and CEK wrapped with AES-192 Key Wrap.
737     ///
738     #[serde(rename = "ECDH-ES+A192KW")]
739     EcdhEsAesKeyWrap192,
740     ///
741     /// ECDH-ES using Concat KDF and CEK wrapped with AES-256 Key Wrap.
742     ///
743     #[serde(rename = "ECDH-ES+A256KW")]
744     EcdhEsAesKeyWrap256,
745     ///
746     /// Key wrapping with AES GCM using 128 bit key.
747     ///
748     #[serde(rename = "A128GCMKW")]
749     Aes128Gcm,
750     ///
751     /// Key wrapping with AES GCM using 192 bit key.
752     ///
753     #[serde(rename = "A192GCMKW")]
754     Aes192Gcm,
755     ///
756     /// Key wrapping with AES GCM using 256 bit key.
757     ///
758     #[serde(rename = "A256GCMKW")]
759     Aes256Gcm,
760     ///
761     /// PBES2 with HMAC SHA-256 wrapped with AES-128 Key Wrap.
762     ///
763     #[serde(rename = "PBES2-HS256+A128KW")]
764     PbEs2HmacSha256AesKeyWrap128,
765     ///
766     /// PBES2 with HMAC SHA-384 wrapped with AES-192 Key Wrap.
767     ///
768     #[serde(rename = "PBES2-HS384+A192KW")]
769     PbEs2HmacSha384AesKeyWrap192,
770     ///
771     /// PBES2 with HMAC SHA-512 wrapped with AES-256 Key Wrap.
772     ///
773     #[serde(rename = "PBES2-HS512+A256KW")]
774     PbEs2HmacSha512AesKeyWrap256,
775 }
776 impl JweKeyManagementAlgorithm for CoreJweKeyManagementAlgorithm {}
777 
778 ///
779 /// OpenID Connect Core JWS signing algorithms.
780 ///
781 /// These algorithms represent the `alg` header parameter values for JSON Web Signature.
782 /// They are used to digitally sign or create a MAC of the contents of the JWS Protected Header and
783 /// the JWS Payload. The values are described in
784 /// [Section 3.1 of RFC 7518](https://tools.ietf.org/html/rfc7518#section-3.1).
785 ///
786 #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
787 #[non_exhaustive]
788 pub enum CoreJwsSigningAlgorithm {
789     ///
790     /// HMAC using SHA-256 (currently unsupported).
791     ///
792     #[serde(rename = "HS256")]
793     HmacSha256,
794     ///
795     /// HMAC using SHA-384 (currently unsupported).
796     ///
797     #[serde(rename = "HS384")]
798     HmacSha384,
799     ///
800     /// HMAC using SHA-512 (currently unsupported).
801     ///
802     #[serde(rename = "HS512")]
803     HmacSha512,
804     ///
805     /// RSA SSA PKCS#1 v1.5 using SHA-256.
806     ///
807     #[serde(rename = "RS256")]
808     RsaSsaPkcs1V15Sha256,
809     ///
810     /// RSA SSA PKCS#1 v1.5 using SHA-384.
811     ///
812     #[serde(rename = "RS384")]
813     RsaSsaPkcs1V15Sha384,
814     ///
815     /// RSA SSA PKCS#1 v1.5 using SHA-512.
816     ///
817     #[serde(rename = "RS512")]
818     RsaSsaPkcs1V15Sha512,
819     ///
820     /// ECDSA using P-256 and SHA-256 (currently unsupported).
821     ///
822     #[serde(rename = "ES256")]
823     EcdsaP256Sha256,
824     ///
825     /// ECDSA using P-384 and SHA-384 (currently unsupported).
826     ///
827     #[serde(rename = "ES384")]
828     EcdsaP384Sha384,
829     ///
830     /// ECDSA using P-521 and SHA-512 (currently unsupported).
831     ///
832     #[serde(rename = "ES512")]
833     EcdsaP521Sha512,
834     ///
835     /// RSA SSA-PSS using SHA-256 and MGF1 with SHA-256.
836     ///
837     #[serde(rename = "PS256")]
838     RsaSsaPssSha256,
839     ///
840     /// RSA SSA-PSS using SHA-384 and MGF1 with SHA-384.
841     ///
842     #[serde(rename = "PS384")]
843     RsaSsaPssSha384,
844     ///
845     /// RSA SSA-PSS using SHA-512 and MGF1 with SHA-512.
846     ///
847     #[serde(rename = "PS512")]
848     RsaSsaPssSha512,
849     ///
850     /// No digital signature or MAC performed.
851     ///
852     /// # Security Warning
853     ///
854     /// This algorithm provides no security over the integrity of the JSON Web Token. Clients
855     /// should be careful not to rely on unsigned JWT's for security purposes. See
856     /// [Critical vulnerabilities in JSON Web Token libraries](
857     ///     https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/) for
858     /// further discussion.
859     ///
860     #[serde(rename = "none")]
861     None,
862 }
863 impl JwsSigningAlgorithm<CoreJsonWebKeyType> for CoreJwsSigningAlgorithm {
key_type(&self) -> Option<CoreJsonWebKeyType>864     fn key_type(&self) -> Option<CoreJsonWebKeyType> {
865         match *self {
866             CoreJwsSigningAlgorithm::HmacSha256
867             | CoreJwsSigningAlgorithm::HmacSha384
868             | CoreJwsSigningAlgorithm::HmacSha512 => Some(CoreJsonWebKeyType::Symmetric),
869             CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256
870             | CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384
871             | CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512
872             | CoreJwsSigningAlgorithm::RsaSsaPssSha256
873             | CoreJwsSigningAlgorithm::RsaSsaPssSha384
874             | CoreJwsSigningAlgorithm::RsaSsaPssSha512 => Some(CoreJsonWebKeyType::RSA),
875             CoreJwsSigningAlgorithm::EcdsaP256Sha256
876             | CoreJwsSigningAlgorithm::EcdsaP384Sha384
877             | CoreJwsSigningAlgorithm::EcdsaP521Sha512 => Some(CoreJsonWebKeyType::EllipticCurve),
878             CoreJwsSigningAlgorithm::None => None,
879         }
880     }
881 
uses_shared_secret(&self) -> bool882     fn uses_shared_secret(&self) -> bool {
883         self.key_type()
884             .map(|kty| kty == CoreJsonWebKeyType::Symmetric)
885             .unwrap_or(false)
886     }
887 
hash_bytes(&self, bytes: &[u8]) -> Result<Vec<u8>, String>888     fn hash_bytes(&self, bytes: &[u8]) -> Result<Vec<u8>, String> {
889         use ring::digest::{digest, SHA256, SHA384, SHA512};
890         Ok(match *self {
891             CoreJwsSigningAlgorithm::HmacSha256
892             | CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256
893             | CoreJwsSigningAlgorithm::RsaSsaPssSha256
894             | CoreJwsSigningAlgorithm::EcdsaP256Sha256 => digest(&SHA256, bytes).as_ref().to_vec(),
895             CoreJwsSigningAlgorithm::HmacSha384
896             | CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha384
897             | CoreJwsSigningAlgorithm::RsaSsaPssSha384
898             | CoreJwsSigningAlgorithm::EcdsaP384Sha384 => digest(&SHA384, bytes).as_ref().to_vec(),
899             CoreJwsSigningAlgorithm::HmacSha512
900             | CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha512
901             | CoreJwsSigningAlgorithm::RsaSsaPssSha512
902             | CoreJwsSigningAlgorithm::EcdsaP521Sha512 => digest(&SHA512, bytes).as_ref().to_vec(),
903             CoreJwsSigningAlgorithm::None => {
904                 return Err(
905                     "signature algorithm `none` has no corresponding hash algorithm".to_string(),
906                 );
907             }
908         })
909     }
910 
rsa_sha_256() -> Self911     fn rsa_sha_256() -> Self {
912         CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256
913     }
914 }
915 
916 ///
917 /// OpenID Connect Core authentication error response types.
918 ///
919 /// This type represents errors returned in a redirect from the Authorization Endpoint to the
920 /// client's redirect URI.
921 ///
922 /// These values are defined across both
923 /// [Section 4.1.2.1](https://tools.ietf.org/html/rfc6749#section-4.1.2.1) of RFC 6749 and
924 /// [Section 3.1.2.6](https://openid.net/specs/openid-connect-core-1_0.html#AuthError) of the
925 /// OpenID Connect Core spec.
926 ///
927 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
928 pub enum CoreAuthErrorResponseType {
929     ///
930     /// The resource owner or authorization server denied the request.
931     ///
932     AccessDenied,
933     ///
934     /// The End-User is REQUIRED to select a session at the Authorization Server. The End-User MAY
935     /// be authenticated at the Authorization Server with different associated accounts, but the
936     /// End-User did not select a session. This error MAY be returned when the `prompt` parameter
937     /// value in the Authentication Request is `none`, but the Authentication Request cannot be
938     /// completed without displaying a user interface to prompt for a session to use.
939     ///
940     AccountSelectionRequired,
941     ///
942     /// The Authorization Server requires End-User consent. This error MAY be returned when the
943     /// `prompt` parameter value in the Authentication Request is `none`, but the Authentication
944     /// Request cannot be completed without displaying a user interface for End-User consent.
945     ///
946     ConsentRequired,
947     ///
948     /// The Authorization Server requires End-User interaction of some form to proceed. This error
949     /// MAY be returned when the `prompt` parameter value in the Authentication Request is `none`,
950     /// but the Authentication Request cannot be completed without displaying a user interface for
951     /// End-User interaction.
952     ///
953     InteractionRequired,
954     ///
955     /// The request is missing a required parameter, includes an invalid parameter value, includes
956     /// a parameter more than once, or is otherwise malformed.
957     ///
958     InvalidRequest,
959     ///
960     /// The `request` parameter contains an invalid Request Object.
961     ///
962     InvalidRequestObject,
963     ///
964     /// The `request_uri` in the Authorization Request returns an error or contains invalid data.
965     ///
966     InvalidRequestUri,
967     ///
968     /// The requested scope is invalid, unknown, or malformed.
969     ///
970     InvalidScope,
971     ///
972     /// The Authorization Server requires End-User authentication. This error MAY be returned when
973     /// the `prompt` parameter value in the Authentication Request is `none`, but the Authentication
974     /// Request cannot be completed without displaying a user interface for End-User authentication.
975     ///
976     LoginRequired,
977     ///
978     /// The OpenID Connect Provider does not support use of the `registration` parameter.
979     ///
980     RegistrationNotSupported,
981     ///
982     /// The OpenID Connect Provider does not support use of the `request` parameter.
983     ///
984     RequestNotSupported,
985     ///
986     /// The OpenID Connect Provider does not support use of the `request_uri` parameter.
987     ///
988     RequestUriNotSupported,
989     ///
990     /// The authorization server encountered an unexpected condition that prevented it from
991     /// fulfilling the request. (This error code is needed because a 500 Internal Server Error HTTP
992     /// status code cannot be returned to the client via an HTTP redirect.)
993     ///
994     ServerError,
995     ///
996     /// The authorization server is currently unable to handle the request due to a temporary
997     /// overloading or maintenance of the server.  (This error code is needed because a 503 Service
998     /// Unavailable HTTP status code cannot be returned to the client via an HTTP redirect.)
999     ///
1000     TemporarilyUnavailable,
1001     ///
1002     /// The client is not authorized to request an authorization code using this method.
1003     ///
1004     UnauthorizedClient,
1005     ///
1006     /// The authorization server does not support obtaining an authorization code using this method.
1007     ///
1008     UnsupportedResponseType,
1009     ///
1010     /// An extension not defined by any of the supported specifications.
1011     ///
1012     Extension(String),
1013 }
1014 deserialize_from_str!(CoreAuthErrorResponseType);
1015 serialize_as_str!(CoreAuthErrorResponseType);
1016 impl CoreAuthErrorResponseType {
from_str(s: &str) -> Self1017     fn from_str(s: &str) -> Self {
1018         match s {
1019             "access_denied" => CoreAuthErrorResponseType::AccessDenied,
1020             "account_selection_required" => CoreAuthErrorResponseType::AccountSelectionRequired,
1021             "consent_required" => CoreAuthErrorResponseType::ConsentRequired,
1022             "interaction_required" => CoreAuthErrorResponseType::InteractionRequired,
1023             "invalid_request" => CoreAuthErrorResponseType::InvalidRequest,
1024             "invalid_request_object" => CoreAuthErrorResponseType::InvalidRequestObject,
1025             "invalid_request_uri" => CoreAuthErrorResponseType::InvalidRequestUri,
1026             "invalid_scope" => CoreAuthErrorResponseType::InvalidScope,
1027             "login_required" => CoreAuthErrorResponseType::LoginRequired,
1028             "registration_not_supported" => CoreAuthErrorResponseType::RegistrationNotSupported,
1029             "request_not_supported" => CoreAuthErrorResponseType::RequestNotSupported,
1030             "request_uri_not_supported" => CoreAuthErrorResponseType::RequestUriNotSupported,
1031             "server_error" => CoreAuthErrorResponseType::ServerError,
1032             "temporarily_unavailable" => CoreAuthErrorResponseType::TemporarilyUnavailable,
1033             "unauthorized_client" => CoreAuthErrorResponseType::UnauthorizedClient,
1034             "unsupported_response_type" => CoreAuthErrorResponseType::UnsupportedResponseType,
1035             ext => CoreAuthErrorResponseType::Extension(ext.to_string()),
1036         }
1037     }
1038 }
1039 impl AsRef<str> for CoreAuthErrorResponseType {
as_ref(&self) -> &str1040     fn as_ref(&self) -> &str {
1041         match *self {
1042             CoreAuthErrorResponseType::AccessDenied => "access_denied",
1043             CoreAuthErrorResponseType::AccountSelectionRequired => "account_selection_required",
1044             CoreAuthErrorResponseType::ConsentRequired => "consent_required",
1045             CoreAuthErrorResponseType::InteractionRequired => "interaction_required",
1046             CoreAuthErrorResponseType::InvalidRequest => "invalid_request",
1047             CoreAuthErrorResponseType::InvalidRequestObject => "invalid_request_obbject",
1048             CoreAuthErrorResponseType::InvalidRequestUri => "invalid_request_uri",
1049             CoreAuthErrorResponseType::InvalidScope => "invalid_scope",
1050             CoreAuthErrorResponseType::LoginRequired => "login_required",
1051             CoreAuthErrorResponseType::RegistrationNotSupported => "registration_not_supported",
1052             CoreAuthErrorResponseType::RequestNotSupported => "request_not_supported",
1053             CoreAuthErrorResponseType::RequestUriNotSupported => "request_uri_not_supported",
1054             CoreAuthErrorResponseType::ServerError => "server_error",
1055             CoreAuthErrorResponseType::TemporarilyUnavailable => "temporarily_unavailable",
1056             CoreAuthErrorResponseType::UnauthorizedClient => "unauthorized_client",
1057             CoreAuthErrorResponseType::UnsupportedResponseType => "unsupported_response_type",
1058             CoreAuthErrorResponseType::Extension(ref ext) => ext.as_str(),
1059         }
1060     }
1061 }
1062 
1063 ///
1064 /// OpenID Connect Core registration error response type.
1065 ///
1066 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1067 pub enum CoreRegisterErrorResponseType {
1068     ///
1069     /// The value of one of the Client Metadata fields is invalid and the server has rejected this
1070     /// request. Note that an Authorization Server MAY choose to substitute a valid value for any
1071     /// requested parameter of a Client's Metadata.
1072     ///
1073     InvalidClientMetadata,
1074     ///
1075     /// The value of one or more `redirect_uri`s is invalid.
1076     ///
1077     InvalidRedirectUri,
1078     ///
1079     /// An extension not defined by any of the supported specifications.
1080     ///
1081     Extension(String),
1082 }
1083 deserialize_from_str!(CoreRegisterErrorResponseType);
1084 serialize_as_str!(CoreRegisterErrorResponseType);
1085 impl CoreRegisterErrorResponseType {
from_str(s: &str) -> Self1086     fn from_str(s: &str) -> Self {
1087         match s {
1088             "invalid_client_metadata" => CoreRegisterErrorResponseType::InvalidClientMetadata,
1089             "invalid_redirect_uri" => CoreRegisterErrorResponseType::InvalidRedirectUri,
1090             ext => CoreRegisterErrorResponseType::Extension(ext.to_string()),
1091         }
1092     }
1093 }
1094 impl AsRef<str> for CoreRegisterErrorResponseType {
as_ref(&self) -> &str1095     fn as_ref(&self) -> &str {
1096         match *self {
1097             CoreRegisterErrorResponseType::InvalidClientMetadata => "invalid_client_metadata",
1098             CoreRegisterErrorResponseType::InvalidRedirectUri => "invalid_redirect_uri",
1099             CoreRegisterErrorResponseType::Extension(ref ext) => ext.as_str(),
1100         }
1101     }
1102 }
1103 impl ErrorResponseType for CoreRegisterErrorResponseType {}
1104 impl RegisterErrorResponseType for CoreRegisterErrorResponseType {}
1105 impl Display for CoreRegisterErrorResponseType {
fmt(&self, f: &mut Formatter) -> Result<(), FormatterError>1106     fn fmt(&self, f: &mut Formatter) -> Result<(), FormatterError> {
1107         write!(f, "{}", self.as_ref())
1108     }
1109 }
1110 
1111 ///
1112 /// OpenID Connect Core response mode.
1113 ///
1114 /// Informs the Authorization Server of the mechanism to be used for returning Authorization
1115 /// Response parameters from the Authorization Endpoint.
1116 ///
1117 /// The default Response Mode for the OAuth 2.0 `code` Response Type is the `query` encoding.
1118 /// The default Response Mode for the OAuth 2.0 `token` Response Type is the `fragment` encoding.
1119 /// These values are defined in
1120 /// [OAuth 2.0 Multiple Response Type Encoding Practices](
1121 ///     http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseTypesAndModes)
1122 /// and [OAuth 2.0 Form Post Response Mode](
1123 ///     http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode).
1124 ///
1125 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1126 pub enum CoreResponseMode {
1127     ///
1128     /// In this mode, Authorization Response parameters are encoded in the query string added to
1129     /// the `redirect_uri` when redirecting back to the Client.
1130     ///
1131     Query,
1132     ///
1133     /// In this mode, Authorization Response parameters are encoded in the fragment added to the
1134     /// `redirect_uri` when redirecting back to the Client.
1135     ///
1136     Fragment,
1137     ///
1138     /// In this mode, Authorization Response parameters are encoded as HTML form values that are
1139     /// auto-submitted in the User Agent, and thus are transmitted via the HTTP `POST` method to the
1140     /// Client, with the result parameters being encoded in the body using the
1141     /// `application/x-www-form-urlencoded` format. The `action` attribute of the form MUST be the
1142     /// Client's Redirection URI. The method of the form attribute MUST be `POST`. Because the
1143     /// Authorization Response is intended to be used only once, the Authorization Server MUST
1144     /// instruct the User Agent (and any intermediaries) not to store or reuse the content of the
1145     /// response.
1146     ///
1147     /// Any technique supported by the User Agent MAY be used to cause the submission of the form,
1148     /// and any form content necessary to support this MAY be included, such as submit controls and
1149     /// client-side scripting commands. However, the Client MUST be able to process the message
1150     /// without regard for the mechanism by which the form submission was initiated.
1151     ///
1152     /// See [OAuth 2.0 Form Post Response Mode](
1153     ///     http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode)
1154     /// for further information.
1155     ///
1156     FormPost,
1157     ///
1158     /// An extension not defined by any of the supported specifications.
1159     ///
1160     Extension(String),
1161 }
1162 deserialize_from_str!(CoreResponseMode);
1163 serialize_as_str!(CoreResponseMode);
1164 impl CoreResponseMode {
from_str(s: &str) -> Self1165     fn from_str(s: &str) -> Self {
1166         match s {
1167             "query" => CoreResponseMode::Query,
1168             "fragment" => CoreResponseMode::Fragment,
1169             "form_post" => CoreResponseMode::FormPost,
1170             ext => CoreResponseMode::Extension(ext.to_string()),
1171         }
1172     }
1173 }
1174 impl AsRef<str> for CoreResponseMode {
as_ref(&self) -> &str1175     fn as_ref(&self) -> &str {
1176         match *self {
1177             CoreResponseMode::Query => "query",
1178             CoreResponseMode::Fragment => "fragment",
1179             CoreResponseMode::FormPost => "form_post",
1180             CoreResponseMode::Extension(ref ext) => ext.as_str(),
1181         }
1182     }
1183 }
1184 impl ResponseMode for CoreResponseMode {}
1185 
1186 ///
1187 /// OpenID Connect Core response type.
1188 ///
1189 /// Informs the Authorization Server of the desired authorization processing flow, including what
1190 /// parameters are returned from the endpoints used.
1191 ///
1192 /// This type represents a single Response Type. Multiple Response Types are represented via the
1193 /// `ResponseTypes` type, which wraps a `Vec<ResponseType>`.
1194 ///
1195 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1196 pub enum CoreResponseType {
1197     ///
1198     /// Used by the OAuth 2.0 Authorization Code Flow.
1199     ///
1200     Code,
1201     ///
1202     /// When supplied as the `response_type` parameter in an OAuth 2.0 Authorization Request, a
1203     /// successful response MUST include the parameter `id_token`.
1204     ///
1205     IdToken,
1206     ///
1207     /// When supplied as the `response_type` parameter in an OAuth 2.0 Authorization Request, the
1208     /// Authorization Server SHOULD NOT return an OAuth 2.0 Authorization Code, Access Token, Access
1209     /// Token Type, or ID Token in a successful response to the grant request. If a `redirect_uri`
1210     /// is supplied, the User Agent SHOULD be redirected there after granting or denying access.
1211     /// The request MAY include a `state` parameter, and if so, the Authorization Server MUST echo
1212     /// its value as a response parameter when issuing either a successful response or an error
1213     /// response. The default Response Mode for this Response Type is the query encoding. Both
1214     /// successful and error responses SHOULD be returned using the supplied Response Mode, or if
1215     /// none is supplied, using the default Response Mode.
1216     ///
1217     /// This Response Type is not generally used with OpenID Connect but may be supported by the
1218     /// Authorization Server.
1219     ///
1220     None,
1221     ///
1222     /// Used by the OAuth 2.0 Implicit Flow.
1223     ///
1224     Token,
1225     ///
1226     /// An extension not defined by the OpenID Connect Core spec.
1227     ///
1228     Extension(String),
1229 }
1230 deserialize_from_str!(CoreResponseType);
1231 serialize_as_str!(CoreResponseType);
1232 impl CoreResponseType {
from_str(s: &str) -> Self1233     fn from_str(s: &str) -> Self {
1234         match s {
1235             "code" => CoreResponseType::Code,
1236             "id_token" => CoreResponseType::IdToken,
1237             "none" => CoreResponseType::None,
1238             "token" => CoreResponseType::Token,
1239             ext => CoreResponseType::Extension(ext.to_string()),
1240         }
1241     }
1242 }
1243 impl AsRef<str> for CoreResponseType {
as_ref(&self) -> &str1244     fn as_ref(&self) -> &str {
1245         match *self {
1246             CoreResponseType::Code => "code",
1247             CoreResponseType::IdToken => "id_token",
1248             CoreResponseType::None => "none",
1249             CoreResponseType::Token => "token",
1250             CoreResponseType::Extension(ref ext) => ext.as_str(),
1251         }
1252     }
1253 }
1254 impl ResponseType for CoreResponseType {
to_oauth2(&self) -> OAuth2ResponseType1255     fn to_oauth2(&self) -> OAuth2ResponseType {
1256         OAuth2ResponseType::new(self.as_ref().to_string())
1257     }
1258 }
1259 
1260 ///
1261 /// OpenID Connect Core Subject Identifier type.
1262 ///
1263 /// A Subject Identifier is a locally unique and never reassigned identifier within the Issuer for
1264 /// the End-User, which is intended to be consumed by the Client.
1265 ///
1266 /// See [Section 8](http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes) for
1267 /// further information.
1268 ///
1269 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1270 pub enum CoreSubjectIdentifierType {
1271     ///
1272     /// This provides a different `sub` value to each Client, so as not to enable Clients to
1273     /// correlate the End-User's activities without permission.
1274     ///
1275     Pairwise,
1276     ///
1277     /// This provides the same `sub` (subject) value to all Clients. It is the default if the
1278     /// provider has no `subject_types_supported` element in its discovery document.
1279     ///
1280     Public,
1281     ///
1282     /// An extension not defined by the OpenID Connect Core spec.
1283     ///
1284     Extension(String),
1285 }
1286 deserialize_from_str!(CoreSubjectIdentifierType);
1287 serialize_as_str!(CoreSubjectIdentifierType);
1288 impl CoreSubjectIdentifierType {
from_str(s: &str) -> Self1289     fn from_str(s: &str) -> Self {
1290         match s {
1291             "pairwise" => CoreSubjectIdentifierType::Pairwise,
1292             "public" => CoreSubjectIdentifierType::Public,
1293             ext => CoreSubjectIdentifierType::Extension(ext.to_string()),
1294         }
1295     }
1296 }
1297 impl AsRef<str> for CoreSubjectIdentifierType {
as_ref(&self) -> &str1298     fn as_ref(&self) -> &str {
1299         match *self {
1300             CoreSubjectIdentifierType::Pairwise => "pairwise",
1301             CoreSubjectIdentifierType::Public => "public",
1302             CoreSubjectIdentifierType::Extension(ref ext) => ext.as_str(),
1303         }
1304     }
1305 }
1306 impl SubjectIdentifierType for CoreSubjectIdentifierType {}
1307 
base64_url_safe_no_pad() -> base64::Config1308 pub(crate) fn base64_url_safe_no_pad() -> base64::Config {
1309     base64::URL_SAFE_NO_PAD.decode_allow_trailing_bits(true)
1310 }
1311 
1312 #[cfg(test)]
1313 mod tests;
1314