diff --git a/src/api/client/appservice.rs b/src/api/client/appservice.rs new file mode 100644 index 00000000..d299185e --- /dev/null +++ b/src/api/client/appservice.rs @@ -0,0 +1,47 @@ +use axum::extract::State; +use conduit::{err, Err, Result}; +use ruma::api::{appservice::ping, client::appservice::request_ping}; + +use crate::Ruma; + +/// # `POST /_matrix/client/v1/appservice/{appserviceId}/ping` +/// +/// Ask the homeserver to ping the application service to ensure the connection +/// works. +pub(crate) async fn appservice_ping( + State(services): State, body: Ruma, +) -> Result { + let appservice_info = body + .appservice_info + .as_ref() + .ok_or_else(|| err!(Request(Forbidden("This endpoint can only be called by appservices."))))?; + + if body.appservice_id != appservice_info.registration.id { + return Err!(Request(Forbidden( + "Appservices can only ping themselves (wrong appservice ID)." + ))); + } + + if appservice_info.registration.url.is_none() { + return Err!(Request(UrlNotSet( + "Appservice does not have a URL set, there is nothing to ping." + ))); + } + + let timer = tokio::time::Instant::now(); + + let _response = services + .sending + .send_appservice_request( + appservice_info.registration.clone(), + ping::send_ping::v1::Request { + transaction_id: body.transaction_id.clone(), + }, + ) + .await? + .expect("We already validated if an appservice URL exists above"); + + Ok(request_ping::v1::Response { + duration: timer.elapsed(), + }) +} diff --git a/src/api/client/mod.rs b/src/api/client/mod.rs index 03c87e5d..5dcdc51a 100644 --- a/src/api/client/mod.rs +++ b/src/api/client/mod.rs @@ -1,5 +1,6 @@ pub(super) mod account; pub(super) mod alias; +pub(super) mod appservice; pub(super) mod backup; pub(super) mod capabilities; pub(super) mod config; @@ -38,6 +39,7 @@ pub(super) mod voip; pub(super) use account::*; pub(super) use alias::*; +pub(super) use appservice::*; pub(super) use backup::*; pub(super) use capabilities::*; pub(super) use config::*; diff --git a/src/api/router.rs b/src/api/router.rs index c2d64599..985f803b 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -22,6 +22,7 @@ use crate::{client, server}; pub fn build(router: Router, server: &Server) -> Router { let config = &server.config; let mut router = router + .ruma_route(client::appservice_ping) .ruma_route(client::get_supported_versions_route) .ruma_route(client::get_register_available_route) .ruma_route(client::register_route)