You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-06 06:02:40 +03:00
Replace parse-display with manual Display/FromStr impls
This commit is contained in:
@@ -17,7 +17,6 @@ serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
language-tags = { version = "0.3.2", features = ["serde"] }
|
||||
url.workspace = true
|
||||
parse-display = "0.9.0"
|
||||
serde_with = { version = "3.7.0", features = ["chrono"] }
|
||||
chrono.workspace = true
|
||||
sha2 = "0.10.8"
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use parse_display::{Display, FromStr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
|
||||
@@ -60,8 +59,7 @@ impl From<ClientErrorCode> for ClientError {
|
||||
}
|
||||
|
||||
/// Client error codes defined in OAuth2.0, OpenID Connect and their extensions.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Display, FromStr, SerializeDisplay, DeserializeFromStr)]
|
||||
#[display(style = "snake_case")]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, SerializeDisplay, DeserializeFromStr)]
|
||||
pub enum ClientErrorCode {
|
||||
/// `invalid_request`
|
||||
///
|
||||
@@ -276,10 +274,77 @@ pub enum ClientErrorCode {
|
||||
UnsupportedTokenType,
|
||||
|
||||
/// Another error code.
|
||||
#[display("{0}")]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ClientErrorCode {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
ClientErrorCode::InvalidRequest => f.write_str("invalid_request"),
|
||||
ClientErrorCode::InvalidClient => f.write_str("invalid_client"),
|
||||
ClientErrorCode::InvalidGrant => f.write_str("invalid_grant"),
|
||||
ClientErrorCode::UnauthorizedClient => f.write_str("unauthorized_client"),
|
||||
ClientErrorCode::UnsupportedGrantType => f.write_str("unsupported_grant_type"),
|
||||
ClientErrorCode::AccessDenied => f.write_str("access_denied"),
|
||||
ClientErrorCode::UnsupportedResponseType => f.write_str("unsupported_response_type"),
|
||||
ClientErrorCode::InvalidScope => f.write_str("invalid_scope"),
|
||||
ClientErrorCode::ServerError => f.write_str("server_error"),
|
||||
ClientErrorCode::TemporarilyUnavailable => f.write_str("temporarily_unavailable"),
|
||||
ClientErrorCode::InteractionRequired => f.write_str("interaction_required"),
|
||||
ClientErrorCode::LoginRequired => f.write_str("login_required"),
|
||||
ClientErrorCode::AccountSelectionRequired => f.write_str("account_selection_required"),
|
||||
ClientErrorCode::ConsentRequired => f.write_str("consent_required"),
|
||||
ClientErrorCode::InvalidRequestUri => f.write_str("invalid_request_uri"),
|
||||
ClientErrorCode::InvalidRequestObject => f.write_str("invalid_request_object"),
|
||||
ClientErrorCode::RequestNotSupported => f.write_str("request_not_supported"),
|
||||
ClientErrorCode::RequestUriNotSupported => f.write_str("request_uri_not_supported"),
|
||||
ClientErrorCode::RegistrationNotSupported => f.write_str("registration_not_supported"),
|
||||
ClientErrorCode::InvalidRedirectUri => f.write_str("invalid_redirect_uri"),
|
||||
ClientErrorCode::InvalidClientMetadata => f.write_str("invalid_client_metadata"),
|
||||
ClientErrorCode::AuthorizationPending => f.write_str("authorization_pending"),
|
||||
ClientErrorCode::SlowDown => f.write_str("slow_down"),
|
||||
ClientErrorCode::ExpiredToken => f.write_str("expired_token"),
|
||||
ClientErrorCode::UnsupportedTokenType => f.write_str("unsupported_token_type"),
|
||||
ClientErrorCode::Unknown(value) => f.write_str(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for ClientErrorCode {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"invalid_request" => Ok(ClientErrorCode::InvalidRequest),
|
||||
"invalid_client" => Ok(ClientErrorCode::InvalidClient),
|
||||
"invalid_grant" => Ok(ClientErrorCode::InvalidGrant),
|
||||
"unauthorized_client" => Ok(ClientErrorCode::UnauthorizedClient),
|
||||
"unsupported_grant_type" => Ok(ClientErrorCode::UnsupportedGrantType),
|
||||
"access_denied" => Ok(ClientErrorCode::AccessDenied),
|
||||
"unsupported_response_type" => Ok(ClientErrorCode::UnsupportedResponseType),
|
||||
"invalid_scope" => Ok(ClientErrorCode::InvalidScope),
|
||||
"server_error" => Ok(ClientErrorCode::ServerError),
|
||||
"temporarily_unavailable" => Ok(ClientErrorCode::TemporarilyUnavailable),
|
||||
"interaction_required" => Ok(ClientErrorCode::InteractionRequired),
|
||||
"login_required" => Ok(ClientErrorCode::LoginRequired),
|
||||
"account_selection_required" => Ok(ClientErrorCode::AccountSelectionRequired),
|
||||
"consent_required" => Ok(ClientErrorCode::ConsentRequired),
|
||||
"invalid_request_uri" => Ok(ClientErrorCode::InvalidRequestUri),
|
||||
"invalid_request_object" => Ok(ClientErrorCode::InvalidRequestObject),
|
||||
"request_not_supported" => Ok(ClientErrorCode::RequestNotSupported),
|
||||
"request_uri_not_supported" => Ok(ClientErrorCode::RequestUriNotSupported),
|
||||
"registration_not_supported" => Ok(ClientErrorCode::RegistrationNotSupported),
|
||||
"invalid_redirect_uri" => Ok(ClientErrorCode::InvalidRedirectUri),
|
||||
"invalid_client_metadata" => Ok(ClientErrorCode::InvalidClientMetadata),
|
||||
"authorization_pending" => Ok(ClientErrorCode::AuthorizationPending),
|
||||
"slow_down" => Ok(ClientErrorCode::SlowDown),
|
||||
"expired_token" => Ok(ClientErrorCode::ExpiredToken),
|
||||
"unsupported_token_type" => Ok(ClientErrorCode::UnsupportedTokenType),
|
||||
_ => Ok(ClientErrorCode::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientErrorCode {
|
||||
/// Get the default description for this `ClientErrorCode`.
|
||||
///
|
||||
|
@@ -16,14 +16,13 @@
|
||||
//!
|
||||
//! [OpenID Connect]: https://openid.net/connect/
|
||||
|
||||
use std::{fmt, ops::Deref, str::FromStr};
|
||||
use std::{fmt, ops::Deref};
|
||||
|
||||
use language_tags::LanguageTag;
|
||||
use mas_iana::{
|
||||
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
||||
oauth::{OAuthAccessTokenType, OAuthClientAuthenticationMethod, PkceCodeChallengeMethod},
|
||||
};
|
||||
use parse_display::{Display, FromStr, ParseError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{
|
||||
formats::SpaceSeparator, serde_as, skip_serializing_none, DeserializeFromStr, SerializeDisplay,
|
||||
@@ -39,14 +38,12 @@ use crate::{
|
||||
|
||||
/// An enum for types that accept either an [`OAuthClientAuthenticationMethod`]
|
||||
/// or an [`OAuthAccessTokenType`].
|
||||
#[derive(SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, Debug, Display)]
|
||||
#[derive(SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum AuthenticationMethodOrAccessTokenType {
|
||||
/// An authentication method.
|
||||
#[display("{0}")]
|
||||
AuthenticationMethod(OAuthClientAuthenticationMethod),
|
||||
|
||||
/// An access token type.
|
||||
#[display("{0}")]
|
||||
AccessTokenType(OAuthAccessTokenType),
|
||||
|
||||
/// An unknown value.
|
||||
@@ -54,10 +51,37 @@ pub enum AuthenticationMethodOrAccessTokenType {
|
||||
/// Note that this variant should only be used as the result parsing a
|
||||
/// string of unknown type. To build a custom variant, first parse a
|
||||
/// string with the wanted type then use `.into()`.
|
||||
#[display("{0}")]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for AuthenticationMethodOrAccessTokenType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::AuthenticationMethod(m) => m.fmt(f),
|
||||
Self::AccessTokenType(t) => t.fmt(f),
|
||||
Self::Unknown(s) => s.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for AuthenticationMethodOrAccessTokenType {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match OAuthClientAuthenticationMethod::from_str(s) {
|
||||
Ok(OAuthClientAuthenticationMethod::Unknown(_)) | Err(_) => {}
|
||||
Ok(m) => return Ok(m.into()),
|
||||
}
|
||||
|
||||
match OAuthAccessTokenType::from_str(s) {
|
||||
Ok(OAuthAccessTokenType::Unknown(_)) | Err(_) => {}
|
||||
Ok(m) => return Ok(m.into()),
|
||||
}
|
||||
|
||||
Ok(Self::Unknown(s.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
impl AuthenticationMethodOrAccessTokenType {
|
||||
/// Get the authentication method of this
|
||||
/// `AuthenticationMethodOrAccessTokenType`.
|
||||
@@ -80,28 +104,6 @@ impl AuthenticationMethodOrAccessTokenType {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for AuthenticationMethodOrAccessTokenType {
|
||||
type Err = ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if let Ok(m) = OAuthClientAuthenticationMethod::from_str(s) {
|
||||
match m {
|
||||
OAuthClientAuthenticationMethod::Unknown(_) => {}
|
||||
m => return Ok(m.into()),
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(t) = OAuthAccessTokenType::from_str(s) {
|
||||
match t {
|
||||
OAuthAccessTokenType::Unknown(_) => {}
|
||||
t => return Ok(t.into()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self::Unknown(s.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OAuthClientAuthenticationMethod> for AuthenticationMethodOrAccessTokenType {
|
||||
fn from(t: OAuthClientAuthenticationMethod) -> Self {
|
||||
Self::AuthenticationMethod(t)
|
||||
@@ -115,16 +117,38 @@ impl From<OAuthAccessTokenType> for AuthenticationMethodOrAccessTokenType {
|
||||
}
|
||||
|
||||
/// The kind of an application.
|
||||
#[derive(
|
||||
SerializeDisplay, DeserializeFromStr, Clone, Copy, PartialEq, Eq, Hash, Debug, Display, FromStr,
|
||||
)]
|
||||
#[display(style = "lowercase")]
|
||||
#[derive(SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum ApplicationType {
|
||||
/// A web application.
|
||||
Web,
|
||||
|
||||
/// A native application.
|
||||
Native,
|
||||
|
||||
/// An unknown value.
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ApplicationType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Web => f.write_str("web"),
|
||||
Self::Native => f.write_str("native"),
|
||||
Self::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for ApplicationType {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"web" => Ok(Self::Web),
|
||||
"native" => Ok(Self::Native),
|
||||
s => Ok(Self::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Subject Identifier types.
|
||||
@@ -132,10 +156,7 @@ pub enum ApplicationType {
|
||||
/// A Subject Identifier is a locally unique and never reassigned identifier
|
||||
/// within the Issuer for the End-User, which is intended to be consumed by the
|
||||
/// Client.
|
||||
#[derive(
|
||||
SerializeDisplay, DeserializeFromStr, Clone, Copy, PartialEq, Eq, Hash, Debug, Display, FromStr,
|
||||
)]
|
||||
#[display(style = "lowercase")]
|
||||
#[derive(SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum SubjectType {
|
||||
/// This provides the same `sub` (subject) value to all Clients.
|
||||
Public,
|
||||
@@ -144,13 +165,35 @@ pub enum SubjectType {
|
||||
/// enable Clients to correlate the End-User's activities without
|
||||
/// permission.
|
||||
Pairwise,
|
||||
|
||||
/// An unknown value.
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for SubjectType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Public => f.write_str("public"),
|
||||
Self::Pairwise => f.write_str("pairwise"),
|
||||
Self::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for SubjectType {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"public" => Ok(Self::Public),
|
||||
"pairwise" => Ok(Self::Pairwise),
|
||||
s => Ok(Self::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Claim types.
|
||||
#[derive(
|
||||
SerializeDisplay, DeserializeFromStr, Clone, Copy, PartialEq, Eq, Hash, Debug, Display, FromStr,
|
||||
)]
|
||||
#[display(style = "lowercase")]
|
||||
#[derive(SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum ClaimType {
|
||||
/// Claims that are directly asserted by the OpenID Provider.
|
||||
Normal,
|
||||
@@ -162,6 +205,33 @@ pub enum ClaimType {
|
||||
/// Claims that are asserted by a Claims Provider other than the OpenID
|
||||
/// Provider but are returned as references by the OpenID Provider.
|
||||
Distributed,
|
||||
|
||||
/// An unknown value.
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ClaimType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Normal => f.write_str("normal"),
|
||||
Self::Aggregated => f.write_str("aggregated"),
|
||||
Self::Distributed => f.write_str("distributed"),
|
||||
Self::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for ClaimType {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"normal" => Ok(Self::Normal),
|
||||
"aggregated" => Ok(Self::Aggregated),
|
||||
"distributed" => Ok(Self::Distributed),
|
||||
s => Ok(Self::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An account management action that a user can take.
|
||||
|
@@ -613,7 +613,9 @@ impl ClientMetadata {
|
||||
/// Defaults to [`DEFAULT_APPLICATION_TYPE`].
|
||||
#[must_use]
|
||||
pub fn application_type(&self) -> ApplicationType {
|
||||
self.application_type.unwrap_or(DEFAULT_APPLICATION_TYPE)
|
||||
self.application_type
|
||||
.clone()
|
||||
.unwrap_or(DEFAULT_APPLICATION_TYPE)
|
||||
}
|
||||
|
||||
/// Requested client authentication method for the [token endpoint].
|
||||
|
@@ -21,7 +21,6 @@ use std::{collections::HashSet, fmt, hash::Hash, num::NonZeroU32};
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use language_tags::LanguageTag;
|
||||
use mas_iana::oauth::{OAuthAccessTokenType, OAuthTokenTypeHint};
|
||||
use parse_display::{Display, FromStr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{
|
||||
formats::SpaceSeparator, serde_as, skip_serializing_none, DeserializeFromStr, DisplayFromStr,
|
||||
@@ -38,19 +37,8 @@ use crate::{response_type::ResponseType, scope::Scope};
|
||||
///
|
||||
/// Defined in [OAuth 2.0 Multiple Response Type Encoding Practices](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes).
|
||||
#[derive(
|
||||
Debug,
|
||||
Hash,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Clone,
|
||||
Display,
|
||||
FromStr,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, SerializeDisplay, DeserializeFromStr,
|
||||
)]
|
||||
#[display(style = "snake_case")]
|
||||
#[non_exhaustive]
|
||||
pub enum ResponseMode {
|
||||
/// Authorization Response parameters are encoded in the query string added
|
||||
@@ -71,28 +59,40 @@ pub enum ResponseMode {
|
||||
FormPost,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ResponseMode {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
ResponseMode::Query => f.write_str("query"),
|
||||
ResponseMode::Fragment => f.write_str("fragment"),
|
||||
ResponseMode::FormPost => f.write_str("form_post"),
|
||||
ResponseMode::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for ResponseMode {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"query" => Ok(ResponseMode::Query),
|
||||
"fragment" => Ok(ResponseMode::Fragment),
|
||||
"form_post" => Ok(ResponseMode::FormPost),
|
||||
s => Ok(ResponseMode::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Value that specifies how the Authorization Server displays the
|
||||
/// authentication and consent user interface pages to the End-User.
|
||||
///
|
||||
/// Defined in [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
|
||||
#[derive(
|
||||
Debug,
|
||||
Hash,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Clone,
|
||||
Display,
|
||||
FromStr,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, SerializeDisplay, DeserializeFromStr,
|
||||
)]
|
||||
#[display(style = "snake_case")]
|
||||
#[non_exhaustive]
|
||||
pub enum Display {
|
||||
/// The Authorization Server should display the authentication and consent
|
||||
@@ -114,10 +114,35 @@ pub enum Display {
|
||||
Wap,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Display {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Display::Page => f.write_str("page"),
|
||||
Display::Popup => f.write_str("popup"),
|
||||
Display::Touch => f.write_str("touch"),
|
||||
Display::Wap => f.write_str("wap"),
|
||||
Display::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for Display {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"page" => Ok(Display::Page),
|
||||
"popup" => Ok(Display::Popup),
|
||||
"touch" => Ok(Display::Touch),
|
||||
"wap" => Ok(Display::Wap),
|
||||
s => Ok(Display::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Display {
|
||||
fn default() -> Self {
|
||||
Self::Page
|
||||
@@ -129,19 +154,8 @@ impl Default for Display {
|
||||
///
|
||||
/// Defined in [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
|
||||
#[derive(
|
||||
Debug,
|
||||
Hash,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Clone,
|
||||
Display,
|
||||
FromStr,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, SerializeDisplay, DeserializeFromStr,
|
||||
)]
|
||||
#[display(style = "snake_case")]
|
||||
#[non_exhaustive]
|
||||
pub enum Prompt {
|
||||
/// The Authorization Server must not display any authentication or consent
|
||||
@@ -171,10 +185,37 @@ pub enum Prompt {
|
||||
Create,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Prompt {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Prompt::None => f.write_str("none"),
|
||||
Prompt::Login => f.write_str("login"),
|
||||
Prompt::Consent => f.write_str("consent"),
|
||||
Prompt::SelectAccount => f.write_str("select_account"),
|
||||
Prompt::Create => f.write_str("create"),
|
||||
Prompt::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for Prompt {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"none" => Ok(Prompt::None),
|
||||
"login" => Ok(Prompt::Login),
|
||||
"consent" => Ok(Prompt::Consent),
|
||||
"select_account" => Ok(Prompt::SelectAccount),
|
||||
"create" => Ok(Prompt::Create),
|
||||
s => Ok(Prompt::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The body of a request to the [Authorization Endpoint].
|
||||
///
|
||||
/// [Authorization Endpoint]: https://www.rfc-editor.org/rfc/rfc6749.html#section-3.1
|
||||
@@ -511,20 +552,8 @@ impl fmt::Debug for DeviceCodeGrant {
|
||||
|
||||
/// All possible values for the `grant_type` parameter.
|
||||
#[derive(
|
||||
Debug,
|
||||
Hash,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Clone,
|
||||
Copy,
|
||||
Display,
|
||||
FromStr,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, SerializeDisplay, DeserializeFromStr,
|
||||
)]
|
||||
#[display(style = "snake_case")]
|
||||
pub enum GrantType {
|
||||
/// [`authorization_code`](https://www.rfc-editor.org/rfc/rfc6749#section-4.1)
|
||||
AuthorizationCode,
|
||||
@@ -542,16 +571,54 @@ pub enum GrantType {
|
||||
Password,
|
||||
|
||||
/// [`urn:ietf:params:oauth:grant-type:device_code`](https://www.rfc-editor.org/rfc/rfc8628)
|
||||
#[display("urn:ietf:params:oauth:grant-type:device_code")]
|
||||
DeviceCode,
|
||||
|
||||
/// [`https://datatracker.ietf.org/doc/html/rfc7523#section-2.1`](https://www.rfc-editor.org/rfc/rfc7523#section-2.1)
|
||||
#[display("urn:ietf:params:oauth:grant-type:jwt-bearer")]
|
||||
JwtBearer,
|
||||
|
||||
/// [`urn:openid:params:grant-type:ciba`](https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html)
|
||||
#[display("urn:openid:params:grant-type:ciba")]
|
||||
ClientInitiatedBackchannelAuthentication,
|
||||
|
||||
/// An unknown value.
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for GrantType {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
GrantType::AuthorizationCode => f.write_str("authorization_code"),
|
||||
GrantType::RefreshToken => f.write_str("refresh_token"),
|
||||
GrantType::Implicit => f.write_str("implicit"),
|
||||
GrantType::ClientCredentials => f.write_str("client_credentials"),
|
||||
GrantType::Password => f.write_str("password"),
|
||||
GrantType::DeviceCode => f.write_str("urn:ietf:params:oauth:grant-type:device_code"),
|
||||
GrantType::JwtBearer => f.write_str("urn:ietf:params:oauth:grant-type:jwt-bearer"),
|
||||
GrantType::ClientInitiatedBackchannelAuthentication => {
|
||||
f.write_str("urn:openid:params:grant-type:ciba")
|
||||
}
|
||||
GrantType::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for GrantType {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"authorization_code" => Ok(GrantType::AuthorizationCode),
|
||||
"refresh_token" => Ok(GrantType::RefreshToken),
|
||||
"implicit" => Ok(GrantType::Implicit),
|
||||
"client_credentials" => Ok(GrantType::ClientCredentials),
|
||||
"password" => Ok(GrantType::Password),
|
||||
"urn:ietf:params:oauth:grant-type:device_code" => Ok(GrantType::DeviceCode),
|
||||
"urn:ietf:params:oauth:grant-type:jwt-bearer" => Ok(GrantType::JwtBearer),
|
||||
"urn:openid:params:grant-type:ciba" => {
|
||||
Ok(GrantType::ClientInitiatedBackchannelAuthentication)
|
||||
}
|
||||
s => Ok(GrantType::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An enum representing the possible requests to the [Token Endpoint].
|
||||
|
@@ -21,7 +21,6 @@
|
||||
use std::{collections::BTreeSet, fmt, iter::FromIterator, str::FromStr};
|
||||
|
||||
use mas_iana::oauth::OAuthAuthorizationEndpointResponseType;
|
||||
use parse_display::{Display, FromStr};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -38,19 +37,8 @@ pub struct InvalidResponseType;
|
||||
/// This type also accepts unknown tokens that can be constructed via it's
|
||||
/// `FromStr` implementation or used via its `Display` implementation.
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, SerializeDisplay, DeserializeFromStr,
|
||||
)]
|
||||
#[display(style = "snake_case")]
|
||||
#[non_exhaustive]
|
||||
pub enum ResponseTypeToken {
|
||||
/// `code`
|
||||
@@ -63,10 +51,33 @@ pub enum ResponseTypeToken {
|
||||
Token,
|
||||
|
||||
/// Unknown token.
|
||||
#[display("{0}")]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ResponseTypeToken {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
ResponseTypeToken::Code => f.write_str("code"),
|
||||
ResponseTypeToken::IdToken => f.write_str("id_token"),
|
||||
ResponseTypeToken::Token => f.write_str("token"),
|
||||
ResponseTypeToken::Unknown(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for ResponseTypeToken {
|
||||
type Err = core::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"code" => Ok(Self::Code),
|
||||
"id_token" => Ok(Self::IdToken),
|
||||
"token" => Ok(Self::Token),
|
||||
s => Ok(Self::Unknown(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An [OAuth 2.0 `response_type` value] that the client can use
|
||||
/// at the [authorization endpoint].
|
||||
///
|
||||
|
Reference in New Issue
Block a user