1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

Make more enum types accept unknown values

This commit is contained in:
Kévin Commaille
2022-10-17 13:50:33 +02:00
committed by Quentin Gliech
parent 10297d29bb
commit 51515358f7
4 changed files with 40 additions and 24 deletions

View File

@ -41,12 +41,15 @@ pub struct CallbackDestination {
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum InvalidRedirectUriError { pub enum IntoCallbackDestinationError {
#[error("Redirect URI can't have a fragment")] #[error("Redirect URI can't have a fragment")]
FragmentNotAllowed, RedirectUriFragmentNotAllowed,
#[error("Existing query parameters are not valid")] #[error("Existing query parameters are not valid")]
InvalidQueryParams(#[from] serde_urlencoded::de::Error), RedirectUriInvalidQueryParams(#[from] serde_urlencoded::de::Error),
#[error("Requested response_mode is not supported")]
UnsupportedResponseMode,
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -59,11 +62,11 @@ pub enum CallbackDestinationError {
} }
impl<S: StorageBackend> TryFrom<&AuthorizationGrant<S>> for CallbackDestination { impl<S: StorageBackend> TryFrom<&AuthorizationGrant<S>> for CallbackDestination {
type Error = InvalidRedirectUriError; type Error = IntoCallbackDestinationError;
fn try_from(value: &AuthorizationGrant<S>) -> Result<Self, Self::Error> { fn try_from(value: &AuthorizationGrant<S>) -> Result<Self, Self::Error> {
Self::try_new( Self::try_new(
value.response_mode, &value.response_mode,
value.redirect_uri.clone(), value.redirect_uri.clone(),
value.state.clone(), value.state.clone(),
) )
@ -72,12 +75,12 @@ impl<S: StorageBackend> TryFrom<&AuthorizationGrant<S>> for CallbackDestination
impl CallbackDestination { impl CallbackDestination {
pub fn try_new( pub fn try_new(
mode: ResponseMode, mode: &ResponseMode,
mut redirect_uri: Url, mut redirect_uri: Url,
state: Option<String>, state: Option<String>,
) -> Result<Self, InvalidRedirectUriError> { ) -> Result<Self, IntoCallbackDestinationError> {
if redirect_uri.fragment().is_some() { if redirect_uri.fragment().is_some() {
return Err(InvalidRedirectUriError::FragmentNotAllowed); return Err(IntoCallbackDestinationError::RedirectUriFragmentNotAllowed);
} }
let mode = match mode { let mode = match mode {
@ -95,6 +98,7 @@ impl CallbackDestination {
} }
ResponseMode::Fragment => CallbackDestinationMode::Fragment, ResponseMode::Fragment => CallbackDestinationMode::Fragment,
ResponseMode::FormPost => CallbackDestinationMode::FormPost, ResponseMode::FormPost => CallbackDestinationMode::FormPost,
_ => return Err(IntoCallbackDestinationError::UnsupportedResponseMode),
}; };
Ok(Self { Ok(Self {

View File

@ -39,7 +39,9 @@ use oauth2_types::requests::{AccessTokenResponse, AuthorizationResponse};
use sqlx::{PgPool, Postgres, Transaction}; use sqlx::{PgPool, Postgres, Transaction};
use thiserror::Error; use thiserror::Error;
use super::callback::{CallbackDestination, CallbackDestinationError, InvalidRedirectUriError}; use super::callback::{
CallbackDestination, CallbackDestinationError, IntoCallbackDestinationError,
};
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum RouteError { pub enum RouteError {
@ -90,8 +92,8 @@ impl From<ActiveSessionLookupError> for RouteError {
} }
} }
impl From<InvalidRedirectUriError> for RouteError { impl From<IntoCallbackDestinationError> for RouteError {
fn from(e: InvalidRedirectUriError) -> Self { fn from(e: IntoCallbackDestinationError) -> Self {
Self::Internal(Box::new(e)) Self::Internal(Box::new(e))
} }
} }
@ -175,8 +177,8 @@ impl From<sqlx::Error> for GrantCompletionError {
} }
} }
impl From<InvalidRedirectUriError> for GrantCompletionError { impl From<IntoCallbackDestinationError> for GrantCompletionError {
fn from(e: InvalidRedirectUriError) -> Self { fn from(e: IntoCallbackDestinationError) -> Self {
Self::Internal(Box::new(e)) Self::Internal(Box::new(e))
} }
} }

View File

@ -58,8 +58,8 @@ pub enum RouteError {
#[error("could not find client")] #[error("could not find client")]
ClientNotFound, ClientNotFound,
#[error("invalid redirect uri")] #[error("invalid parameters")]
InvalidRedirectUri(#[from] self::callback::InvalidRedirectUriError), IntoCallbackDestination(#[from] self::callback::IntoCallbackDestinationError),
#[error("invalid redirect uri")] #[error("invalid redirect uri")]
UnknownRedirectUri(#[from] mas_data_model::InvalidRedirectUriError), UnknownRedirectUri(#[from] mas_data_model::InvalidRedirectUriError),
@ -78,11 +78,9 @@ impl IntoResponse for RouteError {
RouteError::ClientNotFound => { RouteError::ClientNotFound => {
(StatusCode::BAD_REQUEST, "could not find client").into_response() (StatusCode::BAD_REQUEST, "could not find client").into_response()
} }
RouteError::InvalidRedirectUri(e) => ( RouteError::IntoCallbackDestination(e) => {
StatusCode::BAD_REQUEST, (StatusCode::BAD_REQUEST, e.to_string()).into_response()
format!("Invalid redirect URI ({})", e), }
)
.into_response(),
RouteError::UnknownRedirectUri(e) => ( RouteError::UnknownRedirectUri(e) => (
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
format!("Invalid redirect URI ({})", e), format!("Invalid redirect URI ({})", e),
@ -175,7 +173,7 @@ pub(crate) async fn get(
// Now we have a proper callback destination to go to on error // Now we have a proper callback destination to go to on error
let callback_destination = CallbackDestination::try_new( let callback_destination = CallbackDestination::try_new(
response_mode, &response_mode,
redirect_uri.clone(), redirect_uri.clone(),
params.auth.state.clone(), params.auth.state.clone(),
)?; )?;

View File

@ -41,13 +41,13 @@ use crate::{response_type::ResponseType, scope::Scope};
PartialOrd, PartialOrd,
Ord, Ord,
Clone, Clone,
Copy,
Display, Display,
FromStr, FromStr,
SerializeDisplay, SerializeDisplay,
DeserializeFromStr, DeserializeFromStr,
)] )]
#[display(style = "snake_case")] #[display(style = "snake_case")]
#[non_exhaustive]
pub enum ResponseMode { pub enum ResponseMode {
/// Authorization Response parameters are encoded in the query string added /// Authorization Response parameters are encoded in the query string added
/// to the `redirect_uri`. /// to the `redirect_uri`.
@ -65,6 +65,10 @@ pub enum ResponseMode {
/// ///
/// Defined in [OAuth 2.0 Form Post Response Mode](https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html). /// Defined in [OAuth 2.0 Form Post Response Mode](https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html).
FormPost, FormPost,
/// An unknown value.
#[display("{0}")]
Unknown(String),
} }
/// Value that specifies how the Authorization Server displays the /// Value that specifies how the Authorization Server displays the
@ -79,13 +83,13 @@ pub enum ResponseMode {
PartialOrd, PartialOrd,
Ord, Ord,
Clone, Clone,
Copy,
Display, Display,
FromStr, FromStr,
SerializeDisplay, SerializeDisplay,
DeserializeFromStr, DeserializeFromStr,
)] )]
#[display(style = "snake_case")] #[display(style = "snake_case")]
#[non_exhaustive]
pub enum Display { pub enum Display {
/// The Authorization Server should display the authentication and consent /// The Authorization Server should display the authentication and consent
/// UI consistent with a full User Agent page view. /// UI consistent with a full User Agent page view.
@ -104,6 +108,10 @@ pub enum Display {
/// The Authorization Server should display the authentication and consent /// The Authorization Server should display the authentication and consent
/// UI consistent with a "feature phone" type display. /// UI consistent with a "feature phone" type display.
Wap, Wap,
/// An unknown value.
#[display("{0}")]
Unknown(String),
} }
impl Default for Display { impl Default for Display {
@ -124,13 +132,13 @@ impl Default for Display {
PartialOrd, PartialOrd,
Ord, Ord,
Clone, Clone,
Copy,
Display, Display,
FromStr, FromStr,
SerializeDisplay, SerializeDisplay,
DeserializeFromStr, DeserializeFromStr,
)] )]
#[display(style = "snake_case")] #[display(style = "snake_case")]
#[non_exhaustive]
pub enum Prompt { pub enum Prompt {
/// The Authorization Server must not display any authentication or consent /// The Authorization Server must not display any authentication or consent
/// user interface pages. /// user interface pages.
@ -157,6 +165,10 @@ pub enum Prompt {
/// ///
/// Defined in [Initiating User Registration via OpenID Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html). /// Defined in [Initiating User Registration via OpenID Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html).
Create, Create,
/// An unknown value.
#[display("{0}")]
Unknown(String),
} }
/// The body of a request to the [Authorization Endpoint]. /// The body of a request to the [Authorization Endpoint].