Merge branch 'appservice-event-handler'

This commit is contained in:
Damir Jelić
2021-10-26 11:30:30 +02:00
3 changed files with 101 additions and 7 deletions

View 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()
}
}

View File

@@ -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
///

View File

@@ -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("{}")))
}