diff --git a/Cargo.lock b/Cargo.lock index d81fdbc0..0753f81d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,9 +1119,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] @@ -1279,9 +1279,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", ] @@ -3625,7 +3625,8 @@ dependencies = [ [[package]] name = "resolv-conf" version = "0.7.1" -source = "git+https://github.com/girlbossceo/resolv-conf?rev=200e958941d522a70c5877e3d846f55b5586c68d#200e958941d522a70c5877e3d846f55b5586c68d" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4" dependencies = [ "hostname", ] @@ -3653,7 +3654,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.10.1" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "assign", "js_int", @@ -3673,7 +3674,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.10.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "js_int", "ruma-common", @@ -3685,7 +3686,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.18.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "as_variant", "assign", @@ -3708,7 +3709,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.13.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "as_variant", "base64 0.22.1", @@ -3740,7 +3741,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.28.1" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "as_variant", "indexmap 2.8.0", @@ -3765,7 +3766,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.9.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "bytes", "headers", @@ -3787,7 +3788,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.5" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "js_int", "thiserror 2.0.12", @@ -3796,7 +3797,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.9.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "js_int", "ruma-common", @@ -3806,7 +3807,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.13.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3821,7 +3822,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.9.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "js_int", "ruma-common", @@ -3833,7 +3834,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.15.0" -source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" +source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" dependencies = [ "base64 0.22.1", "ed25519-dalek", @@ -4758,9 +4759,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.2" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index fb236a22..d366112b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ license = "Apache-2.0" # See also `rust-toolchain.toml` readme = "README.md" repository = "https://github.com/girlbossceo/conduwuit" -rust-version = "1.86.0" +rust-version = "1.85.0" version = "0.5.0" [workspace.metadata.crane] @@ -242,7 +242,7 @@ default-features = false features = ["std", "async-await"] [workspace.dependencies.tokio] -version = "1.44.2" +version = "1.44.1" default-features = false features = [ "fs", @@ -350,7 +350,7 @@ version = "0.1.2" [workspace.dependencies.ruma] git = "https://github.com/girlbossceo/ruwuma" #branch = "conduwuit-changes" -rev = "920148dca1076454ca0ca5d43b5ce1aa708381d4" +rev = "edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef" features = [ "compat", "rand", @@ -580,13 +580,6 @@ rev = "9c8e51510c35077df888ee72a36b4b05637147da" git = "https://github.com/girlbossceo/hyper-util" rev = "e4ae7628fe4fcdacef9788c4c8415317a4489941" -# allows no-aaaa option in resolv.conf -# bumps rust edition and toolchain to 1.86.0 and 2024 -# use sat_add on line number errors -[patch.crates-io.resolv-conf] -git = "https://github.com/girlbossceo/resolv-conf" -rev = "200e958941d522a70c5877e3d846f55b5586c68d" - # # Our crates # diff --git a/conduwuit-example.toml b/conduwuit-example.toml index 118bc57d..75ecddab 100644 --- a/conduwuit-example.toml +++ b/conduwuit-example.toml @@ -527,9 +527,9 @@ # Default room version conduwuit will create rooms with. # -# Per spec, room version 11 is the default. +# Per spec, room version 10 is the default. # -#default_room_version = 11 +#default_room_version = 10 # This item is undocumented. Please contribute documentation for it. # @@ -594,7 +594,7 @@ # Currently, conduwuit doesn't support inbound batched key requests, so # this list should only contain other Synapse servers. # -# example: ["matrix.org", "tchncs.de"] +# example: ["matrix.org", "envs.net", "tchncs.de"] # #trusted_servers = ["matrix.org"] @@ -1186,16 +1186,13 @@ # #prune_missing_media = false -# Vector list of regex patterns of server names that conduwuit will refuse -# to download remote media from. -# -# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] +# Vector list of servers that conduwuit will refuse to download remote +# media from. # #prevent_media_downloads_from = [] -# List of forbidden server names via regex patterns that we will block -# incoming AND outgoing federation with, and block client room joins / -# remote user invites. +# List of forbidden server names that we will block incoming AND outgoing +# federation with, and block client room joins / remote user invites. # # This check is applied on the room ID, room alias, sender server name, # sender user's server name, inbound federation X-Matrix origin, and @@ -1203,15 +1200,11 @@ # # Basically "global" ACLs. # -# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] -# #forbidden_remote_server_names = [] -# List of forbidden server names via regex patterns that we will block all -# outgoing federated room directory requests for. Useful for preventing -# our users from wandering into bad servers or spaces. -# -# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] +# List of forbidden server names that we will block all outgoing federated +# room directory requests for. Useful for preventing our users from +# wandering into bad servers or spaces. # #forbidden_remote_room_directory_server_names = [] @@ -1322,7 +1315,7 @@ # used, and startup as warnings if any room aliases in your database have # a forbidden room alias/ID. # -# example: ["19dollarfortnitecards", "b[4a]droom", "badphrase"] +# example: ["19dollarfortnitecards", "b[4a]droom"] # #forbidden_alias_names = [] @@ -1335,7 +1328,7 @@ # startup as warnings if any local users in your database have a forbidden # username. # -# example: ["administrator", "b[a4]dusernam[3e]", "badphrase"] +# example: ["administrator", "b[a4]dusernam[3e]"] # #forbidden_usernames = [] diff --git a/flake.nix b/flake.nix index 49e860ed..9db2e90a 100644 --- a/flake.nix +++ b/flake.nix @@ -26,7 +26,7 @@ file = ./rust-toolchain.toml; # See also `rust-toolchain.toml` - sha256 = "sha256-X/4ZBHO3iW0fOenQ3foEvscgAPJYl2abspaBThDOukI="; + sha256 = "sha256-AJ6LX/Q/Er9kS15bn9iflkUwcgYqRQxiOIL2ToVAXaU="; }; mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index aadc8f99..97b4a789 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -9,7 +9,7 @@ # If you're having trouble making the relevant changes, bug a maintainer. [toolchain] -channel = "1.86.0" +channel = "1.85.0" profile = "minimal" components = [ # For rust-analyzer diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index 87ca03a0..c6f6a170 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -6,9 +6,7 @@ use std::{ }; use conduwuit::{ - Error, Result, debug_error, err, info, - matrix::pdu::{PduEvent, PduId, RawPduId}, - trace, utils, + Error, PduEvent, PduId, RawPduId, Result, debug_error, err, info, trace, utils, utils::{ stream::{IterStream, ReadyExt}, string::EMPTY, diff --git a/src/admin/user/commands.rs b/src/admin/user/commands.rs index 45e550be..35067304 100644 --- a/src/admin/user/commands.rs +++ b/src/admin/user/commands.rs @@ -2,8 +2,7 @@ use std::{collections::BTreeMap, fmt::Write as _}; use api::client::{full_user_deactivate, join_room_by_id_helper, leave_room}; use conduwuit::{ - Result, debug, debug_warn, error, info, is_equal_to, - matrix::pdu::PduBuilder, + PduBuilder, Result, debug, debug_warn, error, info, is_equal_to, utils::{self, ReadyExt}, warn, }; diff --git a/src/api/client/account.rs b/src/api/client/account.rs index 32f2530c..e5894d47 100644 --- a/src/api/client/account.rs +++ b/src/api/client/account.rs @@ -3,13 +3,10 @@ use std::fmt::Write; use axum::extract::State; use axum_client_ip::InsecureClientIp; use conduwuit::{ - Err, Error, Result, debug_info, err, error, info, is_equal_to, - matrix::pdu::PduBuilder, - utils, + Err, Error, PduBuilder, Result, debug_info, err, error, info, is_equal_to, utils, utils::{ReadyExt, stream::BroadbandExt}, warn, }; -use conduwuit_service::Services; use futures::{FutureExt, StreamExt}; use register::RegistrationKind; use ruma::{ @@ -33,6 +30,7 @@ use ruma::{ }, push, }; +use service::Services; use super::{DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH, join_room_by_id_helper}; use crate::Ruma; diff --git a/src/api/client/account_data.rs b/src/api/client/account_data.rs index e44ce4e7..60c18b37 100644 --- a/src/api/client/account_data.rs +++ b/src/api/client/account_data.rs @@ -1,6 +1,5 @@ use axum::extract::State; -use conduwuit::{Err, Result, err}; -use conduwuit_service::Services; +use conduwuit::{Err, err}; use ruma::{ RoomId, UserId, api::client::config::{ @@ -16,7 +15,7 @@ use ruma::{ use serde::Deserialize; use serde_json::{json, value::RawValue as RawJsonValue}; -use crate::Ruma; +use crate::{Result, Ruma, service::Services}; /// # `PUT /_matrix/client/r0/user/{userId}/account_data/{type}` /// diff --git a/src/api/client/alias.rs b/src/api/client/alias.rs index 9f1b05f8..319e5141 100644 --- a/src/api/client/alias.rs +++ b/src/api/client/alias.rs @@ -1,12 +1,12 @@ use axum::extract::State; use conduwuit::{Err, Result, debug}; -use conduwuit_service::Services; use futures::StreamExt; use rand::seq::SliceRandom; use ruma::{ OwnedServerName, RoomAliasId, RoomId, api::client::alias::{create_alias, delete_alias, get_alias}, }; +use service::Services; use crate::Ruma; diff --git a/src/api/client/backup.rs b/src/api/client/backup.rs index 2ad37cf3..83955fea 100644 --- a/src/api/client/backup.rs +++ b/src/api/client/backup.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use axum::extract::State; -use conduwuit::{Err, Result, err}; +use conduwuit::{Err, err}; use ruma::{ UInt, api::client::backup::{ @@ -13,7 +13,7 @@ use ruma::{ }, }; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `POST /_matrix/client/r0/room_keys/version` /// diff --git a/src/api/client/context.rs b/src/api/client/context.rs index dbc2a22f..1dda7b53 100644 --- a/src/api/client/context.rs +++ b/src/api/client/context.rs @@ -1,20 +1,18 @@ use axum::extract::State; use conduwuit::{ - Err, Result, at, debug_warn, err, - matrix::pdu::PduEvent, - ref_at, + Err, PduEvent, Result, at, debug_warn, err, ref_at, utils::{ IterStream, future::TryExtExt, stream::{BroadbandExt, ReadyExt, TryIgnore, WidebandExt}, }, }; -use conduwuit_service::rooms::{lazy_loading, lazy_loading::Options, short::ShortStateKey}; use futures::{ FutureExt, StreamExt, TryFutureExt, TryStreamExt, future::{OptionFuture, join, join3, try_join3}, }; use ruma::{OwnedEventId, UserId, api::client::context::get_context, events::StateEventType}; +use service::rooms::{lazy_loading, lazy_loading::Options, short::ShortStateKey}; use crate::{ Ruma, diff --git a/src/api/client/device.rs b/src/api/client/device.rs index 5519a1a5..7603c866 100644 --- a/src/api/client/device.rs +++ b/src/api/client/device.rs @@ -1,6 +1,6 @@ use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduwuit::{Err, Error, Result, debug, err, utils}; +use conduwuit::{Err, debug, err}; use futures::StreamExt; use ruma::{ MilliSecondsSinceUnixEpoch, OwnedDeviceId, @@ -12,7 +12,7 @@ use ruma::{ }; use super::SESSION_ID_LENGTH; -use crate::{Ruma, client::DEVICE_ID_LENGTH}; +use crate::{Error, Result, Ruma, client::DEVICE_ID_LENGTH, utils}; /// # `GET /_matrix/client/r0/devices` /// diff --git a/src/api/client/directory.rs b/src/api/client/directory.rs index b44b9f64..f2f668c8 100644 --- a/src/api/client/directory.rs +++ b/src/api/client/directory.rs @@ -9,7 +9,6 @@ use conduwuit::{ stream::{ReadyExt, WidebandExt}, }, }; -use conduwuit_service::Services; use futures::{ FutureExt, StreamExt, TryFutureExt, future::{join, join4, join5}, @@ -36,6 +35,7 @@ use ruma::{ }, uint, }; +use service::Services; use crate::Ruma; @@ -52,13 +52,10 @@ pub(crate) async fn get_public_rooms_filtered_route( ) -> Result { if let Some(server) = &body.server { if services + .server .config .forbidden_remote_room_directory_server_names - .is_match(server.host()) - || services - .config - .forbidden_remote_server_names - .is_match(server.host()) + .contains(server) { return Err!(Request(Forbidden("Server is banned on this homeserver."))); } @@ -93,13 +90,10 @@ pub(crate) async fn get_public_rooms_route( ) -> Result { if let Some(server) = &body.server { if services + .server .config .forbidden_remote_room_directory_server_names - .is_match(server.host()) - || services - .config - .forbidden_remote_server_names - .is_match(server.host()) + .contains(server) { return Err!(Request(Forbidden("Server is banned on this homeserver."))); } diff --git a/src/api/client/filter.rs b/src/api/client/filter.rs index 97044ffc..84086452 100644 --- a/src/api/client/filter.rs +++ b/src/api/client/filter.rs @@ -1,8 +1,8 @@ use axum::extract::State; -use conduwuit::{Result, err}; +use conduwuit::err; use ruma::api::client::filter::{create_filter, get_filter}; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `GET /_matrix/client/r0/user/{userId}/filter/{filterId}` /// diff --git a/src/api/client/keys.rs b/src/api/client/keys.rs index 650c573f..2fdfc0bc 100644 --- a/src/api/client/keys.rs +++ b/src/api/client/keys.rs @@ -1,8 +1,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use axum::extract::State; -use conduwuit::{Err, Error, Result, debug, debug_warn, err, result::NotFound, utils}; -use conduwuit_service::{Services, users::parse_master_key}; +use conduwuit::{Err, Error, Result, debug, debug_warn, err, info, result::NotFound, utils}; use futures::{StreamExt, stream::FuturesUnordered}; use ruma::{ OneTimeKeyAlgorithm, OwnedDeviceId, OwnedUserId, UserId, @@ -11,7 +10,7 @@ use ruma::{ error::ErrorKind, keys::{ claim_keys, get_key_changes, get_keys, upload_keys, - upload_signatures::{self}, + upload_signatures::{self, v3::Failure}, upload_signing_keys, }, uiaa::{AuthFlow, AuthType, UiaaInfo}, @@ -24,7 +23,10 @@ use ruma::{ use serde_json::json; use super::SESSION_ID_LENGTH; -use crate::Ruma; +use crate::{ + Ruma, + service::{Services, users::parse_master_key}, +}; /// # `POST /_matrix/client/r0/keys/upload` /// @@ -177,7 +179,7 @@ pub(crate) async fn upload_signing_keys_route( body.master_key.as_ref(), ) .await - .inspect_err(|e| debug!(?e)) + .inspect_err(|e| info!(?e)) { | Ok(exists) => { if let Some(result) = exists { @@ -308,59 +310,82 @@ async fn check_for_new_keys( /// /// Uploads end-to-end key signatures from the sender user. /// -/// TODO: clean this timo-code up more and integrate failures. tried to improve -/// it a bit to stop exploding the entire request on bad sigs, but needs way -/// more work. +/// TODO: clean this timo-code up more. tried to improve it a bit to stop +/// exploding the entire request on bad sigs, but needs way more work. pub(crate) async fn upload_signatures_route( State(services): State, body: Ruma, ) -> Result { + use upload_signatures::v3::FailureErrorCode::*; + if body.signed_keys.is_empty() { debug!("Empty signed_keys sent in key signature upload"); return Ok(upload_signatures::v3::Response::new()); } let sender_user = body.sender_user(); + let mut failures: BTreeMap> = BTreeMap::new(); + let mut failure_reasons: BTreeMap = BTreeMap::new(); + let failure = Failure { + errcode: InvalidSignature, + error: String::new(), + }; for (user_id, keys) in &body.signed_keys { for (key_id, key) in keys { let Ok(key) = serde_json::to_value(key) .inspect_err(|e| debug_warn!(?key_id, "Invalid \"key\" JSON: {e}")) else { + let mut failure = failure.clone(); + failure.error = String::from("Invalid \"key\" JSON"); + failure_reasons.insert(key_id.to_owned(), failure); continue; }; let Some(signatures) = key.get("signatures") else { + let mut failure = failure.clone(); + failure.error = String::from("Missing \"signatures\" field"); + failure_reasons.insert(key_id.to_owned(), failure); continue; }; let Some(sender_user_val) = signatures.get(sender_user.to_string()) else { + let mut failure = failure.clone(); + failure.error = String::from("Invalid user in signatures field"); + failure_reasons.insert(key_id.to_owned(), failure); continue; }; let Some(sender_user_object) = sender_user_val.as_object() else { + let mut failure = failure.clone(); + failure.error = String::from("signatures field is not a JSON object"); + failure_reasons.insert(key_id.to_owned(), failure); continue; }; for (signature, val) in sender_user_object.clone() { - let Some(val) = val.as_str().map(ToOwned::to_owned) else { - continue; - }; - let signature = (signature, val); + let signature = (signature, val.to_string()); - if let Err(_e) = services + if let Err(e) = services .users .sign_key(user_id, key_id, signature, sender_user) .await .inspect_err(|e| debug_warn!("{e}")) { + let mut failure = failure.clone(); + failure.error = format!("Error signing key: {e}"); + failure_reasons.insert(key_id.to_owned(), failure); continue; } } } + + if !failure_reasons.is_empty() { + failures.insert(user_id.to_owned(), failure_reasons.clone()); + } } - Ok(upload_signatures::v3::Response { failures: BTreeMap::new() }) + Ok(upload_signatures::v3::Response { failures }) } /// # `POST /_matrix/client/r0/keys/changes` diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs index 1eeacf83..ef40e972 100644 --- a/src/api/client/membership.rs +++ b/src/api/client/membership.rs @@ -9,25 +9,13 @@ use std::{ use axum::extract::State; use axum_client_ip::InsecureClientIp; use conduwuit::{ - Err, Result, at, debug, debug_info, debug_warn, err, error, info, - matrix::{ - StateKey, - pdu::{PduBuilder, PduEvent, gen_event_id, gen_event_id_canonical_json}, - state_res, - }, + Err, PduEvent, Result, StateKey, at, debug, debug_info, debug_warn, err, error, info, + pdu::{PduBuilder, gen_event_id_canonical_json}, result::{FlatOk, NotFound}, - trace, + state_res, trace, utils::{self, IterStream, ReadyExt, shuffle}, warn, }; -use conduwuit_service::{ - Services, - appservice::RegistrationInfo, - rooms::{ - state::RoomMutexGuard, - state_compressor::{CompressedState, HashSetCompressStateEvent}, - }, -}; use futures::{FutureExt, StreamExt, TryFutureExt, future::join4, join}; use ruma::{ CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName, @@ -56,6 +44,15 @@ use ruma::{ }, }, }; +use service::{ + Services, + appservice::RegistrationInfo, + pdu::gen_event_id, + rooms::{ + state::RoomMutexGuard, + state_compressor::{CompressedState, HashSetCompressStateEvent}, + }, +}; use crate::{Ruma, client::full_user_deactivate}; @@ -79,9 +76,10 @@ async fn banned_room_check( if let Some(room_id) = room_id { if services.rooms.metadata.is_banned(room_id).await || services + .server .config .forbidden_remote_server_names - .is_match(room_id.server_name().unwrap().host()) + .contains(&room_id.server_name().unwrap().to_owned()) { warn!( "User {user_id} who is not an admin attempted to send an invite for or \ @@ -119,9 +117,10 @@ async fn banned_room_check( } } else if let Some(server_name) = server_name { if services + .server .config .forbidden_remote_server_names - .is_match(server_name.host()) + .contains(&server_name.to_owned()) { warn!( "User {user_id} who is not an admin tried joining a room which has the server \ diff --git a/src/api/client/message.rs b/src/api/client/message.rs index db11ef4a..03c7335a 100644 --- a/src/api/client/message.rs +++ b/src/api/client/message.rs @@ -1,24 +1,12 @@ use axum::extract::State; use conduwuit::{ - Err, Result, at, - matrix::{ - Event, - pdu::{PduCount, PduEvent}, - }, + Err, Event, PduCount, PduEvent, Result, at, utils::{ IterStream, ReadyExt, result::{FlatOk, LogErr}, stream::{BroadbandExt, TryIgnore, WidebandExt}, }, }; -use conduwuit_service::{ - Services, - rooms::{ - lazy_loading, - lazy_loading::{Options, Witness}, - timeline::PdusIterItem, - }, -}; use futures::{FutureExt, StreamExt, TryFutureExt, future::OptionFuture, pin_mut}; use ruma::{ RoomId, UserId, @@ -29,6 +17,14 @@ use ruma::{ events::{AnyStateEvent, StateEventType, TimelineEventType, TimelineEventType::*}, serde::Raw, }; +use service::{ + Services, + rooms::{ + lazy_loading, + lazy_loading::{Options, Witness}, + timeline::PdusIterItem, + }, +}; use crate::Ruma; @@ -261,9 +257,10 @@ pub(crate) async fn is_ignored_pdu( let ignored_type = IGNORED_MESSAGE_TYPES.binary_search(&pdu.kind).is_ok(); let ignored_server = services + .server .config .forbidden_remote_server_names - .is_match(pdu.sender().server_name().host()); + .contains(pdu.sender().server_name()); if ignored_type && (ignored_server || services.users.user_is_ignored(&pdu.sender, user_id).await) diff --git a/src/api/client/openid.rs b/src/api/client/openid.rs index 8d2de68d..671d0c6d 100644 --- a/src/api/client/openid.rs +++ b/src/api/client/openid.rs @@ -1,14 +1,14 @@ use std::time::Duration; use axum::extract::State; -use conduwuit::{Error, Result, utils}; +use conduwuit::utils; use ruma::{ api::client::{account, error::ErrorKind}, authentication::TokenType, }; use super::TOKEN_LENGTH; -use crate::Ruma; +use crate::{Error, Result, Ruma}; /// # `POST /_matrix/client/v3/user/{userId}/openid/request_token` /// diff --git a/src/api/client/profile.rs b/src/api/client/profile.rs index 3699b590..5abe5b23 100644 --- a/src/api/client/profile.rs +++ b/src/api/client/profile.rs @@ -3,11 +3,10 @@ use std::collections::BTreeMap; use axum::extract::State; use conduwuit::{ Err, Error, Result, - matrix::pdu::PduBuilder, + pdu::PduBuilder, utils::{IterStream, stream::TryIgnore}, warn, }; -use conduwuit_service::Services; use futures::{StreamExt, TryStreamExt, future::join3}; use ruma::{ OwnedMxcUri, OwnedRoomId, UserId, @@ -23,6 +22,7 @@ use ruma::{ events::room::member::{MembershipState, RoomMemberEventContent}, presence::PresenceState, }; +use service::Services; use crate::Ruma; diff --git a/src/api/client/push.rs b/src/api/client/push.rs index 81020ffa..cc1d3be2 100644 --- a/src/api/client/push.rs +++ b/src/api/client/push.rs @@ -1,6 +1,5 @@ use axum::extract::State; -use conduwuit::{Err, Error, Result, err}; -use conduwuit_service::Services; +use conduwuit::{Err, err}; use ruma::{ CanonicalJsonObject, CanonicalJsonValue, api::client::{ @@ -20,8 +19,9 @@ use ruma::{ RemovePushRuleError, Ruleset, }, }; +use service::Services; -use crate::Ruma; +use crate::{Error, Result, Ruma}; /// # `GET /_matrix/client/r0/pushrules/` /// diff --git a/src/api/client/read_marker.rs b/src/api/client/read_marker.rs index fbfc8fea..b334e356 100644 --- a/src/api/client/read_marker.rs +++ b/src/api/client/read_marker.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use axum::extract::State; -use conduwuit::{Err, PduCount, Result, err}; +use conduwuit::{Err, PduCount, err}; use ruma::{ MilliSecondsSinceUnixEpoch, api::client::{read_marker::set_read_marker, receipt::create_receipt}, @@ -11,7 +11,7 @@ use ruma::{ }, }; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `POST /_matrix/client/r0/rooms/{roomId}/read_markers` /// diff --git a/src/api/client/redact.rs b/src/api/client/redact.rs index 8dbe47a6..7b512d06 100644 --- a/src/api/client/redact.rs +++ b/src/api/client/redact.rs @@ -1,10 +1,9 @@ use axum::extract::State; -use conduwuit::{Result, matrix::pdu::PduBuilder}; use ruma::{ api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent, }; -use crate::Ruma; +use crate::{Result, Ruma, service::pdu::PduBuilder}; /// # `PUT /_matrix/client/r0/rooms/{roomId}/redact/{eventId}/{txnId}` /// diff --git a/src/api/client/relations.rs b/src/api/client/relations.rs index b8c2dd4d..7ed40f14 100644 --- a/src/api/client/relations.rs +++ b/src/api/client/relations.rs @@ -1,10 +1,8 @@ use axum::extract::State; use conduwuit::{ - Result, at, - matrix::pdu::PduCount, + PduCount, Result, at, utils::{IterStream, ReadyExt, result::FlatOk, stream::WidebandExt}, }; -use conduwuit_service::{Services, rooms::timeline::PdusIterItem}; use futures::StreamExt; use ruma::{ EventId, RoomId, UInt, UserId, @@ -17,6 +15,7 @@ use ruma::{ }, events::{TimelineEventType, relation::RelationType}, }; +use service::{Services, rooms::timeline::PdusIterItem}; use crate::Ruma; diff --git a/src/api/client/report.rs b/src/api/client/report.rs index 4ee8ebe5..7922caca 100644 --- a/src/api/client/report.rs +++ b/src/api/client/report.rs @@ -2,8 +2,7 @@ use std::time::Duration; use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduwuit::{Err, Error, Result, debug_info, info, matrix::pdu::PduEvent, utils::ReadyExt}; -use conduwuit_service::Services; +use conduwuit::{Err, info, utils::ReadyExt}; use rand::Rng; use ruma::{ EventId, RoomId, UserId, @@ -16,7 +15,10 @@ use ruma::{ }; use tokio::time::sleep; -use crate::Ruma; +use crate::{ + Error, Result, Ruma, debug_info, + service::{Services, pdu::PduEvent}, +}; /// # `POST /_matrix/client/v3/rooms/{roomId}/report` /// diff --git a/src/api/client/room/create.rs b/src/api/client/room/create.rs index 4ce53f15..bdc5d5a5 100644 --- a/src/api/client/room/create.rs +++ b/src/api/client/room/create.rs @@ -2,11 +2,8 @@ use std::collections::BTreeMap; use axum::extract::State; use conduwuit::{ - Err, Error, Result, debug_info, debug_warn, err, error, info, - matrix::{StateKey, pdu::PduBuilder}, - warn, + Err, Error, Result, StateKey, debug_info, debug_warn, err, error, info, pdu::PduBuilder, warn, }; -use conduwuit_service::{Services, appservice::RegistrationInfo}; use futures::FutureExt; use ruma::{ CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId, @@ -32,6 +29,7 @@ use ruma::{ serde::{JsonObject, Raw}, }; use serde_json::{json, value::to_raw_value}; +use service::{Services, appservice::RegistrationInfo}; use crate::{Ruma, client::invite_helper}; diff --git a/src/api/client/room/summary.rs b/src/api/client/room/summary.rs index 67d2e2ad..34820e83 100644 --- a/src/api/client/room/summary.rs +++ b/src/api/client/room/summary.rs @@ -1,16 +1,12 @@ use axum::extract::State; use axum_client_ip::InsecureClientIp; use conduwuit::{ - Err, Result, debug_warn, trace, + Err, Result, debug_warn, utils::{IterStream, future::TryExtExt}, }; -use futures::{ - FutureExt, StreamExt, - future::{OptionFuture, join3}, - stream::FuturesUnordered, -}; +use futures::{FutureExt, StreamExt, future::join3, stream::FuturesUnordered}; use ruma::{ - OwnedServerName, RoomId, UserId, + OwnedRoomId, OwnedServerName, RoomId, UserId, api::{ client::room::get_summary, federation::space::{SpaceHierarchyParentSummary, get_hierarchy}, @@ -74,12 +70,7 @@ async fn room_summary_response( servers: &[OwnedServerName], sender_user: Option<&UserId>, ) -> Result { - if services - .rooms - .state_cache - .server_in_room(services.globals.server_name(), room_id) - .await - { + if services.rooms.metadata.exists(room_id).await { return local_room_summary_response(services, room_id, sender_user) .boxed() .await; @@ -100,9 +91,13 @@ async fn room_summary_response( join_rule: room.join_rule, room_type: room.room_type, room_version: room.room_version, + membership: if sender_user.is_none() { + None + } else { + Some(MembershipState::Leave) + }, encryption: room.encryption, allowed_room_ids: room.allowed_room_ids, - membership: sender_user.is_some().then_some(MembershipState::Leave), }) } @@ -111,22 +106,20 @@ async fn local_room_summary_response( room_id: &RoomId, sender_user: Option<&UserId>, ) -> Result { - trace!(?sender_user, "Sending local room summary response for {room_id:?}"); - let join_rule = services.rooms.state_accessor.get_join_rules(room_id); + let join_rule = services.rooms.state_accessor.get_space_join_rule(room_id); let world_readable = services.rooms.state_accessor.is_world_readable(room_id); let guest_can_join = services.rooms.state_accessor.guest_can_join(room_id); - let (join_rule, world_readable, guest_can_join) = + let ((join_rule, allowed_room_ids), world_readable, guest_can_join) = join3(join_rule, world_readable, guest_can_join).await; - trace!("{join_rule:?}, {world_readable:?}, {guest_can_join:?}"); user_can_see_summary( services, room_id, - &join_rule.clone().into(), + &join_rule, guest_can_join, world_readable, - join_rule.allowed_rooms(), + &allowed_room_ids, sender_user, ) .await?; @@ -136,43 +129,26 @@ async fn local_room_summary_response( .state_accessor .get_canonical_alias(room_id) .ok(); - let name = services.rooms.state_accessor.get_name(room_id).ok(); - let topic = services.rooms.state_accessor.get_room_topic(room_id).ok(); - let room_type = services.rooms.state_accessor.get_room_type(room_id).ok(); - let avatar_url = services .rooms .state_accessor .get_avatar(room_id) .map(|res| res.into_option().unwrap_or_default().url); - let room_version = services.rooms.state.get_room_version(room_id).ok(); - let encryption = services .rooms .state_accessor .get_room_encryption(room_id) .ok(); - let num_joined_members = services .rooms .state_cache .room_joined_count(room_id) .unwrap_or(0); - let membership: OptionFuture<_> = sender_user - .map(|sender_user| { - services - .rooms - .state_accessor - .get_member(room_id, sender_user) - .map_ok_or(MembershipState::Leave, |content| content.membership) - }) - .into(); - let ( canonical_alias, name, @@ -182,7 +158,6 @@ async fn local_room_summary_response( room_type, room_version, encryption, - membership, ) = futures::join!( canonical_alias, name, @@ -192,7 +167,6 @@ async fn local_room_summary_response( room_type, room_version, encryption, - membership, ); Ok(get_summary::msc3266::Response { @@ -204,12 +178,21 @@ async fn local_room_summary_response( num_joined_members: num_joined_members.try_into().unwrap_or_default(), topic, world_readable, + join_rule, room_type, room_version, + membership: if let Some(sender_user) = sender_user { + services + .rooms + .state_accessor + .get_member(room_id, sender_user) + .await + .map_or(Some(MembershipState::Leave), |content| Some(content.membership)) + } else { + None + }, encryption, - membership, - allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(), - join_rule: join_rule.into(), + allowed_room_ids, }) } @@ -220,7 +203,6 @@ async fn remote_room_summary_hierarchy_response( servers: &[OwnedServerName], sender_user: Option<&UserId>, ) -> Result { - trace!(?sender_user, ?servers, "Sending remote room summary response for {room_id:?}"); if !services.config.allow_federation { return Err!(Request(Forbidden("Federation is disabled."))); } @@ -243,7 +225,6 @@ async fn remote_room_summary_hierarchy_response( .collect(); while let Some(Ok(response)) = requests.next().await { - trace!("{response:?}"); let room = response.room.clone(); if room.room_id != room_id { debug_warn!( @@ -260,7 +241,7 @@ async fn remote_room_summary_hierarchy_response( &room.join_rule, room.guest_can_join, room.world_readable, - room.allowed_room_ids.iter().map(AsRef::as_ref), + &room.allowed_room_ids, sender_user, ) .await @@ -273,19 +254,15 @@ async fn remote_room_summary_hierarchy_response( ))) } -async fn user_can_see_summary<'a, I>( +async fn user_can_see_summary( services: &Services, room_id: &RoomId, join_rule: &SpaceRoomJoinRule, guest_can_join: bool, world_readable: bool, - allowed_room_ids: I, + allowed_room_ids: &[OwnedRoomId], sender_user: Option<&UserId>, -) -> Result -where - I: Iterator + Send, -{ - let is_public_room = matches!(join_rule, Public | Knock | KnockRestricted); +) -> Result { match sender_user { | Some(sender_user) => { let user_can_see_state_events = services @@ -294,6 +271,7 @@ where .user_can_see_state_events(sender_user, room_id); let is_guest = services.users.is_deactivated(sender_user).unwrap_or(false); let user_in_allowed_restricted_room = allowed_room_ids + .iter() .stream() .any(|room| services.rooms.state_cache.is_joined(sender_user, room)); @@ -304,7 +282,7 @@ where if user_can_see_state_events || (is_guest && guest_can_join) - || is_public_room + || matches!(&join_rule, &Public | &Knock | &KnockRestricted) || user_in_allowed_restricted_room { return Ok(()); @@ -317,7 +295,7 @@ where ))) }, | None => { - if is_public_room || world_readable { + if matches!(join_rule, Public | Knock | KnockRestricted) || world_readable { return Ok(()); } diff --git a/src/api/client/room/upgrade.rs b/src/api/client/room/upgrade.rs index 9ec0b3bb..3cfb3c28 100644 --- a/src/api/client/room/upgrade.rs +++ b/src/api/client/room/upgrade.rs @@ -1,10 +1,7 @@ use std::cmp::max; use axum::extract::State; -use conduwuit::{ - Error, Result, err, info, - matrix::{StateKey, pdu::PduBuilder}, -}; +use conduwuit::{Error, Result, StateKey, err, info, pdu::PduBuilder}; use futures::StreamExt; use ruma::{ CanonicalJsonObject, RoomId, RoomVersionId, diff --git a/src/api/client/search.rs b/src/api/client/search.rs index d4dcde57..d66df881 100644 --- a/src/api/client/search.rs +++ b/src/api/client/search.rs @@ -2,12 +2,10 @@ use std::collections::BTreeMap; use axum::extract::State; use conduwuit::{ - Err, Result, at, is_true, - matrix::pdu::PduEvent, + Err, PduEvent, Result, at, is_true, result::FlatOk, utils::{IterStream, stream::ReadyExt}, }; -use conduwuit_service::{Services, rooms::search::RoomQuery}; use futures::{FutureExt, StreamExt, TryFutureExt, TryStreamExt, future::OptionFuture}; use ruma::{ OwnedRoomId, RoomId, UInt, UserId, @@ -19,6 +17,7 @@ use ruma::{ serde::Raw, }; use search_events::v3::{Request, Response}; +use service::{Services, rooms::search::RoomQuery}; use crate::Ruma; diff --git a/src/api/client/send.rs b/src/api/client/send.rs index f753fa65..1af74f57 100644 --- a/src/api/client/send.rs +++ b/src/api/client/send.rs @@ -1,11 +1,11 @@ use std::collections::BTreeMap; use axum::extract::State; -use conduwuit::{Err, Result, err, matrix::pdu::PduBuilder, utils}; +use conduwuit::{Err, err}; use ruma::{api::client::message::send_message_event, events::MessageLikeEventType}; use serde_json::from_str; -use crate::Ruma; +use crate::{Result, Ruma, service::pdu::PduBuilder, utils}; /// # `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}` /// diff --git a/src/api/client/session.rs b/src/api/client/session.rs index 2499a43d..3de625e4 100644 --- a/src/api/client/session.rs +++ b/src/api/client/session.rs @@ -2,11 +2,7 @@ use std::time::Duration; use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduwuit::{ - Err, Error, Result, debug, err, info, utils, - utils::{ReadyExt, hash}, -}; -use conduwuit_service::uiaa::SESSION_ID_LENGTH; +use conduwuit::{Err, debug, err, info, utils::ReadyExt}; use futures::StreamExt; use ruma::{ UserId, @@ -26,9 +22,10 @@ use ruma::{ uiaa, }, }; +use service::uiaa::SESSION_ID_LENGTH; use super::{DEVICE_ID_LENGTH, TOKEN_LENGTH}; -use crate::Ruma; +use crate::{Error, Result, Ruma, utils, utils::hash}; /// # `GET /_matrix/client/v3/login` /// diff --git a/src/api/client/space.rs b/src/api/client/space.rs index 4eee9d76..567ac62f 100644 --- a/src/api/client/space.rs +++ b/src/api/client/space.rs @@ -8,16 +8,16 @@ use conduwuit::{ Err, Result, utils::{future::TryExtExt, stream::IterStream}, }; -use conduwuit_service::{ +use futures::{StreamExt, TryFutureExt, future::OptionFuture}; +use ruma::{ + OwnedRoomId, OwnedServerName, RoomId, UInt, UserId, api::client::space::get_hierarchy, +}; +use service::{ Services, rooms::spaces::{ PaginationToken, SummaryAccessibility, get_parent_children_via, summary_to_chunk, }, }; -use futures::{StreamExt, TryFutureExt, future::OptionFuture}; -use ruma::{ - OwnedRoomId, OwnedServerName, RoomId, UInt, UserId, api::client::space::get_hierarchy, -}; use crate::Ruma; diff --git a/src/api/client/state.rs b/src/api/client/state.rs index 2ddc8f14..23583356 100644 --- a/src/api/client/state.rs +++ b/src/api/client/state.rs @@ -1,10 +1,5 @@ use axum::extract::State; -use conduwuit::{ - Err, Result, err, - matrix::pdu::{PduBuilder, PduEvent}, - utils::BoolExt, -}; -use conduwuit_service::Services; +use conduwuit::{Err, PduEvent, Result, err, pdu::PduBuilder, utils::BoolExt}; use futures::TryStreamExt; use ruma::{ OwnedEventId, RoomId, UserId, @@ -21,6 +16,7 @@ use ruma::{ }, serde::Raw, }; +use service::Services; use crate::{Ruma, RumaResponse}; @@ -211,7 +207,7 @@ async fn allowed_to_send_state_event( // irreversible mistakes match json.deserialize_as::() { | Ok(acl_content) => { - if acl_content.allow_is_empty() { + if acl_content.allow.is_empty() { return Err!(Request(BadJson(debug_warn!( ?room_id, "Sending an ACL event with an empty allow key will permanently \ @@ -220,7 +216,9 @@ async fn allowed_to_send_state_event( )))); } - if acl_content.deny_contains("*") && acl_content.allow_contains("*") { + if acl_content.deny.contains(&String::from("*")) + && acl_content.allow.contains(&String::from("*")) + { return Err!(Request(BadJson(debug_warn!( ?room_id, "Sending an ACL event with a deny and allow key value of \"*\" will \ @@ -229,9 +227,11 @@ async fn allowed_to_send_state_event( )))); } - if acl_content.deny_contains("*") + if acl_content.deny.contains(&String::from("*")) && !acl_content.is_allowed(services.globals.server_name()) - && !acl_content.allow_contains(services.globals.server_name().as_str()) + && !acl_content + .allow + .contains(&services.globals.server_name().to_string()) { return Err!(Request(BadJson(debug_warn!( ?room_id, @@ -241,9 +241,11 @@ async fn allowed_to_send_state_event( )))); } - if !acl_content.allow_contains("*") + if !acl_content.allow.contains(&String::from("*")) && !acl_content.is_allowed(services.globals.server_name()) - && !acl_content.allow_contains(services.globals.server_name().as_str()) + && !acl_content + .allow + .contains(&services.globals.server_name().to_string()) { return Err!(Request(BadJson(debug_warn!( ?room_id, diff --git a/src/api/client/sync/mod.rs b/src/api/client/sync/mod.rs index 14459acf..3eab76cc 100644 --- a/src/api/client/sync/mod.rs +++ b/src/api/client/sync/mod.rs @@ -3,14 +3,12 @@ mod v4; mod v5; use conduwuit::{ - Error, PduCount, Result, - matrix::pdu::PduEvent, + PduCount, utils::{ IterStream, stream::{BroadbandExt, ReadyExt, TryIgnore}, }, }; -use conduwuit_service::Services; use futures::{StreamExt, pin_mut}; use ruma::{ RoomId, UserId, @@ -23,6 +21,7 @@ use ruma::{ pub(crate) use self::{ v3::sync_events_route, v4::sync_events_v4_route, v5::sync_events_v5_route, }; +use crate::{Error, PduEvent, Result, service::Services}; pub(crate) const DEFAULT_BUMP_TYPES: &[TimelineEventType; 6] = &[CallInvite, PollStart, Beacon, RoomEncrypted, RoomMessage, Sticker]; diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index 24930941..83ffa55a 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -6,16 +6,12 @@ use std::{ use axum::extract::State; use conduwuit::{ - Result, at, err, error, extract_variant, is_equal_to, - matrix::{ - Event, - pdu::{EventHash, PduCount, PduEvent}, - }, - pair_of, ref_at, + PduCount, PduEvent, Result, at, err, error, extract_variant, is_equal_to, pair_of, + pdu::{Event, EventHash}, + ref_at, result::FlatOk, utils::{ self, BoolExt, IterStream, ReadyExt, TryFutureExtExt, - future::OptionStream, math::ruma_from_u64, stream::{BroadbandExt, Tools, TryExpect, WidebandExt}, }, @@ -1037,7 +1033,7 @@ async fn calculate_state_incremental<'a>( }) .into(); - let state_diff_ids: OptionFuture<_> = (!full_state && state_changed) + let state_diff: OptionFuture<_> = (!full_state && state_changed) .then(|| { StreamExt::into_future( services @@ -1062,9 +1058,45 @@ async fn calculate_state_incremental<'a>( }) .into(); + let lazy_state_ids = lazy_state_ids + .map(|opt| { + opt.map(|(curr, next)| { + let opt = curr; + let iter = Option::into_iter(opt); + IterStream::stream(iter).chain(next) + }) + }) + .map(Option::into_iter) + .map(IterStream::stream) + .flatten_stream() + .flatten(); + + let state_diff_ids = state_diff + .map(|opt| { + opt.map(|(curr, next)| { + let opt = curr; + let iter = Option::into_iter(opt); + IterStream::stream(iter).chain(next) + }) + }) + .map(Option::into_iter) + .map(IterStream::stream) + .flatten_stream() + .flatten(); + let state_events = current_state_ids - .stream() - .chain(state_diff_ids.stream()) + .map(|opt| { + opt.map(|(curr, next)| { + let opt = curr; + let iter = Option::into_iter(opt); + IterStream::stream(iter).chain(next) + }) + }) + .map(Option::into_iter) + .map(IterStream::stream) + .flatten_stream() + .flatten() + .chain(state_diff_ids) .broad_filter_map(|(shortstatekey, shorteventid)| async move { if witness.is_none() || encrypted_room { return Some(shorteventid); @@ -1072,7 +1104,7 @@ async fn calculate_state_incremental<'a>( lazy_filter(services, sender_user, shortstatekey, shorteventid).await }) - .chain(lazy_state_ids.stream()) + .chain(lazy_state_ids) .broad_filter_map(|shorteventid| { services .rooms diff --git a/src/api/client/sync/v5.rs b/src/api/client/sync/v5.rs index 684752ec..c4e71d88 100644 --- a/src/api/client/sync/v5.rs +++ b/src/api/client/sync/v5.rs @@ -6,19 +6,13 @@ use std::{ use axum::extract::State; use conduwuit::{ - Error, Result, debug, error, extract_variant, - matrix::{ - TypeStateKey, - pdu::{PduCount, PduEvent}, - }, - trace, + Error, PduEvent, Result, TypeStateKey, debug, error, extract_variant, trace, utils::{ BoolExt, IterStream, ReadyExt, TryFutureExtExt, math::{ruma_from_usize, usize_from_ruma}, }, warn, }; -use conduwuit_service::rooms::read_receipt::pack_receipts; use futures::{FutureExt, StreamExt, TryFutureExt}; use ruma::{ DeviceId, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId, @@ -33,6 +27,7 @@ use ruma::{ serde::Raw, uint, }; +use service::{PduCount, rooms::read_receipt::pack_receipts}; use super::{filter_rooms, share_encrypted_room}; use crate::{ diff --git a/src/api/client/tag.rs b/src/api/client/tag.rs index caafe10d..3b3b40d4 100644 --- a/src/api/client/tag.rs +++ b/src/api/client/tag.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; use axum::extract::State; -use conduwuit::Result; use ruma::{ api::client::tag::{create_tag, delete_tag, get_tags}, events::{ @@ -10,7 +9,7 @@ use ruma::{ }, }; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `PUT /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags/{tag}` /// diff --git a/src/api/client/thirdparty.rs b/src/api/client/thirdparty.rs index 0713a882..790b27d3 100644 --- a/src/api/client/thirdparty.rs +++ b/src/api/client/thirdparty.rs @@ -1,9 +1,8 @@ use std::collections::BTreeMap; -use conduwuit::Result; use ruma::api::client::thirdparty::get_protocols; -use crate::{Ruma, RumaResponse}; +use crate::{Result, Ruma, RumaResponse}; /// # `GET /_matrix/client/r0/thirdparty/protocols` /// diff --git a/src/api/client/threads.rs b/src/api/client/threads.rs index 5b838bef..00bfe553 100644 --- a/src/api/client/threads.rs +++ b/src/api/client/threads.rs @@ -1,12 +1,9 @@ use axum::extract::State; -use conduwuit::{ - Result, at, - matrix::pdu::{PduCount, PduEvent}, -}; +use conduwuit::{PduCount, PduEvent, at}; use futures::StreamExt; use ruma::{api::client::threads::get_threads, uint}; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `GET /_matrix/client/r0/rooms/{roomId}/threads` pub(crate) async fn get_threads_route( diff --git a/src/api/client/to_device.rs b/src/api/client/to_device.rs index 8ad9dc99..1b942fba 100644 --- a/src/api/client/to_device.rs +++ b/src/api/client/to_device.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use axum::extract::State; use conduwuit::{Error, Result}; -use conduwuit_service::sending::EduBuf; use futures::StreamExt; use ruma::{ api::{ @@ -11,6 +10,7 @@ use ruma::{ }, to_device::DeviceIdOrAllDevices, }; +use service::sending::EduBuf; use crate::Ruma; diff --git a/src/api/client/typing.rs b/src/api/client/typing.rs index 1d8d02fd..b02cc473 100644 --- a/src/api/client/typing.rs +++ b/src/api/client/typing.rs @@ -1,8 +1,8 @@ use axum::extract::State; -use conduwuit::{Err, Result, utils, utils::math::Tried}; +use conduwuit::{Err, utils::math::Tried}; use ruma::api::client::typing::create_typing_event; -use crate::Ruma; +use crate::{Result, Ruma, utils}; /// # `PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}` /// diff --git a/src/api/client/unversioned.rs b/src/api/client/unversioned.rs index 232d5b28..4e2b7d9d 100644 --- a/src/api/client/unversioned.rs +++ b/src/api/client/unversioned.rs @@ -1,11 +1,10 @@ use std::collections::BTreeMap; use axum::{Json, extract::State, response::IntoResponse}; -use conduwuit::Result; use futures::StreamExt; use ruma::api::client::discovery::get_supported_versions; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `GET /_matrix/client/versions` /// diff --git a/src/api/client/user_directory.rs b/src/api/client/user_directory.rs index 99b3bb67..c5d79a56 100644 --- a/src/api/client/user_directory.rs +++ b/src/api/client/user_directory.rs @@ -1,19 +1,15 @@ use axum::extract::State; -use conduwuit::{ - Result, - utils::{future::BoolExt, stream::BroadbandExt}, -}; -use futures::{FutureExt, StreamExt, pin_mut}; +use conduwuit::utils::TryFutureExtExt; +use futures::{StreamExt, pin_mut}; use ruma::{ - api::client::user_directory::search_users::{self}, - events::room::join_rules::JoinRule, + api::client::user_directory::search_users, + events::{ + StateEventType, + room::join_rules::{JoinRule, RoomJoinRulesEventContent}, + }, }; -use crate::Ruma; - -// conduwuit can handle a lot more results than synapse -const LIMIT_MAX: usize = 500; -const LIMIT_DEFAULT: usize = 10; +use crate::{Result, Ruma}; /// # `POST /_matrix/client/r0/user_directory/search` /// @@ -25,63 +21,78 @@ pub(crate) async fn search_users_route( State(services): State, body: Ruma, ) -> Result { - let sender_user = body.sender_user(); - let limit = usize::try_from(body.limit) - .map_or(LIMIT_DEFAULT, usize::from) - .min(LIMIT_MAX); + let sender_user = body.sender_user.as_ref().expect("user is authenticated"); + let limit = usize::try_from(body.limit).map_or(10, usize::from).min(100); // default limit is 10 - let mut users = services - .users - .stream() - .map(ToOwned::to_owned) - .broad_filter_map(async |user_id| { - let user = search_users::v3::User { - user_id: user_id.clone(), - display_name: services.users.displayname(&user_id).await.ok(), - avatar_url: services.users.avatar_url(&user_id).await.ok(), - }; + let users = services.users.stream().filter_map(|user_id| async { + // Filter out buggy users (they should not exist, but you never know...) + let user = search_users::v3::User { + user_id: user_id.to_owned(), + display_name: services.users.displayname(user_id).await.ok(), + avatar_url: services.users.avatar_url(user_id).await.ok(), + }; - let user_id_matches = user - .user_id - .as_str() - .to_lowercase() - .contains(&body.search_term.to_lowercase()); + let user_id_matches = user + .user_id + .to_string() + .to_lowercase() + .contains(&body.search_term.to_lowercase()); - let user_displayname_matches = user.display_name.as_ref().is_some_and(|name| { + let user_displayname_matches = user + .display_name + .as_ref() + .filter(|name| { name.to_lowercase() .contains(&body.search_term.to_lowercase()) - }); + }) + .is_some(); - if !user_id_matches && !user_displayname_matches { - return None; + if !user_id_matches && !user_displayname_matches { + return None; + } + + // It's a matching user, but is the sender allowed to see them? + let mut user_visible = false; + + let user_is_in_public_rooms = services + .rooms + .state_cache + .rooms_joined(&user.user_id) + .any(|room| { + services + .rooms + .state_accessor + .room_state_get_content::( + room, + &StateEventType::RoomJoinRules, + "", + ) + .map_ok_or(false, |content| content.join_rule == JoinRule::Public) + }) + .await; + + if user_is_in_public_rooms { + user_visible = true; + } else { + let user_is_in_shared_rooms = services + .rooms + .state_cache + .user_sees_user(sender_user, &user.user_id) + .await; + + if user_is_in_shared_rooms { + user_visible = true; } + } - let user_in_public_room = services - .rooms - .state_cache - .rooms_joined(&user_id) - .map(ToOwned::to_owned) - .any(|room| async move { - services - .rooms - .state_accessor - .get_join_rules(&room) - .map(|rule| matches!(rule, JoinRule::Public)) - .await - }); + user_visible.then_some(user) + }); - let user_sees_user = services - .rooms - .state_cache - .user_sees_user(sender_user, &user_id); + pin_mut!(users); - pin_mut!(user_in_public_room, user_sees_user); + let limited = users.by_ref().next().await.is_some(); - user_in_public_room.or(user_sees_user).await.then_some(user) - }); - - let results = users.by_ref().take(limit).collect().await; - let limited = users.next().await.is_some(); + let results = users.take(limit).collect().await; Ok(search_users::v3::Response { results, limited }) } diff --git a/src/api/client/voip.rs b/src/api/client/voip.rs index 91991d24..37e67984 100644 --- a/src/api/client/voip.rs +++ b/src/api/client/voip.rs @@ -2,12 +2,12 @@ use std::time::{Duration, SystemTime}; use axum::extract::State; use base64::{Engine as _, engine::general_purpose}; -use conduwuit::{Err, Result, utils}; +use conduwuit::{Err, utils}; use hmac::{Hmac, Mac}; use ruma::{SecondsSinceUnixEpoch, UserId, api::client::voip::get_turn_server_info}; use sha1::Sha1; -use crate::Ruma; +use crate::{Result, Ruma}; const RANDOM_USER_ID_LENGTH: usize = 10; diff --git a/src/api/client/well_known.rs b/src/api/client/well_known.rs index eedab981..abda61b0 100644 --- a/src/api/client/well_known.rs +++ b/src/api/client/well_known.rs @@ -1,5 +1,4 @@ use axum::{Json, extract::State, response::IntoResponse}; -use conduwuit::{Error, Result}; use ruma::api::client::{ discovery::{ discover_homeserver::{self, HomeserverInfo, SlidingSyncProxyInfo}, @@ -8,7 +7,7 @@ use ruma::api::client::{ error::ErrorKind, }; -use crate::Ruma; +use crate::{Error, Result, Ruma}; /// # `GET /.well-known/matrix/client` /// diff --git a/src/api/mod.rs b/src/api/mod.rs index 9ca24e72..090cf897 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -8,6 +8,8 @@ pub mod server; extern crate conduwuit_core as conduwuit; extern crate conduwuit_service as service; +pub(crate) use conduwuit::{Error, Result, debug_info, pdu::PduEvent, utils}; + pub(crate) use self::router::{Ruma, RumaResponse, State}; conduwuit::mod_ctor! {} diff --git a/src/api/router/auth.rs b/src/api/router/auth.rs index 0eb61ca6..5cd7b831 100644 --- a/src/api/router/auth.rs +++ b/src/api/router/auth.rs @@ -317,9 +317,10 @@ fn auth_server_checks(services: &Services, x_matrix: &XMatrix) -> Result<()> { let origin = &x_matrix.origin; if services + .server .config .forbidden_remote_server_names - .is_match(origin.host()) + .contains(origin) { return Err!(Request(Forbidden(debug_warn!( "Federation requests from {origin} denied." diff --git a/src/api/server/hierarchy.rs b/src/api/server/hierarchy.rs index 42c348f9..c759c8ea 100644 --- a/src/api/server/hierarchy.rs +++ b/src/api/server/hierarchy.rs @@ -3,11 +3,9 @@ use conduwuit::{ Err, Result, utils::stream::{BroadbandExt, IterStream}, }; -use conduwuit_service::rooms::spaces::{ - Identifier, SummaryAccessibility, get_parent_children_via, -}; use futures::{FutureExt, StreamExt}; use ruma::api::federation::space::get_hierarchy; +use service::rooms::spaces::{Identifier, SummaryAccessibility, get_parent_children_via}; use crate::Ruma; diff --git a/src/api/server/invite.rs b/src/api/server/invite.rs index edd6ac16..f4cc6eb2 100644 --- a/src/api/server/invite.rs +++ b/src/api/server/invite.rs @@ -1,15 +1,14 @@ use axum::extract::State; use axum_client_ip::InsecureClientIp; use base64::{Engine as _, engine::general_purpose}; -use conduwuit::{ - Err, Error, PduEvent, Result, err, pdu::gen_event_id, utils, utils::hash::sha256, warn, -}; +use conduwuit::{Err, Error, PduEvent, Result, err, utils, utils::hash::sha256, warn}; use ruma::{ CanonicalJsonValue, OwnedUserId, UserId, api::{client::error::ErrorKind, federation::membership::create_invite}, events::room::member::{MembershipState, RoomMemberEventContent}, serde::JsonObject, }; +use service::pdu::gen_event_id; use crate::Ruma; @@ -38,18 +37,20 @@ pub(crate) async fn create_invite_route( if let Some(server) = body.room_id.server_name() { if services + .server .config .forbidden_remote_server_names - .is_match(server.host()) + .contains(&server.to_owned()) { return Err!(Request(Forbidden("Server is banned on this homeserver."))); } } if services + .server .config .forbidden_remote_server_names - .is_match(body.origin().host()) + .contains(body.origin()) { warn!( "Received federated/remote invite from banned server {} for room ID {}. Rejecting.", diff --git a/src/api/server/make_join.rs b/src/api/server/make_join.rs index ac2c5485..f18d1304 100644 --- a/src/api/server/make_join.rs +++ b/src/api/server/make_join.rs @@ -1,8 +1,5 @@ use axum::extract::State; -use conduwuit::{ - Err, Error, Result, debug_info, matrix::pdu::PduBuilder, utils::IterStream, warn, -}; -use conduwuit_service::Services; +use conduwuit::{Err, debug_info, utils::IterStream, warn}; use futures::StreamExt; use ruma::{ CanonicalJsonObject, OwnedUserId, RoomId, RoomVersionId, UserId, @@ -17,7 +14,10 @@ use ruma::{ }; use serde_json::value::to_raw_value; -use crate::Ruma; +use crate::{ + Error, Result, Ruma, + service::{Services, pdu::PduBuilder}, +}; /// # `GET /_matrix/federation/v1/make_join/{roomId}/{userId}` /// @@ -42,9 +42,10 @@ pub(crate) async fn create_join_event_template_route( .await?; if services + .server .config .forbidden_remote_server_names - .is_match(body.origin().host()) + .contains(body.origin()) { warn!( "Server {} for remote user {} tried joining room ID {} which has a server name that \ @@ -58,9 +59,10 @@ pub(crate) async fn create_join_event_template_route( if let Some(server) = body.room_id.server_name() { if services + .server .config .forbidden_remote_server_names - .is_match(server.host()) + .contains(&server.to_owned()) { return Err!(Request(Forbidden(warn!( "Room ID server name {server} is banned on this homeserver." diff --git a/src/api/server/make_knock.rs b/src/api/server/make_knock.rs index 511c13b2..71536439 100644 --- a/src/api/server/make_knock.rs +++ b/src/api/server/make_knock.rs @@ -1,14 +1,15 @@ use RoomVersionId::*; use axum::extract::State; -use conduwuit::{Err, Error, Result, debug_warn, matrix::pdu::PduBuilder, warn}; +use conduwuit::{Err, debug_warn}; use ruma::{ RoomVersionId, api::{client::error::ErrorKind, federation::knock::create_knock_event_template}, events::room::member::{MembershipState, RoomMemberEventContent}, }; use serde_json::value::to_raw_value; +use tracing::warn; -use crate::Ruma; +use crate::{Error, Result, Ruma, service::pdu::PduBuilder}; /// # `GET /_matrix/federation/v1/make_knock/{roomId}/{userId}` /// @@ -33,9 +34,10 @@ pub(crate) async fn create_knock_event_template_route( .await?; if services + .server .config .forbidden_remote_server_names - .is_match(body.origin().host()) + .contains(body.origin()) { warn!( "Server {} for remote user {} tried knocking room ID {} which has a server name \ @@ -49,9 +51,10 @@ pub(crate) async fn create_knock_event_template_route( if let Some(server) = body.room_id.server_name() { if services + .server .config .forbidden_remote_server_names - .is_match(server.host()) + .contains(&server.to_owned()) { return Err!(Request(Forbidden("Server is banned on this homeserver."))); } diff --git a/src/api/server/make_leave.rs b/src/api/server/make_leave.rs index cb6bd2fa..1ed02785 100644 --- a/src/api/server/make_leave.rs +++ b/src/api/server/make_leave.rs @@ -1,5 +1,5 @@ use axum::extract::State; -use conduwuit::{Err, Result, matrix::pdu::PduBuilder}; +use conduwuit::{Err, Result}; use ruma::{ api::federation::membership::prepare_leave_event, events::room::member::{MembershipState, RoomMemberEventContent}, @@ -7,7 +7,7 @@ use ruma::{ use serde_json::value::to_raw_value; use super::make_join::maybe_strip_event_id; -use crate::Ruma; +use crate::{Ruma, service::pdu::PduBuilder}; /// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}` /// diff --git a/src/api/server/openid.rs b/src/api/server/openid.rs index a09cd7ad..4833fbe1 100644 --- a/src/api/server/openid.rs +++ b/src/api/server/openid.rs @@ -1,8 +1,7 @@ use axum::extract::State; -use conduwuit::Result; use ruma::api::federation::openid::get_openid_userinfo; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `GET /_matrix/federation/v1/openid/userinfo` /// diff --git a/src/api/server/publicrooms.rs b/src/api/server/publicrooms.rs index cf66ea71..ff74574a 100644 --- a/src/api/server/publicrooms.rs +++ b/src/api/server/publicrooms.rs @@ -1,6 +1,5 @@ use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduwuit::{Error, Result}; use ruma::{ api::{ client::error::ErrorKind, @@ -9,7 +8,7 @@ use ruma::{ directory::Filter, }; -use crate::Ruma; +use crate::{Error, Result, Ruma}; /// # `POST /_matrix/federation/v1/publicRooms` /// diff --git a/src/api/server/send.rs b/src/api/server/send.rs index 9c5bfd2b..1f467dac 100644 --- a/src/api/server/send.rs +++ b/src/api/server/send.rs @@ -9,15 +9,11 @@ use conduwuit::{ result::LogErr, trace, utils::{ - IterStream, ReadyExt, millis_since_unix_epoch, + IterStream, ReadyExt, stream::{BroadbandExt, TryBroadbandExt, automatic_width}, }, warn, }; -use conduwuit_service::{ - Services, - sending::{EDU_LIMIT, PDU_LIMIT}, -}; use futures::{FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt}; use itertools::Itertools; use ruma::{ @@ -37,8 +33,16 @@ use ruma::{ serde::Raw, to_device::DeviceIdOrAllDevices, }; +use service::{ + Services, + sending::{EDU_LIMIT, PDU_LIMIT}, +}; +use utils::millis_since_unix_epoch; -use crate::Ruma; +use crate::{ + Ruma, + utils::{self}, +}; type ResolvedMap = BTreeMap; type Pdu = (OwnedRoomId, OwnedEventId, CanonicalJsonObject); diff --git a/src/api/server/send_join.rs b/src/api/server/send_join.rs index a66d8890..c1749835 100644 --- a/src/api/server/send_join.rs +++ b/src/api/server/send_join.rs @@ -9,7 +9,6 @@ use conduwuit::{ utils::stream::{IterStream, TryBroadbandExt}, warn, }; -use conduwuit_service::Services; use futures::{FutureExt, StreamExt, TryStreamExt}; use ruma::{ CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, @@ -21,6 +20,7 @@ use ruma::{ }, }; use serde_json::value::{RawValue as RawJsonValue, to_raw_value}; +use service::Services; use crate::Ruma; @@ -268,9 +268,10 @@ pub(crate) async fn create_join_event_v1_route( body: Ruma, ) -> Result { if services + .server .config .forbidden_remote_server_names - .is_match(body.origin().host()) + .contains(body.origin()) { warn!( "Server {} tried joining room ID {} through us who has a server name that is \ @@ -283,9 +284,10 @@ pub(crate) async fn create_join_event_v1_route( if let Some(server) = body.room_id.server_name() { if services + .server .config .forbidden_remote_server_names - .is_match(server.host()) + .contains(&server.to_owned()) { warn!( "Server {} tried joining room ID {} through us which has a server name that is \ @@ -314,18 +316,20 @@ pub(crate) async fn create_join_event_v2_route( body: Ruma, ) -> Result { if services + .server .config .forbidden_remote_server_names - .is_match(body.origin().host()) + .contains(body.origin()) { return Err!(Request(Forbidden("Server is banned on this homeserver."))); } if let Some(server) = body.room_id.server_name() { if services + .server .config .forbidden_remote_server_names - .is_match(server.host()) + .contains(&server.to_owned()) { warn!( "Server {} tried joining room ID {} through us which has a server name that is \ diff --git a/src/api/server/send_knock.rs b/src/api/server/send_knock.rs index ee7b6cba..f7bb0735 100644 --- a/src/api/server/send_knock.rs +++ b/src/api/server/send_knock.rs @@ -1,9 +1,5 @@ use axum::extract::State; -use conduwuit::{ - Err, Result, err, - matrix::pdu::{PduEvent, gen_event_id_canonical_json}, - warn, -}; +use conduwuit::{Err, PduEvent, Result, err, pdu::gen_event_id_canonical_json, warn}; use futures::FutureExt; use ruma::{ OwnedServerName, OwnedUserId, @@ -26,9 +22,10 @@ pub(crate) async fn create_knock_event_v1_route( body: Ruma, ) -> Result { if services + .server .config .forbidden_remote_server_names - .is_match(body.origin().host()) + .contains(body.origin()) { warn!( "Server {} tried knocking room ID {} who has a server name that is globally \ @@ -41,9 +38,10 @@ pub(crate) async fn create_knock_event_v1_route( if let Some(server) = body.room_id.server_name() { if services + .server .config .forbidden_remote_server_names - .is_match(server.host()) + .contains(&server.to_owned()) { warn!( "Server {} tried knocking room ID {} which has a server name that is globally \ diff --git a/src/api/server/send_leave.rs b/src/api/server/send_leave.rs index d3dc994c..71516553 100644 --- a/src/api/server/send_leave.rs +++ b/src/api/server/send_leave.rs @@ -1,8 +1,7 @@ #![allow(deprecated)] use axum::extract::State; -use conduwuit::{Err, Result, err, matrix::pdu::gen_event_id_canonical_json}; -use conduwuit_service::Services; +use conduwuit::{Err, Result, err}; use futures::FutureExt; use ruma::{ OwnedRoomId, OwnedUserId, RoomId, ServerName, @@ -14,7 +13,10 @@ use ruma::{ }; use serde_json::value::RawValue as RawJsonValue; -use crate::Ruma; +use crate::{ + Ruma, + service::{Services, pdu::gen_event_id_canonical_json}, +}; /// # `PUT /_matrix/federation/v1/send_leave/{roomId}/{eventId}` /// diff --git a/src/api/server/version.rs b/src/api/server/version.rs index b08ff77a..036b61f7 100644 --- a/src/api/server/version.rs +++ b/src/api/server/version.rs @@ -1,7 +1,6 @@ -use conduwuit::Result; use ruma::api::federation::discovery::get_server_version; -use crate::Ruma; +use crate::{Result, Ruma}; /// # `GET /_matrix/federation/v1/version` /// diff --git a/src/api/server/well_known.rs b/src/api/server/well_known.rs index 75c7cf5d..48caa7d6 100644 --- a/src/api/server/well_known.rs +++ b/src/api/server/well_known.rs @@ -1,8 +1,7 @@ use axum::extract::State; -use conduwuit::{Error, Result}; use ruma::api::{client::error::ErrorKind, federation::discovery::discover_homeserver}; -use crate::Ruma; +use crate::{Error, Result, Ruma}; /// # `GET /.well-known/matrix/server` /// diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 0ca6bbaf..7be140a5 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -3,7 +3,7 @@ pub mod manager; pub mod proxy; use std::{ - collections::{BTreeMap, BTreeSet}, + collections::{BTreeMap, BTreeSet, HashSet}, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, path::{Path, PathBuf}, }; @@ -640,9 +640,9 @@ pub struct Config { /// Default room version conduwuit will create rooms with. /// - /// Per spec, room version 11 is the default. + /// Per spec, room version 10 is the default. /// - /// default: 11 + /// default: 10 #[serde(default = "default_default_room_version")] pub default_room_version: RoomVersionId, @@ -715,7 +715,7 @@ pub struct Config { /// Currently, conduwuit doesn't support inbound batched key requests, so /// this list should only contain other Synapse servers. /// - /// example: ["matrix.org", "tchncs.de"] + /// example: ["matrix.org", "envs.net", "tchncs.de"] /// /// default: ["matrix.org"] #[serde(default = "default_trusted_servers")] @@ -1361,18 +1361,15 @@ pub struct Config { #[serde(default)] pub prune_missing_media: bool, - /// Vector list of regex patterns of server names that conduwuit will refuse - /// to download remote media from. - /// - /// example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] + /// Vector list of servers that conduwuit will refuse to download remote + /// media from. /// /// default: [] - #[serde(default, with = "serde_regex")] - pub prevent_media_downloads_from: RegexSet, + #[serde(default)] + pub prevent_media_downloads_from: HashSet, - /// List of forbidden server names via regex patterns that we will block - /// incoming AND outgoing federation with, and block client room joins / - /// remote user invites. + /// List of forbidden server names that we will block incoming AND outgoing + /// federation with, and block client room joins / remote user invites. /// /// This check is applied on the room ID, room alias, sender server name, /// sender user's server name, inbound federation X-Matrix origin, and @@ -1380,21 +1377,17 @@ pub struct Config { /// /// Basically "global" ACLs. /// - /// example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] - /// /// default: [] - #[serde(default, with = "serde_regex")] - pub forbidden_remote_server_names: RegexSet, + #[serde(default)] + pub forbidden_remote_server_names: HashSet, - /// List of forbidden server names via regex patterns that we will block all - /// outgoing federated room directory requests for. Useful for preventing - /// our users from wandering into bad servers or spaces. - /// - /// example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] + /// List of forbidden server names that we will block all outgoing federated + /// room directory requests for. Useful for preventing our users from + /// wandering into bad servers or spaces. /// /// default: [] - #[serde(default, with = "serde_regex")] - pub forbidden_remote_room_directory_server_names: RegexSet, + #[serde(default = "HashSet::new")] + pub forbidden_remote_room_directory_server_names: HashSet, /// Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you /// do not want conduwuit to send outbound requests to. Defaults to @@ -1515,10 +1508,11 @@ pub struct Config { /// used, and startup as warnings if any room aliases in your database have /// a forbidden room alias/ID. /// - /// example: ["19dollarfortnitecards", "b[4a]droom", "badphrase"] + /// example: ["19dollarfortnitecards", "b[4a]droom"] /// /// default: [] - #[serde(default, with = "serde_regex")] + #[serde(default)] + #[serde(with = "serde_regex")] pub forbidden_alias_names: RegexSet, /// List of forbidden username patterns/strings. @@ -1530,10 +1524,11 @@ pub struct Config { /// startup as warnings if any local users in your database have a forbidden /// username. /// - /// example: ["administrator", "b[a4]dusernam[3e]", "badphrase"] + /// example: ["administrator", "b[a4]dusernam[3e]"] /// /// default: [] - #[serde(default, with = "serde_regex")] + #[serde(default)] + #[serde(with = "serde_regex")] pub forbidden_usernames: RegexSet, /// Retry failed and incomplete messages to remote servers immediately upon @@ -2175,7 +2170,7 @@ fn default_rocksdb_stats_level() -> u8 { 1 } // I know, it's a great name #[must_use] #[inline] -pub fn default_default_room_version() -> RoomVersionId { RoomVersionId::V11 } +pub fn default_default_room_version() -> RoomVersionId { RoomVersionId::V10 } fn default_ip_range_denylist() -> Vec { vec![ diff --git a/src/core/matrix/mod.rs b/src/core/matrix/mod.rs deleted file mode 100644 index 8c978173..00000000 --- a/src/core/matrix/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Core Matrix Library - -pub mod event; -pub mod pdu; -pub mod state_res; - -pub use event::Event; -pub use pdu::{PduBuilder, PduCount, PduEvent, PduId, RawPduId, StateKey}; -pub use state_res::{EventTypeExt, RoomVersion, StateMap, TypeStateKey}; diff --git a/src/core/mod.rs b/src/core/mod.rs index b91cdf0b..80ebbdcb 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -6,10 +6,11 @@ pub mod debug; pub mod error; pub mod info; pub mod log; -pub mod matrix; pub mod metrics; pub mod mods; +pub mod pdu; pub mod server; +pub mod state_res; pub mod utils; pub use ::arrayvec; @@ -22,8 +23,9 @@ pub use ::tracing; pub use config::Config; pub use error::Error; pub use info::{rustc_flags_capture, version, version::version}; -pub use matrix::{Event, EventTypeExt, PduCount, PduEvent, PduId, RoomVersion, pdu, state_res}; +pub use pdu::{Event, PduBuilder, PduCount, PduEvent, PduId, RawPduId, StateKey}; pub use server::Server; +pub use state_res::{EventTypeExt, RoomVersion, StateMap, TypeStateKey}; pub use utils::{ctor, dtor, implement, result, result::Result}; pub use crate as conduwuit_core; diff --git a/src/core/matrix/pdu/builder.rs b/src/core/pdu/builder.rs similarity index 100% rename from src/core/matrix/pdu/builder.rs rename to src/core/pdu/builder.rs diff --git a/src/core/matrix/pdu/content.rs b/src/core/pdu/content.rs similarity index 100% rename from src/core/matrix/pdu/content.rs rename to src/core/pdu/content.rs diff --git a/src/core/matrix/pdu/count.rs b/src/core/pdu/count.rs similarity index 100% rename from src/core/matrix/pdu/count.rs rename to src/core/pdu/count.rs diff --git a/src/core/pdu/event.rs b/src/core/pdu/event.rs new file mode 100644 index 00000000..09ad1666 --- /dev/null +++ b/src/core/pdu/event.rs @@ -0,0 +1,35 @@ +use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId, events::TimelineEventType}; +use serde_json::value::RawValue as RawJsonValue; + +use super::Pdu; +pub use crate::state_res::Event; + +impl Event for Pdu { + type Id = OwnedEventId; + + fn event_id(&self) -> &Self::Id { &self.event_id } + + fn room_id(&self) -> &RoomId { &self.room_id } + + fn sender(&self) -> &UserId { &self.sender } + + fn event_type(&self) -> &TimelineEventType { &self.kind } + + fn content(&self) -> &RawJsonValue { &self.content } + + fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch { + MilliSecondsSinceUnixEpoch(self.origin_server_ts) + } + + fn state_key(&self) -> Option<&str> { self.state_key.as_deref() } + + fn prev_events(&self) -> impl DoubleEndedIterator + Send + '_ { + self.prev_events.iter() + } + + fn auth_events(&self) -> impl DoubleEndedIterator + Send + '_ { + self.auth_events.iter() + } + + fn redacts(&self) -> Option<&Self::Id> { self.redacts.as_ref() } +} diff --git a/src/core/matrix/pdu/event_id.rs b/src/core/pdu/event_id.rs similarity index 100% rename from src/core/matrix/pdu/event_id.rs rename to src/core/pdu/event_id.rs diff --git a/src/core/matrix/pdu/filter.rs b/src/core/pdu/filter.rs similarity index 100% rename from src/core/matrix/pdu/filter.rs rename to src/core/pdu/filter.rs diff --git a/src/core/matrix/pdu/id.rs b/src/core/pdu/id.rs similarity index 100% rename from src/core/matrix/pdu/id.rs rename to src/core/pdu/id.rs diff --git a/src/core/matrix/pdu.rs b/src/core/pdu/mod.rs similarity index 72% rename from src/core/matrix/pdu.rs rename to src/core/pdu/mod.rs index 7e1ecfa8..9fb2a3da 100644 --- a/src/core/matrix/pdu.rs +++ b/src/core/pdu/mod.rs @@ -1,6 +1,7 @@ mod builder; mod content; mod count; +mod event; mod event_id; mod filter; mod id; @@ -16,8 +17,8 @@ mod unsigned; use std::cmp::Ordering; use ruma::{ - CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, - OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, UInt, UserId, events::TimelineEventType, + CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName, + OwnedUserId, UInt, events::TimelineEventType, }; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue as RawJsonValue; @@ -26,12 +27,12 @@ pub use self::{ Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId, builder::{Builder, Builder as PduBuilder}, count::Count, + event::Event, event_id::*, id::*, raw_id::*, state_key::{ShortStateKey, StateKey}, }; -use super::Event; use crate::Result; /// Persistent Data Unit (Event) @@ -78,36 +79,6 @@ impl Pdu { } } -impl Event for Pdu { - type Id = OwnedEventId; - - fn event_id(&self) -> &Self::Id { &self.event_id } - - fn room_id(&self) -> &RoomId { &self.room_id } - - fn sender(&self) -> &UserId { &self.sender } - - fn event_type(&self) -> &TimelineEventType { &self.kind } - - fn content(&self) -> &RawJsonValue { &self.content } - - fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch { - MilliSecondsSinceUnixEpoch(self.origin_server_ts) - } - - fn state_key(&self) -> Option<&str> { self.state_key.as_deref() } - - fn prev_events(&self) -> impl DoubleEndedIterator + Send + '_ { - self.prev_events.iter() - } - - fn auth_events(&self) -> impl DoubleEndedIterator + Send + '_ { - self.auth_events.iter() - } - - fn redacts(&self) -> Option<&Self::Id> { self.redacts.as_ref() } -} - /// Prevent derived equality which wouldn't limit itself to event_id impl Eq for Pdu {} @@ -116,12 +87,12 @@ impl PartialEq for Pdu { fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id } } -/// Ordering determined by the Pdu's ID, not the memory representations. -impl Ord for Pdu { - fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) } -} - /// Ordering determined by the Pdu's ID, not the memory representations. impl PartialOrd for Pdu { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } + +/// Ordering determined by the Pdu's ID, not the memory representations. +impl Ord for Pdu { + fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) } +} diff --git a/src/core/matrix/pdu/raw_id.rs b/src/core/pdu/raw_id.rs similarity index 100% rename from src/core/matrix/pdu/raw_id.rs rename to src/core/pdu/raw_id.rs diff --git a/src/core/matrix/pdu/redact.rs b/src/core/pdu/redact.rs similarity index 100% rename from src/core/matrix/pdu/redact.rs rename to src/core/pdu/redact.rs diff --git a/src/core/matrix/pdu/relation.rs b/src/core/pdu/relation.rs similarity index 100% rename from src/core/matrix/pdu/relation.rs rename to src/core/pdu/relation.rs diff --git a/src/core/matrix/pdu/state_key.rs b/src/core/pdu/state_key.rs similarity index 100% rename from src/core/matrix/pdu/state_key.rs rename to src/core/pdu/state_key.rs diff --git a/src/core/matrix/pdu/strip.rs b/src/core/pdu/strip.rs similarity index 100% rename from src/core/matrix/pdu/strip.rs rename to src/core/pdu/strip.rs diff --git a/src/core/matrix/pdu/tests.rs b/src/core/pdu/tests.rs similarity index 100% rename from src/core/matrix/pdu/tests.rs rename to src/core/pdu/tests.rs diff --git a/src/core/matrix/pdu/unsigned.rs b/src/core/pdu/unsigned.rs similarity index 100% rename from src/core/matrix/pdu/unsigned.rs rename to src/core/pdu/unsigned.rs diff --git a/src/core/matrix/state_res/LICENSE b/src/core/state_res/LICENSE similarity index 100% rename from src/core/matrix/state_res/LICENSE rename to src/core/state_res/LICENSE diff --git a/src/core/matrix/state_res/benches.rs b/src/core/state_res/benches.rs similarity index 100% rename from src/core/matrix/state_res/benches.rs rename to src/core/state_res/benches.rs diff --git a/src/core/matrix/state_res/error.rs b/src/core/state_res/error.rs similarity index 100% rename from src/core/matrix/state_res/error.rs rename to src/core/state_res/error.rs diff --git a/src/core/matrix/state_res/event_auth.rs b/src/core/state_res/event_auth.rs similarity index 100% rename from src/core/matrix/state_res/event_auth.rs rename to src/core/state_res/event_auth.rs diff --git a/src/core/matrix/state_res/mod.rs b/src/core/state_res/mod.rs similarity index 99% rename from src/core/matrix/state_res/mod.rs rename to src/core/state_res/mod.rs index 93c00d15..1db92e59 100644 --- a/src/core/matrix/state_res/mod.rs +++ b/src/core/state_res/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod error; pub mod event_auth; mod power_levels; mod room_version; +mod state_event; #[cfg(test)] mod test_utils; @@ -35,12 +36,9 @@ use self::power_levels::PowerLevelsContentFields; pub use self::{ event_auth::{auth_check, auth_types_for_event}, room_version::RoomVersion, + state_event::Event, }; -use crate::{ - debug, - matrix::{event::Event, pdu::StateKey}, - trace, warn, -}; +use crate::{debug, pdu::StateKey, trace, warn}; /// A mapping of event type and state_key to some value `T`, usually an /// `EventId`. diff --git a/src/core/matrix/state_res/outcomes.txt b/src/core/state_res/outcomes.txt similarity index 100% rename from src/core/matrix/state_res/outcomes.txt rename to src/core/state_res/outcomes.txt diff --git a/src/core/matrix/state_res/power_levels.rs b/src/core/state_res/power_levels.rs similarity index 99% rename from src/core/matrix/state_res/power_levels.rs rename to src/core/state_res/power_levels.rs index 19ba8fb9..045b1666 100644 --- a/src/core/matrix/state_res/power_levels.rs +++ b/src/core/state_res/power_levels.rs @@ -11,9 +11,9 @@ use ruma::{ }; use serde::Deserialize; use serde_json::{Error, from_str as from_json_str}; +use tracing::error; use super::{Result, RoomVersion}; -use crate::error; #[derive(Deserialize)] struct IntRoomPowerLevelsEventContent { diff --git a/src/core/matrix/state_res/room_version.rs b/src/core/state_res/room_version.rs similarity index 100% rename from src/core/matrix/state_res/room_version.rs rename to src/core/state_res/room_version.rs diff --git a/src/core/matrix/event.rs b/src/core/state_res/state_event.rs similarity index 100% rename from src/core/matrix/event.rs rename to src/core/state_res/state_event.rs diff --git a/src/core/matrix/state_res/test_utils.rs b/src/core/state_res/test_utils.rs similarity index 99% rename from src/core/matrix/state_res/test_utils.rs rename to src/core/state_res/test_utils.rs index f2ee4238..d96ee927 100644 --- a/src/core/matrix/state_res/test_utils.rs +++ b/src/core/state_res/test_utils.rs @@ -28,10 +28,7 @@ use serde_json::{ pub(crate) use self::event::PduEvent; use super::auth_types_for_event; -use crate::{ - Result, info, - matrix::{Event, EventTypeExt, StateMap}, -}; +use crate::{Event, EventTypeExt, Result, StateMap, info}; static SERVER_TIMESTAMP: AtomicU64 = AtomicU64::new(0); diff --git a/src/core/utils/future/mod.rs b/src/core/utils/future/mod.rs index 4edd0102..e1d96941 100644 --- a/src/core/utils/future/mod.rs +++ b/src/core/utils/future/mod.rs @@ -1,11 +1,9 @@ mod bool_ext; mod ext_ext; mod option_ext; -mod option_stream; mod try_ext_ext; pub use bool_ext::{BoolExt, and, or}; pub use ext_ext::ExtExt; pub use option_ext::OptionExt; -pub use option_stream::OptionStream; pub use try_ext_ext::TryExtExt; diff --git a/src/core/utils/future/option_ext.rs b/src/core/utils/future/option_ext.rs index 920dd044..d553e5dc 100644 --- a/src/core/utils/future/option_ext.rs +++ b/src/core/utils/future/option_ext.rs @@ -11,14 +11,11 @@ pub trait OptionExt { impl OptionExt for OptionFuture where Fut: Future + Send, - T: Send, { - #[inline] fn is_none_or(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future + Send { self.map(|o| o.as_ref().is_none_or(f)) } - #[inline] fn is_some_and(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future + Send { self.map(|o| o.as_ref().is_some_and(f)) } diff --git a/src/core/utils/future/option_stream.rs b/src/core/utils/future/option_stream.rs deleted file mode 100644 index 81130c87..00000000 --- a/src/core/utils/future/option_stream.rs +++ /dev/null @@ -1,25 +0,0 @@ -use futures::{Future, FutureExt, Stream, StreamExt, future::OptionFuture}; - -use super::super::IterStream; - -pub trait OptionStream { - fn stream(self) -> impl Stream + Send; -} - -impl OptionStream for OptionFuture -where - Fut: Future + Send, - S: Stream + Send, - O: IntoIterator + Send, - ::IntoIter: Send, - T: Send, -{ - #[inline] - fn stream(self) -> impl Stream + Send { - self.map(|opt| opt.map(|(curr, next)| curr.into_iter().stream().chain(next))) - .map(Option::into_iter) - .map(IterStream::stream) - .flatten_stream() - .flatten() - } -} diff --git a/src/core/utils/mod.rs b/src/core/utils/mod.rs index 117fb739..7593990c 100644 --- a/src/core/utils/mod.rs +++ b/src/core/utils/mod.rs @@ -49,10 +49,10 @@ pub fn exchange(state: &mut T, source: T) -> T { std::mem::replace(state, sou #[macro_export] macro_rules! extract_variant { - ( $e:expr_2021, $( $variant:path )|* ) => { + ($e:expr_2021, $variant:path) => { match $e { - $( $variant(value) => Some(value), )* - _ => None, + | $variant(value) => Some(value), + | _ => None, } }; } diff --git a/src/service/admin/grant.rs b/src/service/admin/grant.rs index 6780b7ae..5173987a 100644 --- a/src/service/admin/grant.rs +++ b/src/service/admin/grant.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use conduwuit::{Err, Result, debug_info, debug_warn, error, implement, matrix::pdu::PduBuilder}; +use conduwuit::{Err, Result, debug_info, debug_warn, error, implement}; use ruma::{ RoomId, UserId, events::{ @@ -14,6 +14,8 @@ use ruma::{ }, }; +use crate::pdu::PduBuilder; + /// Invite the user to the conduwuit admin room. /// /// This is equivalent to granting server admin privileges. diff --git a/src/service/federation/execute.rs b/src/service/federation/execute.rs index 97314ffb..63f2ccfb 100644 --- a/src/service/federation/execute.rs +++ b/src/service/federation/execute.rs @@ -69,7 +69,7 @@ where .server .config .forbidden_remote_server_names - .is_match(dest.host()) + .contains(dest) { return Err!(Request(Forbidden(debug_warn!("Federation with {dest} is not allowed.")))); } diff --git a/src/service/media/remote.rs b/src/service/media/remote.rs index cdcb429e..b6c853d2 100644 --- a/src/service/media/remote.rs +++ b/src/service/media/remote.rs @@ -426,13 +426,7 @@ fn check_fetch_authorized(&self, mxc: &Mxc<'_>) -> Result<()> { .server .config .prevent_media_downloads_from - .is_match(mxc.server_name.host()) - || self - .services - .server - .config - .forbidden_remote_server_names - .is_match(mxc.server_name.host()) + .contains(mxc.server_name) { // we'll lie to the client and say the blocked server's media was not found and // log. the client has no way of telling anyways so this is a security bonus. diff --git a/src/service/mod.rs b/src/service/mod.rs index 63a51213..8f4a84b0 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -31,6 +31,7 @@ pub mod users; extern crate conduwuit_core as conduwuit; extern crate conduwuit_database as database; +pub use conduwuit::{PduBuilder, PduCount, PduEvent, pdu}; pub(crate) use service::{Args, Dep, Service}; pub use crate::services::Services; diff --git a/src/service/rooms/event_handler/state_at_incoming.rs b/src/service/rooms/event_handler/state_at_incoming.rs index eb38c2c3..0402ff14 100644 --- a/src/service/rooms/event_handler/state_at_incoming.rs +++ b/src/service/rooms/event_handler/state_at_incoming.rs @@ -5,9 +5,7 @@ use std::{ }; use conduwuit::{ - Result, debug, err, implement, - matrix::{PduEvent, StateMap}, - trace, + PduEvent, Result, StateMap, debug, err, implement, trace, utils::stream::{BroadbandExt, IterStream, ReadyExt, TryBroadbandExt, TryWidebandExt}, }; use futures::{FutureExt, StreamExt, TryFutureExt, TryStreamExt, future::try_join}; diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 97d3df97..086dc6bd 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -1,8 +1,7 @@ use std::{borrow::Borrow, collections::BTreeMap, iter::once, sync::Arc, time::Instant}; use conduwuit::{ - Err, Result, debug, debug_info, err, implement, - matrix::{EventTypeExt, PduEvent, StateKey, state_res}, + Err, EventTypeExt, PduEvent, Result, StateKey, debug, debug_info, err, implement, state_res, trace, utils::stream::{BroadbandExt, ReadyExt}, warn, diff --git a/src/service/rooms/outlier/mod.rs b/src/service/rooms/outlier/mod.rs index 12b56935..a1b0263a 100644 --- a/src/service/rooms/outlier/mod.rs +++ b/src/service/rooms/outlier/mod.rs @@ -1,9 +1,11 @@ use std::sync::Arc; -use conduwuit::{Result, implement, matrix::pdu::PduEvent}; -use conduwuit_database::{Deserialized, Json, Map}; +use conduwuit::{Result, implement}; +use database::{Deserialized, Json, Map}; use ruma::{CanonicalJsonObject, EventId}; +use crate::PduEvent; + pub struct Service { db: Data, } diff --git a/src/service/rooms/read_receipt/mod.rs b/src/service/rooms/read_receipt/mod.rs index 69e859c4..d6239aee 100644 --- a/src/service/rooms/read_receipt/mod.rs +++ b/src/service/rooms/read_receipt/mod.rs @@ -2,11 +2,7 @@ mod data; use std::{collections::BTreeMap, sync::Arc}; -use conduwuit::{ - Result, debug, err, - matrix::pdu::{PduCount, PduId, RawPduId}, - warn, -}; +use conduwuit::{PduCount, PduId, RawPduId, Result, debug, err, warn}; use futures::{Stream, TryFutureExt, try_join}; use ruma::{ OwnedEventId, OwnedUserId, RoomId, UserId, diff --git a/src/service/rooms/short/mod.rs b/src/service/rooms/short/mod.rs index 06ff6493..3980617e 100644 --- a/src/service/rooms/short/mod.rs +++ b/src/service/rooms/short/mod.rs @@ -1,7 +1,7 @@ use std::{borrow::Borrow, fmt::Debug, mem::size_of_val, sync::Arc}; -pub use conduwuit::matrix::pdu::{ShortEventId, ShortId, ShortRoomId, ShortStateKey}; -use conduwuit::{Result, err, implement, matrix::StateKey, utils, utils::IterStream}; +pub use conduwuit::pdu::{ShortEventId, ShortId, ShortRoomId, ShortStateKey}; +use conduwuit::{Result, StateKey, err, implement, utils, utils::IterStream}; use database::{Deserialized, Get, Map, Qry}; use futures::{Stream, StreamExt}; use ruma::{EventId, RoomId, events::StateEventType}; diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index ea9756ba..f51a5e3a 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -121,22 +121,21 @@ pub async fn get_summary_and_children_local( | None => (), // cache miss | Some(None) => return Ok(None), | Some(Some(cached)) => { - let allowed_rooms = cached.summary.allowed_room_ids.iter().map(AsRef::as_ref); - - let is_accessible_child = self.is_accessible_child( - current_room, - &cached.summary.join_rule, - identifier, - allowed_rooms, - ); - - let accessibility = if is_accessible_child.await { - SummaryAccessibility::Accessible(cached.summary.clone()) - } else { - SummaryAccessibility::Inaccessible - }; - - return Ok(Some(accessibility)); + return Ok(Some( + if self + .is_accessible_child( + current_room, + &cached.summary.join_rule, + identifier, + &cached.summary.allowed_room_ids, + ) + .await + { + SummaryAccessibility::Accessible(cached.summary.clone()) + } else { + SummaryAccessibility::Inaccessible + }, + )); }, } @@ -146,11 +145,12 @@ pub async fn get_summary_and_children_local( .collect() .await; - let Ok(summary) = self + let summary = self .get_room_summary(current_room, children_pdus, identifier) .boxed() - .await - else { + .await; + + let Ok(summary) = summary else { return Ok(None); }; @@ -217,19 +217,20 @@ async fn get_summary_and_children_federation( .await; let identifier = Identifier::UserId(user_id); - let allowed_room_ids = summary.allowed_room_ids.iter().map(AsRef::as_ref); - let is_accessible_child = self - .is_accessible_child(current_room, &summary.join_rule, &identifier, allowed_room_ids) + .is_accessible_child( + current_room, + &summary.join_rule, + &identifier, + &summary.allowed_room_ids, + ) .await; - let accessibility = if is_accessible_child { - SummaryAccessibility::Accessible(summary) - } else { - SummaryAccessibility::Inaccessible - }; + if is_accessible_child { + return Ok(Some(SummaryAccessibility::Accessible(summary))); + } - Ok(Some(accessibility)) + Ok(Some(SummaryAccessibility::Inaccessible)) } /// Simply returns the stripped m.space.child events of a room @@ -304,15 +305,14 @@ async fn get_room_summary( children_state: Vec>, identifier: &Identifier<'_>, ) -> Result { - let join_rule = self.services.state_accessor.get_join_rules(room_id).await; + let (join_rule, allowed_room_ids) = self + .services + .state_accessor + .get_space_join_rule(room_id) + .await; let is_accessible_child = self - .is_accessible_child( - room_id, - &join_rule.clone().into(), - identifier, - join_rule.allowed_rooms(), - ) + .is_accessible_child(room_id, &join_rule, identifier, &allowed_room_ids) .await; if !is_accessible_child { @@ -379,7 +379,7 @@ async fn get_room_summary( encryption, ); - let summary = SpaceHierarchyParentSummary { + Ok(SpaceHierarchyParentSummary { canonical_alias, name, topic, @@ -388,29 +388,24 @@ async fn get_room_summary( avatar_url, room_type, children_state, - encryption, - room_version, + allowed_room_ids, + join_rule, room_id: room_id.to_owned(), num_joined_members: num_joined_members.try_into().unwrap_or_default(), - allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(), - join_rule: join_rule.clone().into(), - }; - - Ok(summary) + encryption, + room_version, + }) } /// With the given identifier, checks if a room is accessable #[implement(Service)] -async fn is_accessible_child<'a, I>( +async fn is_accessible_child( &self, current_room: &RoomId, join_rule: &SpaceRoomJoinRule, identifier: &Identifier<'_>, - allowed_rooms: I, -) -> bool -where - I: Iterator + Send, -{ + allowed_room_ids: &[OwnedRoomId], +) -> bool { if let Identifier::ServerName(server_name) = identifier { // Checks if ACLs allow for the server to participate if self @@ -435,18 +430,21 @@ where } } - match *join_rule { + match join_rule { | SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Knock | SpaceRoomJoinRule::KnockRestricted => true, | SpaceRoomJoinRule::Restricted => - allowed_rooms + allowed_room_ids + .iter() .stream() - .any(async |room| match identifier { - | Identifier::UserId(user) => - self.services.state_cache.is_joined(user, room).await, - | Identifier::ServerName(server) => - self.services.state_cache.server_in_room(server, room).await, + .any(|room| async { + match identifier { + | Identifier::UserId(user) => + self.services.state_cache.is_joined(user, room).await, + | Identifier::ServerName(server) => + self.services.state_cache.server_in_room(server, room).await, + } }) .await, diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index f719fc7b..7fff5935 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -9,7 +9,7 @@ use async_trait::async_trait; use conduwuit::{Result, err}; use database::Map; use ruma::{ - EventEncryptionAlgorithm, JsOption, OwnedRoomAliasId, RoomId, UserId, + EventEncryptionAlgorithm, JsOption, OwnedRoomAliasId, OwnedRoomId, RoomId, UserId, events::{ StateEventType, room::{ @@ -19,13 +19,14 @@ use ruma::{ encryption::RoomEncryptionEventContent, guest_access::{GuestAccess, RoomGuestAccessEventContent}, history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent}, - join_rules::{JoinRule, RoomJoinRulesEventContent}, + join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent, RoomMembership}, member::RoomMemberEventContent, name::RoomNameEventContent, topic::RoomTopicEventContent, }, }, room::RoomType, + space::SpaceRoomJoinRule, }; use crate::{Dep, rooms}; @@ -128,12 +129,42 @@ impl Service { .map(|c: RoomTopicEventContent| c.topic) } + /// Returns the space join rule (`SpaceRoomJoinRule`) for a given room and + /// any allowed room IDs if available. Will default to Invite and empty vec + /// if doesnt exist or invalid, + pub async fn get_space_join_rule( + &self, + room_id: &RoomId, + ) -> (SpaceRoomJoinRule, Vec) { + self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "") + .await + .map_or_else( + |_| (SpaceRoomJoinRule::Invite, vec![]), + |c: RoomJoinRulesEventContent| { + (c.join_rule.clone().into(), self.allowed_room_ids(c.join_rule)) + }, + ) + } + /// Returns the join rules for a given room (`JoinRule` type). Will default /// to Invite if doesnt exist or invalid pub async fn get_join_rules(&self, room_id: &RoomId) -> JoinRule { self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "") .await - .map_or(JoinRule::Invite, |c: RoomJoinRulesEventContent| c.join_rule) + .map_or_else(|_| JoinRule::Invite, |c: RoomJoinRulesEventContent| (c.join_rule)) + } + + /// Returns an empty vec if not a restricted room + pub fn allowed_room_ids(&self, join_rule: JoinRule) -> Vec { + let mut room_ids = Vec::with_capacity(1); // restricted rooms generally only have 1 allowed room ID + if let JoinRule::Restricted(r) | JoinRule::KnockRestricted(r) = join_rule { + for rule in r.allow { + if let AllowRule::RoomMembership(RoomMembership { room_id: membership }) = rule { + room_ids.push(membership.clone()); + } + } + } + room_ids } pub async fn get_room_type(&self, room_id: &RoomId) -> Result { diff --git a/src/service/rooms/state_accessor/room_state.rs b/src/service/rooms/state_accessor/room_state.rs index 89fa2a83..642cd5d2 100644 --- a/src/service/rooms/state_accessor/room_state.rs +++ b/src/service/rooms/state_accessor/room_state.rs @@ -1,9 +1,6 @@ use std::borrow::Borrow; -use conduwuit::{ - Result, err, implement, - matrix::{PduEvent, StateKey}, -}; +use conduwuit::{PduEvent, Result, StateKey, err, implement}; use futures::{Stream, StreamExt, TryFutureExt}; use ruma::{EventId, RoomId, events::StateEventType}; use serde::Deserialize; diff --git a/src/service/rooms/state_accessor/state.rs b/src/service/rooms/state_accessor/state.rs index 169e69e9..8f2dd76f 100644 --- a/src/service/rooms/state_accessor/state.rs +++ b/src/service/rooms/state_accessor/state.rs @@ -1,15 +1,13 @@ use std::{borrow::Borrow, ops::Deref, sync::Arc}; use conduwuit::{ - Result, at, err, implement, - matrix::{PduEvent, StateKey}, - pair_of, + PduEvent, Result, StateKey, at, err, implement, pair_of, utils::{ result::FlatOk, stream::{BroadbandExt, IterStream, ReadyExt, TryIgnore}, }, }; -use conduwuit_database::Deserialized; +use database::Deserialized; use futures::{FutureExt, Stream, StreamExt, TryFutureExt, future::try_join, pin_mut}; use ruma::{ EventId, OwnedEventId, UserId, diff --git a/src/service/rooms/threads/mod.rs b/src/service/rooms/threads/mod.rs index a680df55..7f9a7515 100644 --- a/src/service/rooms/threads/mod.rs +++ b/src/service/rooms/threads/mod.rs @@ -1,14 +1,13 @@ use std::{collections::BTreeMap, sync::Arc}; use conduwuit::{ - Result, err, - matrix::pdu::{PduCount, PduEvent, PduId, RawPduId}, + PduCount, PduEvent, PduId, RawPduId, Result, err, utils::{ ReadyExt, stream::{TryIgnore, WidebandExt}, }, }; -use conduwuit_database::{Deserialized, Map}; +use database::{Deserialized, Map}; use futures::{Stream, StreamExt}; use ruma::{ CanonicalJsonValue, EventId, OwnedUserId, RoomId, UserId, diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 947e1c38..dc359d22 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -10,19 +10,16 @@ use std::{ }; use async_trait::async_trait; -pub use conduwuit::matrix::pdu::{PduId, RawPduId}; use conduwuit::{ Err, Error, Result, Server, at, debug, debug_warn, err, error, implement, info, - matrix::{ - Event, - pdu::{EventHash, PduBuilder, PduCount, PduEvent, gen_event_id}, - state_res::{self, RoomVersion}, - }, + pdu::{EventHash, PduBuilder, PduCount, PduEvent, gen_event_id}, + state_res::{self, Event, RoomVersion}, utils::{ self, IterStream, MutexMap, MutexMapGuard, ReadyExt, future::TryExtExt, stream::TryIgnore, }, validated, warn, }; +pub use conduwuit::{PduId, RawPduId}; use futures::{ Future, FutureExt, Stream, StreamExt, TryStreamExt, future, future::ready, pin_mut, }; diff --git a/tests/test_results/complement/test_results.jsonl b/tests/test_results/complement/test_results.jsonl index 97c2e1b1..c0e28750 100644 --- a/tests/test_results/complement/test_results.jsonl +++ b/tests/test_results/complement/test_results.jsonl @@ -491,7 +491,7 @@ {"Action":"fail","Test":"TestRoomCreationReportsEventsToMyself"} {"Action":"fail","Test":"TestRoomCreationReportsEventsToMyself/parallel"} {"Action":"pass","Test":"TestRoomCreationReportsEventsToMyself/parallel/Joining_room_twice_is_idempotent"} -{"Action":"fail","Test":"TestRoomCreationReportsEventsToMyself/parallel/Room_creation_reports_m.room.create_to_myself"} +{"Action":"pass","Test":"TestRoomCreationReportsEventsToMyself/parallel/Room_creation_reports_m.room.create_to_myself"} {"Action":"pass","Test":"TestRoomCreationReportsEventsToMyself/parallel/Room_creation_reports_m.room.member_to_myself"} {"Action":"pass","Test":"TestRoomCreationReportsEventsToMyself/parallel/Setting_room_topic_reports_m.room.topic_to_myself"} {"Action":"fail","Test":"TestRoomCreationReportsEventsToMyself/parallel/Setting_state_twice_is_idempotent"} @@ -527,17 +527,17 @@ {"Action":"pass","Test":"TestRoomMessagesLazyLoadingLocalUser"} {"Action":"pass","Test":"TestRoomReadMarkers"} {"Action":"pass","Test":"TestRoomReceipts"} -{"Action":"pass","Test":"TestRoomSpecificUsernameAtJoin"} -{"Action":"pass","Test":"TestRoomSpecificUsernameAtJoin/Bob_can_find_Alice_by_mxid"} -{"Action":"pass","Test":"TestRoomSpecificUsernameAtJoin/Bob_can_find_Alice_by_profile_display_name"} -{"Action":"pass","Test":"TestRoomSpecificUsernameAtJoin/Eve_can_find_Alice_by_mxid"} -{"Action":"pass","Test":"TestRoomSpecificUsernameAtJoin/Eve_can_find_Alice_by_profile_display_name"} +{"Action":"fail","Test":"TestRoomSpecificUsernameAtJoin"} +{"Action":"fail","Test":"TestRoomSpecificUsernameAtJoin/Bob_can_find_Alice_by_mxid"} +{"Action":"fail","Test":"TestRoomSpecificUsernameAtJoin/Bob_can_find_Alice_by_profile_display_name"} +{"Action":"fail","Test":"TestRoomSpecificUsernameAtJoin/Eve_can_find_Alice_by_mxid"} +{"Action":"fail","Test":"TestRoomSpecificUsernameAtJoin/Eve_can_find_Alice_by_profile_display_name"} {"Action":"pass","Test":"TestRoomSpecificUsernameAtJoin/Eve_cannot_find_Alice_by_room-specific_name_that_Eve_is_not_privy_to"} -{"Action":"pass","Test":"TestRoomSpecificUsernameChange"} -{"Action":"pass","Test":"TestRoomSpecificUsernameChange/Bob_can_find_Alice_by_mxid"} -{"Action":"pass","Test":"TestRoomSpecificUsernameChange/Bob_can_find_Alice_by_profile_display_name"} -{"Action":"pass","Test":"TestRoomSpecificUsernameChange/Eve_can_find_Alice_by_mxid"} -{"Action":"pass","Test":"TestRoomSpecificUsernameChange/Eve_can_find_Alice_by_profile_display_name"} +{"Action":"fail","Test":"TestRoomSpecificUsernameChange"} +{"Action":"fail","Test":"TestRoomSpecificUsernameChange/Bob_can_find_Alice_by_mxid"} +{"Action":"fail","Test":"TestRoomSpecificUsernameChange/Bob_can_find_Alice_by_profile_display_name"} +{"Action":"fail","Test":"TestRoomSpecificUsernameChange/Eve_can_find_Alice_by_mxid"} +{"Action":"fail","Test":"TestRoomSpecificUsernameChange/Eve_can_find_Alice_by_profile_display_name"} {"Action":"pass","Test":"TestRoomSpecificUsernameChange/Eve_cannot_find_Alice_by_room-specific_name_that_Eve_is_not_privy_to"} {"Action":"fail","Test":"TestRoomState"} {"Action":"fail","Test":"TestRoomState/Parallel"} @@ -589,7 +589,7 @@ {"Action":"fail","Test":"TestSync/parallel/Newly_joined_room_has_correct_timeline_in_incremental_sync"} {"Action":"fail","Test":"TestSync/parallel/Newly_joined_room_includes_presence_in_incremental_sync"} {"Action":"pass","Test":"TestSync/parallel/Newly_joined_room_is_included_in_an_incremental_sync"} -{"Action":"pass","Test":"TestSync/parallel/sync_should_succeed_even_if_the_sync_token_points_to_a_redaction_of_an_unknown_event"} +{"Action":"fail","Test":"TestSync/parallel/sync_should_succeed_even_if_the_sync_token_points_to_a_redaction_of_an_unknown_event"} {"Action":"pass","Test":"TestSyncFilter"} {"Action":"pass","Test":"TestSyncFilter/Can_create_filter"} {"Action":"pass","Test":"TestSyncFilter/Can_download_filter"}