fix optional config section related

split api/client well_known

simplify well_known config access

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-11-24 00:19:55 +00:00
parent 5f1cab6850
commit f30b08f015
9 changed files with 144 additions and 138 deletions

View file

@ -37,6 +37,7 @@ pub(super) mod unstable;
pub(super) mod unversioned;
pub(super) mod user_directory;
pub(super) mod voip;
pub(super) mod well_known;
pub use account::full_user_deactivate;
pub(super) use account::*;
@ -80,6 +81,7 @@ pub(super) use unstable::*;
pub(super) use unversioned::*;
pub(super) use user_directory::*;
pub(super) use voip::*;
pub(super) use well_known::*;
/// generated device ID length
const DEVICE_ID_LENGTH: usize = 10;

View file

@ -198,8 +198,10 @@ pub(crate) async fn login_route(
// send client well-known if specified so the client knows to reconfigure itself
let client_discovery_info: Option<DiscoveryInfo> = services
.globals
.well_known_client()
.server
.config
.well_known
.client
.as_ref()
.map(|server| DiscoveryInfo::new(HomeserverInfo::new(server.to_string())));

View file

@ -2,16 +2,9 @@ use std::collections::BTreeMap;
use axum::{extract::State, response::IntoResponse, Json};
use futures::StreamExt;
use ruma::api::client::{
discovery::{
discover_homeserver::{self, HomeserverInfo, SlidingSyncProxyInfo},
discover_support::{self, Contact},
get_supported_versions,
},
error::ErrorKind,
};
use ruma::api::client::discovery::get_supported_versions;
use crate::{Error, Result, Ruma};
use crate::{Result, Ruma};
/// # `GET /_matrix/client/versions`
///
@ -65,99 +58,6 @@ pub(crate) async fn get_supported_versions_route(
Ok(resp)
}
/// # `GET /.well-known/matrix/client`
///
/// Returns the .well-known URL if it is configured, otherwise returns 404.
pub(crate) async fn well_known_client(
State(services): State<crate::State>, _body: Ruma<discover_homeserver::Request>,
) -> Result<discover_homeserver::Response> {
let client_url = match services.globals.well_known_client() {
Some(url) => url.to_string(),
None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")),
};
Ok(discover_homeserver::Response {
homeserver: HomeserverInfo {
base_url: client_url.clone(),
},
identity_server: None,
sliding_sync_proxy: Some(SlidingSyncProxyInfo {
url: client_url,
}),
tile_server: None,
})
}
/// # `GET /.well-known/matrix/support`
///
/// Server support contact and support page of a homeserver's domain.
pub(crate) async fn well_known_support(
State(services): State<crate::State>, _body: Ruma<discover_support::Request>,
) -> Result<discover_support::Response> {
let support_page = services
.globals
.well_known_support_page()
.as_ref()
.map(ToString::to_string);
let role = services.globals.well_known_support_role().clone();
// support page or role must be either defined for this to be valid
if support_page.is_none() && role.is_none() {
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
}
let email_address = services.globals.well_known_support_email().clone();
let matrix_id = services.globals.well_known_support_mxid().clone();
// if a role is specified, an email address or matrix id is required
if role.is_some() && (email_address.is_none() && matrix_id.is_none()) {
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
}
// TOOD: support defining multiple contacts in the config
let mut contacts: Vec<Contact> = vec![];
if let Some(role) = role {
let contact = Contact {
role,
email_address,
matrix_id,
};
contacts.push(contact);
}
// support page or role+contacts must be either defined for this to be valid
if contacts.is_empty() && support_page.is_none() {
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
}
Ok(discover_support::Response {
contacts,
support_page,
})
}
/// # `GET /client/server.json`
///
/// Endpoint provided by sliding sync proxy used by some clients such as Element
/// Web as a non-standard health check.
pub(crate) async fn syncv3_client_server_json(State(services): State<crate::State>) -> Result<impl IntoResponse> {
let server_url = match services.globals.well_known_client() {
Some(url) => url.to_string(),
None => match services.globals.well_known_server() {
Some(url) => url.to_string(),
None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")),
},
};
Ok(Json(serde_json::json!({
"server": server_url,
"version": conduit::version(),
})))
}
/// # `GET /_conduwuit/server_version`
///
/// Conduwuit-specific API to get the server version, results akin to

View file

@ -0,0 +1,105 @@
use axum::{extract::State, response::IntoResponse, Json};
use ruma::api::client::{
discovery::{
discover_homeserver::{self, HomeserverInfo, SlidingSyncProxyInfo},
discover_support::{self, Contact},
},
error::ErrorKind,
};
use crate::{Error, Result, Ruma};
/// # `GET /.well-known/matrix/client`
///
/// Returns the .well-known URL if it is configured, otherwise returns 404.
pub(crate) async fn well_known_client(
State(services): State<crate::State>, _body: Ruma<discover_homeserver::Request>,
) -> Result<discover_homeserver::Response> {
let client_url = match services.server.config.well_known.client.as_ref() {
Some(url) => url.to_string(),
None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")),
};
Ok(discover_homeserver::Response {
homeserver: HomeserverInfo {
base_url: client_url.clone(),
},
identity_server: None,
sliding_sync_proxy: Some(SlidingSyncProxyInfo {
url: client_url,
}),
tile_server: None,
})
}
/// # `GET /.well-known/matrix/support`
///
/// Server support contact and support page of a homeserver's domain.
pub(crate) async fn well_known_support(
State(services): State<crate::State>, _body: Ruma<discover_support::Request>,
) -> Result<discover_support::Response> {
let support_page = services
.server
.config
.well_known
.support_page
.as_ref()
.map(ToString::to_string);
let role = services.server.config.well_known.support_role.clone();
// support page or role must be either defined for this to be valid
if support_page.is_none() && role.is_none() {
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
}
let email_address = services.server.config.well_known.support_email.clone();
let matrix_id = services.server.config.well_known.support_mxid.clone();
// if a role is specified, an email address or matrix id is required
if role.is_some() && (email_address.is_none() && matrix_id.is_none()) {
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
}
// TOOD: support defining multiple contacts in the config
let mut contacts: Vec<Contact> = vec![];
if let Some(role) = role {
let contact = Contact {
role,
email_address,
matrix_id,
};
contacts.push(contact);
}
// support page or role+contacts must be either defined for this to be valid
if contacts.is_empty() && support_page.is_none() {
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
}
Ok(discover_support::Response {
contacts,
support_page,
})
}
/// # `GET /client/server.json`
///
/// Endpoint provided by sliding sync proxy used by some clients such as Element
/// Web as a non-standard health check.
pub(crate) async fn syncv3_client_server_json(State(services): State<crate::State>) -> Result<impl IntoResponse> {
let server_url = match services.server.config.well_known.client.as_ref() {
Some(url) => url.to_string(),
None => match services.server.config.well_known.server.as_ref() {
Some(url) => url.to_string(),
None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")),
},
};
Ok(Json(serde_json::json!({
"server": server_url,
"version": conduit::version(),
})))
}