feat: swappable database backend

This commit is contained in:
Timo Kösters 2021-06-08 18:10:00 +02:00
parent 81715bd84d
commit d0ee823254
No known key found for this signature in database
GPG key ID: 24DA7517711A2BA4
47 changed files with 1434 additions and 981 deletions

View file

@ -1,4 +1,4 @@
use std::{collections::BTreeMap, convert::TryInto};
use std::{collections::BTreeMap, convert::TryInto, sync::Arc};
use super::{State, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH};
use crate::{pdu::PduBuilder, utils, ConduitResult, Database, Error, Ruma};
@ -42,7 +42,7 @@ const GUEST_NAME_LENGTH: usize = 10;
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_register_available_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_username_availability::Request<'_>>,
) -> ConduitResult<get_username_availability::Response> {
// Validate user id
@ -85,7 +85,7 @@ pub async fn get_register_available_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn register_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<register::Request<'_>>,
) -> ConduitResult<register::Response> {
if !db.globals.allow_registration() {
@ -227,7 +227,7 @@ pub async fn register_route(
)?;
// If this is the first user on this server, create the admins room
if db.users.count() == 1 {
if db.users.count()? == 1 {
// Create a user for the server
let conduit_user = UserId::parse_with_server_name("conduit", db.globals.server_name())
.expect("@conduit:server_name is valid");
@ -506,7 +506,7 @@ pub async fn register_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn change_password_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<change_password::Request<'_>>,
) -> ConduitResult<change_password::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -598,7 +598,7 @@ pub async fn whoami_route(body: Ruma<whoami::Request>) -> ConduitResult<whoami::
)]
#[tracing::instrument(skip(db, body))]
pub async fn deactivate_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<deactivate::Request<'_>>,
) -> ConduitResult<deactivate::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use regex::Regex;
@ -22,7 +24,7 @@ use rocket::{delete, get, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn create_alias_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_alias::Request<'_>>,
) -> ConduitResult<create_alias::Response> {
if db.rooms.id_from_alias(&body.room_alias)?.is_some() {
@ -43,7 +45,7 @@ pub async fn create_alias_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_alias_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_alias::Request<'_>>,
) -> ConduitResult<delete_alias::Response> {
db.rooms.set_alias(&body.room_alias, None, &db.globals)?;
@ -59,7 +61,7 @@ pub async fn delete_alias_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_alias_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_alias::Request<'_>>,
) -> ConduitResult<get_alias::Response> {
get_alias_helper(&db, &body.room_alias).await
@ -86,7 +88,8 @@ pub async fn get_alias_helper(
match db.rooms.id_from_alias(&room_alias)? {
Some(r) => room_id = Some(r),
None => {
for (_id, registration) in db.appservice.iter_all().filter_map(|r| r.ok()) {
let iter = db.appservice.iter_all()?;
for (_id, registration) in iter.filter_map(|r| r.ok()) {
let aliases = registration
.get("namespaces")
.and_then(|ns| ns.get("aliases"))

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::api::client::{
@ -19,7 +21,7 @@ use rocket::{delete, get, post, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn create_backup_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_backup::Request>,
) -> ConduitResult<create_backup::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -38,7 +40,7 @@ pub async fn create_backup_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn update_backup_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<update_backup::Request<'_>>,
) -> ConduitResult<update_backup::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -56,7 +58,7 @@ pub async fn update_backup_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_latest_backup_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_latest_backup::Request>,
) -> ConduitResult<get_latest_backup::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -84,7 +86,7 @@ pub async fn get_latest_backup_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_backup_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_backup::Request<'_>>,
) -> ConduitResult<get_backup::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -111,7 +113,7 @@ pub async fn get_backup_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_backup_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_backup::Request<'_>>,
) -> ConduitResult<delete_backup::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -130,7 +132,7 @@ pub async fn delete_backup_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn add_backup_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<add_backup_keys::Request<'_>>,
) -> ConduitResult<add_backup_keys::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -164,7 +166,7 @@ pub async fn add_backup_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn add_backup_key_sessions_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<add_backup_key_sessions::Request<'_>>,
) -> ConduitResult<add_backup_key_sessions::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -196,7 +198,7 @@ pub async fn add_backup_key_sessions_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn add_backup_key_session_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<add_backup_key_session::Request<'_>>,
) -> ConduitResult<add_backup_key_session::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -225,7 +227,7 @@ pub async fn add_backup_key_session_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_backup_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_backup_keys::Request<'_>>,
) -> ConduitResult<get_backup_keys::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -241,14 +243,14 @@ pub async fn get_backup_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_backup_key_sessions_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_backup_key_sessions::Request<'_>>,
) -> ConduitResult<get_backup_key_sessions::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let sessions = db
.key_backups
.get_room(&sender_user, &body.version, &body.room_id);
.get_room(&sender_user, &body.version, &body.room_id)?;
Ok(get_backup_key_sessions::Response { sessions }.into())
}
@ -259,7 +261,7 @@ pub async fn get_backup_key_sessions_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_backup_key_session_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_backup_key_session::Request<'_>>,
) -> ConduitResult<get_backup_key_session::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -281,7 +283,7 @@ pub async fn get_backup_key_session_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_backup_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_backup_keys::Request<'_>>,
) -> ConduitResult<delete_backup_keys::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -304,7 +306,7 @@ pub async fn delete_backup_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_backup_key_sessions_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_backup_key_sessions::Request<'_>>,
) -> ConduitResult<delete_backup_key_sessions::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -327,7 +329,7 @@ pub async fn delete_backup_key_sessions_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_backup_key_session_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_backup_key_session::Request<'_>>,
) -> ConduitResult<delete_backup_key_session::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::{
@ -23,7 +25,7 @@ use rocket::{get, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_global_account_data_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_global_account_data::Request<'_>>,
) -> ConduitResult<set_global_account_data::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -58,7 +60,7 @@ pub async fn set_global_account_data_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_room_account_data_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_room_account_data::Request<'_>>,
) -> ConduitResult<set_room_account_data::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -90,7 +92,7 @@ pub async fn set_room_account_data_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_global_account_data_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_global_account_data::Request<'_>>,
) -> ConduitResult<get_global_account_data::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -117,7 +119,7 @@ pub async fn get_global_account_data_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_room_account_data_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_room_account_data::Request<'_>>,
) -> ConduitResult<get_room_account_data::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,7 +1,7 @@
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::api::client::{error::ErrorKind, r0::context::get_context};
use std::convert::TryFrom;
use std::{convert::TryFrom, sync::Arc};
#[cfg(feature = "conduit_bin")]
use rocket::get;
@ -12,7 +12,7 @@ use rocket::get;
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_context_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_context::Request<'_>>,
) -> ConduitResult<get_context::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{utils, ConduitResult, Database, Error, Ruma};
use ruma::api::client::{
@ -18,7 +20,7 @@ use rocket::{delete, get, post, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_devices_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_devices::Request>,
) -> ConduitResult<get_devices::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -38,7 +40,7 @@ pub async fn get_devices_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_device_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_device::Request<'_>>,
) -> ConduitResult<get_device::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -57,7 +59,7 @@ pub async fn get_device_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn update_device_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<update_device::Request<'_>>,
) -> ConduitResult<update_device::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -83,7 +85,7 @@ pub async fn update_device_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_device_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_device::Request<'_>>,
) -> ConduitResult<delete_device::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -137,7 +139,7 @@ pub async fn delete_device_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_devices_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_devices::Request<'_>>,
) -> ConduitResult<delete_devices::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Error, Result, Ruma};
use log::info;
@ -33,7 +35,7 @@ use rocket::{get, post, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_public_rooms_filtered_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_public_rooms_filtered::Request<'_>>,
) -> ConduitResult<get_public_rooms_filtered::Response> {
get_public_rooms_filtered_helper(
@ -53,7 +55,7 @@ pub async fn get_public_rooms_filtered_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_public_rooms_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_public_rooms::Request<'_>>,
) -> ConduitResult<get_public_rooms::Response> {
let response = get_public_rooms_filtered_helper(
@ -82,7 +84,7 @@ pub async fn get_public_rooms_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_room_visibility_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_room_visibility::Request<'_>>,
) -> ConduitResult<set_room_visibility::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -112,7 +114,7 @@ pub async fn set_room_visibility_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_room_visibility_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_room_visibility::Request<'_>>,
) -> ConduitResult<get_room_visibility::Response> {
Ok(get_room_visibility::Response {

View file

@ -14,7 +14,10 @@ use ruma::{
encryption::UnsignedDeviceInfo,
DeviceId, DeviceKeyAlgorithm, UserId,
};
use std::collections::{BTreeMap, HashSet};
use std::{
collections::{BTreeMap, HashSet},
sync::Arc,
};
#[cfg(feature = "conduit_bin")]
use rocket::{get, post};
@ -25,7 +28,7 @@ use rocket::{get, post};
)]
#[tracing::instrument(skip(db, body))]
pub async fn upload_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<upload_keys::Request>,
) -> ConduitResult<upload_keys::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -74,7 +77,7 @@ pub async fn upload_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_keys::Request<'_>>,
) -> ConduitResult<get_keys::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -95,7 +98,7 @@ pub async fn get_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn claim_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<claim_keys::Request>,
) -> ConduitResult<claim_keys::Response> {
let response = claim_keys_helper(&body.one_time_keys, &db)?;
@ -111,7 +114,7 @@ pub async fn claim_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn upload_signing_keys_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<upload_signing_keys::Request<'_>>,
) -> ConduitResult<upload_signing_keys::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -174,7 +177,7 @@ pub async fn upload_signing_keys_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn upload_signatures_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<upload_signatures::Request>,
) -> ConduitResult<upload_signatures::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -235,7 +238,7 @@ pub async fn upload_signatures_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_key_changes_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_key_changes::Request<'_>>,
) -> ConduitResult<get_key_changes::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -7,14 +7,14 @@ use ruma::api::client::{
#[cfg(feature = "conduit_bin")]
use rocket::{get, post};
use std::convert::TryInto;
use std::{convert::TryInto, sync::Arc};
const MXC_LENGTH: usize = 32;
#[cfg_attr(feature = "conduit_bin", get("/_matrix/media/r0/config"))]
#[tracing::instrument(skip(db))]
pub async fn get_media_config_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
) -> ConduitResult<get_media_config::Response> {
Ok(get_media_config::Response {
upload_size: db.globals.max_request_size().into(),
@ -28,7 +28,7 @@ pub async fn get_media_config_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn create_content_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_content::Request<'_>>,
) -> ConduitResult<create_content::Response> {
let mxc = format!(
@ -62,7 +62,7 @@ pub async fn create_content_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_content_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_content::Request<'_>>,
) -> ConduitResult<get_content::Response> {
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
@ -112,7 +112,7 @@ pub async fn get_content_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_content_thumbnail_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_content_thumbnail::Request<'_>>,
) -> ConduitResult<get_content_thumbnail::Response> {
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);

View file

@ -44,7 +44,7 @@ use rocket::{get, post};
)]
#[tracing::instrument(skip(db, body))]
pub async fn join_room_by_id_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<join_room_by_id::Request<'_>>,
) -> ConduitResult<join_room_by_id::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -81,7 +81,7 @@ pub async fn join_room_by_id_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn join_room_by_id_or_alias_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<join_room_by_id_or_alias::Request<'_>>,
) -> ConduitResult<join_room_by_id_or_alias::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -135,7 +135,7 @@ pub async fn join_room_by_id_or_alias_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn leave_room_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<leave_room::Request<'_>>,
) -> ConduitResult<leave_room::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -153,7 +153,7 @@ pub async fn leave_room_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn invite_user_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<invite_user::Request<'_>>,
) -> ConduitResult<invite_user::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -173,7 +173,7 @@ pub async fn invite_user_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn kick_user_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<kick_user::Request<'_>>,
) -> ConduitResult<kick_user::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -222,7 +222,7 @@ pub async fn kick_user_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn ban_user_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<ban_user::Request<'_>>,
) -> ConduitResult<ban_user::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -279,7 +279,7 @@ pub async fn ban_user_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn unban_user_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<unban_user::Request<'_>>,
) -> ConduitResult<unban_user::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -327,7 +327,7 @@ pub async fn unban_user_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn forget_room_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<forget_room::Request<'_>>,
) -> ConduitResult<forget_room::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -345,7 +345,7 @@ pub async fn forget_room_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn joined_rooms_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<joined_rooms::Request>,
) -> ConduitResult<joined_rooms::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -366,7 +366,7 @@ pub async fn joined_rooms_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_member_events_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_member_events::Request<'_>>,
) -> ConduitResult<get_member_events::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -396,7 +396,7 @@ pub async fn get_member_events_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn joined_members_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<joined_members::Request<'_>>,
) -> ConduitResult<joined_members::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -11,6 +11,7 @@ use ruma::{
use std::{
collections::BTreeMap,
convert::{TryFrom, TryInto},
sync::Arc,
};
#[cfg(feature = "conduit_bin")]
@ -22,7 +23,7 @@ use rocket::{get, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn send_message_event_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<send_message_event::Request<'_>>,
) -> ConduitResult<send_message_event::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -85,7 +86,7 @@ pub async fn send_message_event_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_message_events_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_message_events::Request<'_>>,
) -> ConduitResult<get_message_events::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,7 +1,7 @@
use super::State;
use crate::{utils, ConduitResult, Database, Ruma};
use ruma::api::client::r0::presence::{get_presence, set_presence};
use std::{convert::TryInto, time::Duration};
use std::{convert::TryInto, sync::Arc, time::Duration};
#[cfg(feature = "conduit_bin")]
use rocket::{get, put};
@ -12,7 +12,7 @@ use rocket::{get, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_presence_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_presence::Request<'_>>,
) -> ConduitResult<set_presence::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -53,7 +53,7 @@ pub async fn set_presence_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_presence_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_presence::Request<'_>>,
) -> ConduitResult<get_presence::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -62,7 +62,7 @@ pub async fn get_presence_route(
for room_id in db
.rooms
.get_shared_rooms(vec![sender_user.clone(), body.user_id.clone()])
.get_shared_rooms(vec![sender_user.clone(), body.user_id.clone()])?
{
let room_id = room_id?;

View file

@ -13,7 +13,7 @@ use ruma::{
#[cfg(feature = "conduit_bin")]
use rocket::{get, put};
use std::convert::TryInto;
use std::{convert::TryInto, sync::Arc};
#[cfg_attr(
feature = "conduit_bin",
@ -21,7 +21,7 @@ use std::convert::TryInto;
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_displayname_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_display_name::Request<'_>>,
) -> ConduitResult<set_display_name::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -107,7 +107,7 @@ pub async fn set_displayname_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_displayname_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_display_name::Request<'_>>,
) -> ConduitResult<get_display_name::Response> {
Ok(get_display_name::Response {
@ -122,7 +122,7 @@ pub async fn get_displayname_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_avatar_url_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_avatar_url::Request<'_>>,
) -> ConduitResult<set_avatar_url::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -208,7 +208,7 @@ pub async fn set_avatar_url_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_avatar_url_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_avatar_url::Request<'_>>,
) -> ConduitResult<get_avatar_url::Response> {
Ok(get_avatar_url::Response {
@ -223,7 +223,7 @@ pub async fn get_avatar_url_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_profile_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_profile::Request<'_>>,
) -> ConduitResult<get_profile::Response> {
if !db.users.exists(&body.user_id)? {

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::{
@ -22,7 +24,7 @@ use rocket::{delete, get, post, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_pushrules_all_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_pushrules_all::Request>,
) -> ConduitResult<get_pushrules_all::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -47,7 +49,7 @@ pub async fn get_pushrules_all_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_pushrule_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_pushrule::Request<'_>>,
) -> ConduitResult<get_pushrule::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -101,7 +103,7 @@ pub async fn get_pushrule_route(
)]
#[tracing::instrument(skip(db, req))]
pub async fn set_pushrule_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
req: Ruma<set_pushrule::Request<'_>>,
) -> ConduitResult<set_pushrule::Response> {
let sender_user = req.sender_user.as_ref().expect("user is authenticated");
@ -204,7 +206,7 @@ pub async fn set_pushrule_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_pushrule_actions_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_pushrule_actions::Request<'_>>,
) -> ConduitResult<get_pushrule_actions::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -263,7 +265,7 @@ pub async fn get_pushrule_actions_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_pushrule_actions_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_pushrule_actions::Request<'_>>,
) -> ConduitResult<set_pushrule_actions::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -337,7 +339,7 @@ pub async fn set_pushrule_actions_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_pushrule_enabled_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_pushrule_enabled::Request<'_>>,
) -> ConduitResult<get_pushrule_enabled::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -398,7 +400,7 @@ pub async fn get_pushrule_enabled_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_pushrule_enabled_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_pushrule_enabled::Request<'_>>,
) -> ConduitResult<set_pushrule_enabled::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -477,7 +479,7 @@ pub async fn set_pushrule_enabled_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_pushrule_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_pushrule::Request<'_>>,
) -> ConduitResult<delete_pushrule::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -546,7 +548,7 @@ pub async fn delete_pushrule_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_pushers_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_pushers::Request>,
) -> ConduitResult<get_pushers::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -563,7 +565,7 @@ pub async fn get_pushers_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_pushers_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_pusher::Request>,
) -> ConduitResult<set_pusher::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -12,7 +12,7 @@ use ruma::{
#[cfg(feature = "conduit_bin")]
use rocket::post;
use std::collections::BTreeMap;
use std::{collections::BTreeMap, sync::Arc};
#[cfg_attr(
feature = "conduit_bin",
@ -20,7 +20,7 @@ use std::collections::BTreeMap;
)]
#[tracing::instrument(skip(db, body))]
pub async fn set_read_marker_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<set_read_marker::Request<'_>>,
) -> ConduitResult<set_read_marker::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -87,7 +87,7 @@ pub async fn set_read_marker_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn create_receipt_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_receipt::Request<'_>>,
) -> ConduitResult<create_receipt::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -4,6 +4,7 @@ use ruma::{
api::client::r0::redact::redact_event,
events::{room::redaction, EventType},
};
use std::sync::Arc;
#[cfg(feature = "conduit_bin")]
use rocket::put;
@ -14,7 +15,7 @@ use rocket::put;
)]
#[tracing::instrument(skip(db, body))]
pub async fn redact_event_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<redact_event::Request<'_>>,
) -> ConduitResult<redact_event::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -13,7 +13,7 @@ use ruma::{
serde::Raw,
RoomAliasId, RoomId, RoomVersionId,
};
use std::{cmp::max, collections::BTreeMap, convert::TryFrom};
use std::{cmp::max, collections::BTreeMap, convert::TryFrom, sync::Arc};
#[cfg(feature = "conduit_bin")]
use rocket::{get, post};
@ -24,7 +24,7 @@ use rocket::{get, post};
)]
#[tracing::instrument(skip(db, body))]
pub async fn create_room_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_room::Request<'_>>,
) -> ConduitResult<create_room::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -304,7 +304,7 @@ pub async fn create_room_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_room_event_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_room_event::Request<'_>>,
) -> ConduitResult<get_room_event::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -332,7 +332,7 @@ pub async fn get_room_event_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn upgrade_room_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<upgrade_room::Request<'_>>,
_room_id: String,
) -> ConduitResult<upgrade_room::Response> {

View file

@ -1,6 +1,7 @@
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::api::client::{error::ErrorKind, r0::search::search_events};
use std::sync::Arc;
#[cfg(feature = "conduit_bin")]
use rocket::post;
@ -13,7 +14,7 @@ use std::collections::BTreeMap;
)]
#[tracing::instrument(skip(db, body))]
pub async fn search_events_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<search_events::Request<'_>>,
) -> ConduitResult<search_events::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::{State, DEVICE_ID_LENGTH, TOKEN_LENGTH};
use crate::{utils, ConduitResult, Database, Error, Ruma};
use log::info;
@ -50,7 +52,7 @@ pub async fn get_login_types_route() -> ConduitResult<get_login_types::Response>
)]
#[tracing::instrument(skip(db, body))]
pub async fn login_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<login::Request<'_>>,
) -> ConduitResult<login::Response> {
// Validate login method
@ -167,7 +169,7 @@ pub async fn login_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn logout_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<logout::Request>,
) -> ConduitResult<logout::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -195,7 +197,7 @@ pub async fn logout_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn logout_all_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<logout_all::Request>,
) -> ConduitResult<logout_all::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{pdu::PduBuilder, ConduitResult, Database, Error, Result, Ruma};
use ruma::{
@ -25,7 +27,7 @@ use rocket::{get, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn send_state_event_for_key_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<send_state_event::Request<'_>>,
) -> ConduitResult<send_state_event::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -51,7 +53,7 @@ pub async fn send_state_event_for_key_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn send_state_event_for_empty_key_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<send_state_event::Request<'_>>,
) -> ConduitResult<send_state_event::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -77,7 +79,7 @@ pub async fn send_state_event_for_empty_key_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_state_events_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_state_events::Request<'_>>,
) -> ConduitResult<get_state_events::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -124,7 +126,7 @@ pub async fn get_state_events_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_state_events_for_key_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_state_events_for_key::Request<'_>>,
) -> ConduitResult<get_state_events_for_key::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -175,7 +177,7 @@ pub async fn get_state_events_for_key_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_state_events_for_empty_key_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_state_events_for_key::Request<'_>>,
) -> ConduitResult<get_state_events_for_key::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,5 +1,5 @@
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use crate::{ConduitResult, Database, Error, Result, Ruma};
use log::error;
use ruma::{
api::client::r0::sync::sync_events,
@ -13,6 +13,7 @@ use rocket::{get, tokio};
use std::{
collections::{hash_map, BTreeMap, HashMap, HashSet},
convert::{TryFrom, TryInto},
sync::Arc,
time::Duration,
};
@ -33,7 +34,7 @@ use std::{
)]
#[tracing::instrument(skip(db, body))]
pub async fn sync_events_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<sync_events::Request<'_>>,
) -> ConduitResult<sync_events::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -71,18 +72,23 @@ pub async fn sync_events_route(
let mut non_timeline_pdus = db
.rooms
.pdus_since(&sender_user, &room_id, since)?
.pdus_until(&sender_user, &room_id, u64::MAX)
.filter_map(|r| {
// Filter out buggy events
if r.is_err() {
error!("Bad pdu in pdus_since: {:?}", r);
}
r.ok()
}); // Filter out buggy events
})
.take_while(|(pduid, _)| {
db.rooms
.pdu_count(pduid)
.map_or(false, |count| count > since)
});
// Take the last 10 events for the timeline
let timeline_pdus = non_timeline_pdus
.by_ref()
.rev()
.take(10)
.collect::<Vec<_>>()
.into_iter()
@ -226,7 +232,7 @@ pub async fn sync_events_route(
match (since_membership, current_membership) {
(MembershipState::Leave, MembershipState::Join) => {
// A new user joined an encrypted room
if !share_encrypted_room(&db, &sender_user, &user_id, &room_id) {
if !share_encrypted_room(&db, &sender_user, &user_id, &room_id)? {
device_list_updates.insert(user_id);
}
}
@ -257,6 +263,7 @@ pub async fn sync_events_route(
.filter(|user_id| {
// Only send keys if the sender doesn't share an encrypted room with the target already
!share_encrypted_room(&db, sender_user, user_id, &room_id)
.unwrap_or(false)
}),
);
}
@ -274,7 +281,7 @@ pub async fn sync_events_route(
for hero in db
.rooms
.all_pdus(&sender_user, &room_id)?
.all_pdus(&sender_user, &room_id)
.filter_map(|pdu| pdu.ok()) // Ignore all broken pdus
.filter(|(_, pdu)| pdu.kind == EventType::RoomMember)
.map(|(_, pdu)| {
@ -411,7 +418,7 @@ pub async fn sync_events_route(
let mut edus = db
.rooms
.edus
.readreceipts_since(&room_id, since)?
.readreceipts_since(&room_id, since)
.filter_map(|r| r.ok()) // Filter out buggy events
.map(|(_, _, v)| v)
.collect::<Vec<_>>();
@ -549,7 +556,7 @@ pub async fn sync_events_route(
for user_id in left_encrypted_users {
let still_share_encrypted_room = db
.rooms
.get_shared_rooms(vec![sender_user.clone(), user_id.clone()])
.get_shared_rooms(vec![sender_user.clone(), user_id.clone()])?
.filter_map(|r| r.ok())
.filter_map(|other_room_id| {
Some(
@ -639,9 +646,10 @@ fn share_encrypted_room(
sender_user: &UserId,
user_id: &UserId,
ignore_room: &RoomId,
) -> bool {
db.rooms
.get_shared_rooms(vec![sender_user.clone(), user_id.clone()])
) -> Result<bool> {
Ok(db
.rooms
.get_shared_rooms(vec![sender_user.clone(), user_id.clone()])?
.filter_map(|r| r.ok())
.filter(|room_id| room_id != ignore_room)
.filter_map(|other_room_id| {
@ -652,5 +660,5 @@ fn share_encrypted_room(
.is_some(),
)
})
.any(|encrypted| encrypted)
.any(|encrypted| encrypted))
}

View file

@ -4,7 +4,7 @@ use ruma::{
api::client::r0::tag::{create_tag, delete_tag, get_tags},
events::EventType,
};
use std::collections::BTreeMap;
use std::{collections::BTreeMap, sync::Arc};
#[cfg(feature = "conduit_bin")]
use rocket::{delete, get, put};
@ -15,7 +15,7 @@ use rocket::{delete, get, put};
)]
#[tracing::instrument(skip(db, body))]
pub async fn update_tag_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_tag::Request<'_>>,
) -> ConduitResult<create_tag::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -52,7 +52,7 @@ pub async fn update_tag_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn delete_tag_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<delete_tag::Request<'_>>,
) -> ConduitResult<delete_tag::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
@ -86,7 +86,7 @@ pub async fn delete_tag_route(
)]
#[tracing::instrument(skip(db, body))]
pub async fn get_tags_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<get_tags::Request<'_>>,
) -> ConduitResult<get_tags::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::api::client::{
@ -14,7 +16,7 @@ use rocket::put;
)]
#[tracing::instrument(skip(db, body))]
pub async fn send_event_to_device_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<send_event_to_device::Request<'_>>,
) -> ConduitResult<send_event_to_device::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{utils, ConduitResult, Database, Ruma};
use create_typing_event::Typing;
@ -12,7 +14,7 @@ use rocket::put;
)]
#[tracing::instrument(skip(db, body))]
pub fn create_typing_event_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<create_typing_event::Request<'_>>,
) -> ConduitResult<create_typing_event::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use super::State;
use crate::{ConduitResult, Database, Ruma};
use ruma::api::client::r0::user_directory::search_users;
@ -11,7 +13,7 @@ use rocket::post;
)]
#[tracing::instrument(skip(db, body))]
pub async fn search_users_route(
db: State<'_, Database>,
db: State<'_, Arc<Database>>,
body: Ruma<search_users::Request<'_>>,
) -> ConduitResult<search_users::Response> {
let limit = u64::from(body.limit) as usize;