You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-09 04:22:45 +03:00
handlers: bootstrap the admin API router
This commit is contained in:
52
Cargo.lock
generated
52
Cargo.lock
generated
@@ -84,6 +84,41 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aide"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b0e3b97a21e41ec5c19bfd9b4fc1f7086be104f8b988681230247ffc91cc8ed"
|
||||||
|
dependencies = [
|
||||||
|
"aide-macros",
|
||||||
|
"axum",
|
||||||
|
"axum-extra",
|
||||||
|
"bytes",
|
||||||
|
"cfg-if",
|
||||||
|
"http",
|
||||||
|
"indexmap 2.2.6",
|
||||||
|
"schemars",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_qs",
|
||||||
|
"thiserror",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aide-macros"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0487f8598afe49e6bc950a613a678bd962c4a6f431022ded62643c8b990301a"
|
||||||
|
dependencies = [
|
||||||
|
"darling 0.20.9",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.68",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
@@ -3283,6 +3318,7 @@ dependencies = [
|
|||||||
name = "mas-handlers"
|
name = "mas-handlers"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aide",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argon2",
|
"argon2",
|
||||||
"async-graphql",
|
"async-graphql",
|
||||||
@@ -3298,6 +3334,7 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"headers",
|
"headers",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"indexmap 2.2.6",
|
||||||
"insta",
|
"insta",
|
||||||
"lettre",
|
"lettre",
|
||||||
"mas-axum-utils",
|
"mas-axum-utils",
|
||||||
@@ -3325,6 +3362,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"rustls 0.23.12",
|
"rustls 0.23.12",
|
||||||
|
"schemars",
|
||||||
"sentry",
|
"sentry",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -5249,6 +5287,7 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"indexmap 1.9.3",
|
"indexmap 1.9.3",
|
||||||
|
"indexmap 2.2.6",
|
||||||
"schemars_derive",
|
"schemars_derive",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -5553,6 +5592,19 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_qs"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"futures",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@@ -55,6 +55,11 @@ mas-templates = { path = "./crates/templates/", version = "=0.9.0" }
|
|||||||
mas-tower = { path = "./crates/tower/", version = "=0.9.0" }
|
mas-tower = { path = "./crates/tower/", version = "=0.9.0" }
|
||||||
oauth2-types = { path = "./crates/oauth2-types/", version = "=0.9.0" }
|
oauth2-types = { path = "./crates/oauth2-types/", version = "=0.9.0" }
|
||||||
|
|
||||||
|
# OpenAPI schema generation and validation
|
||||||
|
[workspace.dependencies.aide]
|
||||||
|
version = "0.13.4"
|
||||||
|
features = ["axum", "axum-headers", "macros"]
|
||||||
|
|
||||||
# GraphQL server
|
# GraphQL server
|
||||||
[workspace.dependencies.async-graphql]
|
[workspace.dependencies.async-graphql]
|
||||||
version = "7.0.7"
|
version = "7.0.7"
|
||||||
|
@@ -36,7 +36,9 @@ axum-macros = "0.4.1"
|
|||||||
axum-extra.workspace = true
|
axum-extra.workspace = true
|
||||||
rustls.workspace = true
|
rustls.workspace = true
|
||||||
|
|
||||||
|
aide.workspace = true
|
||||||
async-graphql.workspace = true
|
async-graphql.workspace = true
|
||||||
|
schemars.workspace = true
|
||||||
|
|
||||||
# Emails
|
# Emails
|
||||||
lettre.workspace = true
|
lettre.workspace = true
|
||||||
@@ -65,6 +67,7 @@ zeroize = "1.8.1"
|
|||||||
base64ct = "1.6.0"
|
base64ct = "1.6.0"
|
||||||
camino.workspace = true
|
camino.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
|
indexmap = "2.2.6"
|
||||||
psl = "2.1.55"
|
psl = "2.1.55"
|
||||||
time = "0.3.36"
|
time = "0.3.36"
|
||||||
url.workspace = true
|
url.workspace = true
|
||||||
|
94
crates/handlers/src/admin/mod.rs
Normal file
94
crates/handlers/src/admin/mod.rs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// Copyright 2024 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 aide::{
|
||||||
|
axum::ApiRouter,
|
||||||
|
openapi::{OAuth2Flow, OAuth2Flows, OpenApi, SecurityScheme, Server, ServerVariable},
|
||||||
|
};
|
||||||
|
use axum::{Json, Router};
|
||||||
|
use hyper::header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE};
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
use mas_http::CorsLayerExt;
|
||||||
|
use mas_router::{OAuth2AuthorizationEndpoint, OAuth2TokenEndpoint, SimpleRoute};
|
||||||
|
use tower_http::cors::{Any, CorsLayer};
|
||||||
|
|
||||||
|
pub fn router<S>() -> (OpenApi, Router<S>)
|
||||||
|
where
|
||||||
|
S: Clone + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let mut api = OpenApi::default();
|
||||||
|
let router = ApiRouter::<S>::new()
|
||||||
|
// TODO: add routes
|
||||||
|
.finish_api_with(&mut api, |t| {
|
||||||
|
t.title("Matrix Authentication Service admin API")
|
||||||
|
.security_scheme(
|
||||||
|
"oauth2",
|
||||||
|
SecurityScheme::OAuth2 {
|
||||||
|
flows: OAuth2Flows {
|
||||||
|
client_credentials: Some(OAuth2Flow::ClientCredentials {
|
||||||
|
refresh_url: Some(OAuth2TokenEndpoint::PATH.to_owned()),
|
||||||
|
token_url: OAuth2TokenEndpoint::PATH.to_owned(),
|
||||||
|
scopes: IndexMap::from([(
|
||||||
|
"urn:mas:admin".to_owned(),
|
||||||
|
"Grant access to the admin API".to_owned(),
|
||||||
|
)]),
|
||||||
|
}),
|
||||||
|
authorization_code: Some(OAuth2Flow::AuthorizationCode {
|
||||||
|
authorization_url: OAuth2AuthorizationEndpoint::PATH.to_owned(),
|
||||||
|
refresh_url: Some(OAuth2TokenEndpoint::PATH.to_owned()),
|
||||||
|
token_url: OAuth2TokenEndpoint::PATH.to_owned(),
|
||||||
|
scopes: IndexMap::from([(
|
||||||
|
"urn:mas:admin".to_owned(),
|
||||||
|
"Grant access to the admin API".to_owned(),
|
||||||
|
)]),
|
||||||
|
}),
|
||||||
|
implicit: None,
|
||||||
|
password: None,
|
||||||
|
},
|
||||||
|
description: None,
|
||||||
|
extensions: IndexMap::default(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.security_requirement_scopes("oauth2", ["urn:mas:admin"])
|
||||||
|
.server(Server {
|
||||||
|
url: "{base}".to_owned(),
|
||||||
|
variables: IndexMap::from([(
|
||||||
|
"base".to_owned(),
|
||||||
|
ServerVariable {
|
||||||
|
default: "/".to_owned(),
|
||||||
|
..ServerVariable::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
..Server::default()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let router = router
|
||||||
|
// Serve the OpenAPI spec as JSON
|
||||||
|
.route(
|
||||||
|
"/api/spec.json",
|
||||||
|
axum::routing::get({
|
||||||
|
let res = Json(api.clone());
|
||||||
|
move || std::future::ready(res.clone())
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.layer(
|
||||||
|
CorsLayer::new()
|
||||||
|
.allow_origin(Any)
|
||||||
|
.allow_methods(Any)
|
||||||
|
.allow_otel_headers([AUTHORIZATION, ACCEPT, CONTENT_TYPE]),
|
||||||
|
);
|
||||||
|
|
||||||
|
(api, router)
|
||||||
|
}
|
@@ -53,6 +53,7 @@ use sqlx::PgPool;
|
|||||||
use tower::util::AndThenLayer;
|
use tower::util::AndThenLayer;
|
||||||
use tower_http::cors::{Any, CorsLayer};
|
use tower_http::cors::{Any, CorsLayer};
|
||||||
|
|
||||||
|
mod admin;
|
||||||
mod compat;
|
mod compat;
|
||||||
mod graphql;
|
mod graphql;
|
||||||
mod health;
|
mod health;
|
||||||
@@ -89,6 +90,7 @@ pub use mas_axum_utils::{
|
|||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
activity_tracker::{ActivityTracker, Bound as BoundActivityTracker},
|
activity_tracker::{ActivityTracker, Bound as BoundActivityTracker},
|
||||||
|
admin::router as admin_api_router,
|
||||||
graphql::{
|
graphql::{
|
||||||
schema as graphql_schema, schema_builder as graphql_schema_builder, Schema as GraphQLSchema,
|
schema as graphql_schema, schema_builder as graphql_schema_builder, Schema as GraphQLSchema,
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user