mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-15 13:16:56 +00:00
Convert in-memory data structures in appservice, rooms::typing, and sync wakers to use SyncRwLock and SyncMutex. Drop appservice locks before making outbound network requests in room alias queries and federation invites.
108 lines
3.2 KiB
Rust
108 lines
3.2 KiB
Rust
use axum::{Json, extract::State, response::IntoResponse};
|
|
use conduwuit::{
|
|
Err, Result,
|
|
matrix::versions::{unstable_features, versions},
|
|
metrics::PROMETHEUS_CONTENT_TYPE,
|
|
utils::string::constant_time_eq,
|
|
};
|
|
use futures::StreamExt;
|
|
use http::{HeaderMap, header};
|
|
use ruma::{api::client::discovery::get_supported_versions, assign};
|
|
|
|
use crate::Ruma;
|
|
|
|
/// # `GET /_matrix/client/versions`
|
|
///
|
|
/// Get the versions of the specification and unstable features supported by
|
|
/// this server.
|
|
///
|
|
/// - Versions take the form MAJOR.MINOR.PATCH
|
|
/// - Only the latest PATCH release will be reported for each MAJOR.MINOR value
|
|
/// - Unstable features are namespaced and may include version information in
|
|
/// their name
|
|
///
|
|
/// Note: Unstable features are used while developing new features. Clients
|
|
/// should avoid using unstable features in their stable releases
|
|
pub(crate) async fn get_supported_versions_route(
|
|
State(services): State<crate::State>,
|
|
_body: Ruma<get_supported_versions::Request>,
|
|
) -> Result<get_supported_versions::Response> {
|
|
let mut unstable_features = unstable_features();
|
|
|
|
if services.config.allow_sticky_events {
|
|
// sticky events (https://github.com/matrix-org/matrix-spec-proposals/pull/4354)
|
|
unstable_features.insert("org.matrix.msc4354".to_owned(), true);
|
|
}
|
|
|
|
Ok(assign!(get_supported_versions::Response::new(versions()), {
|
|
unstable_features
|
|
}))
|
|
}
|
|
|
|
/// # `GET /_continuwuity/server_version`
|
|
///
|
|
/// Conduwuit-specific API to get the server version, results akin to
|
|
/// `/_matrix/federation/v1/version`
|
|
pub(crate) async fn continuwuity_server_version() -> Result<impl IntoResponse> {
|
|
Ok(Json(serde_json::json!({
|
|
"name": conduwuit::BRANDING,
|
|
"version": conduwuit::version(),
|
|
})))
|
|
}
|
|
|
|
/// # `GET /_continuwuity/local_user_count`
|
|
///
|
|
/// conduwuit-specific API to return the amount of users registered on this
|
|
/// homeserver. Endpoint is disabled if federation is disabled for privacy. This
|
|
///
|
|
/// only includes active users (not deactivated, etc)
|
|
pub(crate) async fn continuwuity_local_user_count(
|
|
State(services): State<crate::State>,
|
|
) -> Result<impl IntoResponse> {
|
|
let user_count = services
|
|
.users
|
|
.stream_local_users()
|
|
.filter_map(async |user_id| {
|
|
if !services.users.status(&user_id).await.is_active()
|
|
|| services.appservice.is_exclusive_user_id(&user_id)
|
|
{
|
|
None
|
|
} else {
|
|
Some(user_id)
|
|
}
|
|
})
|
|
.count()
|
|
.await;
|
|
|
|
Ok(Json(serde_json::json!({
|
|
"count": user_count
|
|
})))
|
|
}
|
|
|
|
/// # `GET /_continuwuity/metrics`
|
|
///
|
|
/// Prometheus metrics in the text exposition format. Only routed when
|
|
/// `allow_prometheus_metrics` is enabled.
|
|
pub(crate) async fn continuwuity_metrics(
|
|
State(services): State<crate::State>,
|
|
headers: HeaderMap,
|
|
) -> Result<impl IntoResponse> {
|
|
if let Some(token) = &services.config.prometheus_metrics_token {
|
|
let authorized = headers
|
|
.get(header::AUTHORIZATION)
|
|
.and_then(|value| value.to_str().ok())
|
|
.and_then(|value| value.split_once(' '))
|
|
.is_some_and(|(scheme, provided)| {
|
|
scheme.eq_ignore_ascii_case("bearer") && constant_time_eq(provided, token)
|
|
});
|
|
|
|
if !authorized {
|
|
return Err!(Request(Unauthorized("Invalid metrics token")));
|
|
}
|
|
}
|
|
|
|
let body = services.server.metrics.render()?;
|
|
|
|
Ok(([(header::CONTENT_TYPE, PROMETHEUS_CONTENT_TYPE)], body))
|
|
}
|