mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-07 23:44:53 -04:00
Event handlers for room and user queries
Add a member to AppService which can store closures that will be invoked when the homeserver invokes query endpoints.
This commit is contained in:
35
crates/matrix-sdk-appservice/src/event_handler.rs
Normal file
35
crates/matrix-sdk-appservice/src/event_handler.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::future::BoxFuture;
|
||||
use matrix_sdk::locks::Mutex;
|
||||
|
||||
use crate::{
|
||||
ruma::api::appservice::query::{
|
||||
query_room_alias::v1 as query_room, query_user_id::v1 as query_user,
|
||||
},
|
||||
AppService,
|
||||
};
|
||||
|
||||
pub(crate) type AppserviceFn<A, R> =
|
||||
Box<dyn FnMut(AppService, A) -> BoxFuture<'static, R> + Send + Sync + 'static>;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct EventHandler {
|
||||
pub users: Arc<Mutex<Option<AppserviceFn<query_user::IncomingRequest, bool>>>>,
|
||||
pub rooms: Arc<Mutex<Option<AppserviceFn<query_room::IncomingRequest, bool>>>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for EventHandler {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut debug = f.debug_struct("EventHandler");
|
||||
match self.users.try_lock() {
|
||||
Ok(lock) => debug.field("users", &lock.is_some()),
|
||||
Err(_) => debug.field("users", &format_args!("<locked>")),
|
||||
};
|
||||
match self.rooms.try_lock() {
|
||||
Ok(lock) => debug.field("rooms", &lock.is_some()),
|
||||
Err(_) => debug.field("rooms", &format_args!("<locked>")),
|
||||
};
|
||||
debug.finish()
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,7 @@ use std::{
|
||||
|
||||
use dashmap::DashMap;
|
||||
pub use error::Error;
|
||||
use event_handler::AppserviceFn;
|
||||
use http::Uri;
|
||||
pub use matrix_sdk;
|
||||
#[doc(no_inline)]
|
||||
@@ -100,7 +101,10 @@ use matrix_sdk::{
|
||||
use regex::Regex;
|
||||
use ruma::{
|
||||
api::{
|
||||
appservice::Registration,
|
||||
appservice::{
|
||||
query::{query_room_alias::v1 as query_room, query_user_id::v1 as query_user},
|
||||
Registration,
|
||||
},
|
||||
client::{
|
||||
error::ErrorKind,
|
||||
r0::{account::register, uiaa::UiaaResponse},
|
||||
@@ -113,6 +117,7 @@ use serde::de::DeserializeOwned;
|
||||
use tracing::{info, warn};
|
||||
|
||||
mod error;
|
||||
pub mod event_handler;
|
||||
mod webserver;
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
@@ -203,6 +208,7 @@ pub struct AppService {
|
||||
server_name: ServerNameBox,
|
||||
registration: Arc<AppServiceRegistration>,
|
||||
clients: Arc<DashMap<Localpart, Client>>,
|
||||
event_handler: event_handler::EventHandler,
|
||||
}
|
||||
|
||||
impl AppService {
|
||||
@@ -250,8 +256,10 @@ impl AppService {
|
||||
let registration = Arc::new(registration);
|
||||
let clients = Arc::new(DashMap::new());
|
||||
let sender_localpart = registration.sender_localpart.clone();
|
||||
let event_handler = event_handler::EventHandler::default();
|
||||
|
||||
let appservice = AppService { homeserver_url, server_name, registration, clients };
|
||||
let appservice =
|
||||
AppService { homeserver_url, server_name, registration, clients, event_handler };
|
||||
|
||||
// we create and cache the [`MainUser`] by default
|
||||
appservice.create_and_cache_client(&sender_localpart, client_config).await?;
|
||||
@@ -386,6 +394,28 @@ impl AppService {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register a responder for queries about the existence of a user with a
|
||||
/// given mxid.
|
||||
///
|
||||
/// See [GET /_matrix/app/v1/users/{userId}](https://matrix.org/docs/spec/application_service/r0.1.2#get-matrix-app-v1-users-userid).
|
||||
pub async fn register_user_query(
|
||||
&mut self,
|
||||
handler: AppserviceFn<query_user::IncomingRequest, bool>,
|
||||
) {
|
||||
*self.event_handler.users.lock().await = Some(handler);
|
||||
}
|
||||
|
||||
/// Register a responder for queries about the existence of a room with the
|
||||
/// given alias.
|
||||
///
|
||||
/// See [GET /_matrix/app/v1/rooms/{roomAlias}](https://matrix.org/docs/spec/application_service/r0.1.2#get-matrix-app-v1-rooms-roomalias).
|
||||
pub async fn register_room_query(
|
||||
&mut self,
|
||||
handler: AppserviceFn<query_room::IncomingRequest, bool>,
|
||||
) {
|
||||
*self.event_handler.rooms.lock().await = Some(handler);
|
||||
}
|
||||
|
||||
/// Register a virtual user by sending a [`register::Request`] to the
|
||||
/// homeserver
|
||||
///
|
||||
|
||||
@@ -15,7 +15,18 @@
|
||||
use std::{net::ToSocketAddrs, result::Result as StdResult};
|
||||
|
||||
use futures::TryFutureExt;
|
||||
use matrix_sdk::{bytes::Bytes, ruma};
|
||||
use matrix_sdk::{
|
||||
bytes::Bytes,
|
||||
ruma::{
|
||||
self,
|
||||
api::{
|
||||
appservice::query::{
|
||||
query_room_alias::v1 as query_room, query_user_id::v1 as query_user,
|
||||
},
|
||||
IncomingRequest,
|
||||
},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
use warp::{filters::BoxedFilter, path::FullPath, Filter, Rejection, Reply};
|
||||
|
||||
@@ -156,17 +167,35 @@ mod handlers {
|
||||
|
||||
pub async fn user(
|
||||
_user_id: String,
|
||||
_appservice: AppService,
|
||||
_request: http::Request<Bytes>,
|
||||
appservice: AppService,
|
||||
request: http::Request<Bytes>,
|
||||
) -> StdResult<impl warp::Reply, Rejection> {
|
||||
if let Some(user_exists) = appservice.event_handler.users.lock().await.as_mut() {
|
||||
let request =
|
||||
query_user::IncomingRequest::try_from_http_request(request).map_err(Error::from)?;
|
||||
return if user_exists(appservice.clone(), request).await {
|
||||
Ok(warp::reply::json(&String::from("{}")))
|
||||
} else {
|
||||
Err(warp::reject::not_found())
|
||||
};
|
||||
}
|
||||
Ok(warp::reply::json(&String::from("{}")))
|
||||
}
|
||||
|
||||
pub async fn room(
|
||||
_room_id: String,
|
||||
_appservice: AppService,
|
||||
_request: http::Request<Bytes>,
|
||||
appservice: AppService,
|
||||
request: http::Request<Bytes>,
|
||||
) -> StdResult<impl warp::Reply, Rejection> {
|
||||
if let Some(room_exists) = appservice.event_handler.rooms.lock().await.as_mut() {
|
||||
let request =
|
||||
query_room::IncomingRequest::try_from_http_request(request).map_err(Error::from)?;
|
||||
return if room_exists(appservice.clone(), request).await {
|
||||
Ok(warp::reply::json(&String::from("{}")))
|
||||
} else {
|
||||
Err(warp::reject::not_found())
|
||||
};
|
||||
}
|
||||
Ok(warp::reply::json(&String::from("{}")))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user