You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Return reason for invalid_client_metadata in HTTP response (#298)
This commit is contained in:
@ -17,7 +17,7 @@ use std::sync::Arc;
|
|||||||
use axum::{response::IntoResponse, Extension, Json};
|
use axum::{response::IntoResponse, Extension, Json};
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
use mas_iana::oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod};
|
use mas_iana::oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod};
|
||||||
use mas_policy::PolicyFactory;
|
use mas_policy::{PolicyFactory, Violation};
|
||||||
use mas_storage::oauth2::client::insert_client;
|
use mas_storage::oauth2::client::insert_client;
|
||||||
use oauth2_types::{
|
use oauth2_types::{
|
||||||
errors::{INVALID_CLIENT_METADATA, INVALID_REDIRECT_URI, SERVER_ERROR},
|
errors::{INVALID_CLIENT_METADATA, INVALID_REDIRECT_URI, SERVER_ERROR},
|
||||||
@ -44,7 +44,7 @@ pub(crate) enum RouteError {
|
|||||||
InvalidClientMetadata,
|
InvalidClientMetadata,
|
||||||
|
|
||||||
#[error("denied by the policy")]
|
#[error("denied by the policy")]
|
||||||
PolicyDenied,
|
PolicyDenied(Vec<Violation>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<sqlx::Error> for RouteError {
|
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 {
|
impl IntoResponse for RouteError {
|
||||||
fn into_response(self) -> axum::response::Response {
|
fn into_response(self) -> axum::response::Response {
|
||||||
match self {
|
match self {
|
||||||
Self::Internal(_) | Self::Anyhow(_) => {
|
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 mut policy = policy_factory.instantiate().await?;
|
||||||
let res = policy.evaluate_client_registration(&body).await?;
|
let res = policy.evaluate_client_registration(&body).await?;
|
||||||
if !res.valid() {
|
if !res.valid() {
|
||||||
return Err(RouteError::PolicyDenied);
|
return Err(RouteError::PolicyDenied(res.violations));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab a txn
|
// Grab a txn
|
||||||
|
Reference in New Issue
Block a user