Admin API to expose a few configuration values
This commit is contained in:
@@ -20,7 +20,7 @@ use axum::{
|
||||
use hyper::header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE};
|
||||
use indexmap::IndexMap;
|
||||
use mas_axum_utils::InternalError;
|
||||
use mas_data_model::BoxRng;
|
||||
use mas_data_model::{BoxRng, SiteConfig};
|
||||
use mas_http::CorsLayerExt;
|
||||
use mas_matrix::HomeserverConnection;
|
||||
use mas_policy::PolicyFactory;
|
||||
@@ -43,6 +43,11 @@ use crate::passwords::PasswordManager;
|
||||
|
||||
fn finish(t: TransformOpenApi) -> TransformOpenApi {
|
||||
t.title("Matrix Authentication Service admin API")
|
||||
.tag(Tag {
|
||||
name: "server".to_owned(),
|
||||
description: Some("Information about the server".to_owned()),
|
||||
..Tag::default()
|
||||
})
|
||||
.tag(Tag {
|
||||
name: "compat-session".to_owned(),
|
||||
description: Some("Manage compatibility sessions from legacy clients".to_owned()),
|
||||
@@ -153,6 +158,7 @@ where
|
||||
Templates: FromRef<S>,
|
||||
UrlBuilder: FromRef<S>,
|
||||
Arc<PolicyFactory>: FromRef<S>,
|
||||
SiteConfig: FromRef<S>,
|
||||
{
|
||||
// We *always* want to explicitly set the possible responses, beacuse the
|
||||
// infered ones are not necessarily correct
|
||||
|
||||
@@ -11,7 +11,7 @@ use aide::axum::{
|
||||
routing::{get_with, post_with},
|
||||
};
|
||||
use axum::extract::{FromRef, FromRequestParts};
|
||||
use mas_data_model::BoxRng;
|
||||
use mas_data_model::{BoxRng, SiteConfig};
|
||||
use mas_matrix::HomeserverConnection;
|
||||
use mas_policy::PolicyFactory;
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::passwords::PasswordManager;
|
||||
mod compat_sessions;
|
||||
mod oauth2_sessions;
|
||||
mod policy_data;
|
||||
mod site_config;
|
||||
mod upstream_oauth_links;
|
||||
mod user_emails;
|
||||
mod user_registration_tokens;
|
||||
@@ -32,11 +33,16 @@ where
|
||||
S: Clone + Send + Sync + 'static,
|
||||
Arc<dyn HomeserverConnection>: FromRef<S>,
|
||||
PasswordManager: FromRef<S>,
|
||||
SiteConfig: FromRef<S>,
|
||||
Arc<PolicyFactory>: FromRef<S>,
|
||||
BoxRng: FromRequestParts<S>,
|
||||
CallContext: FromRequestParts<S>,
|
||||
{
|
||||
ApiRouter::<S>::new()
|
||||
.api_route(
|
||||
"/site-config",
|
||||
get_with(self::site_config::handler, self::site_config::doc),
|
||||
)
|
||||
.api_route(
|
||||
"/compat-sessions",
|
||||
get_with(self::compat_sessions::list, self::compat_sessions::list_doc),
|
||||
|
||||
92
crates/handlers/src/admin/v1/site_config.rs
Normal file
92
crates/handlers/src/admin/v1/site_config.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
|
||||
use aide::transform::TransformOperation;
|
||||
use axum::{Json, extract::State};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::admin::call_context::CallContext;
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct SiteConfig {
|
||||
/// The Matrix server name for which this instance is configured
|
||||
server_name: String,
|
||||
|
||||
/// Whether password login is enabled.
|
||||
pub password_login_enabled: bool,
|
||||
|
||||
/// Whether password registration is enabled.
|
||||
pub password_registration_enabled: bool,
|
||||
|
||||
/// Whether registration tokens are required for password registrations.
|
||||
pub registration_token_required: bool,
|
||||
|
||||
/// Whether users can change their email.
|
||||
pub email_change_allowed: bool,
|
||||
|
||||
/// Whether users can change their display name.
|
||||
pub displayname_change_allowed: bool,
|
||||
|
||||
/// Whether users can change their password.
|
||||
pub password_change_allowed: bool,
|
||||
|
||||
/// Whether users can recover their account via email.
|
||||
pub account_recovery_allowed: bool,
|
||||
|
||||
/// Whether users can delete their own account.
|
||||
pub account_deactivation_allowed: bool,
|
||||
|
||||
/// Whether CAPTCHA during registration is enabled.
|
||||
pub captcha_enabled: bool,
|
||||
|
||||
/// Minimum password complexity, between 0 and 4.
|
||||
/// This is a score from zxcvbn.
|
||||
#[schemars(range(min = 0, max = 4))]
|
||||
pub minimum_password_complexity: u8,
|
||||
}
|
||||
|
||||
pub fn doc(operation: TransformOperation) -> TransformOperation {
|
||||
operation
|
||||
.id("siteConfig")
|
||||
.tag("server")
|
||||
.summary("Get informations about the configuration of this MAS instance")
|
||||
.response_with::<200, Json<SiteConfig>, _>(|t| {
|
||||
t.example(SiteConfig {
|
||||
server_name: "example.com".to_owned(),
|
||||
password_login_enabled: true,
|
||||
password_registration_enabled: true,
|
||||
registration_token_required: true,
|
||||
email_change_allowed: true,
|
||||
displayname_change_allowed: true,
|
||||
password_change_allowed: true,
|
||||
account_recovery_allowed: true,
|
||||
account_deactivation_allowed: true,
|
||||
captcha_enabled: true,
|
||||
minimum_password_complexity: 3,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "handler.admin.v1.site_config", skip_all)]
|
||||
pub async fn handler(
|
||||
_: CallContext,
|
||||
State(site_config): State<mas_data_model::SiteConfig>,
|
||||
) -> Json<SiteConfig> {
|
||||
Json(SiteConfig {
|
||||
server_name: site_config.server_name,
|
||||
password_login_enabled: site_config.password_login_enabled,
|
||||
password_registration_enabled: site_config.password_registration_enabled,
|
||||
registration_token_required: site_config.registration_token_required,
|
||||
email_change_allowed: site_config.email_change_allowed,
|
||||
displayname_change_allowed: site_config.displayname_change_allowed,
|
||||
password_change_allowed: site_config.password_change_allowed,
|
||||
account_recovery_allowed: site_config.account_recovery_allowed,
|
||||
account_deactivation_allowed: site_config.account_deactivation_allowed,
|
||||
captcha_enabled: site_config.captcha.is_some(),
|
||||
minimum_password_complexity: site_config.minimum_password_complexity,
|
||||
})
|
||||
}
|
||||
@@ -59,6 +59,7 @@ impl_from_ref!(Arc<dyn mas_matrix::HomeserverConnection>);
|
||||
impl_from_ref!(mas_keystore::Keystore);
|
||||
impl_from_ref!(mas_handlers::passwords::PasswordManager);
|
||||
impl_from_ref!(Arc<mas_policy::PolicyFactory>);
|
||||
impl_from_ref!(mas_data_model::SiteConfig);
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (mut api, _) = mas_handlers::admin_api_router::<DummyState>();
|
||||
|
||||
@@ -16,6 +16,40 @@
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/api/admin/v1/site-config": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"server"
|
||||
],
|
||||
"summary": "Get informations about the configuration of this MAS instance",
|
||||
"operationId": "siteConfig",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SiteConfig"
|
||||
},
|
||||
"example": {
|
||||
"server_name": "example.com",
|
||||
"password_login_enabled": true,
|
||||
"password_registration_enabled": true,
|
||||
"registration_token_required": true,
|
||||
"email_change_allowed": true,
|
||||
"displayname_change_allowed": true,
|
||||
"password_change_allowed": true,
|
||||
"account_recovery_allowed": true,
|
||||
"account_deactivation_allowed": true,
|
||||
"captcha_enabled": true,
|
||||
"minimum_password_complexity": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/v1/compat-sessions": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -3186,6 +3220,71 @@
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"SiteConfig": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"account_deactivation_allowed",
|
||||
"account_recovery_allowed",
|
||||
"captcha_enabled",
|
||||
"displayname_change_allowed",
|
||||
"email_change_allowed",
|
||||
"minimum_password_complexity",
|
||||
"password_change_allowed",
|
||||
"password_login_enabled",
|
||||
"password_registration_enabled",
|
||||
"registration_token_required",
|
||||
"server_name"
|
||||
],
|
||||
"properties": {
|
||||
"server_name": {
|
||||
"description": "The Matrix server name for which this instance is configured",
|
||||
"type": "string"
|
||||
},
|
||||
"password_login_enabled": {
|
||||
"description": "Whether password login is enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"password_registration_enabled": {
|
||||
"description": "Whether password registration is enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"registration_token_required": {
|
||||
"description": "Whether registration tokens are required for password registrations.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"email_change_allowed": {
|
||||
"description": "Whether users can change their email.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"displayname_change_allowed": {
|
||||
"description": "Whether users can change their display name.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"password_change_allowed": {
|
||||
"description": "Whether users can change their password.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"account_recovery_allowed": {
|
||||
"description": "Whether users can recover their account via email.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"account_deactivation_allowed": {
|
||||
"description": "Whether users can delete their own account.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"captcha_enabled": {
|
||||
"description": "Whether CAPTCHA during registration is enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"minimum_password_complexity": {
|
||||
"description": "Minimum password complexity, between 0 and 4. This is a score from zxcvbn.",
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"maximum": 4.0,
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"PaginationParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -4586,6 +4685,10 @@
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"name": "server",
|
||||
"description": "Information about the server"
|
||||
},
|
||||
{
|
||||
"name": "compat-session",
|
||||
"description": "Manage compatibility sessions from legacy clients"
|
||||
|
||||
Reference in New Issue
Block a user