You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-20 12:02:22 +03:00
Simple dynamic client registration
This commit is contained in:
@@ -68,6 +68,7 @@ pub(crate) async fn get(
|
||||
let jwks_uri = Some(url_builder.jwks_uri());
|
||||
let introspection_endpoint = Some(url_builder.oauth_introspection_endpoint());
|
||||
let userinfo_endpoint = Some(url_builder.oidc_userinfo_endpoint());
|
||||
let registration_endpoint = Some(url_builder.oauth_registration_endpoint());
|
||||
|
||||
let scopes_supported = Some(vec![scope::OPENID.to_string(), scope::EMAIL.to_string()]);
|
||||
|
||||
@@ -133,6 +134,7 @@ pub(crate) async fn get(
|
||||
authorization_endpoint,
|
||||
token_endpoint,
|
||||
jwks_uri,
|
||||
registration_endpoint,
|
||||
scopes_supported,
|
||||
response_types_supported,
|
||||
response_modes_supported,
|
||||
|
||||
@@ -16,6 +16,7 @@ pub mod authorization;
|
||||
pub mod discovery;
|
||||
pub mod introspection;
|
||||
pub mod keys;
|
||||
pub mod registration;
|
||||
pub mod token;
|
||||
pub mod userinfo;
|
||||
pub mod webfinger;
|
||||
|
||||
94
crates/handlers/src/oauth2/registration.rs
Normal file
94
crates/handlers/src/oauth2/registration.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use axum::{response::IntoResponse, Extension, Json};
|
||||
use hyper::StatusCode;
|
||||
use mas_storage::oauth2::client::insert_client;
|
||||
use oauth2_types::{
|
||||
errors::SERVER_ERROR,
|
||||
registration::{ClientMetadata, ClientRegistrationResponse},
|
||||
};
|
||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||
use sqlx::PgPool;
|
||||
use thiserror::Error;
|
||||
use tracing::info;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub(crate) enum RouteError {
|
||||
#[error(transparent)]
|
||||
Internal(Box<dyn std::error::Error + Send + Sync>),
|
||||
}
|
||||
|
||||
impl From<sqlx::Error> for RouteError {
|
||||
fn from(e: sqlx::Error) -> Self {
|
||||
Self::Internal(Box::new(e))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for RouteError {
|
||||
fn into_response(self) -> axum::response::Response {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(SERVER_ERROR)).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, err)]
|
||||
pub(crate) async fn post(
|
||||
Extension(pool): Extension<PgPool>,
|
||||
Json(body): Json<ClientMetadata>,
|
||||
) -> Result<impl IntoResponse, RouteError> {
|
||||
info!(?body, "Client registration");
|
||||
|
||||
// Grab a txn
|
||||
let mut txn = pool.begin().await?;
|
||||
|
||||
// Let's generate a random client ID
|
||||
let client_id: String = thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(10)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
|
||||
insert_client(
|
||||
&mut txn,
|
||||
&client_id,
|
||||
&body.redirect_uris,
|
||||
None,
|
||||
&body.response_types,
|
||||
&body.grant_types,
|
||||
&body.contacts,
|
||||
body.client_name.as_deref(),
|
||||
body.logo_uri.as_ref(),
|
||||
body.client_uri.as_ref(),
|
||||
body.policy_uri.as_ref(),
|
||||
body.tos_uri.as_ref(),
|
||||
body.jwks_uri.as_ref(),
|
||||
body.jwks.as_ref(),
|
||||
body.id_token_signed_response_alg,
|
||||
body.token_endpoint_auth_method,
|
||||
body.token_endpoint_auth_signing_alg,
|
||||
body.initiate_login_uri.as_ref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
let response = ClientRegistrationResponse {
|
||||
client_id,
|
||||
client_secret: None,
|
||||
client_id_issued_at: None,
|
||||
client_secret_expires_at: None,
|
||||
};
|
||||
|
||||
Ok((StatusCode::CREATED, Json(response)))
|
||||
}
|
||||
@@ -56,6 +56,7 @@ use serde::Serialize;
|
||||
use serde_with::{serde_as, skip_serializing_none};
|
||||
use sha2::{Digest, Sha256};
|
||||
use sqlx::{PgPool, Postgres, Transaction};
|
||||
use thiserror::Error;
|
||||
use tracing::debug;
|
||||
use url::Url;
|
||||
|
||||
@@ -76,14 +77,30 @@ struct CustomClaims {
|
||||
c_hash: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub(crate) enum RouteError {
|
||||
#[error(transparent)]
|
||||
Internal(Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
Anyhow(anyhow::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Anyhow(#[from] anyhow::Error),
|
||||
|
||||
#[error("bad request")]
|
||||
BadRequest,
|
||||
|
||||
#[error("client not found")]
|
||||
ClientNotFound,
|
||||
|
||||
#[error("client not allowed")]
|
||||
ClientNotAllowed,
|
||||
ClientCredentialsVerification(CredentialsVerificationError),
|
||||
|
||||
#[error("could not verify client credentials")]
|
||||
ClientCredentialsVerification(#[from] CredentialsVerificationError),
|
||||
|
||||
#[error("invalid grant")]
|
||||
InvalidGrant,
|
||||
|
||||
#[error("unauthorized client")]
|
||||
UnauthorizedClient,
|
||||
}
|
||||
|
||||
@@ -138,18 +155,7 @@ impl From<ClaimError> for RouteError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<anyhow::Error> for RouteError {
|
||||
fn from(e: anyhow::Error) -> Self {
|
||||
Self::Anyhow(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CredentialsVerificationError> for RouteError {
|
||||
fn from(e: CredentialsVerificationError) -> Self {
|
||||
Self::ClientCredentialsVerification(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, err)]
|
||||
pub(crate) async fn post(
|
||||
client_authorization: ClientAuthorization<AccessTokenRequest>,
|
||||
Extension(key_store): Extension<Arc<StaticKeystore>>,
|
||||
|
||||
Reference in New Issue
Block a user