1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

Return reason for invalid_client_metadata in HTTP response (#298)

This commit is contained in:
Hugh Nimmo-Smith
2022-07-08 22:11:54 +01:00
committed by GitHub
parent b6d26fff27
commit 0e21f00d17

View File

@ -17,7 +17,7 @@ use std::sync::Arc;
use axum::{response::IntoResponse, Extension, Json};
use hyper::StatusCode;
use mas_iana::oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod};
use mas_policy::PolicyFactory;
use mas_policy::{PolicyFactory, Violation};
use mas_storage::oauth2::client::insert_client;
use oauth2_types::{
errors::{INVALID_CLIENT_METADATA, INVALID_REDIRECT_URI, SERVER_ERROR},
@ -44,7 +44,7 @@ pub(crate) enum RouteError {
InvalidClientMetadata,
#[error("denied by the policy")]
PolicyDenied,
PolicyDenied(Vec<Violation>),
}
impl From<sqlx::Error> for RouteError {
@ -53,17 +53,53 @@ impl From<sqlx::Error> for RouteError {
}
}
// TODO: there is probably a better way to do achieve this. ClientError only
// works for static strings
#[derive(serde::Serialize)]
struct PolicyError {
error: String,
error_description: String,
}
impl PolicyError {
#[must_use]
pub const fn new(error: String, error_description: String) -> Self {
Self {
error,
error_description,
}
}
}
impl IntoResponse for RouteError {
fn into_response(self) -> axum::response::Response {
match self {
Self::Internal(_) | Self::Anyhow(_) => {
(StatusCode::INTERNAL_SERVER_ERROR, Json(SERVER_ERROR))
(StatusCode::INTERNAL_SERVER_ERROR, Json(SERVER_ERROR)).into_response()
}
Self::InvalidRedirectUri => {
(StatusCode::BAD_REQUEST, Json(INVALID_REDIRECT_URI)).into_response()
}
Self::InvalidClientMetadata => {
(StatusCode::BAD_REQUEST, Json(INVALID_CLIENT_METADATA)).into_response()
}
Self::PolicyDenied(violations) => {
let collected = &violations
.iter()
.map(|v| v.msg.clone())
.collect::<Vec<String>>();
let joined = collected.join("; ");
(
StatusCode::UNAUTHORIZED,
Json(PolicyError::new(
"invalid_client_metadata".to_string(),
joined,
)),
)
.into_response()
}
Self::InvalidRedirectUri => (StatusCode::BAD_REQUEST, Json(INVALID_REDIRECT_URI)),
Self::InvalidClientMetadata => (StatusCode::BAD_REQUEST, Json(INVALID_CLIENT_METADATA)),
Self::PolicyDenied => (StatusCode::UNAUTHORIZED, Json(INVALID_CLIENT_METADATA)),
}
.into_response()
}
}
@ -121,7 +157,7 @@ pub(crate) async fn post(
let mut policy = policy_factory.instantiate().await?;
let res = policy.evaluate_client_registration(&body).await?;
if !res.valid() {
return Err(RouteError::PolicyDenied);
return Err(RouteError::PolicyDenied(res.violations));
}
// Grab a txn