From 933868b7325e1202081c9526d9fd783171442690 Mon Sep 17 00:00:00 2001 From: strawberry Date: Sun, 15 Dec 2024 00:05:47 -0500 Subject: [PATCH] apply new rustfmt.toml changes, fix some clippy lints Signed-off-by: strawberry --- .editorconfig | 1 + clippy.toml | 6 +- rustfmt.toml | 12 +- src/admin/admin.rs | 30 +- src/admin/appservice/commands.rs | 36 +- src/admin/check/commands.rs | 5 +- src/admin/check/mod.rs | 7 +- src/admin/debug/commands.rs | 229 +++++--- src/admin/federation/commands.rs | 33 +- src/admin/media/commands.rs | 121 +++-- src/admin/processor.rs | 41 +- src/admin/query/account_data.rs | 17 +- src/admin/query/appservice.rs | 11 +- src/admin/query/globals.rs | 15 +- src/admin/query/mod.rs | 5 +- src/admin/query/presence.rs | 13 +- src/admin/query/pusher.rs | 9 +- src/admin/query/resolver.rs | 23 +- src/admin/query/room_alias.rs | 15 +- src/admin/query/room_state_cache.rs | 71 +-- src/admin/query/sending.rs | 87 +-- src/admin/query/users.rs | 54 +- src/admin/room/alias.rs | 147 +++--- src/admin/room/commands.rs | 12 +- src/admin/room/directory.rs | 21 +- src/admin/room/info.rs | 6 +- src/admin/room/mod.rs | 3 +- src/admin/room/moderation.rs | 215 +++++--- src/admin/server/commands.rs | 34 +- src/admin/user/commands.rs | 177 ++++--- src/admin/utils.rs | 10 +- src/api/client/account.rs | 201 ++++--- src/api/client/account_data.rs | 49 +- src/api/client/alias.rs | 17 +- src/api/client/appservice.rs | 14 +- src/api/client/backup.rs | 75 +-- src/api/client/capabilities.rs | 22 +- src/api/client/context.rs | 21 +- src/api/client/device.rs | 31 +- src/api/client/directory.rs | 80 ++- src/api/client/filter.rs | 6 +- src/api/client/keys.rs | 87 +-- src/api/client/media.rs | 46 +- src/api/client/media_legacy.rs | 83 ++- src/api/client/membership.rs | 496 +++++++++++------- src/api/client/message.rs | 54 +- src/api/client/openid.rs | 3 +- src/api/client/presence.rs | 16 +- src/api/client/profile.rs | 94 ++-- src/api/client/push.rs | 135 ++--- src/api/client/read_marker.rs | 40 +- src/api/client/redact.rs | 11 +- src/api/client/relations.rs | 46 +- src/api/client/report.rs | 32 +- src/api/client/room/aliases.rs | 3 +- src/api/client/room/create.rs | 198 ++++--- src/api/client/room/event.rs | 7 +- src/api/client/room/initial_sync.rs | 3 +- src/api/client/room/upgrade.rs | 46 +- src/api/client/search.rs | 20 +- src/api/client/send.rs | 24 +- src/api/client/session.rs | 74 ++- src/api/client/space.rs | 3 +- src/api/client/state.rs | 74 ++- src/api/client/sync/mod.rs | 13 +- src/api/client/sync/v3.rs | 274 ++++++---- src/api/client/sync/v4.rs | 370 +++++++------ src/api/client/tag.rs | 25 +- src/api/client/thirdparty.rs | 4 +- src/api/client/threads.rs | 3 +- src/api/client/to_device.rs | 29 +- src/api/client/typing.rs | 3 +- src/api/client/unstable.rs | 64 ++- src/api/client/unversioned.rs | 4 +- src/api/client/user_directory.rs | 14 +- src/api/client/voip.rs | 6 +- src/api/client/well_known.rs | 41 +- src/api/router.rs | 13 +- src/api/router/args.rs | 31 +- src/api/router/auth.rs | 137 +++-- src/api/router/handler.rs | 18 +- src/api/router/request.rs | 16 +- src/api/router/state.rs | 4 +- src/api/server/backfill.rs | 3 +- src/api/server/event.rs | 3 +- src/api/server/event_auth.rs | 11 +- src/api/server/get_missing_events.rs | 7 +- src/api/server/hierarchy.rs | 3 +- src/api/server/invite.rs | 14 +- src/api/server/key.rs | 8 +- src/api/server/make_join.rs | 65 ++- src/api/server/make_leave.rs | 8 +- src/api/server/media.rs | 12 +- src/api/server/openid.rs | 3 +- src/api/server/publicrooms.rs | 14 +- src/api/server/query.rs | 19 +- src/api/server/send.rs | 131 +++-- src/api/server/send_join.rs | 65 ++- src/api/server/send_leave.rs | 13 +- src/api/server/state.rs | 8 +- src/api/server/state_ids.rs | 8 +- src/api/server/user.rs | 19 +- src/api/server/utils.rs | 9 +- src/api/server/well_known.rs | 7 +- src/core/alloc/je.rs | 5 +- src/core/alloc/mod.rs | 16 +- src/core/config/check.rs | 97 ++-- src/core/config/mod.rs | 87 +-- src/core/config/proxy.rs | 40 +- src/core/debug.rs | 8 +- src/core/error/err.rs | 7 +- src/core/error/log.rs | 24 +- src/core/error/mod.rs | 35 +- src/core/error/panic.rs | 12 +- src/core/error/response.rs | 34 +- src/core/info/cargo.rs | 13 +- src/core/info/room_version.rs | 4 +- src/core/log/capture/layer.rs | 14 +- src/core/log/capture/mod.rs | 4 +- src/core/log/capture/state.rs | 6 +- src/core/log/color.rs | 20 +- src/core/log/fmt.rs | 3 +- src/core/log/fmt_span.rs | 16 +- src/core/log/suppress.rs | 5 +- src/core/metrics/mod.rs | 4 +- src/core/pdu/builder.rs | 6 +- src/core/pdu/count.rs | 44 +- src/core/pdu/event.rs | 12 +- src/core/pdu/event_id.rs | 8 +- src/core/pdu/filter.rs | 4 +- src/core/pdu/mod.rs | 3 +- src/core/pdu/raw_id.rs | 22 +- src/core/pdu/redact.rs | 8 +- src/core/pdu/strip.rs | 6 +- src/core/pdu/unsigned.rs | 8 +- src/core/server.rs | 10 +- src/core/utils/bool.rs | 12 +- src/core/utils/bytes.rs | 4 +- src/core/utils/content_disposition.rs | 32 +- src/core/utils/debug.rs | 8 +- src/core/utils/defer.rs | 4 +- src/core/utils/future/try_ext_ext.rs | 46 +- src/core/utils/hash/argon.rs | 4 +- src/core/utils/html.rs | 12 +- src/core/utils/json.rs | 16 +- src/core/utils/math.rs | 14 +- src/core/utils/mod.rs | 4 +- src/core/utils/mutex_map.rs | 7 +- src/core/utils/result.rs | 6 +- src/core/utils/result/flat_ok.rs | 8 +- src/core/utils/result/log_err.rs | 4 +- src/core/utils/set.rs | 4 +- src/core/utils/stream/expect.rs | 8 +- src/core/utils/stream/ignore.rs | 8 +- src/core/utils/stream/iter_stream.rs | 13 +- src/core/utils/stream/ready.rs | 87 ++- src/core/utils/stream/tools.rs | 18 +- src/core/utils/stream/try_broadband.rs | 17 +- src/core/utils/stream/try_ready.rs | 48 +- src/core/utils/string/between.rs | 4 +- src/core/utils/string/split.rs | 8 +- src/core/utils/string/unquote.rs | 4 +- src/core/utils/sys.rs | 7 +- src/core/utils/time.rs | 57 +- src/database/cork.rs | 6 +- src/database/database.rs | 9 +- src/database/de.rs | 44 +- src/database/engine.rs | 55 +- src/database/handle.rs | 6 +- src/database/map.rs | 13 +- src/database/map/contains.rs | 11 +- src/database/map/count.rs | 15 +- src/database/map/get.rs | 19 +- src/database/map/get_batch.rs | 13 +- src/database/map/keys_from.rs | 10 +- src/database/map/keys_prefix.rs | 18 +- src/database/map/rev_keys_from.rs | 20 +- src/database/map/rev_keys_prefix.rs | 18 +- src/database/map/rev_stream_from.rs | 16 +- src/database/map/rev_stream_prefix.rs | 14 +- src/database/map/stream_from.rs | 18 +- src/database/map/stream_prefix.rs | 14 +- src/database/opts.rs | 123 +++-- src/database/pool.rs | 12 +- src/database/ser.rs | 113 ++-- src/database/stream/items.rs | 16 +- src/database/stream/items_rev.rs | 16 +- src/database/stream/keys.rs | 16 +- src/database/stream/keys_rev.rs | 16 +- src/database/tests.rs | 24 +- src/database/util.rs | 8 +- src/database/watchers.rs | 9 +- src/macros/admin.rs | 6 +- src/macros/config.rs | 87 +-- src/macros/implement.rs | 11 +- src/macros/refutable.rs | 12 +- src/macros/rustc.rs | 4 +- src/macros/utils.rs | 16 +- src/main/logging.rs | 30 +- src/main/main.rs | 4 +- src/main/mods.rs | 4 +- src/main/server.rs | 23 +- src/router/layers.rs | 20 +- src/router/mod.rs | 12 +- src/router/request.rs | 8 +- src/router/run.rs | 24 +- src/router/serve/mod.rs | 4 +- src/router/serve/plain.rs | 8 +- src/router/serve/tls.rs | 14 +- src/router/serve/unix.rs | 21 +- src/service/account_data/mod.rs | 35 +- src/service/admin/console.rs | 23 +- src/service/admin/create.rs | 68 +-- src/service/admin/grant.rs | 30 +- src/service/admin/mod.rs | 49 +- src/service/admin/startup.rs | 6 +- src/service/appservice/mod.rs | 11 +- src/service/appservice/registration_info.rs | 6 +- src/service/client/mod.rs | 14 +- src/service/emergency/mod.rs | 34 +- src/service/globals/data.rs | 4 +- src/service/globals/mod.rs | 93 ++-- src/service/key_backups/mod.rs | 68 ++- src/service/manager.rs | 32 +- src/service/media/data.rs | 69 ++- src/service/media/migrations.rs | 11 +- src/service/media/mod.rs | 91 ++-- src/service/media/preview.rs | 54 +- src/service/media/remote.rs | 189 ++++--- src/service/media/tests.rs | 32 +- src/service/media/thumbnail.rs | 40 +- src/service/migrations.rs | 35 +- src/service/presence/data.rs | 35 +- src/service/presence/mod.rs | 53 +- src/service/presence/presence.rs | 14 +- src/service/pusher/mod.rs | 109 ++-- src/service/resolver/actual.rs | 161 +++--- src/service/resolver/cache.rs | 20 +- src/service/resolver/dns.rs | 19 +- src/service/resolver/fed.rs | 28 +- src/service/rooms/alias/mod.rs | 74 ++- src/service/rooms/alias/remote.rs | 30 +- src/service/rooms/auth_chain/data.rs | 8 +- src/service/rooms/auth_chain/mod.rs | 37 +- src/service/rooms/directory/mod.rs | 8 +- .../fetch_and_handle_outliers.rs | 80 ++- src/service/rooms/event_handler/fetch_prev.rs | 20 +- .../rooms/event_handler/fetch_state.rs | 27 +- .../event_handler/handle_incoming_pdu.rs | 15 +- .../rooms/event_handler/handle_outlier_pdu.rs | 33 +- .../rooms/event_handler/handle_prev_pdu.rs | 22 +- src/service/rooms/event_handler/mod.rs | 14 +- .../rooms/event_handler/parse_incoming_pdu.rs | 15 +- .../rooms/event_handler/resolve_state.rs | 19 +- .../rooms/event_handler/state_at_incoming.rs | 22 +- .../event_handler/upgrade_outlier_pdu.rs | 35 +- src/service/rooms/lazy_loading/mod.rs | 21 +- src/service/rooms/metadata/mod.rs | 16 +- src/service/rooms/pdu_metadata/data.rs | 21 +- src/service/rooms/pdu_metadata/mod.rs | 24 +- src/service/rooms/read_receipt/data.rs | 23 +- src/service/rooms/read_receipt/mod.rs | 71 +-- src/service/rooms/search/mod.rs | 34 +- src/service/rooms/short/mod.rs | 31 +- src/service/rooms/spaces/mod.rs | 200 ++++--- src/service/rooms/spaces/tests.rs | 21 +- src/service/rooms/state/mod.rs | 116 ++-- src/service/rooms/state_accessor/data.rs | 52 +- src/service/rooms/state_accessor/mod.rs | 155 ++++-- src/service/rooms/state_cache/mod.rs | 156 ++++-- src/service/rooms/state_compressor/mod.rs | 134 +++-- src/service/rooms/threads/mod.rs | 25 +- src/service/rooms/timeline/data.rs | 68 ++- src/service/rooms/timeline/mod.rs | 235 ++++++--- src/service/rooms/typing/mod.rs | 26 +- src/service/rooms/user/mod.rs | 13 +- src/service/sending/appservice.rs | 20 +- src/service/sending/data.rs | 50 +- src/service/sending/dest.rs | 6 +- src/service/sending/mod.rs | 56 +- src/service/sending/send.rs | 79 ++- src/service/sending/sender.rs | 183 ++++--- src/service/server_keys/acquire.rs | 47 +- src/service/server_keys/get.rs | 34 +- src/service/server_keys/keypair.rs | 7 +- src/service/server_keys/mod.rs | 13 +- src/service/server_keys/request.rs | 8 +- src/service/server_keys/sign.rs | 6 +- src/service/server_keys/verify.rs | 30 +- src/service/service.rs | 4 +- src/service/sync/mod.rs | 116 ++-- src/service/transaction_ids/mod.rs | 13 +- src/service/uiaa/mod.rs | 67 ++- src/service/updates/mod.rs | 7 +- src/service/users/mod.rs | 231 ++++++-- 295 files changed, 7130 insertions(+), 4286 deletions(-) diff --git a/.editorconfig b/.editorconfig index b2455005b..2d7438a4a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -21,3 +21,4 @@ indent_size = 2 [*.rs] indent_style = tab +max_line_length = 98 diff --git a/clippy.toml b/clippy.toml index 3a0aa6958..d9dd99cad 100644 --- a/clippy.toml +++ b/clippy.toml @@ -3,7 +3,7 @@ cognitive-complexity-threshold = 94 # TODO reduce me ALARA excessive-nesting-threshold = 11 # TODO reduce me to 4 or 5 future-size-threshold = 7745 # TODO reduce me ALARA stack-size-threshold = 196608 # reduce me ALARA -too-many-lines-threshold = 700 # TODO reduce me to <= 100 +too-many-lines-threshold = 780 # TODO reduce me to <= 100 type-complexity-threshold = 250 # reduce me to ~200 disallowed-macros = [ @@ -13,3 +13,7 @@ disallowed-macros = [ { path = "log::debug", reason = "use conduwuit_core::debug" }, { path = "log::trace", reason = "use conduwuit_core::trace" }, ] + +disallowed-methods = [ + { path = "tokio::spawn", reason = "use and pass conduuwit_core::server::Server::runtime() to spawn from"}, +] diff --git a/rustfmt.toml b/rustfmt.toml index fd912a193..635ec8f80 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -2,9 +2,8 @@ array_width = 80 chain_width = 60 comment_width = 80 condense_wildcard_suffixes = true -edition = "2021" +edition = "2024" fn_call_width = 80 -fn_params_layout = "Compressed" fn_single_line = true format_code_in_doc_comments = true format_macro_bodies = true @@ -14,13 +13,20 @@ group_imports = "StdExternalCrate" hard_tabs = true hex_literal_case = "Upper" imports_granularity = "Crate" +match_arm_blocks = false +match_arm_leading_pipes = "Always" match_block_trailing_comma = true -max_width = 120 +max_width = 98 newline_style = "Unix" normalize_comments = false +overflow_delimited_expr = true reorder_impl_items = true reorder_imports = true +single_line_if_else_max_width = 60 +single_line_let_else_max_width = 80 +struct_lit_width = 40 tab_spaces = 4 +unstable_features = true use_field_init_shorthand = true use_small_heuristics = "Off" use_try_shorthand = true diff --git a/src/admin/admin.rs b/src/admin/admin.rs index 7b7074467..9097a6137 100644 --- a/src/admin/admin.rs +++ b/src/admin/admin.rs @@ -3,9 +3,10 @@ use conduwuit::Result; use ruma::events::room::message::RoomMessageEventContent; use crate::{ - appservice, appservice::AppserviceCommand, check, check::CheckCommand, command::Command, debug, - debug::DebugCommand, federation, federation::FederationCommand, media, media::MediaCommand, query, - query::QueryCommand, room, room::RoomCommand, server, server::ServerCommand, user, user::UserCommand, + appservice, appservice::AppserviceCommand, check, check::CheckCommand, command::Command, + debug, debug::DebugCommand, federation, federation::FederationCommand, media, + media::MediaCommand, query, query::QueryCommand, room, room::RoomCommand, server, + server::ServerCommand, user, user::UserCommand, }; #[derive(Debug, Parser)] @@ -49,18 +50,21 @@ pub(super) enum AdminCommand { } #[tracing::instrument(skip_all, name = "command")] -pub(super) async fn process(command: AdminCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + command: AdminCommand, + context: &Command<'_>, +) -> Result { use AdminCommand::*; Ok(match command { - Appservices(command) => appservice::process(command, context).await?, - Media(command) => media::process(command, context).await?, - Users(command) => user::process(command, context).await?, - Rooms(command) => room::process(command, context).await?, - Federation(command) => federation::process(command, context).await?, - Server(command) => server::process(command, context).await?, - Debug(command) => debug::process(command, context).await?, - Query(command) => query::process(command, context).await?, - Check(command) => check::process(command, context).await?, + | Appservices(command) => appservice::process(command, context).await?, + | Media(command) => media::process(command, context).await?, + | Users(command) => user::process(command, context).await?, + | Rooms(command) => room::process(command, context).await?, + | Federation(command) => federation::process(command, context).await?, + | Server(command) => server::process(command, context).await?, + | Debug(command) => debug::process(command, context).await?, + | Query(command) => query::process(command, context).await?, + | Check(command) => check::process(command, context).await?, }) } diff --git a/src/admin/appservice/commands.rs b/src/admin/appservice/commands.rs index 6d661308b..4f02531a9 100644 --- a/src/admin/appservice/commands.rs +++ b/src/admin/appservice/commands.rs @@ -4,7 +4,9 @@ use crate::{admin_command, Result}; #[admin_command] pub(super) async fn register(&self) -> Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -14,55 +16,63 @@ pub(super) async fn register(&self) -> Result { let appservice_config_body = self.body[1..self.body.len().checked_sub(1).unwrap()].join("\n"); let parsed_config = serde_yaml::from_str::(&appservice_config_body); match parsed_config { - Ok(registration) => match self + | Ok(registration) => match self .services .appservice .register_appservice(®istration, &appservice_config_body) .await { - Ok(()) => Ok(RoomMessageEventContent::text_plain(format!( + | Ok(()) => Ok(RoomMessageEventContent::text_plain(format!( "Appservice registered with ID: {}", registration.id ))), - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Failed to register appservice: {e}" ))), }, - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Could not parse appservice config as YAML: {e}" ))), } } #[admin_command] -pub(super) async fn unregister(&self, appservice_identifier: String) -> Result { +pub(super) async fn unregister( + &self, + appservice_identifier: String, +) -> Result { match self .services .appservice .unregister_appservice(&appservice_identifier) .await { - Ok(()) => Ok(RoomMessageEventContent::text_plain("Appservice unregistered.")), - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Ok(()) => Ok(RoomMessageEventContent::text_plain("Appservice unregistered.")), + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Failed to unregister appservice: {e}" ))), } } #[admin_command] -pub(super) async fn show_appservice_config(&self, appservice_identifier: String) -> Result { +pub(super) async fn show_appservice_config( + &self, + appservice_identifier: String, +) -> Result { match self .services .appservice .get_registration(&appservice_identifier) .await { - Some(config) => { - let config_str = serde_yaml::to_string(&config).expect("config should've been validated on register"); - let output = format!("Config for {appservice_identifier}:\n\n```yaml\n{config_str}\n```",); + | Some(config) => { + let config_str = serde_yaml::to_string(&config) + .expect("config should've been validated on register"); + let output = + format!("Config for {appservice_identifier}:\n\n```yaml\n{config_str}\n```",); Ok(RoomMessageEventContent::notice_markdown(output)) }, - None => Ok(RoomMessageEventContent::text_plain("Appservice does not exist.")), + | None => Ok(RoomMessageEventContent::text_plain("Appservice does not exist.")), } } diff --git a/src/admin/check/commands.rs b/src/admin/check/commands.rs index ecb18c1a0..7e27362f0 100644 --- a/src/admin/check/commands.rs +++ b/src/admin/check/commands.rs @@ -19,8 +19,9 @@ pub(super) async fn check_all_users(&self) -> Result { let ok_count = users.iter().filter(|_user| true).count(); let message = format!( - "Database query completed in {query_time:?}:\n\n```\nTotal entries: {total:?}\nFailure/Invalid user count: \ - {err_count:?}\nSuccess/Valid user count: {ok_count:?}\n```" + "Database query completed in {query_time:?}:\n\n```\nTotal entries: \ + {total:?}\nFailure/Invalid user count: {err_count:?}\nSuccess/Valid user count: \ + {ok_count:?}\n```" ); Ok(RoomMessageEventContent::notice_markdown(message)) diff --git a/src/admin/check/mod.rs b/src/admin/check/mod.rs index 44b1ddf28..4790a6dec 100644 --- a/src/admin/check/mod.rs +++ b/src/admin/check/mod.rs @@ -11,8 +11,11 @@ pub(super) enum CheckCommand { AllUsers, } -pub(super) async fn process(command: CheckCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + command: CheckCommand, + context: &Command<'_>, +) -> Result { Ok(match command { - CheckCommand::AllUsers => context.check_all_users().await?, + | CheckCommand::AllUsers => context.check_all_users().await?, }) } diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index 9d77a1de8..0c5a7cbd4 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -6,7 +6,9 @@ use std::{ time::{Instant, SystemTime}, }; -use conduwuit::{debug_error, err, info, trace, utils, utils::string::EMPTY, warn, Error, PduEvent, Result}; +use conduwuit::{ + debug_error, err, info, trace, utils, utils::string::EMPTY, warn, Error, PduEvent, Result, +}; use futures::{FutureExt, StreamExt}; use ruma::{ api::{client::error::ErrorKind, federation::event::get_room_state}, @@ -26,7 +28,10 @@ pub(super) async fn echo(&self, message: Vec) -> Result) -> Result { +pub(super) async fn get_auth_chain( + &self, + event_id: Box, +) -> Result { let Ok(event) = self.services.rooms.timeline.get_pdu_json(&event_id).await else { return Ok(RoomMessageEventContent::notice_plain("Event not found.")); }; @@ -68,20 +73,26 @@ pub(super) async fn parse_pdu(&self) -> Result { let string = self.body[1..self.body.len().saturating_sub(1)].join("\n"); match serde_json::from_str(&string) { - Ok(value) => match ruma::signatures::reference_hash(&value, &RoomVersionId::V6) { - Ok(hash) => { + | Ok(value) => match ruma::signatures::reference_hash(&value, &RoomVersionId::V6) { + | Ok(hash) => { let event_id = EventId::parse(format!("${hash}")); - match serde_json::from_value::(serde_json::to_value(value).expect("value is json")) { - Ok(pdu) => Ok(RoomMessageEventContent::text_plain(format!("EventId: {event_id:?}\n{pdu:#?}"))), - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + match serde_json::from_value::( + serde_json::to_value(value).expect("value is json"), + ) { + | Ok(pdu) => Ok(RoomMessageEventContent::text_plain(format!( + "EventId: {event_id:?}\n{pdu:#?}" + ))), + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "EventId: {event_id:?}\nCould not parse event: {e}" ))), } }, - Err(e) => Ok(RoomMessageEventContent::text_plain(format!("Could not parse PDU JSON: {e:?}"))), + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + "Could not parse PDU JSON: {e:?}" + ))), }, - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Invalid json in command body: {e}" ))), } @@ -103,8 +114,9 @@ pub(super) async fn get_pdu(&self, event_id: Box) -> Result { - let json_text = serde_json::to_string_pretty(&json).expect("canonical json is valid json"); + | Ok(json) => { + let json_text = + serde_json::to_string_pretty(&json).expect("canonical json is valid json"); Ok(RoomMessageEventContent::notice_markdown(format!( "{}\n```json\n{}\n```", if outlier { @@ -115,13 +127,15 @@ pub(super) async fn get_pdu(&self, event_id: Box) -> Result Ok(RoomMessageEventContent::text_plain("PDU not found locally.")), + | Err(_) => Ok(RoomMessageEventContent::text_plain("PDU not found locally.")), } } #[admin_command] pub(super) async fn get_remote_pdu_list( - &self, server: Box, force: bool, + &self, + server: Box, + force: bool, ) -> Result { if !self.services.globals.config.allow_federation { return Ok(RoomMessageEventContent::text_plain( @@ -131,8 +145,8 @@ pub(super) async fn get_remote_pdu_list( if server == self.services.globals.server_name() { return Ok(RoomMessageEventContent::text_plain( - "Not allowed to send federation requests to ourselves. Please use `get-pdu` for fetching local PDUs from \ - the database.", + "Not allowed to send federation requests to ourselves. Please use `get-pdu` for \ + fetching local PDUs from the database.", )); } @@ -184,7 +198,9 @@ pub(super) async fn get_remote_pdu_list( #[admin_command] pub(super) async fn get_remote_pdu( - &self, event_id: Box, server: Box, + &self, + event_id: Box, + server: Box, ) -> Result { if !self.services.globals.config.allow_federation { return Ok(RoomMessageEventContent::text_plain( @@ -194,30 +210,32 @@ pub(super) async fn get_remote_pdu( if server == self.services.globals.server_name() { return Ok(RoomMessageEventContent::text_plain( - "Not allowed to send federation requests to ourselves. Please use `get-pdu` for fetching local PDUs.", + "Not allowed to send federation requests to ourselves. Please use `get-pdu` for \ + fetching local PDUs.", )); } match self .services .sending - .send_federation_request( - &server, - ruma::api::federation::event::get_event::v1::Request { - event_id: event_id.clone().into(), - include_unredacted_content: None, - }, - ) + .send_federation_request(&server, ruma::api::federation::event::get_event::v1::Request { + event_id: event_id.clone().into(), + include_unredacted_content: None, + }) .await { - Ok(response) => { - let json: CanonicalJsonObject = serde_json::from_str(response.pdu.get()).map_err(|e| { - warn!( - "Requested event ID {event_id} from server but failed to convert from RawValue to \ - CanonicalJsonObject (malformed event/response?): {e}" - ); - Error::BadRequest(ErrorKind::Unknown, "Received response from server but failed to parse PDU") - })?; + | Ok(response) => { + let json: CanonicalJsonObject = + serde_json::from_str(response.pdu.get()).map_err(|e| { + warn!( + "Requested event ID {event_id} from server but failed to convert from \ + RawValue to CanonicalJsonObject (malformed event/response?): {e}" + ); + Error::BadRequest( + ErrorKind::Unknown, + "Received response from server but failed to parse PDU", + ) + })?; trace!("Attempting to parse PDU: {:?}", &response.pdu); let _parsed_pdu = { @@ -229,8 +247,8 @@ pub(super) async fn get_remote_pdu( .await; let (event_id, value, room_id) = match parsed_result { - Ok(t) => t, - Err(e) => { + | Ok(t) => t, + | Err(e) => { warn!("Failed to parse PDU: {e}"); info!("Full PDU: {:?}", &response.pdu); return Ok(RoomMessageEventContent::text_plain(format!( @@ -250,21 +268,27 @@ pub(super) async fn get_remote_pdu( .boxed() .await?; - let json_text = serde_json::to_string_pretty(&json).expect("canonical json is valid json"); + let json_text = + serde_json::to_string_pretty(&json).expect("canonical json is valid json"); Ok(RoomMessageEventContent::notice_markdown(format!( "{}\n```json\n{}\n```", - "Got PDU from specified server and handled as backfilled PDU successfully. Event body:", json_text + "Got PDU from specified server and handled as backfilled PDU successfully. \ + Event body:", + json_text ))) }, - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Remote server did not have PDU or failed sending request to remote server: {e}" ))), } } #[admin_command] -pub(super) async fn get_room_state(&self, room: OwnedRoomOrAliasId) -> Result { +pub(super) async fn get_room_state( + &self, + room: OwnedRoomOrAliasId, +) -> Result { let room_id = self.services.rooms.alias.resolve(&room).await?; let room_state: Vec<_> = self .services @@ -285,7 +309,8 @@ pub(super) async fn get_room_state(&self, room: OwnedRoomOrAliasId) -> Result) -> Result { + | Ok(response) => { let ping_time = timer.elapsed(); let json_text_res = serde_json::to_string_pretty(&response.server); @@ -323,8 +351,11 @@ pub(super) async fn ping(&self, server: Box) -> Result { - warn!("Failed sending federation request to specified server from ping debug command: {e}"); + | Err(e) => { + warn!( + "Failed sending federation request to specified server from ping debug command: \ + {e}" + ); Ok(RoomMessageEventContent::text_plain(format!( "Failed sending federation request to specified server:\n\n{e}", ))) @@ -347,13 +378,17 @@ pub(super) async fn force_device_list_updates(&self) -> Result, reset: bool) -> Result { +pub(super) async fn change_log_level( + &self, + filter: Option, + reset: bool, +) -> Result { let handles = &["console"]; if reset { let old_filter_layer = match EnvFilter::try_new(&self.services.globals.config.log) { - Ok(s) => s, - Err(e) => { + | Ok(s) => s, + | Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( "Log level from config appears to be invalid now: {e}" ))); @@ -367,13 +402,13 @@ pub(super) async fn change_log_level(&self, filter: Option, reset: bool) .reload .reload(&old_filter_layer, Some(handles)) { - Ok(()) => { + | Ok(()) => { return Ok(RoomMessageEventContent::text_plain(format!( "Successfully changed log level back to config value {}", self.services.globals.config.log ))); }, - Err(e) => { + | Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( "Failed to modify and reload the global tracing log level: {e}" ))); @@ -383,8 +418,8 @@ pub(super) async fn change_log_level(&self, filter: Option, reset: bool) if let Some(filter) = filter { let new_filter_layer = match EnvFilter::try_new(filter) { - Ok(s) => s, - Err(e) => { + | Ok(s) => s, + | Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( "Invalid log level filter specified: {e}" ))); @@ -398,10 +433,10 @@ pub(super) async fn change_log_level(&self, filter: Option, reset: bool) .reload .reload(&new_filter_layer, Some(handles)) { - Ok(()) => { + | Ok(()) => { return Ok(RoomMessageEventContent::text_plain("Successfully changed log level")); }, - Err(e) => { + | Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( "Failed to modify and reload the global tracing log level: {e}" ))); @@ -414,7 +449,9 @@ pub(super) async fn change_log_level(&self, filter: Option, reset: bool) #[admin_command] pub(super) async fn sign_json(&self) -> Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -423,21 +460,24 @@ pub(super) async fn sign_json(&self) -> Result { let string = self.body[1..self.body.len().checked_sub(1).unwrap()].join("\n"); match serde_json::from_str(&string) { - Ok(mut value) => { + | Ok(mut value) => { self.services .server_keys .sign_json(&mut value) .expect("our request json is what ruma expects"); - let json_text = serde_json::to_string_pretty(&value).expect("canonical json is valid json"); + let json_text = + serde_json::to_string_pretty(&value).expect("canonical json is valid json"); Ok(RoomMessageEventContent::text_plain(json_text)) }, - Err(e) => Ok(RoomMessageEventContent::text_plain(format!("Invalid json: {e}"))), + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!("Invalid json: {e}"))), } } #[admin_command] pub(super) async fn verify_json(&self) -> Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -446,13 +486,13 @@ pub(super) async fn verify_json(&self) -> Result { let string = self.body[1..self.body.len().checked_sub(1).unwrap()].join("\n"); match serde_json::from_str::(&string) { - Ok(value) => match self.services.server_keys.verify_json(&value, None).await { - Ok(()) => Ok(RoomMessageEventContent::text_plain("Signature correct")), - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Ok(value) => match self.services.server_keys.verify_json(&value, None).await { + | Ok(()) => Ok(RoomMessageEventContent::text_plain("Signature correct")), + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Signature verification failed: {e}" ))), }, - Err(e) => Ok(RoomMessageEventContent::text_plain(format!("Invalid json: {e}"))), + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!("Invalid json: {e}"))), } } @@ -462,9 +502,10 @@ pub(super) async fn verify_pdu(&self, event_id: Box) -> Result "signatures OK, but content hash failed (redaction).", - Ok(ruma::signatures::Verified::All) => "signatures and hashes OK.", - Err(e) => return Err(e), + | Ok(ruma::signatures::Verified::Signatures) => + "signatures OK, but content hash failed (redaction).", + | Ok(ruma::signatures::Verified::All) => "signatures and hashes OK.", + | Err(e) => return Err(e), }; Ok(RoomMessageEventContent::notice_plain(msg)) @@ -472,7 +513,10 @@ pub(super) async fn verify_pdu(&self, event_id: Box) -> Result) -> Result { +pub(super) async fn first_pdu_in_room( + &self, + room_id: Box, +) -> Result { if !self .services .rooms @@ -498,7 +542,10 @@ pub(super) async fn first_pdu_in_room(&self, room_id: Box) -> Result) -> Result { +pub(super) async fn latest_pdu_in_room( + &self, + room_id: Box, +) -> Result { if !self .services .rooms @@ -525,7 +572,9 @@ pub(super) async fn latest_pdu_in_room(&self, room_id: Box) -> Result, server_name: Box, + &self, + room_id: Box, + server_name: Box, ) -> Result { if !self .services @@ -554,13 +603,10 @@ pub(super) async fn force_set_room_state_from_server( let remote_state_response = self .services .sending - .send_federation_request( - &server_name, - get_room_state::v1::Request { - room_id: room_id.clone().into(), - event_id: first_pdu.event_id.clone().into(), - }, - ) + .send_federation_request(&server_name, get_room_state::v1::Request { + room_id: room_id.clone().into(), + event_id: first_pdu.event_id.clone().into(), + }) .await?; for pdu in remote_state_response.pdus.clone() { @@ -571,8 +617,8 @@ pub(super) async fn force_set_room_state_from_server( .parse_incoming_pdu(&pdu) .await { - Ok(t) => t, - Err(e) => { + | Ok(t) => t, + | Err(e) => { warn!("Could not parse PDU, ignoring: {e}"); continue; }, @@ -654,8 +700,8 @@ pub(super) async fn force_set_room_state_from_server( .await?; info!( - "Updating joined counts for room just in case (e.g. we may have found a difference in the room's \ - m.room.member state" + "Updating joined counts for room just in case (e.g. we may have found a difference in \ + the room's m.room.member state" ); self.services .rooms @@ -672,9 +718,13 @@ pub(super) async fn force_set_room_state_from_server( #[admin_command] pub(super) async fn get_signing_keys( - &self, server_name: Option>, notary: Option>, query: bool, + &self, + server_name: Option>, + notary: Option>, + query: bool, ) -> Result { - let server_name = server_name.unwrap_or_else(|| self.services.server.config.server_name.clone().into()); + let server_name = + server_name.unwrap_or_else(|| self.services.server.config.server_name.clone().into()); if let Some(notary) = notary { let signing_keys = self @@ -706,8 +756,12 @@ pub(super) async fn get_signing_keys( } #[admin_command] -pub(super) async fn get_verify_keys(&self, server_name: Option>) -> Result { - let server_name = server_name.unwrap_or_else(|| self.services.server.config.server_name.clone().into()); +pub(super) async fn get_verify_keys( + &self, + server_name: Option>, +) -> Result { + let server_name = + server_name.unwrap_or_else(|| self.services.server.config.server_name.clone().into()); let keys = self .services @@ -727,7 +781,9 @@ pub(super) async fn get_verify_keys(&self, server_name: Option>) #[admin_command] pub(super) async fn resolve_true_destination( - &self, server_name: Box, no_cache: bool, + &self, + server_name: Box, + no_cache: bool, ) -> Result { if !self.services.globals.config.allow_federation { return Ok(RoomMessageEventContent::text_plain( @@ -737,7 +793,8 @@ pub(super) async fn resolve_true_destination( if server_name == self.services.globals.config.server_name { return Ok(RoomMessageEventContent::text_plain( - "Not allowed to send federation requests to ourselves. Please use `get-pdu` for fetching local PDUs.", + "Not allowed to send federation requests to ourselves. Please use `get-pdu` for \ + fetching local PDUs.", )); } @@ -846,7 +903,9 @@ pub(super) async fn list_dependencies(&self, names: bool) -> Result, map: Option, + &self, + property: Option, + map: Option, ) -> Result { let property = property.unwrap_or_else(|| "rocksdb.stats".to_owned()); let map_name = map.as_ref().map_or(EMPTY, String::as_str); diff --git a/src/admin/federation/commands.rs b/src/admin/federation/commands.rs index e0c1598da..75635b1bf 100644 --- a/src/admin/federation/commands.rs +++ b/src/admin/federation/commands.rs @@ -2,7 +2,9 @@ use std::fmt::Write; use conduwuit::Result; use futures::StreamExt; -use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, RoomId, ServerName, UserId}; +use ruma::{ + events::room::message::RoomMessageEventContent, OwnedRoomId, RoomId, ServerName, UserId, +}; use crate::{admin_command, get_room_info}; @@ -38,7 +40,10 @@ pub(super) async fn incoming_federation(&self) -> Result) -> Result { +pub(super) async fn fetch_support_well_known( + &self, + server_name: Box, +) -> Result { let response = self .services .client @@ -60,16 +65,20 @@ pub(super) async fn fetch_support_well_known(&self, server_name: Box } let json: serde_json::Value = match serde_json::from_str(&text) { - Ok(json) => json, - Err(_) => { - return Ok(RoomMessageEventContent::text_plain("Response text/body is not valid JSON.")); + | Ok(json) => json, + | Err(_) => { + return Ok(RoomMessageEventContent::text_plain( + "Response text/body is not valid JSON.", + )); }, }; let pretty_json: String = match serde_json::to_string_pretty(&json) { - Ok(json) => json, - Err(_) => { - return Ok(RoomMessageEventContent::text_plain("Response text/body is not valid JSON.")); + | Ok(json) => json, + | Err(_) => { + return Ok(RoomMessageEventContent::text_plain( + "Response text/body is not valid JSON.", + )); }, }; @@ -79,10 +88,14 @@ pub(super) async fn fetch_support_well_known(&self, server_name: Box } #[admin_command] -pub(super) async fn remote_user_in_rooms(&self, user_id: Box) -> Result { +pub(super) async fn remote_user_in_rooms( + &self, + user_id: Box, +) -> Result { if user_id.server_name() == self.services.globals.config.server_name { return Ok(RoomMessageEventContent::text_plain( - "User belongs to our server, please use `list-joined-rooms` user admin command instead.", + "User belongs to our server, please use `list-joined-rooms` user admin command \ + instead.", )); } diff --git a/src/admin/media/commands.rs b/src/admin/media/commands.rs index 977ecdaea..3d0a9473e 100644 --- a/src/admin/media/commands.rs +++ b/src/admin/media/commands.rs @@ -1,16 +1,21 @@ use std::time::Duration; -use conduwuit::{debug, debug_info, debug_warn, error, info, trace, utils::time::parse_timepoint_ago, Result}; +use conduwuit::{ + debug, debug_info, debug_warn, error, info, trace, utils::time::parse_timepoint_ago, Result, +}; use conduwuit_service::media::Dim; use ruma::{ - events::room::message::RoomMessageEventContent, EventId, Mxc, MxcUri, OwnedMxcUri, OwnedServerName, ServerName, + events::room::message::RoomMessageEventContent, EventId, Mxc, MxcUri, OwnedMxcUri, + OwnedServerName, ServerName, }; use crate::{admin_command, utils::parse_local_user_id}; #[admin_command] pub(super) async fn delete( - &self, mxc: Option>, event_id: Option>, + &self, + mxc: Option>, + event_id: Option>, ) -> Result { if event_id.is_some() && mxc.is_some() { return Ok(RoomMessageEventContent::text_plain( @@ -52,7 +57,10 @@ pub(super) async fn delete( let final_url = url.to_string().replace('"', ""); mxc_urls.push(final_url); } else { - info!("Found a URL in the event ID {event_id} but did not start with mxc://, ignoring"); + info!( + "Found a URL in the event ID {event_id} but did not start with \ + mxc://, ignoring" + ); } } @@ -67,17 +75,24 @@ pub(super) async fn delete( debug!("Found a thumbnail_url in info key: {thumbnail_url}"); if thumbnail_url.to_string().starts_with("\"mxc://") { - debug!("Pushing thumbnail URL {thumbnail_url} to list of MXCs to delete"); - let final_thumbnail_url = thumbnail_url.to_string().replace('"', ""); + debug!( + "Pushing thumbnail URL {thumbnail_url} to list of MXCs \ + to delete" + ); + let final_thumbnail_url = + thumbnail_url.to_string().replace('"', ""); mxc_urls.push(final_thumbnail_url); } else { info!( - "Found a thumbnail URL in the event ID {event_id} but did not start with \ - mxc://, ignoring" + "Found a thumbnail URL in the event ID {event_id} but \ + did not start with mxc://, ignoring" ); } } else { - info!("No \"thumbnail_url\" key in \"info\" key, assuming no thumbnails."); + info!( + "No \"thumbnail_url\" key in \"info\" key, assuming no \ + thumbnails." + ); } } } @@ -98,8 +113,8 @@ pub(super) async fn delete( mxc_urls.push(final_url); } else { info!( - "Found a URL in the event ID {event_id} but did not start with mxc://, \ - ignoring" + "Found a URL in the event ID {event_id} but did not \ + start with mxc://, ignoring" ); } } else { @@ -109,13 +124,14 @@ pub(super) async fn delete( } } else { return Ok(RoomMessageEventContent::text_plain( - "Event ID does not have a \"content\" key or failed parsing the event ID JSON.", + "Event ID does not have a \"content\" key or failed parsing the event \ + ID JSON.", )); } } else { return Ok(RoomMessageEventContent::text_plain( - "Event ID does not have a \"content\" key, this is not a message or an event type that contains \ - media.", + "Event ID does not have a \"content\" key, this is not a message or an \ + event type that contains media.", )); } } else { @@ -126,7 +142,9 @@ pub(super) async fn delete( if mxc_urls.is_empty() { info!("Parsed event ID {event_id} but did not contain any MXC URLs."); - return Ok(RoomMessageEventContent::text_plain("Parsed event ID but found no MXC URLs.")); + return Ok(RoomMessageEventContent::text_plain( + "Parsed event ID but found no MXC URLs.", + )); } let mut mxc_deletion_count: usize = 0; @@ -138,11 +156,11 @@ pub(super) async fn delete( .delete(&mxc_url.as_str().try_into()?) .await { - Ok(()) => { + | Ok(()) => { debug_info!("Successfully deleted {mxc_url} from filesystem and database"); mxc_deletion_count = mxc_deletion_count.saturating_add(1); }, - Err(e) => { + | Err(e) => { debug_warn!("Failed to delete {mxc_url}, ignoring error and skipping: {e}"); continue; }, @@ -150,19 +168,22 @@ pub(super) async fn delete( } return Ok(RoomMessageEventContent::text_plain(format!( - "Deleted {mxc_deletion_count} total MXCs from our database and the filesystem from event ID {event_id}." + "Deleted {mxc_deletion_count} total MXCs from our database and the filesystem from \ + event ID {event_id}." ))); } Ok(RoomMessageEventContent::text_plain( - "Please specify either an MXC using --mxc or an event ID using --event-id of the message containing an image. \ - See --help for details.", + "Please specify either an MXC using --mxc or an event ID using --event-id of the \ + message containing an image. See --help for details.", )) } #[admin_command] pub(super) async fn delete_list(&self) -> Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -192,11 +213,11 @@ pub(super) async fn delete_list(&self) -> Result { for mxc in &mxc_list { trace!(%failed_parsed_mxcs, %mxc_deletion_count, "Deleting MXC {mxc} in bulk"); match self.services.media.delete(mxc).await { - Ok(()) => { + | Ok(()) => { debug_info!("Successfully deleted {mxc} from filesystem and database"); mxc_deletion_count = mxc_deletion_count.saturating_add(1); }, - Err(e) => { + | Err(e) => { debug_warn!("Failed to delete {mxc}, ignoring error and skipping: {e}"); continue; }, @@ -204,14 +225,18 @@ pub(super) async fn delete_list(&self) -> Result { } Ok(RoomMessageEventContent::text_plain(format!( - "Finished bulk MXC deletion, deleted {mxc_deletion_count} total MXCs from our database and the filesystem. \ - {failed_parsed_mxcs} MXCs failed to be parsed from the database.", + "Finished bulk MXC deletion, deleted {mxc_deletion_count} total MXCs from our database \ + and the filesystem. {failed_parsed_mxcs} MXCs failed to be parsed from the database.", ))) } #[admin_command] pub(super) async fn delete_past_remote_media( - &self, duration: String, before: bool, after: bool, yes_i_want_to_delete_local_media: bool, + &self, + duration: String, + before: bool, + after: bool, + yes_i_want_to_delete_local_media: bool, ) -> Result { if before && after { return Ok(RoomMessageEventContent::text_plain( @@ -224,7 +249,12 @@ pub(super) async fn delete_past_remote_media( let deleted_count = self .services .media - .delete_all_remote_media_at_after_time(duration, before, after, yes_i_want_to_delete_local_media) + .delete_all_remote_media_at_after_time( + duration, + before, + after, + yes_i_want_to_delete_local_media, + ) .await?; Ok(RoomMessageEventContent::text_plain(format!( @@ -233,7 +263,10 @@ pub(super) async fn delete_past_remote_media( } #[admin_command] -pub(super) async fn delete_all_from_user(&self, username: String) -> Result { +pub(super) async fn delete_all_from_user( + &self, + username: String, +) -> Result { let user_id = parse_local_user_id(self.services, &username)?; let deleted_count = self.services.media.delete_from_user(&user_id).await?; @@ -245,7 +278,9 @@ pub(super) async fn delete_all_from_user(&self, username: String) -> Result, yes_i_want_to_delete_local_media: bool, + &self, + server_name: Box, + yes_i_want_to_delete_local_media: bool, ) -> Result { if server_name == self.services.globals.server_name() && !yes_i_want_to_delete_local_media { return Ok(RoomMessageEventContent::text_plain( @@ -260,20 +295,26 @@ pub(super) async fn delete_all_from_server( .await .inspect_err(|e| error!("Failed to get MXC URIs from our database: {e}")) else { - return Ok(RoomMessageEventContent::text_plain("Failed to get MXC URIs from our database")); + return Ok(RoomMessageEventContent::text_plain( + "Failed to get MXC URIs from our database", + )); }; let mut deleted_count: usize = 0; for mxc in all_mxcs { let Ok(mxc_server_name) = mxc.server_name().inspect_err(|e| { - debug_warn!("Failed to parse MXC {mxc} server name from database, ignoring error and skipping: {e}"); + debug_warn!( + "Failed to parse MXC {mxc} server name from database, ignoring error and \ + skipping: {e}" + ); }) else { continue; }; if mxc_server_name != server_name - || (self.services.globals.server_is_ours(mxc_server_name) && !yes_i_want_to_delete_local_media) + || (self.services.globals.server_is_ours(mxc_server_name) + && !yes_i_want_to_delete_local_media) { trace!("skipping MXC URI {mxc}"); continue; @@ -282,10 +323,10 @@ pub(super) async fn delete_all_from_server( let mxc: Mxc<'_> = mxc.as_str().try_into()?; match self.services.media.delete(&mxc).await { - Ok(()) => { + | Ok(()) => { deleted_count = deleted_count.saturating_add(1); }, - Err(e) => { + | Err(e) => { debug_warn!("Failed to delete {mxc}, ignoring error and skipping: {e}"); continue; }, @@ -307,7 +348,10 @@ pub(super) async fn get_file_info(&self, mxc: OwnedMxcUri) -> Result, timeout: u32, + &self, + mxc: OwnedMxcUri, + server: Option, + timeout: u32, ) -> Result { let mxc: Mxc<'_> = mxc.as_str().try_into()?; let timeout = Duration::from_millis(timeout.into()); @@ -327,7 +371,12 @@ pub(super) async fn get_remote_file( #[admin_command] pub(super) async fn get_remote_thumbnail( - &self, mxc: OwnedMxcUri, server: Option, timeout: u32, width: u32, height: u32, + &self, + mxc: OwnedMxcUri, + server: Option, + timeout: u32, + width: u32, + height: u32, ) -> Result { let mxc: Mxc<'_> = mxc.as_str().try_into()?; let timeout = Duration::from_millis(timeout.into()); diff --git a/src/admin/processor.rs b/src/admin/processor.rs index e041a8899..ed7d5ed1b 100644 --- a/src/admin/processor.rs +++ b/src/admin/processor.rs @@ -53,8 +53,8 @@ async fn handle_command(services: Arc, command: CommandInput) -> Proce async fn process_command(services: Arc, input: &CommandInput) -> ProcessorResult { let (command, args, body) = match parse(&services, input) { - Err(error) => return Err(error), - Ok(parsed) => parsed, + | Err(error) => return Err(error), + | Ok(parsed) => parsed, }; let context = Command { @@ -68,7 +68,8 @@ async fn process_command(services: Arc, input: &CommandInput) -> Proce } fn handle_panic(error: &Error, command: &CommandInput) -> ProcessorResult { - let link = "Please submit a [bug report](https://github.com/girlbossceo/conduwuit/issues/new). 🥺"; + let link = + "Please submit a [bug report](https://github.com/girlbossceo/conduwuit/issues/new). 🥺"; let msg = format!("Panic occurred while processing command:\n```\n{error:#?}\n```\n{link}"); let content = RoomMessageEventContent::notice_markdown(msg); error!("Panic while processing command: {error:?}"); @@ -76,7 +77,11 @@ fn handle_panic(error: &Error, command: &CommandInput) -> ProcessorResult { } // Parse and process a message from the admin room -async fn process(context: &Command<'_>, command: AdminCommand, args: &[String]) -> ProcessorResult { +async fn process( + context: &Command<'_>, + command: AdminCommand, + args: &[String], +) -> ProcessorResult { let (capture, logs) = capture_create(context); let capture_scope = capture.start(); @@ -100,11 +105,12 @@ async fn process(context: &Command<'_>, command: AdminCommand, args: &[String]) drop(logs); match result { - Ok(content) => { - write!(&mut output, "{0}", content.body()).expect("failed to format command result to output buffer"); + | Ok(content) => { + write!(&mut output, "{0}", content.body()) + .expect("failed to format command result to output buffer"); Ok(Some(reply(RoomMessageEventContent::notice_markdown(output), context.reply_id))) }, - Err(error) => { + | Err(error) => { write!(&mut output, "Command failed with error:\n```\n{error:#?}\n```") .expect("failed to format command result to output"); Err(reply(RoomMessageEventContent::notice_markdown(output), context.reply_id)) @@ -128,8 +134,9 @@ fn capture_create(context: &Command<'_>) -> (Arc, Arc>) { .and_then(LevelFilter::into_level) .unwrap_or(Level::DEBUG); - let filter = - move |data: capture::Data<'_>| data.level() <= log_level && data.our_modules() && data.scope.contains(&"admin"); + let filter = move |data: capture::Data<'_>| { + data.level() <= log_level && data.our_modules() && data.scope.contains(&"admin") + }; let logs = Arc::new(Mutex::new( collect_stream(|s| markdown_table_head(s)).expect("markdown table header"), @@ -146,14 +153,15 @@ fn capture_create(context: &Command<'_>) -> (Arc, Arc>) { // Parse chat messages from the admin room into an AdminCommand object fn parse<'a>( - services: &Arc, input: &'a CommandInput, + services: &Arc, + input: &'a CommandInput, ) -> Result<(AdminCommand, Vec, Vec<&'a str>), CommandOutput> { let lines = input.command.lines().filter(|line| !line.trim().is_empty()); let command_line = lines.clone().next().expect("command missing first line"); let body = lines.skip(1).collect(); match parse_command(command_line) { - Ok((command, args)) => Ok((command, args, body)), - Err(error) => { + | Ok((command, args)) => Ok((command, args, body)), + | Err(error) => { let message = error .to_string() .replace("server.name", services.globals.server_name().as_str()); @@ -255,11 +263,12 @@ fn parse_line(command_line: &str) -> Vec { argv } -fn reply(mut content: RoomMessageEventContent, reply_id: Option<&EventId>) -> RoomMessageEventContent { +fn reply( + mut content: RoomMessageEventContent, + reply_id: Option<&EventId>, +) -> RoomMessageEventContent { content.relates_to = reply_id.map(|event_id| Reply { - in_reply_to: InReplyTo { - event_id: event_id.to_owned(), - }, + in_reply_to: InReplyTo { event_id: event_id.to_owned() }, }); content diff --git a/src/admin/query/account_data.rs b/src/admin/query/account_data.rs index 53ed64dde..43762789c 100644 --- a/src/admin/query/account_data.rs +++ b/src/admin/query/account_data.rs @@ -30,15 +30,14 @@ pub(crate) enum AccountDataCommand { } /// All the getters and iterators from src/database/key_value/account_data.rs -pub(super) async fn process(subcommand: AccountDataCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + subcommand: AccountDataCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - AccountDataCommand::ChangesSince { - user_id, - since, - room_id, - } => { + | AccountDataCommand::ChangesSince { user_id, since, room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .account_data @@ -51,11 +50,7 @@ pub(super) async fn process(subcommand: AccountDataCommand, context: &Command<'_ "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - AccountDataCommand::Get { - user_id, - kind, - room_id, - } => { + | AccountDataCommand::Get { user_id, kind, room_id } => { let timer = tokio::time::Instant::now(); let results = services .account_data diff --git a/src/admin/query/appservice.rs b/src/admin/query/appservice.rs index 6bf9b9ad6..fe4861bc6 100644 --- a/src/admin/query/appservice.rs +++ b/src/admin/query/appservice.rs @@ -18,13 +18,14 @@ pub(crate) enum AppserviceCommand { } /// All the getters and iterators from src/database/key_value/appservice.rs -pub(super) async fn process(subcommand: AppserviceCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + subcommand: AppserviceCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - AppserviceCommand::GetRegistration { - appservice_id, - } => { + | AppserviceCommand::GetRegistration { appservice_id } => { let timer = tokio::time::Instant::now(); let results = services.appservice.get_registration(&appservice_id).await; @@ -34,7 +35,7 @@ pub(super) async fn process(subcommand: AppserviceCommand, context: &Command<'_> "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - AppserviceCommand::All => { + | AppserviceCommand::All => { let timer = tokio::time::Instant::now(); let results = services.appservice.all().await; let query_time = timer.elapsed(); diff --git a/src/admin/query/globals.rs b/src/admin/query/globals.rs index 68f68648e..e356453ff 100644 --- a/src/admin/query/globals.rs +++ b/src/admin/query/globals.rs @@ -21,11 +21,14 @@ pub(crate) enum GlobalsCommand { } /// All the getters and iterators from src/database/key_value/globals.rs -pub(super) async fn process(subcommand: GlobalsCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + subcommand: GlobalsCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - GlobalsCommand::DatabaseVersion => { + | GlobalsCommand::DatabaseVersion => { let timer = tokio::time::Instant::now(); let results = services.globals.db.database_version().await; let query_time = timer.elapsed(); @@ -34,7 +37,7 @@ pub(super) async fn process(subcommand: GlobalsCommand, context: &Command<'_>) - "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - GlobalsCommand::CurrentCount => { + | GlobalsCommand::CurrentCount => { let timer = tokio::time::Instant::now(); let results = services.globals.db.current_count(); let query_time = timer.elapsed(); @@ -43,7 +46,7 @@ pub(super) async fn process(subcommand: GlobalsCommand, context: &Command<'_>) - "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - GlobalsCommand::LastCheckForUpdatesId => { + | GlobalsCommand::LastCheckForUpdatesId => { let timer = tokio::time::Instant::now(); let results = services.updates.last_check_for_updates_id().await; let query_time = timer.elapsed(); @@ -52,9 +55,7 @@ pub(super) async fn process(subcommand: GlobalsCommand, context: &Command<'_>) - "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - GlobalsCommand::SigningKeysFor { - origin, - } => { + | GlobalsCommand::SigningKeysFor { origin } => { let timer = tokio::time::Instant::now(); let results = services.server_keys.verify_keys_for(&origin).await; let query_time = timer.elapsed(); diff --git a/src/admin/query/mod.rs b/src/admin/query/mod.rs index b1849091b..ab269a401 100644 --- a/src/admin/query/mod.rs +++ b/src/admin/query/mod.rs @@ -14,8 +14,9 @@ use conduwuit::Result; use self::{ account_data::AccountDataCommand, appservice::AppserviceCommand, globals::GlobalsCommand, - presence::PresenceCommand, pusher::PusherCommand, resolver::ResolverCommand, room_alias::RoomAliasCommand, - room_state_cache::RoomStateCacheCommand, sending::SendingCommand, users::UsersCommand, + presence::PresenceCommand, pusher::PusherCommand, resolver::ResolverCommand, + room_alias::RoomAliasCommand, room_state_cache::RoomStateCacheCommand, + sending::SendingCommand, users::UsersCommand, }; use crate::admin_command_dispatch; diff --git a/src/admin/query/presence.rs b/src/admin/query/presence.rs index 73e33bf68..45bb6bd97 100644 --- a/src/admin/query/presence.rs +++ b/src/admin/query/presence.rs @@ -23,13 +23,14 @@ pub(crate) enum PresenceCommand { } /// All the getters and iterators in key_value/presence.rs -pub(super) async fn process(subcommand: PresenceCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + subcommand: PresenceCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - PresenceCommand::GetPresence { - user_id, - } => { + | PresenceCommand::GetPresence { user_id } => { let timer = tokio::time::Instant::now(); let results = services.presence.db.get_presence(&user_id).await; let query_time = timer.elapsed(); @@ -38,9 +39,7 @@ pub(super) async fn process(subcommand: PresenceCommand, context: &Command<'_>) "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - PresenceCommand::PresenceSince { - since, - } => { + | PresenceCommand::PresenceSince { since } => { let timer = tokio::time::Instant::now(); let results: Vec<(_, _, _)> = services .presence diff --git a/src/admin/query/pusher.rs b/src/admin/query/pusher.rs index 3004af8be..55532e548 100644 --- a/src/admin/query/pusher.rs +++ b/src/admin/query/pusher.rs @@ -13,13 +13,14 @@ pub(crate) enum PusherCommand { }, } -pub(super) async fn process(subcommand: PusherCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + subcommand: PusherCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - PusherCommand::GetPushers { - user_id, - } => { + | PusherCommand::GetPushers { user_id } => { let timer = tokio::time::Instant::now(); let results = services.pusher.get_pushers(&user_id).await; let query_time = timer.elapsed(); diff --git a/src/admin/query/resolver.rs b/src/admin/query/resolver.rs index 43c637709..3b950d13c 100644 --- a/src/admin/query/resolver.rs +++ b/src/admin/query/resolver.rs @@ -22,20 +22,16 @@ pub(crate) enum ResolverCommand { } #[admin_command] -async fn destinations_cache(&self, server_name: Option) -> Result { +async fn destinations_cache( + &self, + server_name: Option, +) -> Result { use service::resolver::cache::CachedDest; let mut out = String::new(); writeln!(out, "| Server Name | Destination | Hostname | Expires |")?; writeln!(out, "| ----------- | ----------- | -------- | ------- |")?; - let row = |( - name, - &CachedDest { - ref dest, - ref host, - expire, - }, - )| { + let row = |(name, &CachedDest { ref dest, ref host, expire })| { let expire = time::format(expire, "%+"); writeln!(out, "| {name} | {dest} | {host} | {expire} |").expect("wrote line"); }; @@ -64,14 +60,7 @@ async fn overrides_cache(&self, server_name: Option) -> Result) -> Result { +pub(super) async fn process( + subcommand: RoomAliasCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - RoomAliasCommand::ResolveLocalAlias { - alias, - } => { + | RoomAliasCommand::ResolveLocalAlias { alias } => { let timer = tokio::time::Instant::now(); let results = services.rooms.alias.resolve_local_alias(&alias).await; let query_time = timer.elapsed(); @@ -39,9 +40,7 @@ pub(super) async fn process(subcommand: RoomAliasCommand, context: &Command<'_>) "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomAliasCommand::LocalAliasesForRoom { - room_id, - } => { + | RoomAliasCommand::LocalAliasesForRoom { room_id } => { let timer = tokio::time::Instant::now(); let aliases: Vec<_> = services .rooms @@ -56,7 +55,7 @@ pub(super) async fn process(subcommand: RoomAliasCommand, context: &Command<'_>) "Query completed in {query_time:?}:\n\n```rs\n{aliases:#?}\n```" ))) }, - RoomAliasCommand::AllLocalAliases => { + | RoomAliasCommand::AllLocalAliases => { let timer = tokio::time::Instant::now(); let aliases = services .rooms diff --git a/src/admin/query/room_state_cache.rs b/src/admin/query/room_state_cache.rs index 6e84507a9..cd7f5af7f 100644 --- a/src/admin/query/room_state_cache.rs +++ b/src/admin/query/room_state_cache.rs @@ -77,15 +77,13 @@ pub(crate) enum RoomStateCacheCommand { } pub(super) async fn process( - subcommand: RoomStateCacheCommand, context: &Command<'_>, + subcommand: RoomStateCacheCommand, + context: &Command<'_>, ) -> Result { let services = context.services; match subcommand { - RoomStateCacheCommand::ServerInRoom { - server, - room_id, - } => { + | RoomStateCacheCommand::ServerInRoom { server, room_id } => { let timer = tokio::time::Instant::now(); let result = services .rooms @@ -98,9 +96,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{result:#?}\n```" ))) }, - RoomStateCacheCommand::RoomServers { - room_id, - } => { + | RoomStateCacheCommand::RoomServers { room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -115,9 +111,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::ServerRooms { - server, - } => { + | RoomStateCacheCommand::ServerRooms { server } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -132,9 +126,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomMembers { - room_id, - } => { + | RoomStateCacheCommand::RoomMembers { room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -149,9 +141,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::LocalUsersInRoom { - room_id, - } => { + | RoomStateCacheCommand::LocalUsersInRoom { room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -166,9 +156,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::ActiveLocalUsersInRoom { - room_id, - } => { + | RoomStateCacheCommand::ActiveLocalUsersInRoom { room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -183,9 +171,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomJoinedCount { - room_id, - } => { + | RoomStateCacheCommand::RoomJoinedCount { room_id } => { let timer = tokio::time::Instant::now(); let results = services.rooms.state_cache.room_joined_count(&room_id).await; let query_time = timer.elapsed(); @@ -194,9 +180,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomInvitedCount { - room_id, - } => { + | RoomStateCacheCommand::RoomInvitedCount { room_id } => { let timer = tokio::time::Instant::now(); let results = services .rooms @@ -209,9 +193,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomUserOnceJoined { - room_id, - } => { + | RoomStateCacheCommand::RoomUserOnceJoined { room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -226,9 +208,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomMembersInvited { - room_id, - } => { + | RoomStateCacheCommand::RoomMembersInvited { room_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -243,10 +223,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::GetInviteCount { - room_id, - user_id, - } => { + | RoomStateCacheCommand::GetInviteCount { room_id, user_id } => { let timer = tokio::time::Instant::now(); let results = services .rooms @@ -259,10 +236,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::GetLeftCount { - room_id, - user_id, - } => { + | RoomStateCacheCommand::GetLeftCount { room_id, user_id } => { let timer = tokio::time::Instant::now(); let results = services .rooms @@ -275,9 +249,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomsJoined { - user_id, - } => { + | RoomStateCacheCommand::RoomsJoined { user_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -292,9 +264,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomsInvited { - user_id, - } => { + | RoomStateCacheCommand::RoomsInvited { user_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -308,9 +278,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::RoomsLeft { - user_id, - } => { + | RoomStateCacheCommand::RoomsLeft { user_id } => { let timer = tokio::time::Instant::now(); let results: Vec<_> = services .rooms @@ -324,10 +292,7 @@ pub(super) async fn process( "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```" ))) }, - RoomStateCacheCommand::InviteState { - user_id, - room_id, - } => { + | RoomStateCacheCommand::InviteState { user_id, room_id } => { let timer = tokio::time::Instant::now(); let results = services .rooms diff --git a/src/admin/query/sending.rs b/src/admin/query/sending.rs index efb4275f7..696067b79 100644 --- a/src/admin/query/sending.rs +++ b/src/admin/query/sending.rs @@ -62,11 +62,14 @@ pub(crate) enum SendingCommand { } /// All the getters and iterators in key_value/sending.rs -pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + subcommand: SendingCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match subcommand { - SendingCommand::ActiveRequests => { + | SendingCommand::ActiveRequests => { let timer = tokio::time::Instant::now(); let results = services.sending.db.active_requests(); let active_requests = results.collect::>().await; @@ -76,25 +79,29 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - "Query completed in {query_time:?}:\n\n```rs\n{active_requests:#?}\n```" ))) }, - SendingCommand::QueuedRequests { + | SendingCommand::QueuedRequests { appservice_id, server_name, user_id, push_key, } => { - if appservice_id.is_none() && server_name.is_none() && user_id.is_none() && push_key.is_none() { + if appservice_id.is_none() + && server_name.is_none() + && user_id.is_none() + && push_key.is_none() + { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via arguments. See \ - --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); } let timer = tokio::time::Instant::now(); let results = match (appservice_id, server_name, user_id, push_key) { - (Some(appservice_id), None, None, None) => { + | (Some(appservice_id), None, None, None) => { if appservice_id.is_empty() { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via \ - arguments. See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); } @@ -103,15 +110,15 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - .db .queued_requests(&Destination::Appservice(appservice_id)) }, - (None, Some(server_name), None, None) => services + | (None, Some(server_name), None, None) => services .sending .db .queued_requests(&Destination::Normal(server_name.into())), - (None, None, Some(user_id), Some(push_key)) => { + | (None, None, Some(user_id), Some(push_key)) => { if push_key.is_empty() { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via \ - arguments. See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); } @@ -120,16 +127,16 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - .db .queued_requests(&Destination::Push(user_id.into(), push_key)) }, - (Some(_), Some(_), Some(_), Some(_)) => { + | (Some(_), Some(_), Some(_), Some(_)) => { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via arguments. \ - Not all of them See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. Not all of them See --help for more details.", )); }, - _ => { + | _ => { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via arguments. \ - See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); }, }; @@ -141,26 +148,30 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - "Query completed in {query_time:?}:\n\n```rs\n{queued_requests:#?}\n```" ))) }, - SendingCommand::ActiveRequestsFor { + | SendingCommand::ActiveRequestsFor { appservice_id, server_name, user_id, push_key, } => { - if appservice_id.is_none() && server_name.is_none() && user_id.is_none() && push_key.is_none() { + if appservice_id.is_none() + && server_name.is_none() + && user_id.is_none() + && push_key.is_none() + { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via arguments. See \ - --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); } let timer = tokio::time::Instant::now(); let results = match (appservice_id, server_name, user_id, push_key) { - (Some(appservice_id), None, None, None) => { + | (Some(appservice_id), None, None, None) => { if appservice_id.is_empty() { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via \ - arguments. See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); } @@ -169,15 +180,15 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - .db .active_requests_for(&Destination::Appservice(appservice_id)) }, - (None, Some(server_name), None, None) => services + | (None, Some(server_name), None, None) => services .sending .db .active_requests_for(&Destination::Normal(server_name.into())), - (None, None, Some(user_id), Some(push_key)) => { + | (None, None, Some(user_id), Some(push_key)) => { if push_key.is_empty() { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via \ - arguments. See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); } @@ -186,16 +197,16 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - .db .active_requests_for(&Destination::Push(user_id.into(), push_key)) }, - (Some(_), Some(_), Some(_), Some(_)) => { + | (Some(_), Some(_), Some(_), Some(_)) => { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via arguments. \ - Not all of them See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. Not all of them See --help for more details.", )); }, - _ => { + | _ => { return Ok(RoomMessageEventContent::text_plain( - "An appservice ID, server name, or a user ID with push key must be specified via arguments. \ - See --help for more details.", + "An appservice ID, server name, or a user ID with push key must be \ + specified via arguments. See --help for more details.", )); }, }; @@ -207,9 +218,7 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Command<'_>) - "Query completed in {query_time:?}:\n\n```rs\n{active_requests:#?}\n```" ))) }, - SendingCommand::GetLatestEduCount { - server_name, - } => { + | SendingCommand::GetLatestEduCount { server_name } => { let timer = tokio::time::Instant::now(); let results = services.sending.db.get_latest_educount(&server_name).await; let query_time = timer.elapsed(); diff --git a/src/admin/query/users.rs b/src/admin/query/users.rs index d58e2d2a1..2149a1036 100644 --- a/src/admin/query/users.rs +++ b/src/admin/query/users.rs @@ -1,7 +1,9 @@ use clap::Subcommand; use conduwuit::Result; use futures::stream::StreamExt; -use ruma::{events::room::message::RoomMessageEventContent, OwnedDeviceId, OwnedRoomId, OwnedUserId}; +use ruma::{ + events::room::message::RoomMessageEventContent, OwnedDeviceId, OwnedRoomId, OwnedUserId, +}; use crate::{admin_command, admin_command_dispatch}; @@ -91,7 +93,11 @@ pub(crate) enum UsersCommand { #[admin_command] async fn get_backup_session( - &self, user_id: OwnedUserId, version: String, room_id: OwnedRoomId, session_id: String, + &self, + user_id: OwnedUserId, + version: String, + room_id: OwnedRoomId, + session_id: String, ) -> Result { let timer = tokio::time::Instant::now(); let result = self @@ -108,7 +114,10 @@ async fn get_backup_session( #[admin_command] async fn get_room_backups( - &self, user_id: OwnedUserId, version: String, room_id: OwnedRoomId, + &self, + user_id: OwnedUserId, + version: String, + room_id: OwnedRoomId, ) -> Result { let timer = tokio::time::Instant::now(); let result = self @@ -124,7 +133,11 @@ async fn get_room_backups( } #[admin_command] -async fn get_all_backups(&self, user_id: OwnedUserId, version: String) -> Result { +async fn get_all_backups( + &self, + user_id: OwnedUserId, + version: String, +) -> Result { let timer = tokio::time::Instant::now(); let result = self.services.key_backups.get_all(&user_id, &version).await; let query_time = timer.elapsed(); @@ -135,7 +148,11 @@ async fn get_all_backups(&self, user_id: OwnedUserId, version: String) -> Result } #[admin_command] -async fn get_backup_algorithm(&self, user_id: OwnedUserId, version: String) -> Result { +async fn get_backup_algorithm( + &self, + user_id: OwnedUserId, + version: String, +) -> Result { let timer = tokio::time::Instant::now(); let result = self .services @@ -150,7 +167,10 @@ async fn get_backup_algorithm(&self, user_id: OwnedUserId, version: String) -> R } #[admin_command] -async fn get_latest_backup_version(&self, user_id: OwnedUserId) -> Result { +async fn get_latest_backup_version( + &self, + user_id: OwnedUserId, +) -> Result { let timer = tokio::time::Instant::now(); let result = self .services @@ -244,7 +264,11 @@ async fn list_devices_metadata(&self, user_id: OwnedUserId) -> Result Result { +async fn get_device_metadata( + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, +) -> Result { let timer = tokio::time::Instant::now(); let device = self .services @@ -270,7 +294,11 @@ async fn get_devices_version(&self, user_id: OwnedUserId) -> Result Result { +async fn count_one_time_keys( + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, +) -> Result { let timer = tokio::time::Instant::now(); let result = self .services @@ -285,7 +313,11 @@ async fn count_one_time_keys(&self, user_id: OwnedUserId, device_id: OwnedDevice } #[admin_command] -async fn get_device_keys(&self, user_id: OwnedUserId, device_id: OwnedDeviceId) -> Result { +async fn get_device_keys( + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, +) -> Result { let timer = tokio::time::Instant::now(); let result = self .services @@ -327,7 +359,9 @@ async fn get_master_key(&self, user_id: OwnedUserId) -> Result Result { let timer = tokio::time::Instant::now(); let result = self diff --git a/src/admin/room/alias.rs b/src/admin/room/alias.rs index 841bc51aa..835138b24 100644 --- a/src/admin/room/alias.rs +++ b/src/admin/room/alias.rs @@ -3,7 +3,10 @@ use std::fmt::Write; use clap::Subcommand; use conduwuit::Result; use futures::StreamExt; -use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomAliasId, OwnedRoomId, RoomAliasId, RoomId}; +use ruma::{ + events::room::message::RoomMessageEventContent, OwnedRoomAliasId, OwnedRoomId, RoomAliasId, + RoomId, +}; use crate::{escape_html, Command}; @@ -42,82 +45,92 @@ pub(crate) enum RoomAliasCommand { }, } -pub(super) async fn process(command: RoomAliasCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + command: RoomAliasCommand, + context: &Command<'_>, +) -> Result { let services = context.services; let server_user = &services.globals.server_user; match command { - RoomAliasCommand::Set { - ref room_alias_localpart, - .. - } - | RoomAliasCommand::Remove { - ref room_alias_localpart, - } - | RoomAliasCommand::Which { - ref room_alias_localpart, - } => { - let room_alias_str = format!("#{}:{}", room_alias_localpart, services.globals.server_name()); + | RoomAliasCommand::Set { ref room_alias_localpart, .. } + | RoomAliasCommand::Remove { ref room_alias_localpart } + | RoomAliasCommand::Which { ref room_alias_localpart } => { + let room_alias_str = + format!("#{}:{}", room_alias_localpart, services.globals.server_name()); let room_alias = match RoomAliasId::parse_box(room_alias_str) { - Ok(alias) => alias, - Err(err) => return Ok(RoomMessageEventContent::text_plain(format!("Failed to parse alias: {err}"))), + | Ok(alias) => alias, + | Err(err) => + return Ok(RoomMessageEventContent::text_plain(format!( + "Failed to parse alias: {err}" + ))), }; match command { - RoomAliasCommand::Set { - force, - room_id, - .. - } => match (force, services.rooms.alias.resolve_local_alias(&room_alias).await) { - (true, Ok(id)) => match services - .rooms - .alias - .set_alias(&room_alias, &room_id, server_user) - { - Ok(()) => Ok(RoomMessageEventContent::text_plain(format!( - "Successfully overwrote alias (formerly {id})" + | RoomAliasCommand::Set { force, room_id, .. } => + match (force, services.rooms.alias.resolve_local_alias(&room_alias).await) { + | (true, Ok(id)) => { + match services.rooms.alias.set_alias( + &room_alias, + &room_id, + server_user, + ) { + | Ok(()) => Ok(RoomMessageEventContent::text_plain(format!( + "Successfully overwrote alias (formerly {id})" + ))), + | Err(err) => Ok(RoomMessageEventContent::text_plain(format!( + "Failed to remove alias: {err}" + ))), + } + }, + | (false, Ok(id)) => Ok(RoomMessageEventContent::text_plain(format!( + "Refusing to overwrite in use alias for {id}, use -f or --force to \ + overwrite" ))), - Err(err) => Ok(RoomMessageEventContent::text_plain(format!("Failed to remove alias: {err}"))), + | (_, Err(_)) => { + match services.rooms.alias.set_alias( + &room_alias, + &room_id, + server_user, + ) { + | Ok(()) => Ok(RoomMessageEventContent::text_plain( + "Successfully set alias", + )), + | Err(err) => Ok(RoomMessageEventContent::text_plain(format!( + "Failed to remove alias: {err}" + ))), + } + }, }, - (false, Ok(id)) => Ok(RoomMessageEventContent::text_plain(format!( - "Refusing to overwrite in use alias for {id}, use -f or --force to overwrite" - ))), - (_, Err(_)) => match services - .rooms - .alias - .set_alias(&room_alias, &room_id, server_user) - { - Ok(()) => Ok(RoomMessageEventContent::text_plain("Successfully set alias")), - Err(err) => Ok(RoomMessageEventContent::text_plain(format!("Failed to remove alias: {err}"))), + | RoomAliasCommand::Remove { .. } => + match services.rooms.alias.resolve_local_alias(&room_alias).await { + | Ok(id) => match services + .rooms + .alias + .remove_alias(&room_alias, server_user) + .await + { + | Ok(()) => Ok(RoomMessageEventContent::text_plain(format!( + "Removed alias from {id}" + ))), + | Err(err) => Ok(RoomMessageEventContent::text_plain(format!( + "Failed to remove alias: {err}" + ))), + }, + | Err(_) => + Ok(RoomMessageEventContent::text_plain("Alias isn't in use.")), }, - }, - RoomAliasCommand::Remove { - .. - } => match services.rooms.alias.resolve_local_alias(&room_alias).await { - Ok(id) => match services - .rooms - .alias - .remove_alias(&room_alias, server_user) - .await - { - Ok(()) => Ok(RoomMessageEventContent::text_plain(format!("Removed alias from {id}"))), - Err(err) => Ok(RoomMessageEventContent::text_plain(format!("Failed to remove alias: {err}"))), + | RoomAliasCommand::Which { .. } => + match services.rooms.alias.resolve_local_alias(&room_alias).await { + | Ok(id) => Ok(RoomMessageEventContent::text_plain(format!( + "Alias resolves to {id}" + ))), + | Err(_) => + Ok(RoomMessageEventContent::text_plain("Alias isn't in use.")), }, - Err(_) => Ok(RoomMessageEventContent::text_plain("Alias isn't in use.")), - }, - RoomAliasCommand::Which { - .. - } => match services.rooms.alias.resolve_local_alias(&room_alias).await { - Ok(id) => Ok(RoomMessageEventContent::text_plain(format!("Alias resolves to {id}"))), - Err(_) => Ok(RoomMessageEventContent::text_plain("Alias isn't in use.")), - }, - RoomAliasCommand::List { - .. - } => unreachable!(), + | RoomAliasCommand::List { .. } => unreachable!(), } }, - RoomAliasCommand::List { - room_id, - } => { + | RoomAliasCommand::List { room_id } => if let Some(room_id) = room_id { let aliases: Vec = services .rooms @@ -128,7 +141,8 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Command<'_>) -> .await; let plain_list = aliases.iter().fold(String::new(), |mut output, alias| { - writeln!(output, "- {alias}").expect("should be able to write to string buffer"); + writeln!(output, "- {alias}") + .expect("should be able to write to string buffer"); output }); @@ -176,7 +190,6 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Command<'_>) -> let plain = format!("Aliases:\n{plain_list}"); let html = format!("Aliases:\n
    {html_list}
"); Ok(RoomMessageEventContent::text_html(plain, html)) - } - }, + }, } } diff --git a/src/admin/room/commands.rs b/src/admin/room/commands.rs index d2fdbfca9..b58d04c55 100644 --- a/src/admin/room/commands.rs +++ b/src/admin/room/commands.rs @@ -6,7 +6,11 @@ use crate::{admin_command, get_room_info, PAGE_SIZE}; #[admin_command] pub(super) async fn list_rooms( - &self, page: Option, exclude_disabled: bool, exclude_banned: bool, no_details: bool, + &self, + page: Option, + exclude_disabled: bool, + exclude_banned: bool, + no_details: bool, ) -> Result { // TODO: i know there's a way to do this with clap, but i can't seem to find it let page = page.unwrap_or(1); @@ -16,10 +20,12 @@ pub(super) async fn list_rooms( .metadata .iter_ids() .filter_map(|room_id| async move { - (!exclude_disabled || !self.services.rooms.metadata.is_disabled(room_id).await).then_some(room_id) + (!exclude_disabled || !self.services.rooms.metadata.is_disabled(room_id).await) + .then_some(room_id) }) .filter_map(|room_id| async move { - (!exclude_banned || !self.services.rooms.metadata.is_banned(room_id).await).then_some(room_id) + (!exclude_banned || !self.services.rooms.metadata.is_banned(room_id).await) + .then_some(room_id) }) .then(|room_id| get_room_info(self.services, room_id)) .collect::>() diff --git a/src/admin/room/directory.rs b/src/admin/room/directory.rs index d3ed25756..81f254785 100644 --- a/src/admin/room/directory.rs +++ b/src/admin/room/directory.rs @@ -25,24 +25,21 @@ pub(crate) enum RoomDirectoryCommand { }, } -pub(super) async fn process(command: RoomDirectoryCommand, context: &Command<'_>) -> Result { +pub(super) async fn process( + command: RoomDirectoryCommand, + context: &Command<'_>, +) -> Result { let services = context.services; match command { - RoomDirectoryCommand::Publish { - room_id, - } => { + | RoomDirectoryCommand::Publish { room_id } => { services.rooms.directory.set_public(&room_id); Ok(RoomMessageEventContent::notice_plain("Room published")) }, - RoomDirectoryCommand::Unpublish { - room_id, - } => { + | RoomDirectoryCommand::Unpublish { room_id } => { services.rooms.directory.set_not_public(&room_id); Ok(RoomMessageEventContent::notice_plain("Room unpublished")) }, - RoomDirectoryCommand::List { - page, - } => { + | RoomDirectoryCommand::List { page } => { // TODO: i know there's a way to do this with clap, but i can't seem to find it let page = page.unwrap_or(1); let mut rooms: Vec<_> = services @@ -70,7 +67,9 @@ pub(super) async fn process(command: RoomDirectoryCommand, context: &Command<'_> "Rooms (page {page}):\n```\n{}\n```", rooms .iter() - .map(|(id, members, name)| format!("{id} | Members: {members} | Name: {name}")) + .map(|(id, members, name)| format!( + "{id} | Members: {members} | Name: {name}" + )) .collect::>() .join("\n") ); diff --git a/src/admin/room/info.rs b/src/admin/room/info.rs index 6a6ec6953..34abf8a93 100644 --- a/src/admin/room/info.rs +++ b/src/admin/room/info.rs @@ -27,7 +27,11 @@ pub(crate) enum RoomInfoCommand { } #[admin_command] -async fn list_joined_members(&self, room_id: Box, local_only: bool) -> Result { +async fn list_joined_members( + &self, + room_id: Box, + local_only: bool, +) -> Result { let room_name = self .services .rooms diff --git a/src/admin/room/mod.rs b/src/admin/room/mod.rs index ad05d16dd..26d2c2d8c 100644 --- a/src/admin/room/mod.rs +++ b/src/admin/room/mod.rs @@ -9,7 +9,8 @@ use conduwuit::Result; use ruma::OwnedRoomId; use self::{ - alias::RoomAliasCommand, directory::RoomDirectoryCommand, info::RoomInfoCommand, moderation::RoomModerationCommand, + alias::RoomAliasCommand, directory::RoomDirectoryCommand, info::RoomInfoCommand, + moderation::RoomModerationCommand, }; use crate::admin_command_dispatch; diff --git a/src/admin/room/moderation.rs b/src/admin/room/moderation.rs index 427f3e427..b16aff1ff 100644 --- a/src/admin/room/moderation.rs +++ b/src/admin/room/moderation.rs @@ -6,7 +6,10 @@ use conduwuit::{ warn, Result, }; use futures::StreamExt; -use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, RoomAliasId, RoomId, RoomOrAliasId}; +use ruma::{ + events::room::message::RoomMessageEventContent, OwnedRoomId, RoomAliasId, RoomId, + RoomOrAliasId, +}; use crate::{admin_command, admin_command_dispatch, get_room_info}; @@ -75,7 +78,10 @@ pub(crate) enum RoomModerationCommand { #[admin_command] async fn ban_room( - &self, force: bool, disable_federation: bool, room: Box, + &self, + force: bool, + disable_federation: bool, + room: Box, ) -> Result { debug!("Got room alias or ID: {}", room); @@ -89,13 +95,13 @@ async fn ban_room( let room_id = if room.is_room_id() { let room_id = match RoomId::parse(&room) { - Ok(room_id) => room_id, - Err(e) => { + | Ok(room_id) => room_id, + | Err(e) => return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to parse room ID {room}. Please note that this requires a full room ID \ - (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias (`#roomalias:example.com`): {e}" - ))) - }, + "Failed to parse room ID {room}. Please note that this requires a full room \ + ID (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias \ + (`#roomalias:example.com`): {e}" + ))), }; debug!("Room specified is a room ID, banning room ID"); @@ -105,18 +111,18 @@ async fn ban_room( room_id } else if room.is_room_alias_id() { let room_alias = match RoomAliasId::parse(&room) { - Ok(room_alias) => room_alias, - Err(e) => { + | Ok(room_alias) => room_alias, + | Err(e) => return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to parse room ID {room}. Please note that this requires a full room ID \ - (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias (`#roomalias:example.com`): {e}" - ))) - }, + "Failed to parse room ID {room}. Please note that this requires a full room \ + ID (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias \ + (`#roomalias:example.com`): {e}" + ))), }; debug!( - "Room specified is not a room ID, attempting to resolve room alias to a room ID locally, if not using \ - get_alias_helper to fetch room ID remotely" + "Room specified is not a room ID, attempting to resolve room alias to a room ID \ + locally, if not using get_alias_helper to fetch room ID remotely" ); let room_id = if let Ok(room_id) = self @@ -128,7 +134,10 @@ async fn ban_room( { room_id } else { - debug!("We don't have this room alias to a room ID locally, attempting to fetch room ID over federation"); + debug!( + "We don't have this room alias to a room ID locally, attempting to fetch room \ + ID over federation" + ); match self .services @@ -137,11 +146,15 @@ async fn ban_room( .resolve_alias(&room_alias, None) .await { - Ok((room_id, servers)) => { - debug!(?room_id, ?servers, "Got federation response fetching room ID for {room}"); + | Ok((room_id, servers)) => { + debug!( + ?room_id, + ?servers, + "Got federation response fetching room ID for {room}" + ); room_id }, - Err(e) => { + | Err(e) => { return Ok(RoomMessageEventContent::notice_plain(format!( "Failed to resolve room alias {room} to a room ID: {e}" ))); @@ -154,8 +167,9 @@ async fn ban_room( room_id } else { return Ok(RoomMessageEventContent::text_plain( - "Room specified is not a room ID or room alias. Please note that this requires a full room ID \ - (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias (`#roomalias:example.com`)", + "Room specified is not a room ID or room alias. Please note that this requires a \ + full room ID (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias \ + (`#roomalias:example.com`)", )); }; @@ -171,8 +185,8 @@ async fn ban_room( while let Some(local_user) = users.next().await { debug!( - "Attempting leave for user {local_user} in room {room_id} (forced, ignoring all errors, evicting \ - admins too)", + "Attempting leave for user {local_user} in room {room_id} (forced, ignoring all \ + errors, evicting admins too)", ); if let Err(e) = leave_room(self.services, local_user, &room_id, None).await { @@ -196,12 +210,14 @@ async fn ban_room( debug!("Attempting leave for user {} in room {}", &local_user, &room_id); if let Err(e) = leave_room(self.services, local_user, &room_id, None).await { error!( - "Error attempting to make local user {} leave room {} during room banning: {}", + "Error attempting to make local user {} leave room {} during room banning: \ + {}", &local_user, &room_id, e ); return Ok(RoomMessageEventContent::text_plain(format!( - "Error attempting to make local user {} leave room {} during room banning (room is still banned \ - but not removing any more users): {}\nIf you would like to ignore errors, use --force", + "Error attempting to make local user {} leave room {} during room banning \ + (room is still banned but not removing any more users): {}\nIf you would \ + like to ignore errors, use --force", &local_user, &room_id, e ))); } @@ -232,19 +248,26 @@ async fn ban_room( if disable_federation { self.services.rooms.metadata.disable_room(&room_id, true); return Ok(RoomMessageEventContent::text_plain( - "Room banned, removed all our local users, and disabled incoming federation with room.", + "Room banned, removed all our local users, and disabled incoming federation with \ + room.", )); } Ok(RoomMessageEventContent::text_plain( - "Room banned and removed all our local users, use `!admin federation disable-room` to stop receiving new \ - inbound federation events as well if needed.", + "Room banned and removed all our local users, use `!admin federation disable-room` to \ + stop receiving new inbound federation events as well if needed.", )) } #[admin_command] -async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" +async fn ban_list_of_rooms( + &self, + force: bool, + disable_federation: bool, +) -> Result { + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -264,9 +287,10 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu for &room in &rooms_s { match <&RoomOrAliasId>::try_from(room) { - Ok(room_alias_or_id) => { + | Ok(room_alias_or_id) => { if let Ok(admin_room_id) = self.services.admin.get_admin_room().await { - if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(admin_room_alias) { + if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(admin_room_alias) + { info!("User specified admin room in bulk ban list, ignoring"); continue; } @@ -274,19 +298,20 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu if room_alias_or_id.is_room_id() { let room_id = match RoomId::parse(room_alias_or_id) { - Ok(room_id) => room_id, - Err(e) => { + | Ok(room_id) => room_id, + | Err(e) => { if force { // ignore rooms we failed to parse if we're force banning warn!( - "Error parsing room \"{room}\" during bulk room banning, ignoring error and \ - logging here: {e}" + "Error parsing room \"{room}\" during bulk room banning, \ + ignoring error and logging here: {e}" ); continue; } return Ok(RoomMessageEventContent::text_plain(format!( - "{room} is not a valid room ID or room alias, please fix the list and try again: {e}" + "{room} is not a valid room ID or room alias, please fix the \ + list and try again: {e}" ))); }, }; @@ -296,7 +321,7 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu if room_alias_or_id.is_room_alias_id() { match RoomAliasId::parse(room_alias_or_id) { - Ok(room_alias) => { + | Ok(room_alias) => { let room_id = if let Ok(room_id) = self .services .rooms @@ -307,8 +332,8 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu room_id } else { debug!( - "We don't have this room alias to a room ID locally, attempting to fetch room ID \ - over federation" + "We don't have this room alias to a room ID locally, \ + attempting to fetch room ID over federation" ); match self @@ -318,7 +343,7 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu .resolve_alias(&room_alias, None) .await { - Ok((room_id, servers)) => { + | Ok((room_id, servers)) => { debug!( ?room_id, ?servers, @@ -326,15 +351,19 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu ); room_id }, - Err(e) => { + | Err(e) => { // don't fail if force blocking if force { - warn!("Failed to resolve room alias {room} to a room ID: {e}"); + warn!( + "Failed to resolve room alias {room} to a room \ + ID: {e}" + ); continue; } return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to resolve room alias {room} to a room ID: {e}" + "Failed to resolve room alias {room} to a room ID: \ + {e}" ))); }, } @@ -342,34 +371,37 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu room_ids.push(room_id); }, - Err(e) => { + | Err(e) => { if force { // ignore rooms we failed to parse if we're force deleting error!( - "Error parsing room \"{room}\" during bulk room banning, ignoring error and \ - logging here: {e}" + "Error parsing room \"{room}\" during bulk room banning, \ + ignoring error and logging here: {e}" ); continue; } return Ok(RoomMessageEventContent::text_plain(format!( - "{room} is not a valid room ID or room alias, please fix the list and try again: {e}" + "{room} is not a valid room ID or room alias, please fix the \ + list and try again: {e}" ))); }, } } }, - Err(e) => { + | Err(e) => { if force { // ignore rooms we failed to parse if we're force deleting error!( - "Error parsing room \"{room}\" during bulk room banning, ignoring error and logging here: {e}" + "Error parsing room \"{room}\" during bulk room banning, ignoring error \ + and logging here: {e}" ); continue; } return Ok(RoomMessageEventContent::text_plain(format!( - "{room} is not a valid room ID or room alias, please fix the list and try again: {e}" + "{room} is not a valid room ID or room alias, please fix the list and try \ + again: {e}" ))); }, } @@ -393,8 +425,8 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu while let Some(local_user) = users.next().await { debug!( - "Attempting leave for user {local_user} in room {room_id} (forced, ignoring all errors, evicting \ - admins too)", + "Attempting leave for user {local_user} in room {room_id} (forced, ignoring \ + all errors, evicting admins too)", ); if let Err(e) = leave_room(self.services, local_user, &room_id, None).await { @@ -418,14 +450,15 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu debug!("Attempting leave for user {local_user} in room {room_id}"); if let Err(e) = leave_room(self.services, local_user, &room_id, None).await { error!( - "Error attempting to make local user {local_user} leave room {room_id} during bulk room \ - banning: {e}", + "Error attempting to make local user {local_user} leave room {room_id} \ + during bulk room banning: {e}", ); return Ok(RoomMessageEventContent::text_plain(format!( - "Error attempting to make local user {} leave room {} during room banning (room is still \ - banned but not removing any more users and not banning any more rooms): {}\nIf you would \ - like to ignore errors, use --force", + "Error attempting to make local user {} leave room {} during room \ + banning (room is still banned but not removing any more users and not \ + banning any more rooms): {}\nIf you would like to ignore errors, use \ + --force", &local_user, &room_id, e ))); } @@ -458,8 +491,8 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu if disable_federation { Ok(RoomMessageEventContent::text_plain(format!( - "Finished bulk room ban, banned {room_ban_count} total rooms, evicted all users, and disabled incoming \ - federation with the room." + "Finished bulk room ban, banned {room_ban_count} total rooms, evicted all users, \ + and disabled incoming federation with the room." ))) } else { Ok(RoomMessageEventContent::text_plain(format!( @@ -469,16 +502,20 @@ async fn ban_list_of_rooms(&self, force: bool, disable_federation: bool) -> Resu } #[admin_command] -async fn unban_room(&self, enable_federation: bool, room: Box) -> Result { +async fn unban_room( + &self, + enable_federation: bool, + room: Box, +) -> Result { let room_id = if room.is_room_id() { let room_id = match RoomId::parse(&room) { - Ok(room_id) => room_id, - Err(e) => { + | Ok(room_id) => room_id, + | Err(e) => return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to parse room ID {room}. Please note that this requires a full room ID \ - (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias (`#roomalias:example.com`): {e}" - ))) - }, + "Failed to parse room ID {room}. Please note that this requires a full room \ + ID (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias \ + (`#roomalias:example.com`): {e}" + ))), }; debug!("Room specified is a room ID, unbanning room ID"); @@ -488,18 +525,18 @@ async fn unban_room(&self, enable_federation: bool, room: Box) -> room_id } else if room.is_room_alias_id() { let room_alias = match RoomAliasId::parse(&room) { - Ok(room_alias) => room_alias, - Err(e) => { + | Ok(room_alias) => room_alias, + | Err(e) => return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to parse room ID {room}. Please note that this requires a full room ID \ - (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias (`#roomalias:example.com`): {e}" - ))) - }, + "Failed to parse room ID {room}. Please note that this requires a full room \ + ID (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias \ + (`#roomalias:example.com`): {e}" + ))), }; debug!( - "Room specified is not a room ID, attempting to resolve room alias to a room ID locally, if not using \ - get_alias_helper to fetch room ID remotely" + "Room specified is not a room ID, attempting to resolve room alias to a room ID \ + locally, if not using get_alias_helper to fetch room ID remotely" ); let room_id = if let Ok(room_id) = self @@ -511,7 +548,10 @@ async fn unban_room(&self, enable_federation: bool, room: Box) -> { room_id } else { - debug!("We don't have this room alias to a room ID locally, attempting to fetch room ID over federation"); + debug!( + "We don't have this room alias to a room ID locally, attempting to fetch room \ + ID over federation" + ); match self .services @@ -520,11 +560,15 @@ async fn unban_room(&self, enable_federation: bool, room: Box) -> .resolve_alias(&room_alias, None) .await { - Ok((room_id, servers)) => { - debug!(?room_id, ?servers, "Got federation response fetching room ID for room {room}"); + | Ok((room_id, servers)) => { + debug!( + ?room_id, + ?servers, + "Got federation response fetching room ID for room {room}" + ); room_id }, - Err(e) => { + | Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( "Failed to resolve room alias {room} to a room ID: {e}" ))); @@ -537,8 +581,9 @@ async fn unban_room(&self, enable_federation: bool, room: Box) -> room_id } else { return Ok(RoomMessageEventContent::text_plain( - "Room specified is not a room ID or room alias. Please note that this requires a full room ID \ - (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias (`#roomalias:example.com`)", + "Room specified is not a room ID or room alias. Please note that this requires a \ + full room ID (`!awIh6gGInaS5wLQJwa:example.com`) or a room alias \ + (`#roomalias:example.com`)", )); }; @@ -548,8 +593,8 @@ async fn unban_room(&self, enable_federation: bool, room: Box) -> } Ok(RoomMessageEventContent::text_plain( - "Room unbanned, you may need to re-enable federation with the room using enable-room if this is a remote room \ - to make it fully functional.", + "Room unbanned, you may need to re-enable federation with the room using enable-room if \ + this is a remote room to make it fully functional.", )) } diff --git a/src/admin/server/commands.rs b/src/admin/server/commands.rs index 676f2d334..8d3358a8f 100644 --- a/src/admin/server/commands.rs +++ b/src/admin/server/commands.rs @@ -29,13 +29,12 @@ pub(super) async fn show_config(&self) -> Result { #[admin_command] pub(super) async fn list_features( - &self, available: bool, enabled: bool, comma: bool, + &self, + available: bool, + enabled: bool, + comma: bool, ) -> Result { - let delim = if comma { - "," - } else { - " " - }; + let delim = if comma { "," } else { " " }; if enabled && !available { let features = info::rustc::features().join(delim); let out = format!("`\n{features}\n`"); @@ -53,16 +52,8 @@ pub(super) async fn list_features( let available = info::cargo::features(); for feature in available { let active = enabled.contains(&feature.as_str()); - let emoji = if active { - "✅" - } else { - "❌" - }; - let remark = if active { - "[enabled]" - } else { - "" - }; + let emoji = if active { "✅" } else { "❌" }; + let remark = if active { "[enabled]" } else { "" }; writeln!(features, "{emoji} {feature} {remark}")?; } @@ -73,7 +64,8 @@ pub(super) async fn list_features( pub(super) async fn memory_usage(&self) -> Result { let services_usage = self.services.memory_usage().await?; let database_usage = self.services.db.db.memory_usage()?; - let allocator_usage = conduwuit::alloc::memory_usage().map_or(String::new(), |s| format!("\nAllocator:\n{s}")); + let allocator_usage = + conduwuit::alloc::memory_usage().map_or(String::new(), |s| format!("\nAllocator:\n{s}")); Ok(RoomMessageEventContent::text_plain(format!( "Services:\n{services_usage}\nDatabase:\n{database_usage}{allocator_usage}", @@ -106,8 +98,8 @@ pub(super) async fn backup_database(&self) -> Result { .server .runtime() .spawn_blocking(move || match globals.db.backup() { - Ok(()) => String::new(), - Err(e) => e.to_string(), + | Ok(()) => String::new(), + | Err(e) => e.to_string(), }) .await?; @@ -147,8 +139,8 @@ pub(super) async fn restart(&self, force: bool) -> Result Result { } #[admin_command] -pub(super) async fn create_user(&self, username: String, password: Option) -> Result { +pub(super) async fn create_user( + &self, + username: String, + password: Option, +) -> Result { // Validate user id let user_id = parse_local_user_id(self.services, &username)?; if self.services.users.exists(&user_id).await { - return Ok(RoomMessageEventContent::text_plain(format!("Userid {user_id} already exists"))); + return Ok(RoomMessageEventContent::text_plain(format!( + "Userid {user_id} already exists" + ))); } if user_id.is_historical() { @@ -120,7 +126,9 @@ pub(super) async fn create_user(&self, username: String, password: Option { + | Ok(_response) => { info!("Automatically joined room {room} for user {user_id}"); }, - Err(e) => { + | Err(e) => { self.services .admin .send_message(RoomMessageEventContent::text_plain(format!( - "Failed to automatically join room {room} for user {user_id}: {e}" + "Failed to automatically join room {room} for user {user_id}: \ + {e}" ))) .await .ok(); // don't return this error so we don't fail registrations - error!("Failed to automatically join room {room} for user {user_id}: {e}"); + error!( + "Failed to automatically join room {room} for user {user_id}: {e}" + ); }, }; } @@ -181,7 +195,11 @@ pub(super) async fn create_user(&self, username: String, password: Option Result { +pub(super) async fn deactivate( + &self, + no_leave_rooms: bool, + user_id: String, +) -> Result { // Validate user id let user_id = parse_local_user_id(self.services, &user_id)?; @@ -229,7 +247,8 @@ pub(super) async fn reset_password(&self, username: String) -> Result Result Ok(RoomMessageEventContent::text_plain(format!( + | Ok(()) => Ok(RoomMessageEventContent::text_plain(format!( "Successfully reset the password for user {user_id}: `{new_password}`" ))), - Err(e) => Ok(RoomMessageEventContent::text_plain(format!( + | Err(e) => Ok(RoomMessageEventContent::text_plain(format!( "Couldn't reset the password for user {user_id}: {e}" ))), } } #[admin_command] -pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" +pub(super) async fn deactivate_all( + &self, + no_leave_rooms: bool, + force: bool, +) -> Result { + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -269,7 +294,7 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> for username in usernames { match parse_active_local_user_id(self.services, username).await { - Ok(user_id) => { + | Ok(user_id) => { if self.services.users.is_admin(&user_id).await && !force { self.services .admin @@ -296,7 +321,7 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> user_ids.push(user_id); }, - Err(e) => { + | Err(e) => { self.services .admin .send_message(RoomMessageEventContent::text_plain(format!( @@ -313,7 +338,7 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> for user_id in user_ids { match self.services.users.deactivate_account(&user_id).await { - Ok(()) => { + | Ok(()) => { deactivation_count = deactivation_count.saturating_add(1); if !no_leave_rooms { info!("Forcing user {user_id} to leave all rooms apart of deactivate-all"); @@ -328,14 +353,17 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> full_user_deactivate(self.services, &user_id, &all_joined_rooms).await?; update_displayname(self.services, &user_id, None, &all_joined_rooms).await; - update_avatar_url(self.services, &user_id, None, None, &all_joined_rooms).await; + update_avatar_url(self.services, &user_id, None, None, &all_joined_rooms) + .await; leave_all_rooms(self.services, &user_id).await; } }, - Err(e) => { + | Err(e) => { self.services .admin - .send_message(RoomMessageEventContent::text_plain(format!("Failed deactivating user: {e}"))) + .send_message(RoomMessageEventContent::text_plain(format!( + "Failed deactivating user: {e}" + ))) .await .ok(); }, @@ -348,8 +376,8 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> ))) } else { Ok(RoomMessageEventContent::text_plain(format!( - "Deactivated {deactivation_count} accounts.\nSkipped admin accounts: {}. Use --force to deactivate admin \ - accounts", + "Deactivated {deactivation_count} accounts.\nSkipped admin accounts: {}. Use \ + --force to deactivate admin accounts", admins.join(", ") ))) } @@ -391,9 +419,13 @@ pub(super) async fn list_joined_rooms(&self, user_id: String) -> Result Result { - if self.body.len() < 2 || !self.body[0].trim().starts_with("```") || self.body.last().unwrap_or(&"").trim() != "```" + if self.body.len() < 2 + || !self.body[0].trim().starts_with("```") + || self.body.last().unwrap_or(&"").trim() != "```" { return Ok(RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", @@ -402,8 +434,8 @@ pub(super) async fn force_join_list_of_local_users( if !yes_i_want_to_do_this { return Ok(RoomMessageEventContent::notice_markdown( - "You must pass the --yes-i-want-to-do-this-flag to ensure you really want to force bulk join all \ - specified local users.", + "You must pass the --yes-i-want-to-do-this-flag to ensure you really want to force \ + bulk join all specified local users.", )); } @@ -462,7 +494,7 @@ pub(super) async fn force_join_list_of_local_users( for username in usernames { match parse_active_local_user_id(self.services, username).await { - Ok(user_id) => { + | Ok(user_id) => { // don't make the server service account join if user_id == self.services.globals.server_user { self.services @@ -477,7 +509,7 @@ pub(super) async fn force_join_list_of_local_users( user_ids.push(user_id); }, - Err(e) => { + | Err(e) => { self.services .admin .send_message(RoomMessageEventContent::text_plain(format!( @@ -505,10 +537,10 @@ pub(super) async fn force_join_list_of_local_users( ) .await { - Ok(_res) => { + | Ok(_res) => { successful_joins = successful_joins.saturating_add(1); }, - Err(e) => { + | Err(e) => { debug_warn!("Failed force joining {user_id} to {room_id} during bulk join: {e}"); failed_joins = failed_joins.saturating_add(1); }, @@ -516,18 +548,21 @@ pub(super) async fn force_join_list_of_local_users( } Ok(RoomMessageEventContent::notice_markdown(format!( - "{successful_joins} local users have been joined to {room_id}. {failed_joins} joins failed.", + "{successful_joins} local users have been joined to {room_id}. {failed_joins} joins \ + failed.", ))) } #[admin_command] pub(super) async fn force_join_all_local_users( - &self, room_id: OwnedRoomOrAliasId, yes_i_want_to_do_this: bool, + &self, + room_id: OwnedRoomOrAliasId, + yes_i_want_to_do_this: bool, ) -> Result { if !yes_i_want_to_do_this { return Ok(RoomMessageEventContent::notice_markdown( - "You must pass the --yes-i-want-to-do-this-flag to ensure you really want to force bulk join all local \ - users.", + "You must pass the --yes-i-want-to-do-this-flag to ensure you really want to force \ + bulk join all local users.", )); } @@ -598,10 +633,10 @@ pub(super) async fn force_join_all_local_users( ) .await { - Ok(_res) => { + | Ok(_res) => { successful_joins = successful_joins.saturating_add(1); }, - Err(e) => { + | Err(e) => { debug_warn!("Failed force joining {user_id} to {room_id} during bulk join: {e}"); failed_joins = failed_joins.saturating_add(1); }, @@ -609,13 +644,16 @@ pub(super) async fn force_join_all_local_users( } Ok(RoomMessageEventContent::notice_markdown(format!( - "{successful_joins} local users have been joined to {room_id}. {failed_joins} joins failed.", + "{successful_joins} local users have been joined to {room_id}. {failed_joins} joins \ + failed.", ))) } #[admin_command] pub(super) async fn force_join_room( - &self, user_id: String, room_id: OwnedRoomOrAliasId, + &self, + user_id: String, + room_id: OwnedRoomOrAliasId, ) -> Result { let user_id = parse_local_user_id(self.services, &user_id)?; let (room_id, servers) = self @@ -629,7 +667,8 @@ pub(super) async fn force_join_room( self.services.globals.user_is_local(&user_id), "Parsed user_id must be a local user" ); - join_room_by_id_helper(self.services, &user_id, &room_id, None, &servers, None, &None).await?; + join_room_by_id_helper(self.services, &user_id, &room_id, None, &servers, None, &None) + .await?; Ok(RoomMessageEventContent::notice_markdown(format!( "{user_id} has been joined to {room_id}.", @@ -638,7 +677,9 @@ pub(super) async fn force_join_room( #[admin_command] pub(super) async fn force_leave_room( - &self, user_id: String, room_id: OwnedRoomOrAliasId, + &self, + user_id: String, + room_id: OwnedRoomOrAliasId, ) -> Result { let user_id = parse_local_user_id(self.services, &user_id)?; let room_id = self.services.rooms.alias.resolve(&room_id).await?; @@ -656,7 +697,9 @@ pub(super) async fn force_leave_room( #[admin_command] pub(super) async fn force_demote( - &self, user_id: String, room_id: OwnedRoomOrAliasId, + &self, + user_id: String, + room_id: OwnedRoomOrAliasId, ) -> Result { let user_id = parse_local_user_id(self.services, &user_id)?; let room_id = self.services.rooms.alias.resolve(&room_id).await?; @@ -672,14 +715,19 @@ pub(super) async fn force_demote( .services .rooms .state_accessor - .room_state_get_content::(&room_id, &StateEventType::RoomPowerLevels, "") + .room_state_get_content::( + &room_id, + &StateEventType::RoomPowerLevels, + "", + ) .await .ok(); let user_can_demote_self = room_power_levels .as_ref() .is_some_and(|power_levels_content| { - RoomPowerLevels::from(power_levels_content.clone()).user_can_change_user_power_level(&user_id, &user_id) + RoomPowerLevels::from(power_levels_content.clone()) + .user_can_change_user_power_level(&user_id, &user_id) }) || self .services .rooms @@ -710,7 +758,8 @@ pub(super) async fn force_demote( .await?; Ok(RoomMessageEventContent::notice_markdown(format!( - "User {user_id} demoted themselves to the room default power level in {room_id} - {event_id}" + "User {user_id} demoted themselves to the room default power level in {room_id} - \ + {event_id}" ))) } @@ -731,7 +780,10 @@ pub(super) async fn make_user_admin(&self, user_id: String) -> Result, tag: String, + &self, + user_id: String, + room_id: Box, + tag: String, ) -> Result { let user_id = parse_active_local_user_id(self.services, &user_id).await?; @@ -741,9 +793,7 @@ pub(super) async fn put_room_tag( .get_room(&room_id, &user_id, RoomAccountDataEventType::Tag) .await .unwrap_or(TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); tags_event @@ -768,7 +818,10 @@ pub(super) async fn put_room_tag( #[admin_command] pub(super) async fn delete_room_tag( - &self, user_id: String, room_id: Box, tag: String, + &self, + user_id: String, + room_id: Box, + tag: String, ) -> Result { let user_id = parse_active_local_user_id(self.services, &user_id).await?; @@ -778,9 +831,7 @@ pub(super) async fn delete_room_tag( .get_room(&room_id, &user_id, RoomAccountDataEventType::Tag) .await .unwrap_or(TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); tags_event.content.tags.remove(&tag.clone().into()); @@ -796,12 +847,17 @@ pub(super) async fn delete_room_tag( .await?; Ok(RoomMessageEventContent::text_plain(format!( - "Successfully updated room account data for {user_id} and room {room_id}, deleting room tag {tag}" + "Successfully updated room account data for {user_id} and room {room_id}, deleting room \ + tag {tag}" ))) } #[admin_command] -pub(super) async fn get_room_tags(&self, user_id: String, room_id: Box) -> Result { +pub(super) async fn get_room_tags( + &self, + user_id: String, + room_id: Box, +) -> Result { let user_id = parse_active_local_user_id(self.services, &user_id).await?; let tags_event = self @@ -810,9 +866,7 @@ pub(super) async fn get_room_tags(&self, user_id: String, room_id: Box) .get_room(&room_id, &user_id, RoomAccountDataEventType::Tag) .await .unwrap_or(TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); Ok(RoomMessageEventContent::notice_markdown(format!( @@ -822,7 +876,10 @@ pub(super) async fn get_room_tags(&self, user_id: String, room_id: Box) } #[admin_command] -pub(super) async fn redact_event(&self, event_id: Box) -> Result { +pub(super) async fn redact_event( + &self, + event_id: Box, +) -> Result { let Ok(event) = self .services .rooms @@ -841,7 +898,9 @@ pub(super) async fn redact_event(&self, event_id: Box) -> Result String { .replace('>', ">") } -pub(crate) async fn get_room_info(services: &Services, room_id: &RoomId) -> (OwnedRoomId, u64, String) { +pub(crate) async fn get_room_info( + services: &Services, + room_id: &RoomId, +) -> (OwnedRoomId, u64, String) { ( room_id.into(), services @@ -44,7 +47,10 @@ pub(crate) fn parse_local_user_id(services: &Services, user_id: &str) -> Result< } /// Parses user ID that is an active (not guest or deactivated) local user -pub(crate) async fn parse_active_local_user_id(services: &Services, user_id: &str) -> Result { +pub(crate) async fn parse_active_local_user_id( + services: &Services, + user_id: &str, +) -> Result { let user_id = parse_local_user_id(services, user_id)?; if !services.users.exists(&user_id).await { diff --git a/src/api/client/account.rs b/src/api/client/account.rs index 71e18fd3a..e67481249 100644 --- a/src/api/client/account.rs +++ b/src/api/client/account.rs @@ -2,16 +2,19 @@ use std::fmt::Write; use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduwuit::{debug_info, error, info, is_equal_to, utils, utils::ReadyExt, warn, Error, PduBuilder, Result}; +use conduwuit::{ + debug_info, error, info, is_equal_to, utils, utils::ReadyExt, warn, Error, PduBuilder, Result, +}; use futures::{FutureExt, StreamExt}; use register::RegistrationKind; use ruma::{ api::client::{ account::{ - change_password, check_registration_token_validity, deactivate, get_3pids, get_username_availability, + change_password, check_registration_token_validity, deactivate, get_3pids, + get_username_availability, register::{self, LoginType}, - request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, whoami, - ThirdPartyIdRemovalStatus, + request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, + whoami, ThirdPartyIdRemovalStatus, }, error::ErrorKind, uiaa::{AuthFlow, AuthType, UiaaInfo}, @@ -45,7 +48,8 @@ const RANDOM_USER_ID_LENGTH: usize = 10; /// invalid when trying to register #[tracing::instrument(skip_all, fields(%client), name = "register_available")] pub(crate) async fn get_register_available_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { // workaround for https://github.com/matrix-org/matrix-appservice-irc/issues/1780 due to inactivity of fixing the issue @@ -66,7 +70,8 @@ pub(crate) async fn get_register_available_route( let user_id = UserId::parse_with_server_name(body_username, services.globals.server_name()) .ok() .filter(|user_id| { - (!user_id.is_historical() || is_matrix_appservice_irc) && services.globals.user_is_local(user_id) + (!user_id.is_historical() || is_matrix_appservice_irc) + && services.globals.user_is_local(user_id) }) .ok_or(Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."))?; @@ -86,9 +91,7 @@ pub(crate) async fn get_register_available_route( // TODO add check for appservice namespaces // If no if check is true we have an username that's available to be used. - Ok(get_username_availability::v3::Response { - available: true, - }) + Ok(get_username_availability::v3::Response { available: true }) } /// # `POST /_matrix/client/v3/register` @@ -111,12 +114,14 @@ pub(crate) async fn get_register_available_route( #[allow(clippy::doc_markdown)] #[tracing::instrument(skip_all, fields(%client), name = "register")] pub(crate) async fn register_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, body: Ruma, + State(services): State, + InsecureClientIp(client): InsecureClientIp, + body: Ruma, ) -> Result { if !services.globals.allow_registration() && body.appservice_info.is_none() { info!( - "Registration disabled and request not from known appservice, rejecting registration attempt for username \ - \"{}\"", + "Registration disabled and request not from known appservice, rejecting \ + registration attempt for username \"{}\"", body.username.as_deref().unwrap_or("") ); return Err(Error::BadRequest(ErrorKind::forbidden(), "Registration has been disabled.")); @@ -126,11 +131,12 @@ pub(crate) async fn register_route( if is_guest && (!services.globals.allow_guest_registration() - || (services.globals.allow_registration() && services.globals.registration_token.is_some())) + || (services.globals.allow_registration() + && services.globals.registration_token.is_some())) { info!( - "Guest registration disabled / registration enabled with token configured, rejecting guest registration \ - attempt, initial device name: \"{}\"", + "Guest registration disabled / registration enabled with token configured, \ + rejecting guest registration attempt, initial device name: \"{}\"", body.initial_device_display_name.as_deref().unwrap_or("") ); return Err(Error::BadRequest( @@ -143,21 +149,25 @@ pub(crate) async fn register_route( // generic user error. if is_guest && services.users.count().await < 2 { warn!( - "Guest account attempted to register before a real admin user has been registered, rejecting \ - registration. Guest's initial device name: \"{}\"", + "Guest account attempted to register before a real admin user has been registered, \ + rejecting registration. Guest's initial device name: \"{}\"", body.initial_device_display_name.as_deref().unwrap_or("") ); - return Err(Error::BadRequest(ErrorKind::forbidden(), "Registration temporarily disabled.")); + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "Registration temporarily disabled.", + )); } let user_id = match (&body.username, is_guest) { - (Some(username), false) => { + | (Some(username), false) => { // workaround for https://github.com/matrix-org/matrix-appservice-irc/issues/1780 due to inactivity of fixing the issue - let is_matrix_appservice_irc = body.appservice_info.as_ref().is_some_and(|appservice| { - appservice.registration.id == "irc" - || appservice.registration.id.contains("matrix-appservice-irc") - || appservice.registration.id.contains("matrix_appservice_irc") - }); + let is_matrix_appservice_irc = + body.appservice_info.as_ref().is_some_and(|appservice| { + appservice.registration.id == "irc" + || appservice.registration.id.contains("matrix-appservice-irc") + || appservice.registration.id.contains("matrix_appservice_irc") + }); // don't force the username lowercase if it's from matrix-appservice-irc let body_username = if is_matrix_appservice_irc { @@ -166,15 +176,23 @@ pub(crate) async fn register_route( username.to_lowercase() }; - let proposed_user_id = UserId::parse_with_server_name(body_username, services.globals.server_name()) - .ok() - .filter(|user_id| { - (!user_id.is_historical() || is_matrix_appservice_irc) && services.globals.user_is_local(user_id) - }) - .ok_or(Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."))?; + let proposed_user_id = + UserId::parse_with_server_name(body_username, services.globals.server_name()) + .ok() + .filter(|user_id| { + (!user_id.is_historical() || is_matrix_appservice_irc) + && services.globals.user_is_local(user_id) + }) + .ok_or(Error::BadRequest( + ErrorKind::InvalidUsername, + "Username is invalid.", + ))?; if services.users.exists(&proposed_user_id).await { - return Err(Error::BadRequest(ErrorKind::UserInUse, "Desired user ID is already taken.")); + return Err(Error::BadRequest( + ErrorKind::UserInUse, + "Desired user ID is already taken.", + )); } if services @@ -187,7 +205,7 @@ pub(crate) async fn register_route( proposed_user_id }, - _ => loop { + | _ => loop { let proposed_user_id = UserId::parse_with_server_name( utils::random_string(RANDOM_USER_ID_LENGTH).to_lowercase(), services.globals.server_name(), @@ -228,9 +246,7 @@ pub(crate) async fn register_route( } else { // No registration token necessary, but clients must still go through the flow uiaainfo = UiaaInfo { - flows: vec![AuthFlow { - stages: vec![AuthType::Dummy], - }], + flows: vec![AuthFlow { stages: vec![AuthType::Dummy] }], completed: Vec::new(), params: Box::default(), session: None, @@ -244,7 +260,8 @@ pub(crate) async fn register_route( let (worked, uiaainfo) = services .uiaa .try_auth( - &UserId::parse_with_server_name("", services.globals.server_name()).expect("we know this is valid"), + &UserId::parse_with_server_name("", services.globals.server_name()) + .expect("we know this is valid"), "".into(), auth, &uiaainfo, @@ -257,7 +274,8 @@ pub(crate) async fn register_route( } else if let Some(json) = body.json_body { uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); services.uiaa.create( - &UserId::parse_with_server_name("", services.globals.server_name()).expect("we know this is valid"), + &UserId::parse_with_server_name("", services.globals.server_name()) + .expect("we know this is valid"), "".into(), &uiaainfo, &json, @@ -268,11 +286,7 @@ pub(crate) async fn register_route( } } - let password = if is_guest { - None - } else { - body.password.as_deref() - }; + let password = if is_guest { None } else { body.password.as_deref() }; // Create user services.users.create(&user_id, password)?; @@ -282,7 +296,9 @@ pub(crate) async fn register_route( // If `new_user_displayname_suffix` is set, registration will push whatever // content is set to the user's display name with a space before it - if !services.globals.new_user_displayname_suffix().is_empty() && body.appservice_info.is_none() { + if !services.globals.new_user_displayname_suffix().is_empty() + && body.appservice_info.is_none() + { write!(displayname, " {}", services.globals.config.new_user_displayname_suffix) .expect("should be able to write to string buffer"); } @@ -319,12 +335,8 @@ pub(crate) async fn register_route( } // Generate new device id if the user didn't specify one - let device_id = if is_guest { - None - } else { - body.device_id.clone() - } - .unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH).into()); + let device_id = if is_guest { None } else { body.device_id.clone() } + .unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH).into()); // Generate new token for the device let token = utils::random_string(TOKEN_LENGTH); @@ -349,15 +361,16 @@ pub(crate) async fn register_route( if body.appservice_info.is_none() && !is_guest { if !device_display_name.is_empty() { info!( - "New user \"{user_id}\" registered on this server with device display name: \"{device_display_name}\"" + "New user \"{user_id}\" registered on this server with device display name: \ + \"{device_display_name}\"" ); if services.globals.config.admin_room_notices { services .admin .send_message(RoomMessageEventContent::notice_plain(format!( - "New user \"{user_id}\" registered on this server from IP {client} and device display name \ - \"{device_display_name}\"" + "New user \"{user_id}\" registered on this server from IP {client} and \ + device display name \"{device_display_name}\"" ))) .await .ok(); @@ -386,8 +399,8 @@ pub(crate) async fn register_route( services .admin .send_message(RoomMessageEventContent::notice_plain(format!( - "Guest user \"{user_id}\" with device display name \"{device_display_name}\" registered on \ - this server from IP {client}" + "Guest user \"{user_id}\" with device display name \ + \"{device_display_name}\" registered on this server from IP {client}" ))) .await .ok(); @@ -398,8 +411,8 @@ pub(crate) async fn register_route( services .admin .send_message(RoomMessageEventContent::notice_plain(format!( - "Guest user \"{user_id}\" with no device display name registered on this server from IP \ - {client}", + "Guest user \"{user_id}\" with no device display name registered on \ + this server from IP {client}", ))) .await .ok(); @@ -430,7 +443,10 @@ pub(crate) async fn register_route( { for room in &services.globals.config.auto_join_rooms { let Ok(room_id) = services.rooms.alias.resolve(room).await else { - error!("Failed to resolve room alias to room ID when attempting to auto join {room}, skipping"); + error!( + "Failed to resolve room alias to room ID when attempting to auto join \ + {room}, skipping" + ); continue; }; @@ -440,7 +456,9 @@ pub(crate) async fn register_route( .server_in_room(services.globals.server_name(), &room_id) .await { - warn!("Skipping room {room} to automatically join as we have never joined before."); + warn!( + "Skipping room {room} to automatically join as we have never joined before." + ); continue; } @@ -494,7 +512,8 @@ pub(crate) async fn register_route( /// - Triggers device list updates #[tracing::instrument(skip_all, fields(%client), name = "change_password")] pub(crate) async fn change_password_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { // Authentication for this endpoint was made optional, but we need @@ -506,9 +525,7 @@ pub(crate) async fn change_password_route( let sender_device = body.sender_device.as_ref().expect("user is authenticated"); let mut uiaainfo = UiaaInfo { - flows: vec![AuthFlow { - stages: vec![AuthType::Password], - }], + flows: vec![AuthFlow { stages: vec![AuthType::Password] }], completed: Vec::new(), params: Box::default(), session: None, @@ -572,7 +589,8 @@ pub(crate) async fn change_password_route( /// /// Note: Also works for Application Services pub(crate) async fn whoami_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let device_id = body.sender_device.clone(); @@ -580,7 +598,8 @@ pub(crate) async fn whoami_route( Ok(whoami::v3::Response { user_id: sender_user.clone(), device_id, - is_guest: services.users.is_deactivated(sender_user).await? && body.appservice_info.is_none(), + is_guest: services.users.is_deactivated(sender_user).await? + && body.appservice_info.is_none(), }) } @@ -597,7 +616,8 @@ pub(crate) async fn whoami_route( /// - Removes ability to log in again #[tracing::instrument(skip_all, fields(%client), name = "deactivate")] pub(crate) async fn deactivate_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { // Authentication for this endpoint was made optional, but we need @@ -609,9 +629,7 @@ pub(crate) async fn deactivate_route( let sender_device = body.sender_device.as_ref().expect("user is authenticated"); let mut uiaainfo = UiaaInfo { - flows: vec![AuthFlow { - stages: vec![AuthType::Password], - }], + flows: vec![AuthFlow { stages: vec![AuthType::Password] }], completed: Vec::new(), params: Box::default(), session: None, @@ -675,7 +693,9 @@ pub(crate) async fn deactivate_route( /// Get a list of third party identifiers associated with this account. /// /// - Currently always returns empty list -pub(crate) async fn third_party_route(body: Ruma) -> Result { +pub(crate) async fn third_party_route( + body: Ruma, +) -> Result { let _sender_user = body.sender_user.as_ref().expect("user is authenticated"); Ok(get_3pids::v3::Response::new(Vec::new())) @@ -720,7 +740,8 @@ pub(crate) async fn request_3pid_management_token_via_msisdn_route( /// Currently does not have any ratelimiting, and this isn't very practical as /// there is only one registration token allowed. pub(crate) async fn check_registration_token_validity( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let Some(reg_token) = services.globals.registration_token.clone() else { return Err(Error::BadRequest( @@ -729,9 +750,7 @@ pub(crate) async fn check_registration_token_validity( )); }; - Ok(check_registration_token_validity::v1::Response { - valid: reg_token == body.token, - }) + Ok(check_registration_token_validity::v1::Response { valid: reg_token == body.token }) } /// Runs through all the deactivation steps: @@ -742,7 +761,9 @@ pub(crate) async fn check_registration_token_validity( /// - Removing all profile data /// - Leaving all rooms (and forgets all of them) pub async fn full_user_deactivate( - services: &Services, user_id: &UserId, all_joined_rooms: &[OwnedRoomId], + services: &Services, + user_id: &UserId, + all_joined_rooms: &[OwnedRoomId], ) -> Result<()> { services.users.deactivate_account(user_id).await.ok(); super::update_displayname(services, user_id, None, all_joined_rooms).await; @@ -751,7 +772,9 @@ pub async fn full_user_deactivate( services .users .all_profile_keys(user_id) - .ready_for_each(|(profile_key, _)| services.users.set_profile_key(user_id, &profile_key, None)) + .ready_for_each(|(profile_key, _)| { + services.users.set_profile_key(user_id, &profile_key, None); + }) .await; for room_id in all_joined_rooms { @@ -760,20 +783,26 @@ pub async fn full_user_deactivate( let room_power_levels = services .rooms .state_accessor - .room_state_get_content::(room_id, &StateEventType::RoomPowerLevels, "") + .room_state_get_content::( + room_id, + &StateEventType::RoomPowerLevels, + "", + ) .await .ok(); - let user_can_demote_self = room_power_levels - .as_ref() - .is_some_and(|power_levels_content| { - RoomPowerLevels::from(power_levels_content.clone()).user_can_change_user_power_level(user_id, user_id) - }) || services - .rooms - .state_accessor - .room_state_get(room_id, &StateEventType::RoomCreate, "") - .await - .is_ok_and(|event| event.sender == user_id); + let user_can_demote_self = + room_power_levels + .as_ref() + .is_some_and(|power_levels_content| { + RoomPowerLevels::from(power_levels_content.clone()) + .user_can_change_user_power_level(user_id, user_id) + }) || services + .rooms + .state_accessor + .room_state_get(room_id, &StateEventType::RoomCreate, "") + .await + .is_ok_and(|event| event.sender == user_id); if user_can_demote_self { let mut power_levels_content = room_power_levels.unwrap_or_default(); diff --git a/src/api/client/account_data.rs b/src/api/client/account_data.rs index 2fc788088..9f84f2279 100644 --- a/src/api/client/account_data.rs +++ b/src/api/client/account_data.rs @@ -2,11 +2,12 @@ use axum::extract::State; use conduwuit::{err, Err}; use ruma::{ api::client::config::{ - get_global_account_data, get_room_account_data, set_global_account_data, set_room_account_data, + get_global_account_data, get_room_account_data, set_global_account_data, + set_room_account_data, }, events::{ - AnyGlobalAccountDataEventContent, AnyRoomAccountDataEventContent, GlobalAccountDataEventType, - RoomAccountDataEventType, + AnyGlobalAccountDataEventContent, AnyRoomAccountDataEventContent, + GlobalAccountDataEventType, RoomAccountDataEventType, }, serde::Raw, RoomId, UserId, @@ -20,7 +21,8 @@ use crate::{service::Services, Result, Ruma}; /// /// Sets some account data for the sender user. pub(crate) async fn set_global_account_data_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -28,7 +30,14 @@ pub(crate) async fn set_global_account_data_route( return Err!(Request(Forbidden("You cannot set account data for other users."))); } - set_account_data(&services, None, &body.user_id, &body.event_type.to_string(), body.data.json()).await?; + set_account_data( + &services, + None, + &body.user_id, + &body.event_type.to_string(), + body.data.json(), + ) + .await?; Ok(set_global_account_data::v3::Response {}) } @@ -37,7 +46,8 @@ pub(crate) async fn set_global_account_data_route( /// /// Sets some room account data for the sender user. pub(crate) async fn set_room_account_data_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -61,7 +71,8 @@ pub(crate) async fn set_room_account_data_route( /// /// Gets some account data for the sender user. pub(crate) async fn get_global_account_data_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -75,16 +86,15 @@ pub(crate) async fn get_global_account_data_route( .await .map_err(|_| err!(Request(NotFound("Data not found."))))?; - Ok(get_global_account_data::v3::Response { - account_data: account_data.content, - }) + Ok(get_global_account_data::v3::Response { account_data: account_data.content }) } /// # `GET /_matrix/client/r0/user/{userId}/rooms/{roomId}/account_data/{type}` /// /// Gets some room account data for the sender user. pub(crate) async fn get_room_account_data_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -98,17 +108,20 @@ pub(crate) async fn get_room_account_data_route( .await .map_err(|_| err!(Request(NotFound("Data not found."))))?; - Ok(get_room_account_data::v3::Response { - account_data: account_data.content, - }) + Ok(get_room_account_data::v3::Response { account_data: account_data.content }) } async fn set_account_data( - services: &Services, room_id: Option<&RoomId>, sender_user: &UserId, event_type_s: &str, data: &RawJsonValue, + services: &Services, + room_id: Option<&RoomId>, + sender_user: &UserId, + event_type_s: &str, + data: &RawJsonValue, ) -> Result { if event_type_s == RoomAccountDataEventType::FullyRead.to_cow_str() { return Err!(Request(BadJson( - "This endpoint cannot be used for marking a room as fully read (setting m.fully_read)" + "This endpoint cannot be used for marking a room as fully read (setting \ + m.fully_read)" ))); } @@ -118,8 +131,8 @@ async fn set_account_data( ))); } - let data: serde_json::Value = - serde_json::from_str(data.get()).map_err(|e| err!(Request(BadJson(warn!("Invalid JSON provided: {e}")))))?; + let data: serde_json::Value = serde_json::from_str(data.get()) + .map_err(|e| err!(Request(BadJson(warn!("Invalid JSON provided: {e}")))))?; services .account_data diff --git a/src/api/client/alias.rs b/src/api/client/alias.rs index c60a2f4cf..e1af416e9 100644 --- a/src/api/client/alias.rs +++ b/src/api/client/alias.rs @@ -14,7 +14,8 @@ use crate::Ruma; /// /// Creates a new room alias on this server. pub(crate) async fn create_alias_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -58,7 +59,8 @@ pub(crate) async fn create_alias_route( /// /// - TODO: Update canonical alias event pub(crate) async fn delete_alias_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -83,11 +85,13 @@ pub(crate) async fn delete_alias_route( /// /// Resolve an alias locally or over federation. pub(crate) async fn get_alias_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let room_alias = body.body.room_alias; - let Ok((room_id, servers)) = services.rooms.alias.resolve_alias(&room_alias, None).await else { + let Ok((room_id, servers)) = services.rooms.alias.resolve_alias(&room_alias, None).await + else { return Err!(Request(NotFound("Room with alias not found."))); }; @@ -98,7 +102,10 @@ pub(crate) async fn get_alias_route( } async fn room_available_servers( - services: &Services, room_id: &RoomId, room_alias: &RoomAliasId, pre_servers: Vec, + services: &Services, + room_id: &RoomId, + room_alias: &RoomAliasId, + pre_servers: Vec, ) -> Vec { // find active servers in room state cache to suggest let mut servers: Vec = services diff --git a/src/api/client/appservice.rs b/src/api/client/appservice.rs index 9dbd141e3..e4071ab08 100644 --- a/src/api/client/appservice.rs +++ b/src/api/client/appservice.rs @@ -9,12 +9,12 @@ use crate::Ruma; /// Ask the homeserver to ping the application service to ensure the connection /// works. pub(crate) async fn appservice_ping( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { - let appservice_info = body - .appservice_info - .as_ref() - .ok_or_else(|| err!(Request(Forbidden("This endpoint can only be called by appservices."))))?; + let appservice_info = body.appservice_info.as_ref().ok_or_else(|| { + err!(Request(Forbidden("This endpoint can only be called by appservices."))) + })?; if body.appservice_id != appservice_info.registration.id { return Err!(Request(Forbidden( @@ -41,7 +41,5 @@ pub(crate) async fn appservice_ping( .await? .expect("We already validated if an appservice URL exists above"); - Ok(request_ping::v1::Response { - duration: timer.elapsed(), - }) + Ok(request_ping::v1::Response { duration: timer.elapsed() }) } diff --git a/src/api/client/backup.rs b/src/api/client/backup.rs index 9e4746ca1..d330952db 100644 --- a/src/api/client/backup.rs +++ b/src/api/client/backup.rs @@ -2,10 +2,11 @@ use axum::extract::State; use conduwuit::{err, Err}; use ruma::{ api::client::backup::{ - add_backup_keys, add_backup_keys_for_room, add_backup_keys_for_session, create_backup_version, - delete_backup_keys, delete_backup_keys_for_room, delete_backup_keys_for_session, delete_backup_version, - get_backup_info, get_backup_keys, get_backup_keys_for_room, get_backup_keys_for_session, - get_latest_backup_info, update_backup_version, + add_backup_keys, add_backup_keys_for_room, add_backup_keys_for_session, + create_backup_version, delete_backup_keys, delete_backup_keys_for_room, + delete_backup_keys_for_session, delete_backup_version, get_backup_info, get_backup_keys, + get_backup_keys_for_room, get_backup_keys_for_session, get_latest_backup_info, + update_backup_version, }, UInt, }; @@ -16,15 +17,14 @@ use crate::{Result, Ruma}; /// /// Creates a new backup. pub(crate) async fn create_backup_version_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let version = services .key_backups .create_backup(body.sender_user(), &body.algorithm)?; - Ok(create_backup_version::v3::Response { - version, - }) + Ok(create_backup_version::v3::Response { version }) } /// # `PUT /_matrix/client/r0/room_keys/version/{version}` @@ -32,7 +32,8 @@ pub(crate) async fn create_backup_version_route( /// Update information about an existing backup. Only `auth_data` can be /// modified. pub(crate) async fn update_backup_version_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { services .key_backups @@ -46,7 +47,8 @@ pub(crate) async fn update_backup_version_route( /// /// Get information about the latest backup version. pub(crate) async fn get_latest_backup_info_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let (version, algorithm) = services .key_backups @@ -75,13 +77,16 @@ pub(crate) async fn get_latest_backup_info_route( /// /// Get information about an existing backup. pub(crate) async fn get_backup_info_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let algorithm = services .key_backups .get_backup(body.sender_user(), &body.version) .await - .map_err(|_| err!(Request(NotFound("Key backup does not exist at version {:?}", body.version))))?; + .map_err(|_| { + err!(Request(NotFound("Key backup does not exist at version {:?}", body.version))) + })?; Ok(get_backup_info::v3::Response { algorithm, @@ -105,7 +110,8 @@ pub(crate) async fn get_backup_info_route( /// - Deletes both information about the backup, as well as all key data related /// to the backup pub(crate) async fn delete_backup_version_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { services .key_backups @@ -124,7 +130,8 @@ pub(crate) async fn delete_backup_version_route( /// - Adds the keys to the backup /// - Returns the new number of keys in this backup and the etag pub(crate) async fn add_backup_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if services .key_backups @@ -168,7 +175,8 @@ pub(crate) async fn add_backup_keys_route( /// - Adds the keys to the backup /// - Returns the new number of keys in this backup and the etag pub(crate) async fn add_backup_keys_for_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if services .key_backups @@ -210,7 +218,8 @@ pub(crate) async fn add_backup_keys_for_room_route( /// - Adds the keys to the backup /// - Returns the new number of keys in this backup and the etag pub(crate) async fn add_backup_keys_for_session_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if services .key_backups @@ -251,56 +260,56 @@ pub(crate) async fn add_backup_keys_for_session_route( /// /// Retrieves all keys from the backup. pub(crate) async fn get_backup_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let rooms = services .key_backups .get_all(body.sender_user(), &body.version) .await; - Ok(get_backup_keys::v3::Response { - rooms, - }) + Ok(get_backup_keys::v3::Response { rooms }) } /// # `GET /_matrix/client/r0/room_keys/keys/{roomId}` /// /// Retrieves all keys from the backup for a given room. pub(crate) async fn get_backup_keys_for_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sessions = services .key_backups .get_room(body.sender_user(), &body.version, &body.room_id) .await; - Ok(get_backup_keys_for_room::v3::Response { - sessions, - }) + Ok(get_backup_keys_for_room::v3::Response { sessions }) } /// # `GET /_matrix/client/r0/room_keys/keys/{roomId}/{sessionId}` /// /// Retrieves a key from the backup. pub(crate) async fn get_backup_keys_for_session_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let key_data = services .key_backups .get_session(body.sender_user(), &body.version, &body.room_id, &body.session_id) .await - .map_err(|_| err!(Request(NotFound(debug_error!("Backup key not found for this user's session.")))))?; + .map_err(|_| { + err!(Request(NotFound(debug_error!("Backup key not found for this user's session.")))) + })?; - Ok(get_backup_keys_for_session::v3::Response { - key_data, - }) + Ok(get_backup_keys_for_session::v3::Response { key_data }) } /// # `DELETE /_matrix/client/r0/room_keys/keys` /// /// Delete the keys from the backup. pub(crate) async fn delete_backup_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { services .key_backups @@ -324,7 +333,8 @@ pub(crate) async fn delete_backup_keys_route( /// /// Delete the keys from the backup for a given room. pub(crate) async fn delete_backup_keys_for_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { services .key_backups @@ -348,7 +358,8 @@ pub(crate) async fn delete_backup_keys_for_room_route( /// /// Delete a key from the backup. pub(crate) async fn delete_backup_keys_for_session_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { services .key_backups diff --git a/src/api/client/capabilities.rs b/src/api/client/capabilities.rs index 20f9cb58b..e122611f7 100644 --- a/src/api/client/capabilities.rs +++ b/src/api/client/capabilities.rs @@ -3,8 +3,8 @@ use std::collections::BTreeMap; use axum::extract::State; use ruma::{ api::client::discovery::get_capabilities::{ - self, Capabilities, GetLoginTokenCapability, RoomVersionStability, RoomVersionsCapability, - ThirdPartyIdChangesCapability, + self, Capabilities, GetLoginTokenCapability, RoomVersionStability, + RoomVersionsCapability, ThirdPartyIdChangesCapability, }, RoomVersionId, }; @@ -17,9 +17,11 @@ use crate::{Result, Ruma}; /// Get information on the supported feature set and other relevent capabilities /// of this server. pub(crate) async fn get_capabilities_route( - State(services): State, _body: Ruma, + State(services): State, + _body: Ruma, ) -> Result { - let available: BTreeMap = services.server.available_room_versions().collect(); + let available: BTreeMap = + services.server.available_room_versions().collect(); let mut capabilities = Capabilities::default(); capabilities.room_versions = RoomVersionsCapability { @@ -28,21 +30,15 @@ pub(crate) async fn get_capabilities_route( }; // we do not implement 3PID stuff - capabilities.thirdparty_id_changes = ThirdPartyIdChangesCapability { - enabled: false, - }; + capabilities.thirdparty_id_changes = ThirdPartyIdChangesCapability { enabled: false }; // we dont support generating tokens yet - capabilities.get_login_token = GetLoginTokenCapability { - enabled: false, - }; + capabilities.get_login_token = GetLoginTokenCapability { enabled: false }; // MSC4133 capability capabilities .set("uk.tcpip.msc4133.profile_fields", json!({"enabled": true})) .expect("this is valid JSON we created"); - Ok(get_capabilities::v3::Response { - capabilities, - }) + Ok(get_capabilities::v3::Response { capabilities }) } diff --git a/src/api/client/context.rs b/src/api/client/context.rs index 52f27692d..30ba170d7 100644 --- a/src/api/client/context.rs +++ b/src/api/client/context.rs @@ -32,7 +32,8 @@ const LIMIT_DEFAULT: usize = 10; /// - Only works if the user is joined (TODO: always allow, but only show events /// if the user was joined, depending on history_visibility) pub(crate) async fn get_context_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let filter = &body.filter; let sender = body.sender(); @@ -50,9 +51,8 @@ pub(crate) async fn get_context_route( // members for "inline" profiles on the timeline to work properly let lazy_load_enabled = matches!(filter.lazy_load_options, LazyLoadOptions::Enabled { .. }); - let lazy_load_redundant = if let LazyLoadOptions::Enabled { - include_redundant_members, - } = filter.lazy_load_options + let lazy_load_redundant = if let LazyLoadOptions::Enabled { include_redundant_members } = + filter.lazy_load_options { include_redundant_members } else { @@ -91,10 +91,11 @@ pub(crate) async fn get_context_route( return Err!(Request(Forbidden("You don't have permission to view this event."))); } - let events_before = services - .rooms - .timeline - .pdus_rev(Some(sender_user), room_id, Some(base_token)); + let events_before = + services + .rooms + .timeline + .pdus_rev(Some(sender_user), room_id, Some(base_token)); let events_after = services .rooms @@ -166,7 +167,9 @@ pub(crate) async fn get_context_route( .filter(|&user_id: &&UserId| lazy.contains(user_id)) .map(|_| event_id) }) - .broad_filter_map(|event_id: &OwnedEventId| services.rooms.timeline.get_pdu(event_id).ok()) + .broad_filter_map(|event_id: &OwnedEventId| { + services.rooms.timeline.get_pdu(event_id).ok() + }) .map(|pdu| pdu.to_state_event()) .collect() .await; diff --git a/src/api/client/device.rs b/src/api/client/device.rs index 63f0c210d..bb0773dd7 100644 --- a/src/api/client/device.rs +++ b/src/api/client/device.rs @@ -18,7 +18,8 @@ use crate::{utils, Error, Result, Ruma}; /// /// Get metadata on all devices of the sender user. pub(crate) async fn get_devices_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -28,16 +29,15 @@ pub(crate) async fn get_devices_route( .collect() .await; - Ok(get_devices::v3::Response { - devices, - }) + Ok(get_devices::v3::Response { devices }) } /// # `GET /_matrix/client/r0/devices/{deviceId}` /// /// Get metadata on a single device of the sender user. pub(crate) async fn get_device_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -47,9 +47,7 @@ pub(crate) async fn get_device_route( .await .map_err(|_| err!(Request(NotFound("Device not found."))))?; - Ok(get_device::v3::Response { - device, - }) + Ok(get_device::v3::Response { device }) } /// # `PUT /_matrix/client/r0/devices/{deviceId}` @@ -57,7 +55,8 @@ pub(crate) async fn get_device_route( /// Updates the metadata on a given device of the sender user. #[tracing::instrument(skip_all, fields(%client), name = "update_device")] pub(crate) async fn update_device_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -93,16 +92,15 @@ pub(crate) async fn update_device_route( /// - Forgets to-device events /// - Triggers device list updates pub(crate) async fn delete_device_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); // UIAA let mut uiaainfo = UiaaInfo { - flows: vec![AuthFlow { - stages: vec![AuthType::Password], - }], + flows: vec![AuthFlow { stages: vec![AuthType::Password] }], completed: Vec::new(), params: Box::default(), session: None, @@ -151,16 +149,15 @@ pub(crate) async fn delete_device_route( /// - Forgets to-device events /// - Triggers device list updates pub(crate) async fn delete_devices_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); // UIAA let mut uiaainfo = UiaaInfo { - flows: vec![AuthFlow { - stages: vec![AuthType::Password], - }], + flows: vec![AuthFlow { stages: vec![AuthType::Password] }], completed: Vec::new(), params: Box::default(), session: None, diff --git a/src/api/client/directory.rs b/src/api/client/directory.rs index 9407a0bd6..c8faaa464 100644 --- a/src/api/client/directory.rs +++ b/src/api/client/directory.rs @@ -5,7 +5,10 @@ use futures::{StreamExt, TryFutureExt}; use ruma::{ api::{ client::{ - directory::{get_public_rooms, get_public_rooms_filtered, get_room_visibility, set_room_visibility}, + directory::{ + get_public_rooms, get_public_rooms_filtered, get_room_visibility, + set_room_visibility, + }, error::ErrorKind, room, }, @@ -32,7 +35,8 @@ use crate::Ruma; /// - Rooms are ordered by the number of joined members #[tracing::instrument(skip_all, fields(%client), name = "publicrooms")] pub(crate) async fn get_public_rooms_filtered_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { if let Some(server) = &body.server { @@ -57,7 +61,10 @@ pub(crate) async fn get_public_rooms_filtered_route( .await .map_err(|e| { warn!(?body.server, "Failed to return /publicRooms: {e}"); - Error::BadRequest(ErrorKind::Unknown, "Failed to return the requested server's public room list.") + Error::BadRequest( + ErrorKind::Unknown, + "Failed to return the requested server's public room list.", + ) })?; Ok(response) @@ -70,7 +77,8 @@ pub(crate) async fn get_public_rooms_filtered_route( /// - Rooms are ordered by the number of joined members #[tracing::instrument(skip_all, fields(%client), name = "publicrooms")] pub(crate) async fn get_public_rooms_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { if let Some(server) = &body.server { @@ -95,7 +103,10 @@ pub(crate) async fn get_public_rooms_route( .await .map_err(|e| { warn!(?body.server, "Failed to return /publicRooms: {e}"); - Error::BadRequest(ErrorKind::Unknown, "Failed to return the requested server's public room list.") + Error::BadRequest( + ErrorKind::Unknown, + "Failed to return the requested server's public room list.", + ) })?; Ok(get_public_rooms::v3::Response { @@ -111,7 +122,8 @@ pub(crate) async fn get_public_rooms_route( /// Sets the visibility of a given room in the room directory. #[tracing::instrument(skip_all, fields(%client), name = "room_directory")] pub(crate) async fn set_room_visibility_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -139,14 +151,14 @@ pub(crate) async fn set_room_visibility_route( } match &body.visibility { - room::Visibility::Public => { + | room::Visibility::Public => { if services.globals.config.lockdown_public_room_directory && !services.users.is_admin(sender_user).await && body.appservice_info.is_none() { info!( - "Non-admin user {sender_user} tried to publish {0} to the room directory while \ - \"lockdown_public_room_directory\" is enabled", + "Non-admin user {sender_user} tried to publish {0} to the room directory \ + while \"lockdown_public_room_directory\" is enabled", body.room_id ); @@ -154,8 +166,8 @@ pub(crate) async fn set_room_visibility_route( services .admin .send_text(&format!( - "Non-admin user {sender_user} tried to publish {0} to the room directory while \ - \"lockdown_public_room_directory\" is enabled", + "Non-admin user {sender_user} tried to publish {0} to the room \ + directory while \"lockdown_public_room_directory\" is enabled", body.room_id )) .await; @@ -172,13 +184,16 @@ pub(crate) async fn set_room_visibility_route( if services.globals.config.admin_room_notices { services .admin - .send_text(&format!("{sender_user} made {} public to the room directory", body.room_id)) + .send_text(&format!( + "{sender_user} made {} public to the room directory", + body.room_id + )) .await; } info!("{sender_user} made {0} public to the room directory", body.room_id); }, - room::Visibility::Private => services.rooms.directory.set_not_public(&body.room_id), - _ => { + | room::Visibility::Private => services.rooms.directory.set_not_public(&body.room_id), + | _ => { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Room visibility type is not supported.", @@ -193,7 +208,8 @@ pub(crate) async fn set_room_visibility_route( /// /// Gets the visibility of a given room in the room directory. pub(crate) async fn get_room_visibility_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.rooms.metadata.exists(&body.room_id).await { // Return 404 if the room doesn't exist @@ -210,10 +226,16 @@ pub(crate) async fn get_room_visibility_route( } pub(crate) async fn get_public_rooms_filtered_helper( - services: &Services, server: Option<&ServerName>, limit: Option, since: Option<&str>, filter: &Filter, + services: &Services, + server: Option<&ServerName>, + limit: Option, + since: Option<&str>, + filter: &Filter, _network: &RoomNetwork, ) -> Result { - if let Some(other_server) = server.filter(|server_name| !services.globals.server_is_ours(server_name)) { + if let Some(other_server) = + server.filter(|server_name| !services.globals.server_is_ours(server_name)) + { let response = services .sending .send_federation_request( @@ -245,9 +267,10 @@ pub(crate) async fn get_public_rooms_filtered_helper( if let Some(s) = &since { let mut characters = s.chars(); let backwards = match characters.next() { - Some('n') => false, - Some('p') => true, - _ => return Err(Error::BadRequest(ErrorKind::InvalidParam, "Invalid `since` token")), + | Some('n') => false, + | Some('p') => true, + | _ => + return Err(Error::BadRequest(ErrorKind::InvalidParam, "Invalid `since` token")), }; num_since = characters @@ -337,7 +360,11 @@ pub(crate) async fn get_public_rooms_filtered_helper( /// Check whether the user can publish to the room directory via power levels of /// room history visibility event or room creator -async fn user_can_publish_room(services: &Services, user_id: &UserId, room_id: &RoomId) -> Result { +async fn user_can_publish_room( + services: &Services, + user_id: &UserId, + room_id: &RoomId, +) -> Result { if let Ok(event) = services .rooms .state_accessor @@ -347,7 +374,8 @@ async fn user_can_publish_room(services: &Services, user_id: &UserId, room_id: & serde_json::from_str(event.content.get()) .map_err(|_| Error::bad_database("Invalid event content for m.room.power_levels")) .map(|content: RoomPowerLevelsEventContent| { - RoomPowerLevels::from(content).user_can_send_state(user_id, StateEventType::RoomHistoryVisibility) + RoomPowerLevels::from(content) + .user_can_send_state(user_id, StateEventType::RoomHistoryVisibility) }) } else if let Ok(event) = services .rooms @@ -406,10 +434,10 @@ async fn public_rooms_chunk(services: &Services, room_id: OwnedRoomId) -> Public .state_accessor .room_state_get_content(&room_id, &StateEventType::RoomJoinRules, "") .map_ok(|c: RoomJoinRulesEventContent| match c.join_rule { - JoinRule::Public => PublicRoomJoinRule::Public, - JoinRule::Knock => "knock".into(), - JoinRule::KnockRestricted(_) => "knock_restricted".into(), - _ => "invite".into(), + | JoinRule::Public => PublicRoomJoinRule::Public, + | JoinRule::Knock => "knock".into(), + | JoinRule::KnockRestricted(_) => "knock_restricted".into(), + | _ => "invite".into(), }) .await .unwrap_or_default(), diff --git a/src/api/client/filter.rs b/src/api/client/filter.rs index a1576e8e9..840864529 100644 --- a/src/api/client/filter.rs +++ b/src/api/client/filter.rs @@ -10,7 +10,8 @@ use crate::{Result, Ruma}; /// /// - A user can only access their own filters pub(crate) async fn get_filter_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -26,7 +27,8 @@ pub(crate) async fn get_filter_route( /// /// Creates a new filter to be used by other endpoints. pub(crate) async fn create_filter_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client/keys.rs b/src/api/client/keys.rs index 13dc34679..7bf0a5dac 100644 --- a/src/api/client/keys.rs +++ b/src/api/client/keys.rs @@ -7,7 +7,10 @@ use ruma::{ api::{ client::{ error::ErrorKind, - keys::{claim_keys, get_key_changes, get_keys, upload_keys, upload_signatures, upload_signing_keys}, + keys::{ + claim_keys, get_key_changes, get_keys, upload_keys, upload_signatures, + upload_signing_keys, + }, uiaa::{AuthFlow, AuthType, UiaaInfo}, }, federation, @@ -31,7 +34,8 @@ use crate::{ /// - If there are no device keys yet: Adds device keys (TODO: merge with /// existing keys?) pub(crate) async fn upload_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let (sender_user, sender_device) = body.sender(); @@ -75,7 +79,8 @@ pub(crate) async fn upload_keys_route( /// - The master and self-signing keys contain signatures that the user is /// allowed to see pub(crate) async fn get_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -93,7 +98,8 @@ pub(crate) async fn get_keys_route( /// /// Claims one-time keys pub(crate) async fn claim_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { claim_keys_helper(&services, &body.one_time_keys).await } @@ -104,16 +110,15 @@ pub(crate) async fn claim_keys_route( /// /// - Requires UIAA to verify password pub(crate) async fn upload_signing_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); // UIAA let mut uiaainfo = UiaaInfo { - flows: vec![AuthFlow { - stages: vec![AuthType::Password], - }], + flows: vec![AuthFlow { stages: vec![AuthType::Password] }], completed: Vec::new(), params: Box::default(), session: None, @@ -161,7 +166,8 @@ pub(crate) async fn upload_signing_keys_route( /// /// Uploads end-to-end key signatures from the sender user. pub(crate) async fn upload_signatures_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -174,7 +180,10 @@ pub(crate) async fn upload_signatures_route( .get("signatures") .ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Missing signatures field."))? .get(sender_user.to_string()) - .ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Invalid user in signatures field."))? + .ok_or(Error::BadRequest( + ErrorKind::InvalidParam, + "Invalid user in signatures field.", + ))? .as_object() .ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Invalid signature."))? .clone() @@ -185,7 +194,10 @@ pub(crate) async fn upload_signatures_route( signature .1 .as_str() - .ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Invalid signature value."))? + .ok_or(Error::BadRequest( + ErrorKind::InvalidParam, + "Invalid signature value.", + ))? .to_owned(), ); @@ -209,7 +221,8 @@ pub(crate) async fn upload_signatures_route( /// /// - TODO: left users pub(crate) async fn get_key_changes_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -255,8 +268,11 @@ pub(crate) async fn get_key_changes_route( } pub(crate) async fn get_keys_helper( - services: &Services, sender_user: Option<&UserId>, device_keys_input: &BTreeMap>, - allowed_signatures: F, include_display_names: bool, + services: &Services, + sender_user: Option<&UserId>, + device_keys_input: &BTreeMap>, + allowed_signatures: F, + include_display_names: bool, ) -> Result where F: Fn(&UserId) -> bool + Send + Sync, @@ -289,7 +305,9 @@ where .users .get_device_metadata(user_id, device_id) .await - .map_err(|_| err!(Database("all_device_keys contained nonexistent device.")))?; + .map_err(|_| { + err!(Database("all_device_keys contained nonexistent device.")) + })?; add_unsigned_device_display_name(&mut keys, metadata, include_display_names) .map_err(|_| err!(Database("invalid device keys in database")))?; @@ -307,7 +325,11 @@ where .users .get_device_metadata(user_id, device_id) .await - .map_err(|_| err!(Request(InvalidParam("Tried to get keys for nonexistent device."))))?; + .map_err(|_| { + err!(Request(InvalidParam( + "Tried to get keys for nonexistent device." + ))) + })?; add_unsigned_device_display_name(&mut keys, metadata, include_display_names) .map_err(|_| err!(Database("invalid device keys in database")))?; @@ -350,9 +372,8 @@ where device_keys_input_fed.insert(user_id.to_owned(), keys.clone()); } - let request = federation::keys::get_keys::v1::Request { - device_keys: device_keys_input_fed, - }; + let request = + federation::keys::get_keys::v1::Request { device_keys: device_keys_input_fed }; let response = services .sending @@ -382,8 +403,8 @@ where .users .add_cross_signing_keys( &user, &raw, &None, &None, - false, /* Dont notify. A notification would trigger another key request resulting in an - * endless loop */ + false, /* Dont notify. A notification would trigger another key request + * resulting in an endless loop */ ) .await?; master_keys.insert(user.clone(), raw); @@ -406,7 +427,8 @@ where } fn add_unsigned_device_display_name( - keys: &mut Raw, metadata: ruma::api::client::device::Device, + keys: &mut Raw, + metadata: ruma::api::client::device::Device, include_display_names: bool, ) -> serde_json::Result<()> { if let Some(display_name) = metadata.display_name { @@ -431,7 +453,8 @@ fn add_unsigned_device_display_name( } pub(crate) async fn claim_keys_helper( - services: &Services, one_time_keys_input: &BTreeMap>, + services: &Services, + one_time_keys_input: &BTreeMap>, ) -> Result { let mut one_time_keys = BTreeMap::new(); @@ -473,12 +496,9 @@ pub(crate) async fn claim_keys_helper( server, services .sending - .send_federation_request( - server, - federation::keys::claim_keys::v1::Request { - one_time_keys: one_time_keys_input_fed, - }, - ) + .send_federation_request(server, federation::keys::claim_keys::v1::Request { + one_time_keys: one_time_keys_input_fed, + }) .await, ) }) @@ -486,17 +506,14 @@ pub(crate) async fn claim_keys_helper( while let Some((server, response)) = futures.next().await { match response { - Ok(keys) => { + | Ok(keys) => { one_time_keys.extend(keys.one_time_keys); }, - Err(_e) => { + | Err(_e) => { failures.insert(server.to_string(), json!({})); }, } } - Ok(claim_keys::v3::Response { - failures, - one_time_keys, - }) + Ok(claim_keys::v3::Response { failures, one_time_keys }) } diff --git a/src/api/client/media.rs b/src/api/client/media.rs index a9792c3b5..e58ba626b 100644 --- a/src/api/client/media.rs +++ b/src/api/client/media.rs @@ -15,7 +15,8 @@ use reqwest::Url; use ruma::{ api::client::{ authenticated_media::{ - get_content, get_content_as_filename, get_content_thumbnail, get_media_config, get_media_preview, + get_content, get_content_as_filename, get_content_thumbnail, get_media_config, + get_media_preview, }, media::create_content, }, @@ -26,7 +27,8 @@ use crate::Ruma; /// # `GET /_matrix/client/v1/media/config` pub(crate) async fn get_media_config_route( - State(services): State, _body: Ruma, + State(services): State, + _body: Ruma, ) -> Result { Ok(get_media_config::v1::Response { upload_size: ruma_from_usize(services.globals.config.max_request_size), @@ -46,7 +48,8 @@ pub(crate) async fn get_media_config_route( fields(%client), )] pub(crate) async fn create_content_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let user = body.sender_user.as_ref().expect("user is authenticated"); @@ -79,7 +82,8 @@ pub(crate) async fn create_content_route( fields(%client), )] pub(crate) async fn get_content_thumbnail_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let user = body.sender_user.as_ref().expect("user is authenticated"); @@ -115,7 +119,8 @@ pub(crate) async fn get_content_thumbnail_route( fields(%client), )] pub(crate) async fn get_content_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let user = body.sender_user.as_ref().expect("user is authenticated"); @@ -150,7 +155,8 @@ pub(crate) async fn get_content_route( fields(%client), )] pub(crate) async fn get_content_as_filename_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let user = body.sender_user.as_ref().expect("user is authenticated"); @@ -185,7 +191,8 @@ pub(crate) async fn get_content_as_filename_route( fields(%client), )] pub(crate) async fn get_media_preview_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -223,7 +230,11 @@ pub(crate) async fn get_media_preview_route( } async fn fetch_thumbnail( - services: &Services, mxc: &Mxc<'_>, user: &UserId, timeout_ms: Duration, dim: &Dim, + services: &Services, + mxc: &Mxc<'_>, + user: &UserId, + timeout_ms: Duration, + dim: &Dim, ) -> Result { let FileMeta { content, @@ -245,7 +256,11 @@ async fn fetch_thumbnail( } async fn fetch_file( - services: &Services, mxc: &Mxc<'_>, user: &UserId, timeout_ms: Duration, filename: Option<&str>, + services: &Services, + mxc: &Mxc<'_>, + user: &UserId, + timeout_ms: Duration, + filename: Option<&str>, ) -> Result { let FileMeta { content, @@ -267,7 +282,11 @@ async fn fetch_file( } async fn fetch_thumbnail_meta( - services: &Services, mxc: &Mxc<'_>, user: &UserId, timeout_ms: Duration, dim: &Dim, + services: &Services, + mxc: &Mxc<'_>, + user: &UserId, + timeout_ms: Duration, + dim: &Dim, ) -> Result { if let Some(filemeta) = services.media.get_thumbnail(mxc, dim).await? { return Ok(filemeta); @@ -283,7 +302,12 @@ async fn fetch_thumbnail_meta( .await } -async fn fetch_file_meta(services: &Services, mxc: &Mxc<'_>, user: &UserId, timeout_ms: Duration) -> Result { +async fn fetch_file_meta( + services: &Services, + mxc: &Mxc<'_>, + user: &UserId, + timeout_ms: Duration, +) -> Result { if let Some(filemeta) = services.media.get(mxc).await? { return Ok(filemeta); } diff --git a/src/api/client/media_legacy.rs b/src/api/client/media_legacy.rs index a8b366edb..6f54a683e 100644 --- a/src/api/client/media_legacy.rs +++ b/src/api/client/media_legacy.rs @@ -11,8 +11,8 @@ use conduwuit_service::media::{Dim, FileMeta, CACHE_CONTROL_IMMUTABLE, CORP_CROS use reqwest::Url; use ruma::{ api::client::media::{ - create_content, get_content, get_content_as_filename, get_content_thumbnail, get_media_config, - get_media_preview, + create_content, get_content, get_content_as_filename, get_content_thumbnail, + get_media_config, get_media_preview, }, Mxc, }; @@ -23,7 +23,8 @@ use crate::{client::create_content_route, Ruma, RumaResponse}; /// /// Returns max upload size. pub(crate) async fn get_media_config_legacy_route( - State(services): State, _body: Ruma, + State(services): State, + _body: Ruma, ) -> Result { Ok(get_media_config::v3::Response { upload_size: ruma_from_usize(services.globals.config.max_request_size), @@ -38,7 +39,8 @@ pub(crate) async fn get_media_config_legacy_route( /// /// Returns max upload size. pub(crate) async fn get_media_config_legacy_legacy_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result> { get_media_config_legacy_route(State(services), body) .await @@ -50,7 +52,8 @@ pub(crate) async fn get_media_config_legacy_legacy_route( /// Returns URL preview. #[tracing::instrument(skip_all, fields(%client), name = "url_preview_legacy")] pub(crate) async fn get_media_preview_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -91,7 +94,8 @@ pub(crate) async fn get_media_preview_legacy_route( /// /// Returns URL preview. pub(crate) async fn get_media_preview_legacy_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result> { get_media_preview_legacy_route(State(services), InsecureClientIp(client), body) @@ -110,7 +114,8 @@ pub(crate) async fn get_media_preview_legacy_legacy_route( /// - Some metadata will be saved in the database /// - Media will be saved in the media/ directory pub(crate) async fn create_content_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result> { create_content_route(State(services), InsecureClientIp(client), body) @@ -128,7 +133,8 @@ pub(crate) async fn create_content_legacy_route( /// seconds #[tracing::instrument(skip_all, fields(%client), name = "media_get_legacy")] pub(crate) async fn get_content_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let mxc = Mxc { @@ -142,7 +148,8 @@ pub(crate) async fn get_content_legacy_route( content_disposition, }) = services.media.get(&mxc).await? { - let content_disposition = make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); + let content_disposition = + make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); Ok(get_content::v3::Response { file: content.expect("entire file contents"), @@ -156,10 +163,15 @@ pub(crate) async fn get_content_legacy_route( .media .fetch_remote_content_legacy(&mxc, body.allow_redirect, body.timeout_ms) .await - .map_err(|e| err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}")))))?; + .map_err(|e| { + err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}")))) + })?; - let content_disposition = - make_content_disposition(response.content_disposition.as_ref(), response.content_type.as_deref(), None); + let content_disposition = make_content_disposition( + response.content_disposition.as_ref(), + response.content_type.as_deref(), + None, + ); Ok(get_content::v3::Response { file: response.file, @@ -187,7 +199,8 @@ pub(crate) async fn get_content_legacy_route( /// seconds #[tracing::instrument(skip_all, fields(%client), name = "media_get_legacy")] pub(crate) async fn get_content_legacy_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result> { get_content_legacy_route(State(services), InsecureClientIp(client), body) @@ -205,7 +218,8 @@ pub(crate) async fn get_content_legacy_legacy_route( /// seconds #[tracing::instrument(skip_all, fields(%client), name = "media_get_legacy")] pub(crate) async fn get_content_as_filename_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let mxc = Mxc { @@ -219,8 +233,11 @@ pub(crate) async fn get_content_as_filename_legacy_route( content_disposition, }) = services.media.get(&mxc).await? { - let content_disposition = - make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), Some(&body.filename)); + let content_disposition = make_content_disposition( + content_disposition.as_ref(), + content_type.as_deref(), + Some(&body.filename), + ); Ok(get_content_as_filename::v3::Response { file: content.expect("entire file contents"), @@ -234,10 +251,15 @@ pub(crate) async fn get_content_as_filename_legacy_route( .media .fetch_remote_content_legacy(&mxc, body.allow_redirect, body.timeout_ms) .await - .map_err(|e| err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}")))))?; + .map_err(|e| { + err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}")))) + })?; - let content_disposition = - make_content_disposition(response.content_disposition.as_ref(), response.content_type.as_deref(), None); + let content_disposition = make_content_disposition( + response.content_disposition.as_ref(), + response.content_type.as_deref(), + None, + ); Ok(get_content_as_filename::v3::Response { content_disposition: Some(content_disposition), @@ -264,7 +286,8 @@ pub(crate) async fn get_content_as_filename_legacy_route( /// - Uses client-provided `timeout_ms` if available, else defaults to 20 /// seconds pub(crate) async fn get_content_as_filename_legacy_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result> { get_content_as_filename_legacy_route(State(services), InsecureClientIp(client), body) @@ -282,7 +305,8 @@ pub(crate) async fn get_content_as_filename_legacy_legacy_route( /// seconds #[tracing::instrument(skip_all, fields(%client), name = "media_thumbnail_get_legacy")] pub(crate) async fn get_content_thumbnail_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let mxc = Mxc { @@ -297,7 +321,8 @@ pub(crate) async fn get_content_thumbnail_legacy_route( content_disposition, }) = services.media.get_thumbnail(&mxc, &dim).await? { - let content_disposition = make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); + let content_disposition = + make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); Ok(get_content_thumbnail::v3::Response { file: content.expect("entire file contents"), @@ -311,10 +336,15 @@ pub(crate) async fn get_content_thumbnail_legacy_route( .media .fetch_remote_thumbnail_legacy(&body) .await - .map_err(|e| err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}")))))?; + .map_err(|e| { + err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}")))) + })?; - let content_disposition = - make_content_disposition(response.content_disposition.as_ref(), response.content_type.as_deref(), None); + let content_disposition = make_content_disposition( + response.content_disposition.as_ref(), + response.content_type.as_deref(), + None, + ); Ok(get_content_thumbnail::v3::Response { file: response.file, @@ -341,7 +371,8 @@ pub(crate) async fn get_content_thumbnail_legacy_route( /// - Uses client-provided `timeout_ms` if available, else defaults to 20 /// seconds pub(crate) async fn get_content_thumbnail_legacy_legacy_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result> { get_content_thumbnail_legacy_route(State(services), InsecureClientIp(client), body) diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs index 021662712..0ddcab32c 100644 --- a/src/api/client/membership.rs +++ b/src/api/client/membership.rs @@ -20,7 +20,8 @@ use ruma::{ client::{ error::ErrorKind, membership::{ - ban_user, forget_room, get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, + ban_user, forget_room, get_member_events, invite_user, join_room_by_id, + join_room_by_id_or_alias, joined_members::{self, v3::RoomMember}, joined_rooms, kick_user, leave_room, unban_user, ThirdPartySigned, }, @@ -36,8 +37,8 @@ use ruma::{ }, StateEventType, }, - state_res, CanonicalJsonObject, CanonicalJsonValue, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, - RoomVersionId, ServerName, UserId, + state_res, CanonicalJsonObject, CanonicalJsonValue, OwnedRoomId, OwnedServerName, + OwnedUserId, RoomId, RoomVersionId, ServerName, UserId, }; use service::{ appservice::RegistrationInfo, @@ -54,7 +55,10 @@ use crate::{client::full_user_deactivate, Ruma}; /// enabled #[tracing::instrument(skip(services))] async fn banned_room_check( - services: &Services, user_id: &UserId, room_id: Option<&RoomId>, server_name: Option<&ServerName>, + services: &Services, + user_id: &UserId, + room_id: Option<&RoomId>, + server_name: Option<&ServerName>, client_ip: IpAddr, ) -> Result { if services.users.is_admin(user_id).await { @@ -70,19 +74,21 @@ async fn banned_room_check( .contains(&room_id.server_name().unwrap().to_owned()) { warn!( - "User {user_id} who is not an admin attempted to send an invite for or attempted to join a banned \ - room or banned room server name: {room_id}" + "User {user_id} who is not an admin attempted to send an invite for or \ + attempted to join a banned room or banned room server name: {room_id}" ); if services.globals.config.auto_deactivate_banned_room_attempts { - warn!("Automatically deactivating user {user_id} due to attempted banned room join"); + warn!( + "Automatically deactivating user {user_id} due to attempted banned room join" + ); if services.globals.config.admin_room_notices { services .admin .send_message(RoomMessageEventContent::text_plain(format!( - "Automatically deactivating user {user_id} due to attempted banned room join from IP \ - {client_ip}" + "Automatically deactivating user {user_id} due to attempted banned \ + room join from IP {client_ip}" ))) .await .ok(); @@ -109,19 +115,21 @@ async fn banned_room_check( .contains(&server_name.to_owned()) { warn!( - "User {user_id} who is not an admin tried joining a room which has the server name {server_name} that \ - is globally forbidden. Rejecting.", + "User {user_id} who is not an admin tried joining a room which has the server \ + name {server_name} that is globally forbidden. Rejecting.", ); if services.globals.config.auto_deactivate_banned_room_attempts { - warn!("Automatically deactivating user {user_id} due to attempted banned room join"); + warn!( + "Automatically deactivating user {user_id} due to attempted banned room join" + ); if services.globals.config.admin_room_notices { services .admin .send_message(RoomMessageEventContent::text_plain(format!( - "Automatically deactivating user {user_id} due to attempted banned room join from IP \ - {client_ip}" + "Automatically deactivating user {user_id} due to attempted banned \ + room join from IP {client_ip}" ))) .await .ok(); @@ -155,12 +163,20 @@ async fn banned_room_check( /// federation #[tracing::instrument(skip_all, fields(%client), name = "join")] pub(crate) async fn join_room_by_id_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user(); - banned_room_check(&services, sender_user, Some(&body.room_id), body.room_id.server_name(), client).await?; + banned_room_check( + &services, + sender_user, + Some(&body.room_id), + body.room_id.server_name(), + client, + ) + .await?; // There is no body.server_name for /roomId/join let mut servers: Vec<_> = services @@ -216,7 +232,8 @@ pub(crate) async fn join_room_by_id_route( /// via room alias server name and room ID server name #[tracing::instrument(skip_all, fields(%client), name = "join")] pub(crate) async fn join_room_by_id_or_alias_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_deref().expect("user is authenticated"); @@ -224,8 +241,15 @@ pub(crate) async fn join_room_by_id_or_alias_route( let body = body.body; let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias) { - Ok(room_id) => { - banned_room_check(&services, sender_user, Some(&room_id), room_id.server_name(), client).await?; + | Ok(room_id) => { + banned_room_check( + &services, + sender_user, + Some(&room_id), + room_id.server_name(), + client, + ) + .await?; let mut servers = body.via.clone(); servers.extend( @@ -261,14 +285,21 @@ pub(crate) async fn join_room_by_id_or_alias_route( (servers, room_id) }, - Err(room_alias) => { + | Err(room_alias) => { let (room_id, mut servers) = services .rooms .alias .resolve_alias(&room_alias, Some(body.via.clone())) .await?; - banned_room_check(&services, sender_user, Some(&room_id), Some(room_alias.server_name()), client).await?; + banned_room_check( + &services, + sender_user, + Some(&room_id), + Some(room_alias.server_name()), + client, + ) + .await?; let addl_via_servers = services .rooms @@ -314,9 +345,7 @@ pub(crate) async fn join_room_by_id_or_alias_route( .boxed() .await?; - Ok(join_room_by_id_or_alias::v3::Response { - room_id: join_room_response.room_id, - }) + Ok(join_room_by_id_or_alias::v3::Response { room_id: join_room_response.room_id }) } /// # `POST /_matrix/client/v3/rooms/{roomId}/leave` @@ -325,7 +354,8 @@ pub(crate) async fn join_room_by_id_or_alias_route( /// /// - This should always work if the user is currently joined. pub(crate) async fn leave_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { leave_room(&services, body.sender_user(), &body.room_id, body.reason.clone()).await?; @@ -337,7 +367,8 @@ pub(crate) async fn leave_room_route( /// Tries to send an invite event into the room. #[tracing::instrument(skip_all, fields(%client), name = "invite")] pub(crate) async fn invite_user_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -350,12 +381,16 @@ pub(crate) async fn invite_user_route( return Err!(Request(Forbidden("Invites are not allowed on this server."))); } - banned_room_check(&services, sender_user, Some(&body.room_id), body.room_id.server_name(), client).await?; + banned_room_check( + &services, + sender_user, + Some(&body.room_id), + body.room_id.server_name(), + client, + ) + .await?; - if let invite_user::v3::InvitationRecipient::UserId { - user_id, - } = &body.recipient - { + if let invite_user::v3::InvitationRecipient::UserId { user_id } = &body.recipient { let sender_ignored_recipient = services.users.user_is_ignored(sender_user, user_id); let recipient_ignored_by_sender = services.users.user_is_ignored(user_id, sender_user); @@ -363,7 +398,9 @@ pub(crate) async fn invite_user_route( join!(sender_ignored_recipient, recipient_ignored_by_sender); if sender_ignored_recipient { - return Err!(Request(Forbidden("You cannot invite users you have ignored to rooms."))); + return Err!(Request(Forbidden( + "You cannot invite users you have ignored to rooms." + ))); } if recipient_ignored_by_sender { @@ -386,7 +423,8 @@ pub(crate) async fn invite_user_route( /// /// Tries to send a kick event into the room. pub(crate) async fn kick_user_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let state_lock = services.rooms.state.mutex.lock(&body.room_id).await; @@ -405,17 +443,14 @@ pub(crate) async fn kick_user_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - body.user_id.to_string(), - &RoomMemberEventContent { - membership: MembershipState::Leave, - reason: body.reason.clone(), - is_direct: None, - join_authorized_via_users_server: None, - third_party_invite: None, - ..event - }, - ), + PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent { + membership: MembershipState::Leave, + reason: body.reason.clone(), + is_direct: None, + join_authorized_via_users_server: None, + third_party_invite: None, + ..event + }), body.sender_user(), &body.room_id, &state_lock, @@ -431,7 +466,8 @@ pub(crate) async fn kick_user_route( /// /// Tries to send a ban event into the room. pub(crate) async fn ban_user_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -452,19 +488,16 @@ pub(crate) async fn ban_user_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - body.user_id.to_string(), - &RoomMemberEventContent { - membership: MembershipState::Ban, - reason: body.reason.clone(), - displayname: None, // display name may be offensive - avatar_url: None, // avatar may be offensive - is_direct: None, - join_authorized_via_users_server: None, - third_party_invite: None, - ..current_member_content - }, - ), + PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent { + membership: MembershipState::Ban, + reason: body.reason.clone(), + displayname: None, // display name may be offensive + avatar_url: None, // avatar may be offensive + is_direct: None, + join_authorized_via_users_server: None, + third_party_invite: None, + ..current_member_content + }), sender_user, &body.room_id, &state_lock, @@ -480,7 +513,8 @@ pub(crate) async fn ban_user_route( /// /// Tries to send an unban event into the room. pub(crate) async fn unban_user_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let state_lock = services.rooms.state.mutex.lock(&body.room_id).await; @@ -502,17 +536,14 @@ pub(crate) async fn unban_user_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - body.user_id.to_string(), - &RoomMemberEventContent { - membership: MembershipState::Leave, - reason: body.reason.clone(), - join_authorized_via_users_server: None, - third_party_invite: None, - is_direct: None, - ..current_member_content - }, - ), + PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent { + membership: MembershipState::Leave, + reason: body.reason.clone(), + join_authorized_via_users_server: None, + third_party_invite: None, + is_direct: None, + ..current_member_content + }), body.sender_user(), &body.room_id, &state_lock, @@ -534,7 +565,8 @@ pub(crate) async fn unban_user_route( /// Note: Other devices of the user have no way of knowing the room was /// forgotten, so this has to be called from every device pub(crate) async fn forget_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -559,7 +591,8 @@ pub(crate) async fn forget_room_route( /// /// Lists all rooms the user has joined. pub(crate) async fn joined_rooms_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { Ok(joined_rooms::v3::Response { joined_rooms: services @@ -579,7 +612,8 @@ pub(crate) async fn joined_rooms_route( /// /// - Only works if the user is currently joined pub(crate) async fn get_member_events_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -612,7 +646,8 @@ pub(crate) async fn get_member_events_route( /// - The sender user must be in the room /// - TODO: An appservice just needs a puppet joined pub(crate) async fn joined_members_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -631,25 +666,25 @@ pub(crate) async fn joined_members_route( .room_members(&body.room_id) .map(ToOwned::to_owned) .then(|user| async move { - ( - user.clone(), - RoomMember { - display_name: services.users.displayname(&user).await.ok(), - avatar_url: services.users.avatar_url(&user).await.ok(), - }, - ) + (user.clone(), RoomMember { + display_name: services.users.displayname(&user).await.ok(), + avatar_url: services.users.avatar_url(&user).await.ok(), + }) }) .collect() .await; - Ok(joined_members::v3::Response { - joined, - }) + Ok(joined_members::v3::Response { joined }) } pub async fn join_room_by_id_helper( - services: &Services, sender_user: &UserId, room_id: &RoomId, reason: Option, servers: &[OwnedServerName], - third_party_signed: Option<&ThirdPartySigned>, appservice_info: &Option, + services: &Services, + sender_user: &UserId, + room_id: &RoomId, + reason: Option, + servers: &[OwnedServerName], + third_party_signed: Option<&ThirdPartySigned>, + appservice_info: &Option, ) -> Result { let state_lock = services.rooms.state.mutex.lock(room_id).await; @@ -671,9 +706,7 @@ pub async fn join_room_by_id_helper( .await { debug_warn!("{sender_user} is already joined in {room_id}"); - return Ok(join_room_by_id::v3::Response { - room_id: room_id.into(), - }); + return Ok(join_room_by_id::v3::Response { room_id: room_id.into() }); } if let Ok(membership) = services @@ -694,18 +727,35 @@ pub async fn join_room_by_id_helper( .server_in_room(services.globals.server_name(), room_id) .await; - let local_join = - server_in_room || servers.is_empty() || (servers.len() == 1 && services.globals.server_is_ours(&servers[0])); + let local_join = server_in_room + || servers.is_empty() + || (servers.len() == 1 && services.globals.server_is_ours(&servers[0])); if local_join { - join_room_by_id_helper_local(services, sender_user, room_id, reason, servers, third_party_signed, state_lock) - .boxed() - .await?; + join_room_by_id_helper_local( + services, + sender_user, + room_id, + reason, + servers, + third_party_signed, + state_lock, + ) + .boxed() + .await?; } else { // Ask a remote server if we are not participating in this room - join_room_by_id_helper_remote(services, sender_user, room_id, reason, servers, third_party_signed, state_lock) - .boxed() - .await?; + join_room_by_id_helper_remote( + services, + sender_user, + room_id, + reason, + servers, + third_party_signed, + state_lock, + ) + .boxed() + .await?; } Ok(join_room_by_id::v3::Response::new(room_id.to_owned())) @@ -713,12 +763,18 @@ pub async fn join_room_by_id_helper( #[tracing::instrument(skip_all, fields(%sender_user, %room_id), name = "join_remote")] async fn join_room_by_id_helper_remote( - services: &Services, sender_user: &UserId, room_id: &RoomId, reason: Option, servers: &[OwnedServerName], - _third_party_signed: Option<&ThirdPartySigned>, state_lock: RoomMutexGuard, + services: &Services, + sender_user: &UserId, + room_id: &RoomId, + reason: Option, + servers: &[OwnedServerName], + _third_party_signed: Option<&ThirdPartySigned>, + state_lock: RoomMutexGuard, ) -> Result { info!("Joining {room_id} over federation."); - let (make_join_response, remote_server) = make_join_request(services, sender_user, room_id, servers).await?; + let (make_join_response, remote_server) = + make_join_request(services, sender_user, room_id, servers).await?; info!("make_join finished"); @@ -783,8 +839,8 @@ async fn join_room_by_id_helper_remote( // We keep the "event_id" in the pdu only in v1 or // v2 rooms match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - _ => { + | RoomVersionId::V1 | RoomVersionId::V2 => {}, + | _ => { join_event_stub.remove("event_id"); }, }; @@ -799,7 +855,8 @@ async fn join_room_by_id_helper_remote( let event_id = pdu::gen_event_id(&join_event_stub, &room_version_id)?; // Add event_id back - join_event_stub.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.clone().into())); + join_event_stub + .insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.clone().into())); // It has enough fields to be called a proper event now let mut join_event = join_event_stub; @@ -825,12 +882,16 @@ async fn join_room_by_id_helper_remote( if join_authorized_via_users_server.is_some() { if let Some(signed_raw) = &send_join_response.room_state.event { debug_info!( - "There is a signed event with join_authorized_via_users_server. This room is probably using \ - restricted joins. Adding signature to our event" + "There is a signed event with join_authorized_via_users_server. This room is \ + probably using restricted joins. Adding signature to our event" ); - let (signed_event_id, signed_value) = gen_event_id_canonical_json(signed_raw, &room_version_id) - .map_err(|e| err!(Request(BadJson(warn!("Could not convert event to canonical JSON: {e}")))))?; + let (signed_event_id, signed_value) = + gen_event_id_canonical_json(signed_raw, &room_version_id).map_err(|e| { + err!(Request(BadJson(warn!( + "Could not convert event to canonical JSON: {e}" + )))) + })?; if signed_event_id != event_id { return Err!(Request(BadJson( @@ -840,15 +901,20 @@ async fn join_room_by_id_helper_remote( match signed_value["signatures"] .as_object() - .ok_or_else(|| err!(BadServerResponse(warn!("Server {remote_server} sent invalid signatures type")))) + .ok_or_else(|| { + err!(BadServerResponse(warn!( + "Server {remote_server} sent invalid signatures type" + ))) + }) .and_then(|e| { e.get(remote_server.as_str()).ok_or_else(|| { err!(BadServerResponse(warn!( - "Server {remote_server} did not send its signature for a restricted room" + "Server {remote_server} did not send its signature for a restricted \ + room" ))) }) }) { - Ok(signature) => { + | Ok(signature) => { join_event .get_mut("signatures") .expect("we created a valid pdu") @@ -856,10 +922,10 @@ async fn join_room_by_id_helper_remote( .expect("we created a valid pdu") .insert(remote_server.to_string(), signature.clone()); }, - Err(e) => { + | Err(e) => { warn!( - "Server {remote_server} sent invalid signature in send_join signatures for event \ - {signed_value:?}: {e:?}", + "Server {remote_server} sent invalid signature in send_join signatures \ + for event {signed_value:?}: {e:?}", ); }, } @@ -900,8 +966,8 @@ async fn join_room_by_id_helper_remote( .ready_filter_map(Result::ok) .fold(HashMap::new(), |mut state, (event_id, value)| async move { let pdu = match PduEvent::from_id_val(&event_id, value.clone()) { - Ok(pdu) => pdu, - Err(e) => { + | Ok(pdu) => pdu, + | Err(e) => { debug_warn!("Invalid PDU in send_join response: {e:?}: {value:#?}"); return state; }, @@ -937,7 +1003,9 @@ async fn join_room_by_id_helper_remote( .validate_and_add_event_id_no_fetch(pdu, &room_version_id) }) .ready_filter_map(Result::ok) - .ready_for_each(|(event_id, value)| services.rooms.outlier.add_pdu_outlier(&event_id, &value)) + .ready_for_each(|(event_id, value)| { + services.rooms.outlier.add_pdu_outlier(&event_id, &value); + }) .await; drop(cork); @@ -1031,29 +1099,38 @@ async fn join_room_by_id_helper_remote( #[tracing::instrument(skip_all, fields(%sender_user, %room_id), name = "join_local")] async fn join_room_by_id_helper_local( - services: &Services, sender_user: &UserId, room_id: &RoomId, reason: Option, servers: &[OwnedServerName], - _third_party_signed: Option<&ThirdPartySigned>, state_lock: RoomMutexGuard, + services: &Services, + sender_user: &UserId, + room_id: &RoomId, + reason: Option, + servers: &[OwnedServerName], + _third_party_signed: Option<&ThirdPartySigned>, + state_lock: RoomMutexGuard, ) -> Result { debug_info!("We can join locally"); let join_rules_event_content = services .rooms .state_accessor - .room_state_get_content::(room_id, &StateEventType::RoomJoinRules, "") + .room_state_get_content::( + room_id, + &StateEventType::RoomJoinRules, + "", + ) .await; let restriction_rooms = match join_rules_event_content { - Ok(RoomJoinRulesEventContent { + | Ok(RoomJoinRulesEventContent { join_rule: JoinRule::Restricted(restricted) | JoinRule::KnockRestricted(restricted), }) => restricted .allow .into_iter() .filter_map(|a| match a { - AllowRule::RoomMembership(r) => Some(r.room_id), - _ => None, + | AllowRule::RoomMembership(r) => Some(r.room_id), + | _ => None, }) .collect(), - _ => Vec::new(), + | _ => Vec::new(), }; let join_authorized_via_users_server: Option = { @@ -1073,10 +1150,12 @@ async fn join_room_by_id_helper_local( .state_cache .local_users_in_room(room_id) .filter(|user| { - services - .rooms - .state_accessor - .user_can_invite(room_id, user, sender_user, &state_lock) + services.rooms.state_accessor.user_can_invite( + room_id, + user, + sender_user, + &state_lock, + ) }) .boxed() .next() @@ -1112,13 +1191,18 @@ async fn join_room_by_id_helper_local( }; if restriction_rooms.is_empty() - && (servers.is_empty() || servers.len() == 1 && services.globals.server_is_ours(&servers[0])) + && (servers.is_empty() + || servers.len() == 1 && services.globals.server_is_ours(&servers[0])) { return Err(error); } - warn!("We couldn't do the join locally, maybe federation can help to satisfy the restricted join requirements"); - let Ok((make_join_response, remote_server)) = make_join_request(services, sender_user, room_id, servers).await + warn!( + "We couldn't do the join locally, maybe federation can help to satisfy the restricted \ + join requirements" + ); + let Ok((make_join_response, remote_server)) = + make_join_request(services, sender_user, room_id, servers).await else { return Err(error); }; @@ -1133,8 +1217,10 @@ async fn join_room_by_id_helper_local( )); } - let mut join_event_stub: CanonicalJsonObject = serde_json::from_str(make_join_response.event.get()) - .map_err(|e| err!(BadServerResponse("Invalid make_join event json received from server: {e:?}")))?; + let mut join_event_stub: CanonicalJsonObject = + serde_json::from_str(make_join_response.event.get()).map_err(|e| { + err!(BadServerResponse("Invalid make_join event json received from server: {e:?}")) + })?; let join_authorized_via_users_server = join_event_stub .get("content") @@ -1173,8 +1259,8 @@ async fn join_room_by_id_helper_local( // We keep the "event_id" in the pdu only in v1 or // v2 rooms match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - _ => { + | RoomVersionId::V1 | RoomVersionId::V2 => {}, + | _ => { join_event_stub.remove("event_id"); }, }; @@ -1189,7 +1275,8 @@ async fn join_room_by_id_helper_local( let event_id = pdu::gen_event_id(&join_event_stub, &room_version_id)?; // Add event_id back - join_event_stub.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.clone().into())); + join_event_stub + .insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.clone().into())); // It has enough fields to be called a proper event now let join_event = join_event_stub; @@ -1211,8 +1298,10 @@ async fn join_room_by_id_helper_local( .await?; if let Some(signed_raw) = send_join_response.room_state.event { - let (signed_event_id, signed_value) = gen_event_id_canonical_json(&signed_raw, &room_version_id) - .map_err(|e| err!(Request(BadJson(warn!("Could not convert event to canonical JSON: {e}")))))?; + let (signed_event_id, signed_value) = + gen_event_id_canonical_json(&signed_raw, &room_version_id).map_err(|e| { + err!(Request(BadJson(warn!("Could not convert event to canonical JSON: {e}")))) + })?; if signed_event_id != event_id { return Err!(Request(BadJson( @@ -1234,9 +1323,13 @@ async fn join_room_by_id_helper_local( } async fn make_join_request( - services: &Services, sender_user: &UserId, room_id: &RoomId, servers: &[OwnedServerName], + services: &Services, + sender_user: &UserId, + room_id: &RoomId, + servers: &[OwnedServerName], ) -> Result<(federation::membership::prepare_join_event::v1::Response, OwnedServerName)> { - let mut make_join_response_and_server = Err!(BadServerResponse("No server available to assist in joining.")); + let mut make_join_response_and_server = + Err!(BadServerResponse("No server available to assist in joining.")); let mut make_join_counter: usize = 0; let mut incompatible_room_version_count: usize = 0; @@ -1266,23 +1359,28 @@ async fn make_join_request( e.kind(), ErrorKind::IncompatibleRoomVersion { .. } | ErrorKind::UnsupportedRoomVersion ) { - incompatible_room_version_count = incompatible_room_version_count.saturating_add(1); + incompatible_room_version_count = + incompatible_room_version_count.saturating_add(1); } if incompatible_room_version_count > 15 { info!( - "15 servers have responded with M_INCOMPATIBLE_ROOM_VERSION or M_UNSUPPORTED_ROOM_VERSION, \ - assuming that conduwuit does not support the room version {room_id}: {e}" + "15 servers have responded with M_INCOMPATIBLE_ROOM_VERSION or \ + M_UNSUPPORTED_ROOM_VERSION, assuming that conduwuit does not support the \ + room version {room_id}: {e}" ); - make_join_response_and_server = Err!(BadServerResponse("Room version is not supported by Conduwuit")); + make_join_response_and_server = + Err!(BadServerResponse("Room version is not supported by Conduwuit")); return make_join_response_and_server; } if make_join_counter > 40 { warn!( - "40 servers failed to provide valid make_join response, assuming no server can assist in joining." + "40 servers failed to provide valid make_join response, assuming no server \ + can assist in joining." ); - make_join_response_and_server = Err!(BadServerResponse("No server available to assist in joining.")); + make_join_response_and_server = + Err!(BadServerResponse("No server available to assist in joining.")); return make_join_response_and_server; } } @@ -1298,11 +1396,18 @@ async fn make_join_request( } pub(crate) async fn invite_helper( - services: &Services, sender_user: &UserId, user_id: &UserId, room_id: &RoomId, reason: Option, + services: &Services, + sender_user: &UserId, + user_id: &UserId, + room_id: &RoomId, + reason: Option, is_direct: bool, ) -> Result { if !services.users.is_admin(sender_user).await && services.globals.block_non_admin_invites() { - info!("User {sender_user} is not an admin and attempted to send an invite to room {room_id}"); + info!( + "User {sender_user} is not an admin and attempted to send an invite to room \ + {room_id}" + ); return Err!(Request(Forbidden("Invites are not allowed on this server."))); } @@ -1339,31 +1444,30 @@ pub(crate) async fn invite_helper( let response = services .sending - .send_federation_request( - user_id.server_name(), - create_invite::v2::Request { - room_id: room_id.to_owned(), - event_id: (*pdu.event_id).to_owned(), - room_version: room_version_id.clone(), - event: services - .sending - .convert_to_outgoing_federation_event(pdu_json.clone()) - .await, - invite_room_state, - via: services - .rooms - .state_cache - .servers_route_via(room_id) - .await - .ok(), - }, - ) + .send_federation_request(user_id.server_name(), create_invite::v2::Request { + room_id: room_id.to_owned(), + event_id: (*pdu.event_id).to_owned(), + room_version: room_version_id.clone(), + event: services + .sending + .convert_to_outgoing_federation_event(pdu_json.clone()) + .await, + invite_room_state, + via: services + .rooms + .state_cache + .servers_route_via(room_id) + .await + .ok(), + }) .await?; // We do not add the event_id field to the pdu here because of signature and // hashes checks let (event_id, value) = gen_event_id_canonical_json(&response.event, &room_version_id) - .map_err(|e| err!(Request(BadJson(warn!("Could not convert event to canonical JSON: {e}")))))?; + .map_err(|e| { + err!(Request(BadJson(warn!("Could not convert event to canonical JSON: {e}")))) + })?; if pdu.event_id != event_id { return Err!(Request(BadJson( @@ -1379,14 +1483,18 @@ pub(crate) async fn invite_helper( ) .expect("CanonicalJson is valid json value"), ) - .map_err(|e| err!(Request(BadJson(warn!("Origin field in event is not a valid server name: {e}")))))?; + .map_err(|e| { + err!(Request(BadJson(warn!("Origin field in event is not a valid server name: {e}")))) + })?; let pdu_id = services .rooms .event_handler .handle_incoming_pdu(&origin, room_id, &event_id, value, true) .await? - .ok_or_else(|| err!(Request(InvalidParam("Could not accept incoming PDU as timeline event."))))?; + .ok_or_else(|| { + err!(Request(InvalidParam("Could not accept incoming PDU as timeline event."))) + })?; return services.sending.send_pdu_room(room_id, &pdu_id).await; } @@ -1456,7 +1564,12 @@ pub async fn leave_all_rooms(services: &Services, user_id: &UserId) { } } -pub async fn leave_room(services: &Services, user_id: &UserId, room_id: &RoomId, reason: Option) -> Result<()> { +pub async fn leave_room( + services: &Services, + user_id: &UserId, + room_id: &RoomId, + reason: Option, +) -> Result<()> { //use conduwuit::utils::stream::OptionStream; use futures::TryFutureExt; @@ -1500,7 +1613,11 @@ pub async fn leave_room(services: &Services, user_id: &UserId, room_id: &RoomId, let Ok(event) = services .rooms .state_accessor - .room_state_get_content::(room_id, &StateEventType::RoomMember, user_id.as_str()) + .room_state_get_content::( + room_id, + &StateEventType::RoomMember, + user_id.as_str(), + ) .await else { // Fix for broken rooms @@ -1527,14 +1644,11 @@ pub async fn leave_room(services: &Services, user_id: &UserId, room_id: &RoomId, .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - user_id.to_string(), - &RoomMemberEventContent { - membership: MembershipState::Leave, - reason, - ..event - }, - ), + PduBuilder::state(user_id.to_string(), &RoomMemberEventContent { + membership: MembershipState::Leave, + reason, + ..event + }), user_id, room_id, &state_lock, @@ -1545,8 +1659,13 @@ pub async fn leave_room(services: &Services, user_id: &UserId, room_id: &RoomId, Ok(()) } -async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &RoomId) -> Result<()> { - let mut make_leave_response_and_server = Err!(BadServerResponse("No server available to assist in leaving.")); +async fn remote_leave_room( + services: &Services, + user_id: &UserId, + room_id: &RoomId, +) -> Result<()> { + let mut make_leave_response_and_server = + Err!(BadServerResponse("No server available to assist in leaving.")); let invite_state = services .rooms @@ -1608,8 +1727,12 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room )); } - let mut leave_event_stub = serde_json::from_str::(make_leave_response.event.get()) - .map_err(|e| err!(BadServerResponse("Invalid make_leave event json received from server: {e:?}")))?; + let mut leave_event_stub = serde_json::from_str::( + make_leave_response.event.get(), + ) + .map_err(|e| { + err!(BadServerResponse("Invalid make_leave event json received from server: {e:?}")) + })?; // TODO: Is origin needed? leave_event_stub.insert( @@ -1627,8 +1750,8 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room // room v3 and above removed the "event_id" field from remote PDU format match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - _ => { + | RoomVersionId::V1 | RoomVersionId::V2 => {}, + | _ => { leave_event_stub.remove("event_id"); }, }; @@ -1643,7 +1766,8 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room let event_id = pdu::gen_event_id(&leave_event_stub, &room_version_id)?; // Add event_id back - leave_event_stub.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.clone().into())); + leave_event_stub + .insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.clone().into())); // It has enough fields to be called a proper event now let leave_event = leave_event_stub; diff --git a/src/api/client/message.rs b/src/api/client/message.rs index 32e0b1e31..93582de02 100644 --- a/src/api/client/message.rs +++ b/src/api/client/message.rs @@ -56,7 +56,8 @@ const LIMIT_DEFAULT: usize = 10; /// - Only works if the user is joined (TODO: always allow, but only show events /// where the user was joined, depending on `history_visibility`) pub(crate) async fn get_message_events_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender = body.sender(); let (sender_user, sender_device) = sender; @@ -69,8 +70,8 @@ pub(crate) async fn get_message_events_route( .map(str::parse) .transpose()? .unwrap_or_else(|| match body.dir { - Direction::Forward => PduCount::min(), - Direction::Backward => PduCount::max(), + | Direction::Forward => PduCount::min(), + | Direction::Backward => PduCount::max(), }); let to: Option = body.to.as_deref().map(str::parse).flat_ok(); @@ -81,10 +82,12 @@ pub(crate) async fn get_message_events_route( .unwrap_or(LIMIT_DEFAULT) .min(LIMIT_MAX); - services - .rooms - .lazy_loading - .lazy_load_confirm_delivery(sender_user, sender_device, room_id, from); + services.rooms.lazy_loading.lazy_load_confirm_delivery( + sender_user, + sender_device, + room_id, + from, + ); if matches!(body.dir, Direction::Backward) { services @@ -98,14 +101,14 @@ pub(crate) async fn get_message_events_route( } let it = match body.dir { - Direction::Forward => services + | Direction::Forward => services .rooms .timeline .pdus(Some(sender_user), room_id, Some(from)) .await? .boxed(), - Direction::Backward => services + | Direction::Backward => services .rooms .timeline .pdus_rev(Some(sender_user), room_id, Some(from)) @@ -141,10 +144,13 @@ pub(crate) async fn get_message_events_route( if !cfg!(feature = "element_hacks") { if let Some(next_token) = next_token { - services - .rooms - .lazy_loading - .lazy_load_mark_sent(sender_user, sender_device, room_id, lazy, next_token); + services.rooms.lazy_loading.lazy_load_mark_sent( + sender_user, + sender_device, + room_id, + lazy, + next_token, + ); } } @@ -162,7 +168,11 @@ pub(crate) async fn get_message_events_route( }) } -async fn get_member_event(services: &Services, room_id: &RoomId, user_id: &UserId) -> Option> { +async fn get_member_event( + services: &Services, + room_id: &RoomId, + user_id: &UserId, +) -> Option> { services .rooms .state_accessor @@ -173,7 +183,11 @@ async fn get_member_event(services: &Services, room_id: &RoomId, user_id: &UserI } pub(crate) async fn update_lazy( - services: &Services, room_id: &RoomId, sender: (&UserId, &DeviceId), mut lazy: LazySet, item: &PdusIterItem, + services: &Services, + room_id: &RoomId, + sender: (&UserId, &DeviceId), + mut lazy: LazySet, + item: &PdusIterItem, force: bool, ) -> LazySet { let (_, event) = &item; @@ -204,7 +218,11 @@ pub(crate) async fn update_lazy( lazy } -pub(crate) async fn ignored_filter(services: &Services, item: PdusIterItem, user_id: &UserId) -> Option { +pub(crate) async fn ignored_filter( + services: &Services, + item: PdusIterItem, + user_id: &UserId, +) -> Option { let (_, pdu) = &item; // exclude Synapse's dummy events from bloating up response bodies. clients @@ -223,7 +241,9 @@ pub(crate) async fn ignored_filter(services: &Services, item: PdusIterItem, user } pub(crate) async fn visibility_filter( - services: &Services, item: PdusIterItem, user_id: &UserId, + services: &Services, + item: PdusIterItem, + user_id: &UserId, ) -> Option { let (_, pdu) = &item; diff --git a/src/api/client/openid.rs b/src/api/client/openid.rs index b8bbfb911..4b2ff7270 100644 --- a/src/api/client/openid.rs +++ b/src/api/client/openid.rs @@ -16,7 +16,8 @@ use crate::{Error, Result, Ruma}; /// /// - The token generated is only valid for the OpenID API pub(crate) async fn create_openid_token_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client/presence.rs b/src/api/client/presence.rs index 948d6caa3..1a3ad26ef 100644 --- a/src/api/client/presence.rs +++ b/src/api/client/presence.rs @@ -12,10 +12,14 @@ use crate::{Error, Result, Ruma}; /// /// Sets the presence state of the sender user. pub(crate) async fn set_presence_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.allow_local_presence() { - return Err(Error::BadRequest(ErrorKind::forbidden(), "Presence is disabled on this server")); + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "Presence is disabled on this server", + )); } let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -40,10 +44,14 @@ pub(crate) async fn set_presence_route( /// /// - Only works if you share a room with the user pub(crate) async fn get_presence_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.allow_local_presence() { - return Err(Error::BadRequest(ErrorKind::forbidden(), "Presence is disabled on this server")); + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "Presence is disabled on this server", + )); } let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client/profile.rs b/src/api/client/profile.rs index ea74cdafb..584adfc19 100644 --- a/src/api/client/profile.rs +++ b/src/api/client/profile.rs @@ -11,7 +11,9 @@ use ruma::{ api::{ client::{ error::ErrorKind, - profile::{get_avatar_url, get_display_name, get_profile, set_avatar_url, set_display_name}, + profile::{ + get_avatar_url, get_display_name, get_profile, set_avatar_url, set_display_name, + }, }, federation, }, @@ -29,7 +31,8 @@ use crate::Ruma; /// /// - Also makes sure other users receive the update using presence EDUs pub(crate) async fn set_displayname_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -45,7 +48,8 @@ pub(crate) async fn set_displayname_route( .collect() .await; - update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms).await; + update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms) + .await; if services.globals.allow_local_presence() { // Presence update @@ -65,7 +69,8 @@ pub(crate) async fn set_displayname_route( /// - If user is on another server and we do not have a local copy already fetch /// displayname over federation pub(crate) async fn get_displayname_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.user_is_local(&body.user_id) { // Create and update our local copy of the user @@ -94,9 +99,7 @@ pub(crate) async fn get_displayname_route( .users .set_blurhash(&body.user_id, response.blurhash.clone()); - return Ok(get_display_name::v3::Response { - displayname: response.displayname, - }); + return Ok(get_display_name::v3::Response { displayname: response.displayname }); } } @@ -117,7 +120,8 @@ pub(crate) async fn get_displayname_route( /// /// - Also makes sure other users receive the update using presence EDUs pub(crate) async fn set_avatar_url_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -161,7 +165,8 @@ pub(crate) async fn set_avatar_url_route( /// - If user is on another server and we do not have a local copy already fetch /// `avatar_url` and blurhash over federation pub(crate) async fn get_avatar_url_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.user_is_local(&body.user_id) { // Create and update our local copy of the user @@ -218,7 +223,8 @@ pub(crate) async fn get_avatar_url_route( /// - If user is on another server and we do not have a local copy already, /// fetch profile over federation. pub(crate) async fn get_profile_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.user_is_local(&body.user_id) { // Create and update our local copy of the user @@ -254,9 +260,11 @@ pub(crate) async fn get_profile_route( .set_timezone(&body.user_id, response.tz.clone()); for (profile_key, profile_key_value) in &response.custom_profile_fields { - services - .users - .set_profile_key(&body.user_id, profile_key, Some(profile_key_value.clone())); + services.users.set_profile_key( + &body.user_id, + profile_key, + Some(profile_key_value.clone()), + ); } return Ok(get_profile::v3::Response { @@ -295,7 +303,10 @@ pub(crate) async fn get_profile_route( } pub async fn update_displayname( - services: &Services, user_id: &UserId, displayname: Option, all_joined_rooms: &[OwnedRoomId], + services: &Services, + user_id: &UserId, + displayname: Option, + all_joined_rooms: &[OwnedRoomId], ) { let (current_avatar_url, current_blurhash, current_displayname) = join3( services.users.avatar_url(user_id), @@ -322,19 +333,16 @@ pub async fn update_displayname( .iter() .try_stream() .and_then(|room_id: &OwnedRoomId| async move { - let pdu = PduBuilder::state( - user_id.to_string(), - &RoomMemberEventContent { - displayname: displayname.clone(), - membership: MembershipState::Join, - avatar_url: avatar_url.clone(), - blurhash: blurhash.clone(), - join_authorized_via_users_server: None, - reason: None, - is_direct: None, - third_party_invite: None, - }, - ); + let pdu = PduBuilder::state(user_id.to_string(), &RoomMemberEventContent { + displayname: displayname.clone(), + membership: MembershipState::Join, + avatar_url: avatar_url.clone(), + blurhash: blurhash.clone(), + join_authorized_via_users_server: None, + reason: None, + is_direct: None, + third_party_invite: None, + }); Ok((pdu, room_id)) }) @@ -346,7 +354,10 @@ pub async fn update_displayname( } pub async fn update_avatar_url( - services: &Services, user_id: &UserId, avatar_url: Option, blurhash: Option, + services: &Services, + user_id: &UserId, + avatar_url: Option, + blurhash: Option, all_joined_rooms: &[OwnedRoomId], ) { let (current_avatar_url, current_blurhash, current_displayname) = join3( @@ -375,19 +386,16 @@ pub async fn update_avatar_url( .iter() .try_stream() .and_then(|room_id: &OwnedRoomId| async move { - let pdu = PduBuilder::state( - user_id.to_string(), - &RoomMemberEventContent { - avatar_url: avatar_url.clone(), - blurhash: blurhash.clone(), - membership: MembershipState::Join, - displayname: displayname.clone(), - join_authorized_via_users_server: None, - reason: None, - is_direct: None, - third_party_invite: None, - }, - ); + let pdu = PduBuilder::state(user_id.to_string(), &RoomMemberEventContent { + avatar_url: avatar_url.clone(), + blurhash: blurhash.clone(), + membership: MembershipState::Join, + displayname: displayname.clone(), + join_authorized_via_users_server: None, + reason: None, + is_direct: None, + third_party_invite: None, + }); Ok((pdu, room_id)) }) @@ -399,7 +407,9 @@ pub async fn update_avatar_url( } pub async fn update_all_rooms( - services: &Services, all_joined_rooms: Vec<(PduBuilder, &OwnedRoomId)>, user_id: &UserId, + services: &Services, + all_joined_rooms: Vec<(PduBuilder, &OwnedRoomId)>, + user_id: &UserId, ) { for (pdu_builder, room_id) in all_joined_rooms { let state_lock = services.rooms.state.mutex.lock(room_id).await; diff --git a/src/api/client/push.rs b/src/api/client/push.rs index e290c952b..ed7371e4e 100644 --- a/src/api/client/push.rs +++ b/src/api/client/push.rs @@ -4,15 +4,19 @@ use ruma::{ api::client::{ error::ErrorKind, push::{ - delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, get_pushrule_enabled, get_pushrules_all, - get_pushrules_global_scope, set_pusher, set_pushrule, set_pushrule_actions, set_pushrule_enabled, + delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, + get_pushrule_enabled, get_pushrules_all, get_pushrules_global_scope, set_pusher, + set_pushrule, set_pushrule_actions, set_pushrule_enabled, }, }, events::{ push_rules::{PushRulesEvent, PushRulesEventContent}, GlobalAccountDataEventType, }, - push::{InsertPushRuleError, PredefinedContentRuleId, PredefinedOverrideRuleId, RemovePushRuleError, Ruleset}, + push::{ + InsertPushRuleError, PredefinedContentRuleId, PredefinedOverrideRuleId, + RemovePushRuleError, Ruleset, + }, CanonicalJsonObject, CanonicalJsonValue, }; use service::Services; @@ -23,7 +27,8 @@ use crate::{Error, Result, Ruma}; /// /// Retrieves the push rules event for this user. pub(crate) async fn get_pushrules_all_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -40,8 +45,10 @@ pub(crate) async fn get_pushrules_all_route( return recreate_push_rules_and_return(&services, sender_user).await; }; - let account_data_content = serde_json::from_value::(content_value.into()) - .map_err(|e| err!(Database(warn!("Invalid push rules account data event in database: {e}"))))?; + let account_data_content = + serde_json::from_value::(content_value.into()).map_err(|e| { + err!(Database(warn!("Invalid push rules account data event in database: {e}"))) + })?; let mut global_ruleset = account_data_content.global; @@ -79,9 +86,7 @@ pub(crate) async fn get_pushrules_all_route( sender_user, GlobalAccountDataEventType::PushRules.to_string().into(), &serde_json::to_value(PushRulesEvent { - content: PushRulesEventContent { - global: global_ruleset.clone(), - }, + content: PushRulesEventContent { global: global_ruleset.clone() }, }) .expect("to json always works"), ) @@ -89,9 +94,7 @@ pub(crate) async fn get_pushrules_all_route( } }; - Ok(get_pushrules_all::v3::Response { - global: global_ruleset, - }) + Ok(get_pushrules_all::v3::Response { global: global_ruleset }) } /// # `GET /_matrix/client/r0/pushrules/global/` @@ -100,7 +103,8 @@ pub(crate) async fn get_pushrules_all_route( /// /// This appears to be the exact same as `GET /_matrix/client/r0/pushrules/`. pub(crate) async fn get_pushrules_global_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -134,8 +138,10 @@ pub(crate) async fn get_pushrules_global_route( }); }; - let account_data_content = serde_json::from_value::(content_value.into()) - .map_err(|e| err!(Database(warn!("Invalid push rules account data event in database: {e}"))))?; + let account_data_content = + serde_json::from_value::(content_value.into()).map_err(|e| { + err!(Database(warn!("Invalid push rules account data event in database: {e}"))) + })?; let mut global_ruleset = account_data_content.global; @@ -173,9 +179,7 @@ pub(crate) async fn get_pushrules_global_route( sender_user, GlobalAccountDataEventType::PushRules.to_string().into(), &serde_json::to_value(PushRulesEvent { - content: PushRulesEventContent { - global: global_ruleset.clone(), - }, + content: PushRulesEventContent { global: global_ruleset.clone() }, }) .expect("to json always works"), ) @@ -183,16 +187,15 @@ pub(crate) async fn get_pushrules_global_route( } }; - Ok(get_pushrules_global_scope::v3::Response { - global: global_ruleset, - }) + Ok(get_pushrules_global_scope::v3::Response { global: global_ruleset }) } /// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}` /// /// Retrieves a single specified push rule for this user. pub(crate) async fn get_pushrule_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -218,9 +221,7 @@ pub(crate) async fn get_pushrule_route( .map(Into::into); if let Some(rule) = rule { - Ok(get_pushrule::v3::Response { - rule, - }) + Ok(get_pushrule::v3::Response { rule }) } else { Err(Error::BadRequest(ErrorKind::NotFound, "Push rule not found.")) } @@ -230,7 +231,8 @@ pub(crate) async fn get_pushrule_route( /// /// Creates a single specified push rule for this user. pub(crate) async fn set_pushrule_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let body = body.body; @@ -241,32 +243,33 @@ pub(crate) async fn set_pushrule_route( .await .map_err(|_| err!(Request(NotFound("PushRules event not found."))))?; - if let Err(error) = - account_data - .content - .global - .insert(body.rule.clone(), body.after.as_deref(), body.before.as_deref()) - { + if let Err(error) = account_data.content.global.insert( + body.rule.clone(), + body.after.as_deref(), + body.before.as_deref(), + ) { let err = match error { - InsertPushRuleError::ServerDefaultRuleId => Error::BadRequest( + | InsertPushRuleError::ServerDefaultRuleId => Error::BadRequest( ErrorKind::InvalidParam, "Rule IDs starting with a dot are reserved for server-default rules.", ), - InsertPushRuleError::InvalidRuleId => { - Error::BadRequest(ErrorKind::InvalidParam, "Rule ID containing invalid characters.") - }, - InsertPushRuleError::RelativeToServerDefaultRule => Error::BadRequest( + | InsertPushRuleError::InvalidRuleId => Error::BadRequest( + ErrorKind::InvalidParam, + "Rule ID containing invalid characters.", + ), + | InsertPushRuleError::RelativeToServerDefaultRule => Error::BadRequest( ErrorKind::InvalidParam, "Can't place a push rule relatively to a server-default rule.", ), - InsertPushRuleError::UnknownRuleId => { - Error::BadRequest(ErrorKind::NotFound, "The before or after rule could not be found.") - }, - InsertPushRuleError::BeforeHigherThanAfter => Error::BadRequest( + | InsertPushRuleError::UnknownRuleId => Error::BadRequest( + ErrorKind::NotFound, + "The before or after rule could not be found.", + ), + | InsertPushRuleError::BeforeHigherThanAfter => Error::BadRequest( ErrorKind::InvalidParam, "The before rule has a higher priority than the after rule.", ), - _ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."), + | _ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."), }; return Err(err); @@ -289,7 +292,8 @@ pub(crate) async fn set_pushrule_route( /// /// Gets the actions of a single specified push rule for this user. pub(crate) async fn get_pushrule_actions_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -315,16 +319,15 @@ pub(crate) async fn get_pushrule_actions_route( .map(|rule| rule.actions().to_owned()) .ok_or_else(|| err!(Request(NotFound("Push rule not found."))))?; - Ok(get_pushrule_actions::v3::Response { - actions, - }) + Ok(get_pushrule_actions::v3::Response { actions }) } /// # `PUT /_matrix/client/r0/pushrules/global/{kind}/{ruleId}/actions` /// /// Sets the actions of a single specified push rule for this user. pub(crate) async fn set_pushrule_actions_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -360,7 +363,8 @@ pub(crate) async fn set_pushrule_actions_route( /// /// Gets the enabled status of a single specified push rule for this user. pub(crate) async fn get_pushrule_enabled_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -370,9 +374,7 @@ pub(crate) async fn get_pushrule_enabled_route( || body.rule_id.as_str() == PredefinedOverrideRuleId::ContainsDisplayName.as_str() || body.rule_id.as_str() == PredefinedOverrideRuleId::RoomNotif.as_str() { - return Ok(get_pushrule_enabled::v3::Response { - enabled: false, - }); + return Ok(get_pushrule_enabled::v3::Response { enabled: false }); } let event: PushRulesEvent = services @@ -388,16 +390,15 @@ pub(crate) async fn get_pushrule_enabled_route( .map(ruma::push::AnyPushRuleRef::enabled) .ok_or_else(|| err!(Request(NotFound("Push rule not found."))))?; - Ok(get_pushrule_enabled::v3::Response { - enabled, - }) + Ok(get_pushrule_enabled::v3::Response { enabled }) } /// # `PUT /_matrix/client/r0/pushrules/global/{kind}/{ruleId}/enabled` /// /// Sets the enabled status of a single specified push rule for this user. pub(crate) async fn set_pushrule_enabled_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -433,7 +434,8 @@ pub(crate) async fn set_pushrule_enabled_route( /// /// Deletes a single specified push rule for this user. pub(crate) async fn delete_pushrule_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -449,11 +451,13 @@ pub(crate) async fn delete_pushrule_route( .remove(body.kind.clone(), &body.rule_id) { let err = match error { - RemovePushRuleError::ServerDefault => { - Error::BadRequest(ErrorKind::InvalidParam, "Cannot delete a server-default pushrule.") - }, - RemovePushRuleError::NotFound => Error::BadRequest(ErrorKind::NotFound, "Push rule not found."), - _ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."), + | RemovePushRuleError::ServerDefault => Error::BadRequest( + ErrorKind::InvalidParam, + "Cannot delete a server-default pushrule.", + ), + | RemovePushRuleError::NotFound => + Error::BadRequest(ErrorKind::NotFound, "Push rule not found."), + | _ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."), }; return Err(err); @@ -476,7 +480,8 @@ pub(crate) async fn delete_pushrule_route( /// /// Gets all currently active pushers for the sender user. pub(crate) async fn get_pushers_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -491,7 +496,8 @@ pub(crate) async fn get_pushers_route( /// /// - TODO: Handle `append` pub(crate) async fn set_pushers_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -506,7 +512,8 @@ pub(crate) async fn set_pushers_route( /// user somehow has bad push rules, these must always exist per spec. /// so recreate it and return server default silently async fn recreate_push_rules_and_return( - services: &Services, sender_user: &ruma::UserId, + services: &Services, + sender_user: &ruma::UserId, ) -> Result { services .account_data diff --git a/src/api/client/read_marker.rs b/src/api/client/read_marker.rs index d7f241015..2e98afbc8 100644 --- a/src/api/client/read_marker.rs +++ b/src/api/client/read_marker.rs @@ -21,15 +21,14 @@ use crate::{Result, Ruma}; /// - If `read_receipt` is set: Update private marker and public read receipt /// EDU pub(crate) async fn set_read_marker_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); if let Some(event) = &body.fully_read { let fully_read_event = ruma::events::fully_read::FullyReadEvent { - content: ruma::events::fully_read::FullyReadEventContent { - event_id: event.clone(), - }, + content: ruma::events::fully_read::FullyReadEventContent { event_id: event.clone() }, }; services @@ -55,13 +54,10 @@ pub(crate) async fn set_read_marker_route( event.to_owned(), BTreeMap::from_iter([( ReceiptType::Read, - BTreeMap::from_iter([( - sender_user.to_owned(), - ruma::events::receipt::Receipt { - ts: Some(MilliSecondsSinceUnixEpoch::now()), - thread: ReceiptThread::Unthreaded, - }, - )]), + BTreeMap::from_iter([(sender_user.to_owned(), ruma::events::receipt::Receipt { + ts: Some(MilliSecondsSinceUnixEpoch::now()), + thread: ReceiptThread::Unthreaded, + })]), )]), )]); @@ -88,7 +84,9 @@ pub(crate) async fn set_read_marker_route( .map_err(|_| err!(Request(NotFound("Event not found."))))?; let PduCount::Normal(count) = count else { - return Err!(Request(InvalidParam("Event is a backfilled PDU and cannot be marked as read."))); + return Err!(Request(InvalidParam( + "Event is a backfilled PDU and cannot be marked as read." + ))); }; services @@ -104,7 +102,8 @@ pub(crate) async fn set_read_marker_route( /// /// Sets private read marker and public read receipt EDU. pub(crate) async fn create_receipt_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); @@ -119,7 +118,7 @@ pub(crate) async fn create_receipt_route( } match body.receipt_type { - create_receipt::v3::ReceiptType::FullyRead => { + | create_receipt::v3::ReceiptType::FullyRead => { let fully_read_event = ruma::events::fully_read::FullyReadEvent { content: ruma::events::fully_read::FullyReadEventContent { event_id: body.event_id.clone(), @@ -135,7 +134,7 @@ pub(crate) async fn create_receipt_route( ) .await?; }, - create_receipt::v3::ReceiptType::Read => { + | create_receipt::v3::ReceiptType::Read => { let receipt_content = BTreeMap::from_iter([( body.event_id.clone(), BTreeMap::from_iter([( @@ -163,7 +162,7 @@ pub(crate) async fn create_receipt_route( ) .await; }, - create_receipt::v3::ReceiptType::ReadPrivate => { + | create_receipt::v3::ReceiptType::ReadPrivate => { let count = services .rooms .timeline @@ -172,7 +171,9 @@ pub(crate) async fn create_receipt_route( .map_err(|_| err!(Request(NotFound("Event not found."))))?; let PduCount::Normal(count) = count else { - return Err!(Request(InvalidParam("Event is a backfilled PDU and cannot be marked as read."))); + return Err!(Request(InvalidParam( + "Event is a backfilled PDU and cannot be marked as read." + ))); }; services @@ -180,12 +181,11 @@ pub(crate) async fn create_receipt_route( .read_receipt .private_read_set(&body.room_id, sender_user, count); }, - _ => { + | _ => return Err!(Request(InvalidParam(warn!( "Received unknown read receipt type: {}", &body.receipt_type - )))) - }, + )))), } Ok(create_receipt::v3::Response {}) diff --git a/src/api/client/redact.rs b/src/api/client/redact.rs index a986dc18b..0b01238f0 100644 --- a/src/api/client/redact.rs +++ b/src/api/client/redact.rs @@ -1,5 +1,7 @@ use axum::extract::State; -use ruma::{api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent}; +use ruma::{ + api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent, +}; use crate::{service::pdu::PduBuilder, Result, Ruma}; @@ -9,7 +11,8 @@ use crate::{service::pdu::PduBuilder, Result, Ruma}; /// /// - TODO: Handle txn id pub(crate) async fn redact_event_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let body = body.body; @@ -35,7 +38,5 @@ pub(crate) async fn redact_event_route( drop(state_lock); - Ok(redact_event::v3::Response { - event_id: event_id.into(), - }) + Ok(redact_event::v3::Response { event_id: event_id.into() }) } diff --git a/src/api/client/relations.rs b/src/api/client/relations.rs index c47bc60f1..87fb1eac2 100644 --- a/src/api/client/relations.rs +++ b/src/api/client/relations.rs @@ -8,7 +8,8 @@ use futures::StreamExt; use ruma::{ api::{ client::relations::{ - get_relating_events, get_relating_events_with_rel_type, get_relating_events_with_rel_type_and_event_type, + get_relating_events, get_relating_events_with_rel_type, + get_relating_events_with_rel_type_and_event_type, }, Direction, }, @@ -21,7 +22,8 @@ use crate::Ruma; /// # `GET /_matrix/client/r0/rooms/{roomId}/relations/{eventId}/{relType}/{eventType}` pub(crate) async fn get_relating_events_with_rel_type_and_event_type_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { paginate_relations_with_filter( &services, @@ -47,7 +49,8 @@ pub(crate) async fn get_relating_events_with_rel_type_and_event_type_route( /// # `GET /_matrix/client/r0/rooms/{roomId}/relations/{eventId}/{relType}` pub(crate) async fn get_relating_events_with_rel_type_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { paginate_relations_with_filter( &services, @@ -73,7 +76,8 @@ pub(crate) async fn get_relating_events_with_rel_type_route( /// # `GET /_matrix/client/r0/rooms/{roomId}/relations/{eventId}` pub(crate) async fn get_relating_events_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { paginate_relations_with_filter( &services, @@ -93,16 +97,24 @@ pub(crate) async fn get_relating_events_route( #[allow(clippy::too_many_arguments)] async fn paginate_relations_with_filter( - services: &Services, sender_user: &UserId, room_id: &RoomId, target: &EventId, - filter_event_type: Option, filter_rel_type: Option, from: Option<&str>, - to: Option<&str>, limit: Option, recurse: bool, dir: Direction, + services: &Services, + sender_user: &UserId, + room_id: &RoomId, + target: &EventId, + filter_event_type: Option, + filter_rel_type: Option, + from: Option<&str>, + to: Option<&str>, + limit: Option, + recurse: bool, + dir: Direction, ) -> Result { let start: PduCount = from .map(str::parse) .transpose()? .unwrap_or_else(|| match dir { - Direction::Forward => PduCount::min(), - Direction::Backward => PduCount::max(), + | Direction::Forward => PduCount::min(), + | Direction::Backward => PduCount::max(), }); let to: Option = to.map(str::parse).flat_ok(); @@ -115,11 +127,7 @@ async fn paginate_relations_with_filter( .min(100); // Spec (v1.10) recommends depth of at least 3 - let depth: u8 = if recurse { - 3 - } else { - 1 - }; + let depth: u8 = if recurse { 3 } else { 1 }; let events: Vec = services .rooms @@ -145,8 +153,8 @@ async fn paginate_relations_with_filter( .await; let next_batch = match dir { - Direction::Forward => events.last(), - Direction::Backward => events.first(), + | Direction::Forward => events.last(), + | Direction::Backward => events.first(), } .map(at!(0)) .as_ref() @@ -164,7 +172,11 @@ async fn paginate_relations_with_filter( }) } -async fn visibility_filter(services: &Services, sender_user: &UserId, item: PdusIterItem) -> Option { +async fn visibility_filter( + services: &Services, + sender_user: &UserId, + item: PdusIterItem, +) -> Option { let (_, pdu) = &item; services diff --git a/src/api/client/report.rs b/src/api/client/report.rs index 429cd033f..fe23b7bdd 100644 --- a/src/api/client/report.rs +++ b/src/api/client/report.rs @@ -25,7 +25,8 @@ use crate::{ /// Reports an abusive room to homeserver admins #[tracing::instrument(skip_all, fields(%client), name = "report_room")] pub(crate) async fn report_room_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { // user authentication @@ -78,14 +79,16 @@ pub(crate) async fn report_room_route( /// Reports an inappropriate event to homeserver admins #[tracing::instrument(skip_all, fields(%client), name = "report_event")] pub(crate) async fn report_event_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { // user authentication let sender_user = body.sender_user.as_ref().expect("user is authenticated"); info!( - "Received event report by user {sender_user} for room {} and event ID {}, with reason: \"{}\"", + "Received event report by user {sender_user} for room {} and event ID {}, with reason: \ + \"{}\"", body.room_id, body.event_id, body.reason.as_deref().unwrap_or("") @@ -114,8 +117,8 @@ pub(crate) async fn report_event_route( services .admin .send_message(message::RoomMessageEventContent::text_markdown(format!( - "@room Event report received from {} -\n\nEvent ID: {}\nRoom ID: {}\nSent By: {}\n\nReport Score: \ - {}\nReport Reason: {}", + "@room Event report received from {} -\n\nEvent ID: {}\nRoom ID: {}\nSent By: \ + {}\n\nReport Score: {}\nReport Reason: {}", sender_user.to_owned(), pdu.event_id, pdu.room_id, @@ -136,10 +139,18 @@ pub(crate) async fn report_event_route( /// check if report reasoning is less than or equal to 750 characters /// check if reporting user is in the reporting room async fn is_event_report_valid( - services: &Services, event_id: &EventId, room_id: &RoomId, sender_user: &UserId, reason: Option<&String>, - score: Option, pdu: &PduEvent, + services: &Services, + event_id: &EventId, + room_id: &RoomId, + sender_user: &UserId, + reason: Option<&String>, + score: Option, + pdu: &PduEvent, ) -> Result<()> { - debug_info!("Checking if report from user {sender_user} for event {event_id} in room {room_id} is valid"); + debug_info!( + "Checking if report from user {sender_user} for event {event_id} in room {room_id} is \ + valid" + ); if room_id != pdu.room_id { return Err(Error::BadRequest( @@ -183,6 +194,9 @@ async fn is_event_report_valid( /// enumerating for potential events existing in our server. async fn delay_response() { let time_to_wait = rand::thread_rng().gen_range(2..5); - debug_info!("Got successful /report request, waiting {time_to_wait} seconds before sending successful response."); + debug_info!( + "Got successful /report request, waiting {time_to_wait} seconds before sending \ + successful response." + ); sleep(Duration::from_secs(time_to_wait)).await; } diff --git a/src/api/client/room/aliases.rs b/src/api/client/room/aliases.rs index f500e9c79..3f0016af9 100644 --- a/src/api/client/room/aliases.rs +++ b/src/api/client/room/aliases.rs @@ -12,7 +12,8 @@ use crate::Ruma; /// - Only users joined to the room are allowed to call this, or if /// `history_visibility` is world readable in the room pub(crate) async fn get_room_aliases_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client/room/create.rs b/src/api/client/room/create.rs index b98f1dab0..89cddc0f0 100644 --- a/src/api/client/room/create.rs +++ b/src/api/client/room/create.rs @@ -24,7 +24,8 @@ use ruma::{ }, int, serde::{JsonObject, Raw}, - CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, RoomVersionId, + CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, + RoomVersionId, }; use serde_json::{json, value::to_raw_value}; use service::{appservice::RegistrationInfo, Services}; @@ -49,7 +50,8 @@ use crate::{client::invite_helper, Ruma}; /// - Send invite events #[allow(clippy::large_stack_frames)] pub(crate) async fn create_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { use create_room::v3::RoomPreset; @@ -59,7 +61,10 @@ pub(crate) async fn create_room_route( && body.appservice_info.is_none() && !services.users.is_admin(sender_user).await { - return Err(Error::BadRequest(ErrorKind::forbidden(), "Room creation has been disabled.")); + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "Room creation has been disabled.", + )); } let room_id: OwnedRoomId = if let Some(custom_room_id) = &body.room_id { @@ -91,8 +96,8 @@ pub(crate) async fn create_room_route( services .admin .send_text(&format!( - "Non-admin user {sender_user} tried to publish {0} to the room directory while \ - \"lockdown_public_room_directory\" is enabled", + "Non-admin user {sender_user} tried to publish {0} to the room directory \ + while \"lockdown_public_room_directory\" is enabled", &room_id )) .await; @@ -115,7 +120,7 @@ pub(crate) async fn create_room_route( }; let room_version = match body.room_version.clone() { - Some(room_version) => { + | Some(room_version) => if services.server.supported_room_version(&room_version) { room_version } else { @@ -123,13 +128,12 @@ pub(crate) async fn create_room_route( ErrorKind::UnsupportedRoomVersion, "This server does not support that room version.", )); - } - }, - None => services.server.config.default_room_version.clone(), + }, + | None => services.server.config.default_room_version.clone(), }; let create_content = match &body.creation_content { - Some(content) => { + | Some(content) => { use RoomVersionId::*; let mut content = content @@ -139,7 +143,7 @@ pub(crate) async fn create_room_route( Error::bad_database("Failed to deserialise content as canonical JSON.") })?; match room_version { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { content.insert( "creator".into(), json!(&sender_user).try_into().map_err(|e| { @@ -148,24 +152,25 @@ pub(crate) async fn create_room_route( })?, ); }, - _ => { + | _ => { // V11+ removed the "creator" key }, } content.insert( "room_version".into(), - json!(room_version.as_str()) - .try_into() - .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid creation content"))?, + json!(room_version.as_str()).try_into().map_err(|_| { + Error::BadRequest(ErrorKind::BadJson, "Invalid creation content") + })?, ); content }, - None => { + | None => { use RoomVersionId::*; let content = match room_version { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => RoomCreateEventContent::new_v1(sender_user.clone()), - _ => RoomCreateEventContent::new_v11(), + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => + RoomCreateEventContent::new_v1(sender_user.clone()), + | _ => RoomCreateEventContent::new_v11(), }; let mut content = serde_json::from_str::( to_raw_value(&content) @@ -190,7 +195,8 @@ pub(crate) async fn create_room_route( .build_and_append_pdu( PduBuilder { event_type: TimelineEventType::RoomCreate, - content: to_raw_value(&create_content).expect("create event content serialization"), + content: to_raw_value(&create_content) + .expect("create event content serialization"), state_key: Some(String::new()), ..Default::default() }, @@ -206,16 +212,13 @@ pub(crate) async fn create_room_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - sender_user.to_string(), - &RoomMemberEventContent { - displayname: services.users.displayname(sender_user).await.ok(), - avatar_url: services.users.avatar_url(sender_user).await.ok(), - blurhash: services.users.blurhash(sender_user).await.ok(), - is_direct: Some(body.is_direct), - ..RoomMemberEventContent::new(MembershipState::Join) - }, - ), + PduBuilder::state(sender_user.to_string(), &RoomMemberEventContent { + displayname: services.users.displayname(sender_user).await.ok(), + avatar_url: services.users.avatar_url(sender_user).await.ok(), + blurhash: services.users.blurhash(sender_user).await.ok(), + is_direct: Some(body.is_direct), + ..RoomMemberEventContent::new(MembershipState::Join) + }), sender_user, &room_id, &state_lock, @@ -227,8 +230,8 @@ pub(crate) async fn create_room_route( // Figure out preset. We need it for preset specific events let preset = body.preset.clone().unwrap_or(match &body.visibility { - room::Visibility::Public => RoomPreset::PublicChat, - _ => RoomPreset::PrivateChat, // Room visibility should not be custom + | room::Visibility::Public => RoomPreset::PublicChat, + | _ => RoomPreset::PrivateChat, // Room visibility should not be custom }); let mut users = BTreeMap::from_iter([(sender_user.clone(), int!(100))]); @@ -236,7 +239,9 @@ pub(crate) async fn create_room_route( if preset == RoomPreset::TrustedPrivateChat { for invite in &body.invite { if services.users.user_is_ignored(sender_user, invite).await { - return Err!(Request(Forbidden("You cannot invite users you have ignored to rooms."))); + return Err!(Request(Forbidden( + "You cannot invite users you have ignored to rooms." + ))); } else if services.users.user_is_ignored(invite, sender_user).await { // silently drop the invite to the recipient if they've been ignored by the // sender, pretend it worked @@ -247,8 +252,11 @@ pub(crate) async fn create_room_route( } } - let power_levels_content = - default_power_levels_content(body.power_level_content_override.as_ref(), &body.visibility, users)?; + let power_levels_content = default_power_levels_content( + body.power_level_content_override.as_ref(), + &body.visibility, + users, + )?; services .rooms @@ -256,7 +264,8 @@ pub(crate) async fn create_room_route( .build_and_append_pdu( PduBuilder { event_type: TimelineEventType::RoomPowerLevels, - content: to_raw_value(&power_levels_content).expect("serialized power_levels event content"), + content: to_raw_value(&power_levels_content) + .expect("serialized power_levels event content"), state_key: Some(String::new()), ..Default::default() }, @@ -273,13 +282,10 @@ pub(crate) async fn create_room_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomCanonicalAliasEventContent { - alias: Some(room_alias_id.to_owned()), - alt_aliases: vec![], - }, - ), + PduBuilder::state(String::new(), &RoomCanonicalAliasEventContent { + alias: Some(room_alias_id.to_owned()), + alt_aliases: vec![], + }), sender_user, &room_id, &state_lock, @@ -298,9 +304,9 @@ pub(crate) async fn create_room_route( PduBuilder::state( String::new(), &RoomJoinRulesEventContent::new(match preset { - RoomPreset::PublicChat => JoinRule::Public, + | RoomPreset::PublicChat => JoinRule::Public, // according to spec "invite" is the default - _ => JoinRule::Invite, + | _ => JoinRule::Invite, }), ), sender_user, @@ -334,8 +340,8 @@ pub(crate) async fn create_room_route( PduBuilder::state( String::new(), &RoomGuestAccessEventContent::new(match preset { - RoomPreset::PublicChat => GuestAccess::Forbidden, - _ => GuestAccess::CanJoin, + | RoomPreset::PublicChat => GuestAccess::Forbidden, + | _ => GuestAccess::CanJoin, }), ), sender_user, @@ -367,7 +373,9 @@ pub(crate) async fn create_room_route( pdu_builder.state_key.get_or_insert_with(String::new); // Silently skip encryption events if they are not allowed - if pdu_builder.event_type == TimelineEventType::RoomEncryption && !services.globals.allow_encryption() { + if pdu_builder.event_type == TimelineEventType::RoomEncryption + && !services.globals.allow_encryption() + { continue; } @@ -399,12 +407,7 @@ pub(crate) async fn create_room_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomTopicEventContent { - topic: topic.clone(), - }, - ), + PduBuilder::state(String::new(), &RoomTopicEventContent { topic: topic.clone() }), sender_user, &room_id, &state_lock, @@ -417,16 +420,19 @@ pub(crate) async fn create_room_route( drop(state_lock); for user_id in &body.invite { if services.users.user_is_ignored(sender_user, user_id).await { - return Err!(Request(Forbidden("You cannot invite users you have ignored to rooms."))); + return Err!(Request(Forbidden( + "You cannot invite users you have ignored to rooms." + ))); } else if services.users.user_is_ignored(user_id, sender_user).await { // silently drop the invite to the recipient if they've been ignored by the // sender, pretend it worked continue; } - if let Err(e) = invite_helper(&services, sender_user, user_id, &room_id, None, body.is_direct) - .boxed() - .await + if let Err(e) = + invite_helper(&services, sender_user, user_id, &room_id, None, body.is_direct) + .boxed() + .await { warn!(%e, "Failed to send invite"); } @@ -446,7 +452,10 @@ pub(crate) async fn create_room_route( if services.globals.config.admin_room_notices { services .admin - .send_text(&format!("{sender_user} made {} public to the room directory", &room_id)) + .send_text(&format!( + "{sender_user} made {} public to the room directory", + &room_id + )) .await; } info!("{sender_user} made {0} public to the room directory", &room_id); @@ -459,21 +468,24 @@ pub(crate) async fn create_room_route( /// creates the power_levels_content for the PDU builder fn default_power_levels_content( - power_level_content_override: Option<&Raw>, visibility: &room::Visibility, + power_level_content_override: Option<&Raw>, + visibility: &room::Visibility, users: BTreeMap, ) -> Result { - let mut power_levels_content = serde_json::to_value(RoomPowerLevelsEventContent { - users, - ..Default::default() - }) - .expect("event is valid, we just created it"); + let mut power_levels_content = + serde_json::to_value(RoomPowerLevelsEventContent { users, ..Default::default() }) + .expect("event is valid, we just created it"); // secure proper defaults of sensitive/dangerous permissions that moderators // (power level 50) should not have easy access to - power_levels_content["events"]["m.room.power_levels"] = serde_json::to_value(100).expect("100 is valid Value"); - power_levels_content["events"]["m.room.server_acl"] = serde_json::to_value(100).expect("100 is valid Value"); - power_levels_content["events"]["m.room.tombstone"] = serde_json::to_value(100).expect("100 is valid Value"); - power_levels_content["events"]["m.room.encryption"] = serde_json::to_value(100).expect("100 is valid Value"); + power_levels_content["events"]["m.room.power_levels"] = + serde_json::to_value(100).expect("100 is valid Value"); + power_levels_content["events"]["m.room.server_acl"] = + serde_json::to_value(100).expect("100 is valid Value"); + power_levels_content["events"]["m.room.tombstone"] = + serde_json::to_value(100).expect("100 is valid Value"); + power_levels_content["events"]["m.room.encryption"] = + serde_json::to_value(100).expect("100 is valid Value"); power_levels_content["events"]["m.room.history_visibility"] = serde_json::to_value(100).expect("100 is valid Value"); @@ -481,14 +493,18 @@ fn default_power_levels_content( // useful in read-only announcement rooms that post a public poll. power_levels_content["events"]["org.matrix.msc3381.poll.response"] = serde_json::to_value(0).expect("0 is valid Value"); - power_levels_content["events"]["m.poll.response"] = serde_json::to_value(0).expect("0 is valid Value"); + power_levels_content["events"]["m.poll.response"] = + serde_json::to_value(0).expect("0 is valid Value"); // synapse does this too. clients do not expose these permissions. it prevents // default users from calling public rooms, for obvious reasons. if *visibility == room::Visibility::Public { - power_levels_content["events"]["m.call.invite"] = serde_json::to_value(50).expect("50 is valid Value"); - power_levels_content["events"]["m.call"] = serde_json::to_value(50).expect("50 is valid Value"); - power_levels_content["events"]["m.call.member"] = serde_json::to_value(50).expect("50 is valid Value"); + power_levels_content["events"]["m.call.invite"] = + serde_json::to_value(50).expect("50 is valid Value"); + power_levels_content["events"]["m.call"] = + serde_json::to_value(50).expect("50 is valid Value"); + power_levels_content["events"]["m.call.member"] = + serde_json::to_value(50).expect("50 is valid Value"); power_levels_content["events"]["org.matrix.msc3401.call"] = serde_json::to_value(50).expect("50 is valid Value"); power_levels_content["events"]["org.matrix.msc3401.call.member"] = @@ -497,7 +513,9 @@ fn default_power_levels_content( if let Some(power_level_content_override) = power_level_content_override { let json: JsonObject = serde_json::from_str(power_level_content_override.json().get()) - .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid power_level_content_override."))?; + .map_err(|_| { + Error::BadRequest(ErrorKind::BadJson, "Invalid power_level_content_override.") + })?; for (key, value) in json { power_levels_content[key] = value; @@ -509,14 +527,16 @@ fn default_power_levels_content( /// if a room is being created with a room alias, run our checks async fn room_alias_check( - services: &Services, room_alias_name: &str, appservice_info: Option<&RegistrationInfo>, + services: &Services, + room_alias_name: &str, + appservice_info: Option<&RegistrationInfo>, ) -> Result { // Basic checks on the room alias validity if room_alias_name.contains(':') { return Err(Error::BadRequest( ErrorKind::InvalidParam, - "Room alias contained `:` which is not allowed. Please note that this expects a localpart, not the full \ - room alias.", + "Room alias contained `:` which is not allowed. Please note that this expects a \ + localpart, not the full room alias.", )); } else if room_alias_name.contains(char::is_whitespace) { return Err(Error::BadRequest( @@ -534,8 +554,11 @@ async fn room_alias_check( return Err(Error::BadRequest(ErrorKind::Unknown, "Room alias name is forbidden.")); } - let full_room_alias = RoomAliasId::parse(format!("#{}:{}", room_alias_name, services.globals.config.server_name)) - .map_err(|e| { + let full_room_alias = RoomAliasId::parse(format!( + "#{}:{}", + room_alias_name, services.globals.config.server_name + )) + .map_err(|e| { info!("Failed to parse room alias {room_alias_name}: {e}"); Error::BadRequest(ErrorKind::InvalidParam, "Invalid room alias specified.") })?; @@ -552,14 +575,20 @@ async fn room_alias_check( if let Some(info) = appservice_info { if !info.aliases.is_match(full_room_alias.as_str()) { - return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace.")); + return Err(Error::BadRequest( + ErrorKind::Exclusive, + "Room alias is not in namespace.", + )); } } else if services .appservice .is_exclusive_alias(&full_room_alias) .await { - return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice.")); + return Err(Error::BadRequest( + ErrorKind::Exclusive, + "Room alias reserved by appservice.", + )); } debug_info!("Full room alias: {full_room_alias}"); @@ -581,8 +610,8 @@ fn custom_room_id_check(services: &Services, custom_room_id: &str) -> Result Result, ref body: Ruma, + State(services): State, + ref body: Ruma, ) -> Result { let event = services .rooms @@ -47,7 +48,5 @@ pub(crate) async fn get_room_event_route( let event = event.to_room_event(); - Ok(get_room_event::v3::Response { - event, - }) + Ok(get_room_event::v3::Response { event }) } diff --git a/src/api/client/room/initial_sync.rs b/src/api/client/room/initial_sync.rs index 8b2e45df9..cc3c9420a 100644 --- a/src/api/client/room/initial_sync.rs +++ b/src/api/client/room/initial_sync.rs @@ -8,7 +8,8 @@ use crate::Ruma; const LIMIT_MAX: usize = 100; pub(crate) async fn room_initial_sync_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let room_id = &body.room_id; diff --git a/src/api/client/room/upgrade.rs b/src/api/client/room/upgrade.rs index 401bf800a..cc6cca5e9 100644 --- a/src/api/client/room/upgrade.rs +++ b/src/api/client/room/upgrade.rs @@ -43,7 +43,8 @@ const TRANSFERABLE_STATE_EVENTS: &[StateEventType; 9] = &[ /// - Moves local aliases /// - Modifies old room power levels to prevent users from speaking pub(crate) async fn upgrade_room_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -72,13 +73,10 @@ pub(crate) async fn upgrade_room_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomTombstoneEventContent { - body: "This room has been replaced".to_owned(), - replacement_room: replacement_room.clone(), - }, - ), + PduBuilder::state(String::new(), &RoomTombstoneEventContent { + body: "This room has been replaced".to_owned(), + replacement_room: replacement_room.clone(), + }), sender_user, &body.room_id, &state_lock, @@ -108,7 +106,7 @@ pub(crate) async fn upgrade_room_route( { use RoomVersionId::*; match body.new_version { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { create_event_content.insert( "creator".into(), json!(&sender_user).try_into().map_err(|e| { @@ -117,7 +115,7 @@ pub(crate) async fn upgrade_room_route( })?, ); }, - _ => { + | _ => { // "creator" key no longer exists in V11+ rooms create_event_content.remove("creator"); }, @@ -154,7 +152,8 @@ pub(crate) async fn upgrade_room_route( .build_and_append_pdu( PduBuilder { event_type: TimelineEventType::RoomCreate, - content: to_raw_value(&create_event_content).expect("event is valid, we just created it"), + content: to_raw_value(&create_event_content) + .expect("event is valid, we just created it"), unsigned: None, state_key: Some(String::new()), redacts: None, @@ -203,8 +202,8 @@ pub(crate) async fn upgrade_room_route( .room_state_get(&body.room_id, event_type, "") .await { - Ok(v) => v.content.clone(), - Err(_) => continue, // Skipping missing events. + | Ok(v) => v.content.clone(), + | Err(_) => continue, // Skipping missing events. }; services @@ -258,7 +257,9 @@ pub(crate) async fn upgrade_room_route( power_levels_event_content .users_default .checked_add(int!(1)) - .ok_or_else(|| err!(Request(BadJson("users_default power levels event content is not valid"))))?, + .ok_or_else(|| { + err!(Request(BadJson("users_default power levels event content is not valid"))) + })?, ); // Modify the power levels in the old room to prevent sending of events and @@ -267,14 +268,11 @@ pub(crate) async fn upgrade_room_route( .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomPowerLevelsEventContent { - events_default: new_level, - invite: new_level, - ..power_levels_event_content - }, - ), + PduBuilder::state(String::new(), &RoomPowerLevelsEventContent { + events_default: new_level, + invite: new_level, + ..power_levels_event_content + }), sender_user, &body.room_id, &state_lock, @@ -284,7 +282,5 @@ pub(crate) async fn upgrade_room_route( drop(state_lock); // Return the replacement room id - Ok(upgrade_room::v3::Response { - replacement_room, - }) + Ok(upgrade_room::v3::Response { replacement_room }) } diff --git a/src/api/client/search.rs b/src/api/client/search.rs index 28a8891c8..e60bd26d9 100644 --- a/src/api/client/search.rs +++ b/src/api/client/search.rs @@ -35,7 +35,10 @@ const BATCH_MAX: usize = 20; /// /// - Only works if the user is currently joined to the room (TODO: Respect /// history visibility) -pub(crate) async fn search_events_route(State(services): State, body: Ruma) -> Result { +pub(crate) async fn search_events_route( + State(services): State, + body: Ruma, +) -> Result { let sender_user = body.sender_user(); let next_batch = body.next_batch.as_deref(); let room_events_result: OptionFuture<_> = body @@ -56,7 +59,10 @@ pub(crate) async fn search_events_route(State(services): State, bo #[allow(clippy::map_unwrap_or)] async fn category_room_events( - services: &Services, sender_user: &UserId, next_batch: Option<&str>, criteria: &Criteria, + services: &Services, + sender_user: &UserId, + next_batch: Option<&str>, + criteria: &Criteria, ) -> Result { let filter = &criteria.filter; @@ -186,11 +192,17 @@ async fn procure_room_state(services: &Services, room_id: &RoomId) -> Result Result { +async fn check_room_visible( + services: &Services, + user_id: &UserId, + room_id: &RoomId, + search: &Criteria, +) -> Result { let check_visible = search.filter.rooms.is_some(); let check_state = check_visible && search.include_state.is_some_and(is_true!()); - let is_joined = !check_visible || services.rooms.state_cache.is_joined(user_id, room_id).await; + let is_joined = + !check_visible || services.rooms.state_cache.is_joined(user_id, room_id).await; let state_visible = !check_state || services diff --git a/src/api/client/send.rs b/src/api/client/send.rs index e909ebbf8..9afa7e8c0 100644 --- a/src/api/client/send.rs +++ b/src/api/client/send.rs @@ -17,14 +17,17 @@ use crate::{service::pdu::PduBuilder, utils, Result, Ruma}; /// - Tries to send the event into the room, auth rules will determine if it is /// allowed pub(crate) async fn send_message_event_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user(); let sender_device = body.sender_device.as_deref(); let appservice_info = body.appservice_info.as_ref(); // Forbid m.room.encrypted if encryption is disabled - if MessageLikeEventType::RoomEncrypted == body.event_type && !services.globals.allow_encryption() { + if MessageLikeEventType::RoomEncrypted == body.event_type + && !services.globals.allow_encryption() + { return Err!(Request(Forbidden("Encryption has been disabled"))); } @@ -60,8 +63,8 @@ pub(crate) async fn send_message_event_route( let mut unsigned = BTreeMap::new(); unsigned.insert("transaction_id".to_owned(), body.txn_id.to_string().into()); - let content = - from_str(body.body.body.json().get()).map_err(|e| err!(Request(BadJson("Invalid JSON body: {e}"))))?; + let content = from_str(body.body.body.json().get()) + .map_err(|e| err!(Request(BadJson("Invalid JSON body: {e}"))))?; let event_id = services .rooms @@ -80,13 +83,14 @@ pub(crate) async fn send_message_event_route( ) .await?; - services - .transaction_ids - .add_txnid(sender_user, sender_device, &body.txn_id, event_id.as_bytes()); + services.transaction_ids.add_txnid( + sender_user, + sender_device, + &body.txn_id, + event_id.as_bytes(), + ); drop(state_lock); - Ok(send_message_event::v3::Response { - event_id: event_id.into(), - }) + Ok(send_message_event::v3::Response { event_id: event_id.into() }) } diff --git a/src/api/client/session.rs b/src/api/client/session.rs index e30c94d70..90cd4cb46 100644 --- a/src/api/client/session.rs +++ b/src/api/client/session.rs @@ -37,7 +37,8 @@ struct Claims { /// the `type` field when logging in. #[tracing::instrument(skip_all, fields(%client), name = "login")] pub(crate) async fn get_login_types_route( - InsecureClientIp(client): InsecureClientIp, _body: Ruma, + InsecureClientIp(client): InsecureClientIp, + _body: Ruma, ) -> Result { Ok(get_login_types::v3::Response::new(vec![ get_login_types::v3::LoginType::Password(PasswordLoginType::default()), @@ -61,13 +62,15 @@ pub(crate) async fn get_login_types_route( /// supported login types. #[tracing::instrument(skip_all, fields(%client), name = "login")] pub(crate) async fn login_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, body: Ruma, + State(services): State, + InsecureClientIp(client): InsecureClientIp, + body: Ruma, ) -> Result { // Validate login method // TODO: Other login methods let user_id = match &body.login_info { #[allow(deprecated)] - login::v3::LoginInfo::Password(login::v3::Password { + | login::v3::LoginInfo::Password(login::v3::Password { identifier, password, user, @@ -75,7 +78,10 @@ pub(crate) async fn login_route( }) => { debug!("Got password login type"); let user_id = if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { - UserId::parse_with_server_name(user_id.to_lowercase(), services.globals.server_name()) + UserId::parse_with_server_name( + user_id.to_lowercase(), + services.globals.server_name(), + ) } else if let Some(user) = user { UserId::parse(user) } else { @@ -100,22 +106,29 @@ pub(crate) async fn login_route( user_id }, - login::v3::LoginInfo::Token(login::v3::Token { - token, - }) => { + | login::v3::LoginInfo::Token(login::v3::Token { token }) => { debug!("Got token login type"); if let Some(jwt_decoding_key) = services.globals.jwt_decoding_key() { - let token = - jsonwebtoken::decode::(token, jwt_decoding_key, &jsonwebtoken::Validation::default()) - .map_err(|e| { - warn!("Failed to parse JWT token from user logging in: {e}"); - Error::BadRequest(ErrorKind::InvalidUsername, "Token is invalid.") - })?; + let token = jsonwebtoken::decode::( + token, + jwt_decoding_key, + &jsonwebtoken::Validation::default(), + ) + .map_err(|e| { + warn!("Failed to parse JWT token from user logging in: {e}"); + Error::BadRequest(ErrorKind::InvalidUsername, "Token is invalid.") + })?; let username = token.claims.sub.to_lowercase(); - UserId::parse_with_server_name(username, services.globals.server_name()) - .map_err(|e| err!(Request(InvalidUsername(debug_error!(?e, "Failed to parse login username")))))? + UserId::parse_with_server_name(username, services.globals.server_name()).map_err( + |e| { + err!(Request(InvalidUsername(debug_error!( + ?e, + "Failed to parse login username" + )))) + }, + )? } else { return Err!(Request(Unknown( "Token login is not supported (server has no jwt decoding key)." @@ -123,13 +136,16 @@ pub(crate) async fn login_route( } }, #[allow(deprecated)] - login::v3::LoginInfo::ApplicationService(login::v3::ApplicationService { + | login::v3::LoginInfo::ApplicationService(login::v3::ApplicationService { identifier, user, }) => { debug!("Got appservice login type"); let user_id = if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { - UserId::parse_with_server_name(user_id.to_lowercase(), services.globals.server_name()) + UserId::parse_with_server_name( + user_id.to_lowercase(), + services.globals.server_name(), + ) } else if let Some(user) = user { UserId::parse(user) } else { @@ -143,18 +159,27 @@ pub(crate) async fn login_route( if let Some(ref info) = body.appservice_info { if !info.is_user_match(&user_id) { - return Err(Error::BadRequest(ErrorKind::Exclusive, "User is not in namespace.")); + return Err(Error::BadRequest( + ErrorKind::Exclusive, + "User is not in namespace.", + )); } } else { - return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing appservice token.")); + return Err(Error::BadRequest( + ErrorKind::MissingToken, + "Missing appservice token.", + )); } user_id }, - _ => { + | _ => { warn!("Unsupported or unknown login type: {:?}", &body.login_info); debug!("JSON body: {:?}", &body.json_body); - return Err(Error::BadRequest(ErrorKind::Unknown, "Unsupported or unknown login type.")); + return Err(Error::BadRequest( + ErrorKind::Unknown, + "Unsupported or unknown login type.", + )); }, }; @@ -233,7 +258,9 @@ pub(crate) async fn login_route( /// - Triggers device list updates #[tracing::instrument(skip_all, fields(%client), name = "logout")] pub(crate) async fn logout_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, body: Ruma, + State(services): State, + InsecureClientIp(client): InsecureClientIp, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); @@ -261,7 +288,8 @@ pub(crate) async fn logout_route( /// user. #[tracing::instrument(skip_all, fields(%client), name = "logout")] pub(crate) async fn logout_all_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client/space.rs b/src/api/client/space.rs index a3031a3af..409c90836 100644 --- a/src/api/client/space.rs +++ b/src/api/client/space.rs @@ -13,7 +13,8 @@ use crate::{service::rooms::spaces::PaginationToken, Error, Result, Ruma}; /// Paginates over the space tree in a depth-first manner to locate child rooms /// of a given space. pub(crate) async fn get_hierarchy_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client/state.rs b/src/api/client/state.rs index 881eca982..6a65f0f95 100644 --- a/src/api/client/state.rs +++ b/src/api/client/state.rs @@ -31,7 +31,8 @@ use crate::{Ruma, RumaResponse}; /// allowed /// - If event is new `canonical_alias`: Rejects if alias is incorrect pub(crate) async fn send_state_event_for_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -63,7 +64,8 @@ pub(crate) async fn send_state_event_for_key_route( /// allowed /// - If event is new `canonical_alias`: Rejects if alias is incorrect pub(crate) async fn send_state_event_for_empty_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result> { send_state_event_for_key_route(State(services), body) .await @@ -77,7 +79,8 @@ pub(crate) async fn send_state_event_for_empty_key_route( /// - If not joined: Only works if current room history visibility is world /// readable pub(crate) async fn get_state_events_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -111,7 +114,8 @@ pub(crate) async fn get_state_events_route( /// - If not joined: Only works if current room history visibility is world /// readable pub(crate) async fn get_state_events_for_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -157,7 +161,8 @@ pub(crate) async fn get_state_events_for_key_route( /// - If not joined: Only works if current room history visibility is world /// readable pub(crate) async fn get_state_events_for_empty_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result> { get_state_events_for_key_route(State(services), body) .await @@ -165,8 +170,13 @@ pub(crate) async fn get_state_events_for_empty_key_route( } async fn send_state_event_for_key_helper( - services: &Services, sender: &UserId, room_id: &RoomId, event_type: &StateEventType, - json: &Raw, state_key: String, timestamp: Option, + services: &Services, + sender: &UserId, + room_id: &RoomId, + event_type: &StateEventType, + json: &Raw, + state_key: String, + timestamp: Option, ) -> Result> { allowed_to_send_state_event(services, room_id, event_type, json).await?; let state_lock = services.rooms.state.mutex.lock(room_id).await; @@ -191,20 +201,27 @@ async fn send_state_event_for_key_helper( } async fn allowed_to_send_state_event( - services: &Services, room_id: &RoomId, event_type: &StateEventType, json: &Raw, + services: &Services, + room_id: &RoomId, + event_type: &StateEventType, + json: &Raw, ) -> Result { match event_type { // Forbid m.room.encryption if encryption is disabled - StateEventType::RoomEncryption => { + | StateEventType::RoomEncryption => if !services.globals.allow_encryption() { - return Err(Error::BadRequest(ErrorKind::forbidden(), "Encryption has been disabled")); - } - }, + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "Encryption has been disabled", + )); + }, // admin room is a sensitive room, it should not ever be made public - StateEventType::RoomJoinRules => { + | StateEventType::RoomJoinRules => { if let Ok(admin_room_id) = services.admin.get_admin_room().await { if admin_room_id == room_id { - if let Ok(join_rule) = serde_json::from_str::(json.json().get()) { + if let Ok(join_rule) = + serde_json::from_str::(json.json().get()) + { if join_rule.join_rule == JoinRule::Public { return Err(Error::BadRequest( ErrorKind::forbidden(), @@ -216,16 +233,20 @@ async fn allowed_to_send_state_event( } }, // admin room is a sensitive room, it should not ever be made world readable - StateEventType::RoomHistoryVisibility => { + | StateEventType::RoomHistoryVisibility => { if let Ok(admin_room_id) = services.admin.get_admin_room().await { if admin_room_id == room_id { - if let Ok(visibility_content) = - serde_json::from_str::(json.json().get()) + if let Ok(visibility_content) = serde_json::from_str::< + RoomHistoryVisibilityEventContent, + >(json.json().get()) { - if visibility_content.history_visibility == HistoryVisibility::WorldReadable { + if visibility_content.history_visibility + == HistoryVisibility::WorldReadable + { return Err(Error::BadRequest( ErrorKind::forbidden(), - "Admin room is not allowed to be made world readable (public room history).", + "Admin room is not allowed to be made world readable (public \ + room history).", )); } } @@ -233,8 +254,10 @@ async fn allowed_to_send_state_event( } }, // TODO: allow alias if it previously existed - StateEventType::RoomCanonicalAlias => { - if let Ok(canonical_alias) = serde_json::from_str::(json.json().get()) { + | StateEventType::RoomCanonicalAlias => { + if let Ok(canonical_alias) = + serde_json::from_str::(json.json().get()) + { let mut aliases = canonical_alias.alt_aliases.clone(); if let Some(alias) = canonical_alias.alias { @@ -243,7 +266,9 @@ async fn allowed_to_send_state_event( for alias in aliases { if !services.globals.server_is_ours(alias.server_name()) { - return Err!(Request(Forbidden("canonical_alias must be for this server"))); + return Err!(Request(Forbidden( + "canonical_alias must be for this server" + ))); } if !services @@ -255,13 +280,14 @@ async fn allowed_to_send_state_event( // Make sure it's the right room { return Err!(Request(Forbidden( - "You are only allowed to send canonical_alias events when its aliases already exist" + "You are only allowed to send canonical_alias events when its \ + aliases already exist" ))); } } } }, - _ => (), + | _ => (), } Ok(()) diff --git a/src/api/client/sync/mod.rs b/src/api/client/sync/mod.rs index 2b8d478cb..b772fbf19 100644 --- a/src/api/client/sync/mod.rs +++ b/src/api/client/sync/mod.rs @@ -12,8 +12,12 @@ pub(crate) use self::{v3::sync_events_route, v4::sync_events_v4_route}; use crate::{service::Services, Error, PduEvent, Result}; async fn load_timeline( - services: &Services, sender_user: &UserId, room_id: &RoomId, roomsincecount: PduCount, - next_batch: Option, limit: usize, + services: &Services, + sender_user: &UserId, + room_id: &RoomId, + roomsincecount: PduCount, + next_batch: Option, + limit: usize, ) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> { let last_timeline_count = services .rooms @@ -51,7 +55,10 @@ async fn load_timeline( } async fn share_encrypted_room( - services: &Services, sender_user: &UserId, user_id: &UserId, ignore_room: Option<&RoomId>, + services: &Services, + sender_user: &UserId, + user_id: &UserId, + ignore_room: Option<&RoomId>, ) -> bool { services .rooms diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index c5ec38863..adf00860c 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -32,8 +32,9 @@ use ruma::{ sync::sync_events::{ self, v3::{ - Ephemeral, Filter, GlobalAccountData, InviteState, InvitedRoom, JoinedRoom, LeftRoom, Presence, - RoomAccountData, RoomSummary, Rooms, State as RoomState, Timeline, ToDevice, + Ephemeral, Filter, GlobalAccountData, InviteState, InvitedRoom, JoinedRoom, + LeftRoom, Presence, RoomAccountData, RoomSummary, Rooms, State as RoomState, + Timeline, ToDevice, }, DeviceLists, UnreadNotificationsCount, }, @@ -107,7 +108,8 @@ type PresenceUpdates = HashMap; ) )] pub(crate) async fn sync_events_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result> { let (sender_user, sender_device) = body.sender(); @@ -127,9 +129,9 @@ pub(crate) async fn sync_events_route( // Load filter let filter = match body.body.filter.as_ref() { - None => FilterDefinition::default(), - Some(Filter::FilterDefinition(ref filter)) => filter.clone(), - Some(Filter::FilterId(ref filter_id)) => services + | None => FilterDefinition::default(), + | Some(Filter::FilterDefinition(ref filter)) => filter.clone(), + | Some(Filter::FilterId(ref filter_id)) => services .users .get_filter(sender_user, filter_id) .await @@ -138,11 +140,11 @@ pub(crate) async fn sync_events_route( // some clients, at least element, seem to require knowledge of redundant // members for "inline" profiles on the timeline to work properly - let (lazy_load_enabled, lazy_load_send_redundant) = match filter.room.state.lazy_load_options { - LazyLoadOptions::Enabled { - include_redundant_members, - } => (true, include_redundant_members), - LazyLoadOptions::Disabled => (false, cfg!(feature = "element_hacks")), + let (lazy_load_enabled, lazy_load_send_redundant) = match filter.room.state.lazy_load_options + { + | LazyLoadOptions::Enabled { include_redundant_members } => + (true, include_redundant_members), + | LazyLoadOptions::Disabled => (false, cfg!(feature = "element_hacks")), }; let full_state = body.body.full_state; @@ -230,9 +232,7 @@ pub(crate) async fn sync_events_route( } let invited_room = InvitedRoom { - invite_state: InviteState { - events: invite_state, - }, + invite_state: InviteState { events: invite_state }, }; invited_rooms.insert(room_id, invited_room); @@ -268,9 +268,10 @@ pub(crate) async fn sync_events_route( .count_one_time_keys(sender_user, sender_device); // Remove all to-device events the device received *last time* - let remove_to_device_events = services - .users - .remove_to_device_events(sender_user, sender_device, since); + let remove_to_device_events = + services + .users + .remove_to_device_events(sender_user, sender_device, since); let rooms = join3(joined_rooms, left_rooms, invited_rooms); let ephemeral = join3(remove_to_device_events, to_device_events, presence_updates); @@ -290,7 +291,8 @@ pub(crate) async fn sync_events_route( .into_iter() .stream() .broad_filter_map(|user_id| async move { - let no_shared_encrypted_room = !share_encrypted_room(&services, sender_user, &user_id, None).await; + let no_shared_encrypted_room = + !share_encrypted_room(&services, sender_user, &user_id, None).await; no_shared_encrypted_room.then_some(user_id) }) .ready_fold(HashSet::new(), |mut device_list_left, user_id| { @@ -300,9 +302,7 @@ pub(crate) async fn sync_events_route( .await; let response = sync_events::v3::Response { - account_data: GlobalAccountData { - events: account_data, - }, + account_data: GlobalAccountData { events: account_data }, device_lists: DeviceLists { changed: device_list_updates.into_iter().collect(), left: device_list_left.into_iter().collect(), @@ -324,9 +324,7 @@ pub(crate) async fn sync_events_route( invite: invited_rooms, knock: BTreeMap::new(), // TODO }, - to_device: ToDevice { - events: to_device_events, - }, + to_device: ToDevice { events: to_device_events }, }; // TODO: Retry the endpoint instead of returning @@ -348,7 +346,11 @@ pub(crate) async fn sync_events_route( } #[tracing::instrument(name = "presence", level = "debug", skip_all)] -async fn process_presence_updates(services: &Services, since: u64, syncing_user: &UserId) -> PresenceUpdates { +async fn process_presence_updates( + services: &Services, + since: u64, + syncing_user: &UserId, +) -> PresenceUpdates { services .presence .presence_since(since) @@ -367,10 +369,10 @@ async fn process_presence_updates(services: &Services, since: u64, syncing_user: }) .ready_fold(PresenceUpdates::new(), |mut updates, (user_id, event)| { match updates.entry(user_id.into()) { - Entry::Vacant(slot) => { + | Entry::Vacant(slot) => { slot.insert(event); }, - Entry::Occupied(mut slot) => { + | Entry::Occupied(mut slot) => { let curr_event = slot.get_mut(); let curr_content = &mut curr_event.content; let new_content = event.content; @@ -380,7 +382,8 @@ async fn process_presence_updates(services: &Services, since: u64, syncing_user: curr_content.status_msg = new_content .status_msg .or_else(|| curr_content.status_msg.take()); - curr_content.last_active_ago = new_content.last_active_ago.or(curr_content.last_active_ago); + curr_content.last_active_ago = + new_content.last_active_ago.or(curr_content.last_active_ago); curr_content.displayname = new_content .displayname .or_else(|| curr_content.displayname.take()); @@ -410,8 +413,13 @@ async fn process_presence_updates(services: &Services, since: u64, syncing_user: )] #[allow(clippy::too_many_arguments)] async fn handle_left_room( - services: &Services, since: u64, ref room_id: OwnedRoomId, sender_user: &UserId, next_batch_string: &str, - full_state: bool, lazy_load_enabled: bool, + services: &Services, + since: u64, + ref room_id: OwnedRoomId, + sender_user: &UserId, + next_batch_string: &str, + full_state: bool, + lazy_load_enabled: bool, ) -> Result> { // Get and drop the lock to wait for remaining operations to finish let insert_lock = services.rooms.timeline.mutex_insert.lock(room_id).await; @@ -440,7 +448,8 @@ async fn handle_left_room( .try_into() .expect("Timestamp is valid js_int value"), kind: RoomMember, - content: serde_json::from_str(r#"{"membership":"leave"}"#).expect("this is valid JSON"), + content: serde_json::from_str(r#"{"membership":"leave"}"#) + .expect("this is valid JSON"), state_key: Some(sender_user.to_string()), unsigned: None, // The following keys are dropped on conversion @@ -449,16 +458,12 @@ async fn handle_left_room( depth: uint!(1), auth_events: vec![], redacts: None, - hashes: EventHash { - sha256: String::new(), - }, + hashes: EventHash { sha256: String::new() }, signatures: None, }; return Ok(Some(LeftRoom { - account_data: RoomAccountData { - events: Vec::new(), - }, + account_data: RoomAccountData { events: Vec::new() }, timeline: Timeline { limited: false, prev_batch: Some(next_batch_string.to_owned()), @@ -479,8 +484,8 @@ async fn handle_left_room( .await; let since_state_ids = match since_shortstatehash { - Ok(s) => services.rooms.state_accessor.state_full_ids(s).await?, - Err(_) => HashMap::new(), + | Ok(s) => services.rooms.state_accessor.state_full_ids(s).await?, + | Err(_) => HashMap::new(), }; let Ok(left_event_id): Result = services @@ -542,17 +547,14 @@ async fn handle_left_room( } Ok(Some(LeftRoom { - account_data: RoomAccountData { - events: Vec::new(), - }, + account_data: RoomAccountData { events: Vec::new() }, timeline: Timeline { - limited: true, // TODO: support left timeline events so we dont need to set this to true + limited: true, /* TODO: support left timeline events so we dont need to set this to + * true */ prev_batch: Some(next_batch_string.to_owned()), events: Vec::new(), // and so we dont need to set this to empty vec }, - state: RoomState { - events: left_state_events, - }, + state: RoomState { events: left_state_events }, })) } @@ -566,8 +568,15 @@ async fn handle_left_room( )] #[allow(clippy::too_many_arguments)] async fn load_joined_room( - services: &Services, sender_user: &UserId, sender_device: &DeviceId, ref room_id: OwnedRoomId, since: u64, - next_batch: u64, lazy_load_enabled: bool, lazy_load_send_redundant: bool, full_state: bool, + services: &Services, + sender_user: &UserId, + sender_device: &DeviceId, + ref room_id: OwnedRoomId, + since: u64, + next_batch: u64, + lazy_load_enabled: bool, + lazy_load_send_redundant: bool, + full_state: bool, ) -> Result<(JoinedRoom, HashSet, HashSet)> { // Get and drop the lock to wait for remaining operations to finish // This will make sure the we have all events until next_batch @@ -590,18 +599,26 @@ async fn load_joined_room( .ok() .map(Ok); - let timeline = load_timeline(services, sender_user, room_id, sincecount, Some(next_batchcount), 10_usize); + let timeline = load_timeline( + services, + sender_user, + room_id, + sincecount, + Some(next_batchcount), + 10_usize, + ); let (current_shortstatehash, since_shortstatehash, timeline) = try_join3(current_shortstatehash, since_shortstatehash, timeline).await?; let (timeline_pdus, limited) = timeline; - let timeline_users = timeline_pdus - .iter() - .fold(HashSet::new(), |mut timeline_users, (_, event)| { - timeline_users.insert(event.sender.as_str().to_owned()); - timeline_users - }); + let timeline_users = + timeline_pdus + .iter() + .fold(HashSet::new(), |mut timeline_users, (_, event)| { + timeline_users.insert(event.sender.as_str().to_owned()); + timeline_users + }); let last_notification_read: OptionFuture<_> = timeline_pdus .is_empty() @@ -617,13 +634,16 @@ async fn load_joined_room( .is_none_or(|&count| count > since) .await; - services - .rooms - .lazy_loading - .lazy_load_confirm_delivery(sender_user, sender_device, room_id, sincecount); + services.rooms.lazy_loading.lazy_load_confirm_delivery( + sender_user, + sender_device, + room_id, + sincecount, + ); let no_state_changes = timeline_pdus.is_empty() - && (since_shortstatehash.is_none() || since_shortstatehash.is_some_and(is_equal_to!(current_shortstatehash))); + && (since_shortstatehash.is_none() + || since_shortstatehash.is_some_and(is_equal_to!(current_shortstatehash))); let mut device_list_updates = HashSet::::new(); let mut left_encrypted_users = HashSet::::new(); @@ -732,9 +752,10 @@ async fn load_joined_room( let events = join4(room_events, account_data_events, receipt_events, typing_events); let unread_notifications = join(notification_count, highlight_count); - let (unread_notifications, events, device_updates) = join3(unread_notifications, events, device_updates) - .boxed() - .await; + let (unread_notifications, events, device_updates) = + join3(unread_notifications, events, device_updates) + .boxed() + .await; let (room_events, account_data_events, receipt_events, typing_events) = events; let (notification_count, highlight_count) = unread_notifications; @@ -773,9 +794,7 @@ async fn load_joined_room( .await; let joined_room = JoinedRoom { - account_data: RoomAccountData { - events: account_data_events, - }, + account_data: RoomAccountData { events: account_data_events }, summary: RoomSummary { joined_member_count: joined_member_count.map(ruma_from_u64), invited_member_count: invited_member_count.map(ruma_from_u64), @@ -786,10 +805,7 @@ async fn load_joined_room( .filter_map(Result::ok) .collect(), }, - unread_notifications: UnreadNotificationsCount { - highlight_count, - notification_count, - }, + unread_notifications: UnreadNotificationsCount { highlight_count, notification_count }, timeline: Timeline { limited: limited || joined_since_last_sync, events: room_events, @@ -805,9 +821,7 @@ async fn load_joined_room( .map(PduEvent::to_sync_state_event) .collect(), }, - ephemeral: Ephemeral { - events: edus, - }, + ephemeral: Ephemeral { events: edus }, unread_thread_notifications: BTreeMap::new(), }; @@ -827,11 +841,20 @@ async fn load_joined_room( )] #[allow(clippy::too_many_arguments)] async fn calculate_state_changes( - services: &Services, sender_user: &UserId, sender_device: &DeviceId, room_id: &RoomId, next_batchcount: PduCount, - lazy_load_enabled: bool, lazy_load_send_redundant: bool, full_state: bool, - device_list_updates: &mut HashSet, left_encrypted_users: &mut HashSet, - since_shortstatehash: Option, current_shortstatehash: ShortStateHash, - timeline_pdus: &Vec<(PduCount, PduEvent)>, timeline_users: &HashSet, + services: &Services, + sender_user: &UserId, + sender_device: &DeviceId, + room_id: &RoomId, + next_batchcount: PduCount, + lazy_load_enabled: bool, + lazy_load_send_redundant: bool, + full_state: bool, + device_list_updates: &mut HashSet, + left_encrypted_users: &mut HashSet, + since_shortstatehash: Option, + current_shortstatehash: ShortStateHash, + timeline_pdus: &Vec<(PduCount, PduEvent)>, + timeline_users: &HashSet, ) -> Result { let since_sender_member: OptionFuture<_> = since_shortstatehash .map(|short| { @@ -886,8 +909,14 @@ async fn calculate_state_changes( #[tracing::instrument(name = "initial", level = "trace", skip_all)] #[allow(clippy::too_many_arguments)] async fn calculate_state_initial( - services: &Services, sender_user: &UserId, sender_device: &DeviceId, room_id: &RoomId, next_batchcount: PduCount, - lazy_load_enabled: bool, full_state: bool, current_shortstatehash: ShortStateHash, + services: &Services, + sender_user: &UserId, + sender_device: &DeviceId, + room_id: &RoomId, + next_batchcount: PduCount, + lazy_load_enabled: bool, + full_state: bool, + current_shortstatehash: ShortStateHash, timeline_users: &HashSet, ) -> Result { // Probably since = 0, we will do an initial sync @@ -956,10 +985,13 @@ async fn calculate_state_initial( // The state_events above should contain all timeline_users, let's mark them as // lazy loaded. - services - .rooms - .lazy_loading - .lazy_load_mark_sent(sender_user, sender_device, room_id, lazy_loaded, next_batchcount); + services.rooms.lazy_loading.lazy_load_mark_sent( + sender_user, + sender_device, + room_id, + lazy_loaded, + next_batchcount, + ); Ok(StateChanges { heroes, @@ -973,13 +1005,23 @@ async fn calculate_state_initial( #[tracing::instrument(name = "incremental", level = "trace", skip_all)] #[allow(clippy::too_many_arguments)] async fn calculate_state_incremental( - services: &Services, sender_user: &UserId, sender_device: &DeviceId, room_id: &RoomId, next_batchcount: PduCount, - lazy_load_send_redundant: bool, full_state: bool, device_list_updates: &mut HashSet, - left_encrypted_users: &mut HashSet, since_shortstatehash: Option, - current_shortstatehash: ShortStateHash, timeline_pdus: &Vec<(PduCount, PduEvent)>, joined_since_last_sync: bool, + services: &Services, + sender_user: &UserId, + sender_device: &DeviceId, + room_id: &RoomId, + next_batchcount: PduCount, + lazy_load_send_redundant: bool, + full_state: bool, + device_list_updates: &mut HashSet, + left_encrypted_users: &mut HashSet, + since_shortstatehash: Option, + current_shortstatehash: ShortStateHash, + timeline_pdus: &Vec<(PduCount, PduEvent)>, + joined_since_last_sync: bool, ) -> Result { // Incremental /sync - let since_shortstatehash = since_shortstatehash.expect("missing since_shortstatehash on incremental sync"); + let since_shortstatehash = + since_shortstatehash.expect("missing since_shortstatehash on incremental sync"); let mut delta_state_events = Vec::new(); @@ -994,8 +1036,10 @@ async fn calculate_state_incremental( .state_accessor .state_full_ids(since_shortstatehash); - let (current_state_ids, since_state_ids): (HashMap<_, OwnedEventId>, HashMap<_, OwnedEventId>) = - try_join(current_state_ids, since_state_ids).await?; + let (current_state_ids, since_state_ids): ( + HashMap<_, OwnedEventId>, + HashMap<_, OwnedEventId>, + ) = try_join(current_state_ids, since_state_ids).await?; current_state_ids .iter() @@ -1044,17 +1088,19 @@ async fn calculate_state_incremental( let content: RoomMemberEventContent = state_event.get_content()?; match content.membership { - MembershipState::Join => { + | MembershipState::Join => { // A new user joined an encrypted room - if !share_encrypted_room(services, sender_user, &user_id, Some(room_id)).await { + if !share_encrypted_room(services, sender_user, &user_id, Some(room_id)) + .await + { device_list_updates.insert(user_id); } }, - MembershipState::Leave => { + | MembershipState::Leave => { // Write down users that have left encrypted rooms we are in left_encrypted_users.insert(user_id); }, - _ => {}, + | _ => {}, } } } @@ -1139,10 +1185,13 @@ async fn calculate_state_incremental( state_events.push(member_event); } - services - .rooms - .lazy_loading - .lazy_load_mark_sent(sender_user, sender_device, room_id, lazy_loaded, next_batchcount); + services.rooms.lazy_loading.lazy_load_mark_sent( + sender_user, + sender_device, + room_id, + lazy_loaded, + next_batchcount, + ); Ok(StateChanges { heroes, @@ -1154,7 +1203,9 @@ async fn calculate_state_incremental( } async fn calculate_counts( - services: &Services, room_id: &RoomId, sender_user: &UserId, + services: &Services, + room_id: &RoomId, + sender_user: &UserId, ) -> Result<(Option, Option, Option>)> { let joined_member_count = services .rooms @@ -1168,7 +1219,8 @@ async fn calculate_counts( .room_invited_count(room_id) .unwrap_or(0); - let (joined_member_count, invited_member_count) = join(joined_member_count, invited_member_count).await; + let (joined_member_count, invited_member_count) = + join(joined_member_count, invited_member_count).await; let small_room = joined_member_count.saturating_add(invited_member_count) > 5; @@ -1179,20 +1231,32 @@ async fn calculate_counts( Ok((Some(joined_member_count), Some(invited_member_count), heroes.await)) } -async fn calculate_heroes(services: &Services, room_id: &RoomId, sender_user: &UserId) -> Vec { +async fn calculate_heroes( + services: &Services, + room_id: &RoomId, + sender_user: &UserId, +) -> Vec { services .rooms .timeline .all_pdus(sender_user, room_id) .ready_filter(|(_, pdu)| pdu.kind == RoomMember) - .fold_default(|heroes: Vec<_>, (_, pdu)| fold_hero(heroes, services, room_id, sender_user, pdu)) + .fold_default(|heroes: Vec<_>, (_, pdu)| { + fold_hero(heroes, services, room_id, sender_user, pdu) + }) .await } async fn fold_hero( - mut heroes: Vec, services: &Services, room_id: &RoomId, sender_user: &UserId, pdu: PduEvent, + mut heroes: Vec, + services: &Services, + room_id: &RoomId, + sender_user: &UserId, + pdu: PduEvent, ) -> Vec { - let Some(user_id): Option<&UserId> = pdu.state_key.as_deref().map(TryInto::try_into).flat_ok() else { + let Some(user_id): Option<&UserId> = + pdu.state_key.as_deref().map(TryInto::try_into).flat_ok() + else { return heroes; }; diff --git a/src/api/client/sync/v4.rs b/src/api/client/sync/v4.rs index 140b647d8..f463acf28 100644 --- a/src/api/client/sync/v4.rs +++ b/src/api/client/sync/v4.rs @@ -46,7 +46,8 @@ const DEFAULT_BUMP_TYPES: &[TimelineEventType; 6] = /// /// Sliding Sync endpoint (future endpoint: `/_matrix/client/v4/sync`) pub(crate) async fn sync_events_v4_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.expect("user is authenticated"); @@ -81,16 +82,19 @@ pub(crate) async fn sync_events_v4_route( } if globalsince == 0 { - services - .sync - .forget_sync_request_connection(sender_user.clone(), sender_device.clone(), conn_id.clone()); + services.sync.forget_sync_request_connection( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + ); } // Get sticky parameters from cache - let known_rooms = - services - .sync - .update_sync_request_with_cache(sender_user.clone(), sender_device.clone(), &mut body); + let known_rooms = services.sync.update_sync_request_with_cache( + sender_user.clone(), + sender_device.clone(), + &mut body, + ); let all_joined_rooms: Vec<_> = services .rooms @@ -125,9 +129,7 @@ pub(crate) async fn sync_events_v4_route( let mut device_list_changes = HashSet::new(); let mut device_list_left = HashSet::new(); - let mut receipts = sync_events::v4::Receipts { - rooms: BTreeMap::new(), - }; + let mut receipts = sync_events::v4::Receipts { rooms: BTreeMap::new() }; let mut account_data = sync_events::v4::AccountData { global: Vec::new(), @@ -168,7 +170,9 @@ pub(crate) async fn sync_events_v4_route( ); for room_id in &all_joined_rooms { - let Ok(current_shortstatehash) = services.rooms.state.get_room_shortstatehash(room_id).await else { + let Ok(current_shortstatehash) = + services.rooms.state.get_room_shortstatehash(room_id).await + else { error!("Room {room_id} has no state"); continue; }; @@ -202,12 +206,16 @@ pub(crate) async fn sync_events_v4_route( let since_sender_member: Option = services .rooms .state_accessor - .state_get_content(since_shortstatehash, &StateEventType::RoomMember, sender_user.as_str()) + .state_get_content( + since_shortstatehash, + &StateEventType::RoomMember, + sender_user.as_str(), + ) .ok() .await; - let joined_since_last_sync = - since_sender_member.map_or(true, |member| member.membership != MembershipState::Join); + let joined_since_last_sync = since_sender_member + .map_or(true, |member| member.membership != MembershipState::Join); let new_encrypted_room = encrypted_room && since_encryption.is_err(); @@ -232,8 +240,10 @@ pub(crate) async fn sync_events_v4_route( }; if pdu.kind == RoomMember { if let Some(state_key) = &pdu.state_key { - let user_id = UserId::parse(state_key.clone()) - .map_err(|_| Error::bad_database("Invalid UserId in member PDU."))?; + let user_id = + UserId::parse(state_key.clone()).map_err(|_| { + Error::bad_database("Invalid UserId in member PDU.") + })?; if user_id == *sender_user { continue; @@ -241,19 +251,25 @@ pub(crate) async fn sync_events_v4_route( let content: RoomMemberEventContent = pdu.get_content()?; match content.membership { - MembershipState::Join => { + | MembershipState::Join => { // A new user joined an encrypted room - if !share_encrypted_room(&services, sender_user, &user_id, Some(room_id)) - .await + if !share_encrypted_room( + &services, + sender_user, + &user_id, + Some(room_id), + ) + .await { device_list_changes.insert(user_id); } }, - MembershipState::Leave => { - // Write down users that have left encrypted rooms we are in + | MembershipState::Leave => { + // Write down users that have left encrypted rooms we + // are in left_encrypted_users.insert(user_id); }, - _ => {}, + | _ => {}, } } } @@ -293,7 +309,8 @@ pub(crate) async fn sync_events_v4_route( } for user_id in left_encrypted_users { - let dont_share_encrypted_room = !share_encrypted_room(&services, sender_user, &user_id, None).await; + let dont_share_encrypted_room = + !share_encrypted_room(&services, sender_user, &user_id, None).await; // If the user doesn't share an encrypted room with the target anymore, we need // to tell them @@ -308,85 +325,85 @@ pub(crate) async fn sync_events_v4_route( for (list_id, list) in &body.lists { let active_rooms = match list.filters.clone().and_then(|f| f.is_invite) { - Some(true) => &all_invited_rooms, - Some(false) => &all_joined_rooms, - None => &all_rooms, + | Some(true) => &all_invited_rooms, + | Some(false) => &all_joined_rooms, + | None => &all_rooms, }; let active_rooms = match list.filters.clone().map(|f| f.not_room_types) { - Some(filter) if filter.is_empty() => active_rooms.clone(), - Some(value) => filter_rooms(&services, active_rooms, &value, true).await, - None => active_rooms.clone(), + | Some(filter) if filter.is_empty() => active_rooms.clone(), + | Some(value) => filter_rooms(&services, active_rooms, &value, true).await, + | None => active_rooms.clone(), }; let active_rooms = match list.filters.clone().map(|f| f.room_types) { - Some(filter) if filter.is_empty() => active_rooms.clone(), - Some(value) => filter_rooms(&services, &active_rooms, &value, false).await, - None => active_rooms, + | Some(filter) if filter.is_empty() => active_rooms.clone(), + | Some(value) => filter_rooms(&services, &active_rooms, &value, false).await, + | None => active_rooms, }; let mut new_known_rooms = BTreeSet::new(); let ranges = list.ranges.clone(); - lists.insert( - list_id.clone(), - sync_events::v4::SyncList { - ops: ranges - .into_iter() - .map(|mut r| { - r.0 = r.0.clamp( - uint!(0), - UInt::try_from(active_rooms.len().saturating_sub(1)).unwrap_or(UInt::MAX), + lists.insert(list_id.clone(), sync_events::v4::SyncList { + ops: ranges + .into_iter() + .map(|mut r| { + r.0 = r.0.clamp( + uint!(0), + UInt::try_from(active_rooms.len().saturating_sub(1)).unwrap_or(UInt::MAX), + ); + r.1 = r.1.clamp( + r.0, + UInt::try_from(active_rooms.len().saturating_sub(1)).unwrap_or(UInt::MAX), + ); + + let room_ids = if !active_rooms.is_empty() { + active_rooms[usize_from_ruma(r.0)..=usize_from_ruma(r.1)].to_vec() + } else { + Vec::new() + }; + + new_known_rooms.extend(room_ids.iter().cloned()); + for room_id in &room_ids { + let todo_room = todo_rooms.entry(room_id.clone()).or_insert(( + BTreeSet::new(), + 0_usize, + u64::MAX, + )); + + let limit: usize = list + .room_details + .timeline_limit + .map(u64::from) + .map_or(10, usize_from_u64_truncated) + .min(100); + + todo_room + .0 + .extend(list.room_details.required_state.iter().cloned()); + + todo_room.1 = todo_room.1.max(limit); + // 0 means unknown because it got out of date + todo_room.2 = todo_room.2.min( + known_rooms + .get(list_id.as_str()) + .and_then(|k| k.get(room_id)) + .copied() + .unwrap_or(0), ); - r.1 = - r.1.clamp(r.0, UInt::try_from(active_rooms.len().saturating_sub(1)).unwrap_or(UInt::MAX)); - - let room_ids = if !active_rooms.is_empty() { - active_rooms[usize_from_ruma(r.0)..=usize_from_ruma(r.1)].to_vec() - } else { - Vec::new() - }; - - new_known_rooms.extend(room_ids.iter().cloned()); - for room_id in &room_ids { - let todo_room = - todo_rooms - .entry(room_id.clone()) - .or_insert((BTreeSet::new(), 0_usize, u64::MAX)); - - let limit: usize = list - .room_details - .timeline_limit - .map(u64::from) - .map_or(10, usize_from_u64_truncated) - .min(100); - - todo_room - .0 - .extend(list.room_details.required_state.iter().cloned()); - - todo_room.1 = todo_room.1.max(limit); - // 0 means unknown because it got out of date - todo_room.2 = todo_room.2.min( - known_rooms - .get(list_id.as_str()) - .and_then(|k| k.get(room_id)) - .copied() - .unwrap_or(0), - ); - } - sync_events::v4::SyncOp { - op: SlidingOp::Sync, - range: Some(r), - index: None, - room_ids, - room_id: None, - } - }) - .collect(), - count: ruma_from_usize(active_rooms.len()), - }, - ); + } + sync_events::v4::SyncOp { + op: SlidingOp::Sync, + range: Some(r), + index: None, + room_ids, + room_id: None, + } + }) + .collect(), + count: ruma_from_usize(active_rooms.len()), + }); if let Some(conn_id) = &body.conn_id { services.sync.update_sync_known_rooms( @@ -405,9 +422,10 @@ pub(crate) async fn sync_events_v4_route( if !services.rooms.metadata.exists(room_id).await { continue; } - let todo_room = todo_rooms - .entry(room_id.clone()) - .or_insert((BTreeSet::new(), 0_usize, u64::MAX)); + let todo_room = + todo_rooms + .entry(room_id.clone()) + .or_insert((BTreeSet::new(), 0_usize, u64::MAX)); let limit: usize = room .timeline_limit @@ -471,14 +489,22 @@ pub(crate) async fn sync_events_v4_route( (timeline_pdus, limited) = (Vec::new(), true); } else { - (timeline_pdus, limited) = - match load_timeline(&services, sender_user, room_id, roomsincecount, None, *timeline_limit).await { - Ok(value) => value, - Err(err) => { - warn!("Encountered missing timeline in {}, error {}", room_id, err); - continue; - }, - }; + (timeline_pdus, limited) = match load_timeline( + &services, + sender_user, + room_id, + roomsincecount, + None, + *timeline_limit, + ) + .await + { + | Ok(value) => value, + | Err(err) => { + warn!("Encountered missing timeline in {}, error {}", room_id, err); + continue; + }, + }; } account_data.rooms.insert( @@ -543,11 +569,11 @@ pub(crate) async fn sync_events_v4_route( .first() .map_or(Ok::<_, Error>(None), |(pdu_count, _)| { Ok(Some(match pdu_count { - PduCount::Backfilled(_) => { + | PduCount::Backfilled(_) => { error!("timeline in backfill state?!"); "0".to_owned() }, - PduCount::Normal(c) => c.to_string(), + | PduCount::Normal(c) => c.to_string(), })) })? .or_else(|| { @@ -568,7 +594,9 @@ pub(crate) async fn sync_events_v4_route( for (_, pdu) in timeline_pdus { let ts = MilliSecondsSinceUnixEpoch(pdu.origin_server_ts); - if DEFAULT_BUMP_TYPES.contains(pdu.event_type()) && timestamp.is_none_or(|time| time <= ts) { + if DEFAULT_BUMP_TYPES.contains(pdu.event_type()) + && timestamp.is_none_or(|time| time <= ts) + { timestamp = Some(ts); } } @@ -611,7 +639,7 @@ pub(crate) async fn sync_events_v4_route( .await; let name = match heroes.len().cmp(&(1_usize)) { - Ordering::Greater => { + | Ordering::Greater => { let firsts = heroes[1..] .iter() .map(|h| h.name.clone().unwrap_or_else(|| h.user_id.to_string())) @@ -625,13 +653,13 @@ pub(crate) async fn sync_events_v4_route( Some(format!("{firsts} and {last}")) }, - Ordering::Equal => Some( + | Ordering::Equal => Some( heroes[0] .name .clone() .unwrap_or_else(|| heroes[0].user_id.to_string()), ), - Ordering::Less => None, + | Ordering::Less => None, }; let heroes_avatar = if heroes.len() == 1 { @@ -640,77 +668,74 @@ pub(crate) async fn sync_events_v4_route( None }; - rooms.insert( - room_id.clone(), - sync_events::v4::SlidingSyncRoom { - name: services - .rooms - .state_accessor - .get_name(room_id) - .await - .ok() - .or(name), - avatar: if let Some(heroes_avatar) = heroes_avatar { - ruma::JsOption::Some(heroes_avatar) - } else { - match services.rooms.state_accessor.get_avatar(room_id).await { - ruma::JsOption::Some(avatar) => ruma::JsOption::from_option(avatar.url), - ruma::JsOption::Null => ruma::JsOption::Null, - ruma::JsOption::Undefined => ruma::JsOption::Undefined, - } - }, - initial: Some(roomsince == &0), - is_dm: None, - invite_state, - unread_notifications: UnreadNotificationsCount { - highlight_count: Some( - services - .rooms - .user - .highlight_count(sender_user, room_id) - .await - .try_into() - .expect("notification count can't go that high"), - ), - notification_count: Some( - services - .rooms - .user - .notification_count(sender_user, room_id) - .await - .try_into() - .expect("notification count can't go that high"), - ), - }, - timeline: room_events, - required_state, - prev_batch, - limited, - joined_count: Some( + rooms.insert(room_id.clone(), sync_events::v4::SlidingSyncRoom { + name: services + .rooms + .state_accessor + .get_name(room_id) + .await + .ok() + .or(name), + avatar: if let Some(heroes_avatar) = heroes_avatar { + ruma::JsOption::Some(heroes_avatar) + } else { + match services.rooms.state_accessor.get_avatar(room_id).await { + | ruma::JsOption::Some(avatar) => ruma::JsOption::from_option(avatar.url), + | ruma::JsOption::Null => ruma::JsOption::Null, + | ruma::JsOption::Undefined => ruma::JsOption::Undefined, + } + }, + initial: Some(roomsince == &0), + is_dm: None, + invite_state, + unread_notifications: UnreadNotificationsCount { + highlight_count: Some( services .rooms - .state_cache - .room_joined_count(room_id) + .user + .highlight_count(sender_user, room_id) .await - .unwrap_or(0) .try_into() - .unwrap_or_else(|_| uint!(0)), + .expect("notification count can't go that high"), ), - invited_count: Some( + notification_count: Some( services .rooms - .state_cache - .room_invited_count(room_id) + .user + .notification_count(sender_user, room_id) .await - .unwrap_or(0) .try_into() - .unwrap_or_else(|_| uint!(0)), + .expect("notification count can't go that high"), ), - num_live: None, // Count events in timeline greater than global sync counter - timestamp, - heroes: Some(heroes), }, - ); + timeline: room_events, + required_state, + prev_batch, + limited, + joined_count: Some( + services + .rooms + .state_cache + .room_joined_count(room_id) + .await + .unwrap_or(0) + .try_into() + .unwrap_or_else(|_| uint!(0)), + ), + invited_count: Some( + services + .rooms + .state_cache + .room_invited_count(room_id) + .await + .unwrap_or(0) + .try_into() + .unwrap_or_else(|_| uint!(0)), + ), + num_live: None, // Count events in timeline greater than global sync counter + timestamp, + heroes: Some(heroes), + }); } if rooms @@ -757,16 +782,17 @@ pub(crate) async fn sync_events_v4_route( }, account_data, receipts, - typing: sync_events::v4::Typing { - rooms: BTreeMap::new(), - }, + typing: sync_events::v4::Typing { rooms: BTreeMap::new() }, }, delta_token: None, }) } async fn filter_rooms( - services: &Services, rooms: &[OwnedRoomId], filter: &[RoomTypeFilter], negate: bool, + services: &Services, + rooms: &[OwnedRoomId], + filter: &[RoomTypeFilter], + negate: bool, ) -> Vec { rooms .iter() diff --git a/src/api/client/tag.rs b/src/api/client/tag.rs index b5fa19e3a..820ee4a18 100644 --- a/src/api/client/tag.rs +++ b/src/api/client/tag.rs @@ -17,7 +17,8 @@ use crate::{Result, Ruma}; /// /// - Inserts the tag into the tag event of the room account data. pub(crate) async fn update_tag_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -26,9 +27,7 @@ pub(crate) async fn update_tag_route( .get_room(&body.room_id, sender_user, RoomAccountDataEventType::Tag) .await .unwrap_or(TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); tags_event @@ -55,7 +54,8 @@ pub(crate) async fn update_tag_route( /// /// - Removes the tag from the tag event of the room account data. pub(crate) async fn delete_tag_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -64,9 +64,7 @@ pub(crate) async fn delete_tag_route( .get_room(&body.room_id, sender_user, RoomAccountDataEventType::Tag) .await .unwrap_or(TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); tags_event.content.tags.remove(&body.tag.clone().into()); @@ -90,7 +88,8 @@ pub(crate) async fn delete_tag_route( /// /// - Gets the tag event of the room account data. pub(crate) async fn get_tags_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -99,12 +98,8 @@ pub(crate) async fn get_tags_route( .get_room(&body.room_id, sender_user, RoomAccountDataEventType::Tag) .await .unwrap_or(TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); - Ok(get_tags::v3::Response { - tags: tags_event.content.tags, - }) + Ok(get_tags::v3::Response { tags: tags_event.content.tags }) } diff --git a/src/api/client/thirdparty.rs b/src/api/client/thirdparty.rs index f6af8729c..790b27d32 100644 --- a/src/api/client/thirdparty.rs +++ b/src/api/client/thirdparty.rs @@ -11,9 +11,7 @@ pub(crate) async fn get_protocols_route( _body: Ruma, ) -> Result { // TODO - Ok(get_protocols::v3::Response { - protocols: BTreeMap::new(), - }) + Ok(get_protocols::v3::Response { protocols: BTreeMap::new() }) } /// # `GET /_matrix/client/unstable/thirdparty/protocols` diff --git a/src/api/client/threads.rs b/src/api/client/threads.rs index 07badaf78..f0cbf467a 100644 --- a/src/api/client/threads.rs +++ b/src/api/client/threads.rs @@ -7,7 +7,8 @@ use crate::{Result, Ruma}; /// # `GET /_matrix/client/r0/rooms/{roomId}/threads` pub(crate) async fn get_threads_route( - State(services): State, ref body: Ruma, + State(services): State, + ref body: Ruma, ) -> Result { // Use limit or else 10, with maximum 100 let limit = body diff --git a/src/api/client/to_device.rs b/src/api/client/to_device.rs index aab59394a..2ded04e7a 100644 --- a/src/api/client/to_device.rs +++ b/src/api/client/to_device.rs @@ -17,7 +17,8 @@ use crate::Ruma; /// /// Send a to-device event to a set of client devices. pub(crate) async fn send_event_to_device_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_deref(); @@ -43,12 +44,14 @@ pub(crate) async fn send_event_to_device_route( services.sending.send_edu_server( target_user_id.server_name(), - serde_json::to_vec(&federation::transactions::edu::Edu::DirectToDevice(DirectDeviceContent { - sender: sender_user.clone(), - ev_type: body.event_type.clone(), - message_id: count.to_string().into(), - messages, - })) + serde_json::to_vec(&federation::transactions::edu::Edu::DirectToDevice( + DirectDeviceContent { + sender: sender_user.clone(), + ev_type: body.event_type.clone(), + message_id: count.to_string().into(), + messages, + }, + )) .expect("DirectToDevice EDU can be serialized"), )?; @@ -62,14 +65,20 @@ pub(crate) async fn send_event_to_device_route( .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid"))?; match target_device_id_maybe { - DeviceIdOrAllDevices::DeviceId(target_device_id) => { + | DeviceIdOrAllDevices::DeviceId(target_device_id) => { services .users - .add_to_device_event(sender_user, target_user_id, target_device_id, event_type, event) + .add_to_device_event( + sender_user, + target_user_id, + target_device_id, + event_type, + event, + ) .await; }, - DeviceIdOrAllDevices::AllDevices => { + | DeviceIdOrAllDevices::AllDevices => { let (event_type, event) = (&event_type, &event); services .users diff --git a/src/api/client/typing.rs b/src/api/client/typing.rs index 932d221ed..4ae3ac5ee 100644 --- a/src/api/client/typing.rs +++ b/src/api/client/typing.rs @@ -7,7 +7,8 @@ use crate::{utils, Error, Result, Ruma}; /// /// Sets the typing state of the sender user. pub(crate) async fn create_typing_event_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { use create_typing_event::v3::Typing; diff --git a/src/api/client/unstable.rs b/src/api/client/unstable.rs index c546d6a78..2c9add44a 100644 --- a/src/api/client/unstable.rs +++ b/src/api/client/unstable.rs @@ -10,8 +10,8 @@ use ruma::{ error::ErrorKind, membership::mutual_rooms, profile::{ - delete_profile_key, delete_timezone_key, get_profile_key, get_timezone_key, set_profile_key, - set_timezone_key, + delete_profile_key, delete_timezone_key, get_profile_key, get_timezone_key, + set_profile_key, set_timezone_key, }, room::get_summary, }, @@ -34,7 +34,8 @@ use crate::{Error, Result, Ruma, RumaResponse}; /// An implementation of [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) #[tracing::instrument(skip_all, fields(%client), name = "mutual_rooms")] pub(crate) async fn get_mutual_rooms_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -47,10 +48,7 @@ pub(crate) async fn get_mutual_rooms_route( } if !services.users.exists(&body.user_id).await { - return Ok(mutual_rooms::unstable::Response { - joined: vec![], - next_batch_token: None, - }); + return Ok(mutual_rooms::unstable::Response { joined: vec![], next_batch_token: None }); } let mutual_rooms: Vec = services @@ -77,7 +75,8 @@ pub(crate) async fn get_mutual_rooms_route( /// /// An implementation of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266) pub(crate) async fn get_room_summary_legacy( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result> { get_room_summary(State(services), InsecureClientIp(client), body) @@ -94,7 +93,8 @@ pub(crate) async fn get_room_summary_legacy( /// An implementation of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266) #[tracing::instrument(skip_all, fields(%client), name = "room_summary")] pub(crate) async fn get_room_summary( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref(); @@ -194,7 +194,8 @@ pub(crate) async fn get_room_summary( /// /// - Also makes sure other users receive the update using presence EDUs pub(crate) async fn delete_timezone_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -221,7 +222,8 @@ pub(crate) async fn delete_timezone_key_route( /// /// - Also makes sure other users receive the update using presence EDUs pub(crate) async fn set_timezone_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -248,7 +250,8 @@ pub(crate) async fn set_timezone_key_route( /// /// This also handles the avatar_url and displayname being updated. pub(crate) async fn set_profile_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -264,7 +267,9 @@ pub(crate) async fn set_profile_key_route( if body.kv_pair.len() > 1 { // TODO: support PATCH or "recursively" adding keys in some sort - return Err!(Request(BadJson("This endpoint can only take one key-value pair at a time"))); + return Err!(Request(BadJson( + "This endpoint can only take one key-value pair at a time" + ))); } let Some(profile_key_value) = body.kv_pair.get(&body.key) else { @@ -294,7 +299,13 @@ pub(crate) async fn set_profile_key_route( .collect() .await; - update_displayname(&services, &body.user_id, Some(profile_key_value.to_string()), &all_joined_rooms).await; + update_displayname( + &services, + &body.user_id, + Some(profile_key_value.to_string()), + &all_joined_rooms, + ) + .await; } else if body.key == "avatar_url" { let mxc = ruma::OwnedMxcUri::from(profile_key_value.to_string()); @@ -330,7 +341,8 @@ pub(crate) async fn set_profile_key_route( /// /// This also handles the avatar_url and displayname being updated. pub(crate) async fn delete_profile_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -340,7 +352,9 @@ pub(crate) async fn delete_profile_key_route( if body.kv_pair.len() > 1 { // TODO: support PATCH or "recursively" adding keys in some sort - return Err!(Request(BadJson("This endpoint can only take one key-value pair at a time"))); + return Err!(Request(BadJson( + "This endpoint can only take one key-value pair at a time" + ))); } if body.key == "displayname" { @@ -387,7 +401,8 @@ pub(crate) async fn delete_profile_key_route( /// - If user is on another server and we do not have a local copy already fetch /// `timezone` over federation pub(crate) async fn get_timezone_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.user_is_local(&body.user_id) { // Create and update our local copy of the user @@ -422,9 +437,7 @@ pub(crate) async fn get_timezone_key_route( .users .set_timezone(&body.user_id, response.tz.clone()); - return Ok(get_timezone_key::unstable::Response { - tz: response.tz, - }); + return Ok(get_timezone_key::unstable::Response { tz: response.tz }); } } @@ -446,7 +459,8 @@ pub(crate) async fn get_timezone_key_route( /// - If user is on another server and we do not have a local copy already fetch /// `timezone` over federation pub(crate) async fn get_profile_key_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let mut profile_key_value: BTreeMap = BTreeMap::new(); @@ -492,9 +506,7 @@ pub(crate) async fn get_profile_key_route( return Err!(Request(NotFound("The requested profile key does not exist."))); } - return Ok(get_profile_key::unstable::Response { - value: profile_key_value, - }); + return Ok(get_profile_key::unstable::Response { value: profile_key_value }); } } @@ -510,7 +522,5 @@ pub(crate) async fn get_profile_key_route( return Err!(Request(NotFound("The requested profile key does not exist."))); } - Ok(get_profile_key::unstable::Response { - value: profile_key_value, - }) + Ok(get_profile_key::unstable::Response { value: profile_key_value }) } diff --git a/src/api/client/unversioned.rs b/src/api/client/unversioned.rs index 91fe5a7ca..b4856d728 100644 --- a/src/api/client/unversioned.rs +++ b/src/api/client/unversioned.rs @@ -74,7 +74,9 @@ pub(crate) async fn conduwuit_server_version() -> Result { /// conduwuit-specific API to return the amount of users registered on this /// homeserver. Endpoint is disabled if federation is disabled for privacy. This /// only includes active users (not deactivated, no guests, etc) -pub(crate) async fn conduwuit_local_user_count(State(services): State) -> Result { +pub(crate) async fn conduwuit_local_user_count( + State(services): State, +) -> Result { let user_count = services.users.list_local_users().count().await; Ok(Json(serde_json::json!({ diff --git a/src/api/client/user_directory.rs b/src/api/client/user_directory.rs index bc7460f0e..182e30dbc 100644 --- a/src/api/client/user_directory.rs +++ b/src/api/client/user_directory.rs @@ -18,7 +18,8 @@ use crate::{Result, Ruma}; /// - Hides any local users that aren't in any public rooms (i.e. those that /// have the join rule set to public) and don't share a room with the sender pub(crate) async fn search_users_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { 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 @@ -61,7 +62,11 @@ pub(crate) async fn search_users_route( services .rooms .state_accessor - .room_state_get_content::(room, &StateEventType::RoomJoinRules, "") + .room_state_get_content::( + room, + &StateEventType::RoomJoinRules, + "", + ) .map_ok_or(false, |content| content.join_rule == JoinRule::Public) }) .await; @@ -89,8 +94,5 @@ pub(crate) async fn search_users_route( let results = users.take(limit).collect().await; - Ok(search_users::v3::Response { - results, - limited, - }) + Ok(search_users::v3::Response { results, limited }) } diff --git a/src/api/client/voip.rs b/src/api/client/voip.rs index b41cc8a1b..ec8045709 100644 --- a/src/api/client/voip.rs +++ b/src/api/client/voip.rs @@ -17,7 +17,8 @@ type HmacSha1 = Hmac; /// /// TODO: Returns information about the recommended turn server. pub(crate) async fn turn_server_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { // MSC4166: return M_NOT_FOUND 404 if no TURN URIs are specified in any way if services.server.config.turn_uris.is_empty() { @@ -44,7 +45,8 @@ pub(crate) async fn turn_server_route( let username: String = format!("{}:{}", expiry.get(), user); - let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes()).expect("HMAC can take key of any size"); + let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes()) + .expect("HMAC can take key of any size"); mac.update(username.as_bytes()); let password: String = general_purpose::STANDARD.encode(mac.finalize().into_bytes()); diff --git a/src/api/client/well_known.rs b/src/api/client/well_known.rs index b66217e8a..5c53d0131 100644 --- a/src/api/client/well_known.rs +++ b/src/api/client/well_known.rs @@ -13,21 +13,18 @@ use crate::{Error, Result, Ruma}; /// /// Returns the .well-known URL if it is configured, otherwise returns 404. pub(crate) async fn well_known_client( - State(services): State, _body: Ruma, + State(services): State, + _body: Ruma, ) -> Result { let client_url = match services.server.config.well_known.client.as_ref() { - Some(url) => url.to_string(), - None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")), + | Some(url) => url.to_string(), + | None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")), }; Ok(discover_homeserver::Response { - homeserver: HomeserverInfo { - base_url: client_url.clone(), - }, + homeserver: HomeserverInfo { base_url: client_url.clone() }, identity_server: None, - sliding_sync_proxy: Some(SlidingSyncProxyInfo { - url: client_url, - }), + sliding_sync_proxy: Some(SlidingSyncProxyInfo { url: client_url }), tile_server: None, }) } @@ -36,7 +33,8 @@ pub(crate) async fn well_known_client( /// /// Server support contact and support page of a homeserver's domain. pub(crate) async fn well_known_support( - State(services): State, _body: Ruma, + State(services): State, + _body: Ruma, ) -> Result { let support_page = services .server @@ -65,11 +63,7 @@ pub(crate) async fn well_known_support( let mut contacts: Vec = vec![]; if let Some(role) = role { - let contact = Contact { - role, - email_address, - matrix_id, - }; + let contact = Contact { role, email_address, matrix_id }; contacts.push(contact); } @@ -79,22 +73,21 @@ pub(crate) async fn well_known_support( return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")); } - Ok(discover_support::Response { - contacts, - support_page, - }) + Ok(discover_support::Response { contacts, support_page }) } /// # `GET /client/server.json` /// /// Endpoint provided by sliding sync proxy used by some clients such as Element /// Web as a non-standard health check. -pub(crate) async fn syncv3_client_server_json(State(services): State) -> Result { +pub(crate) async fn syncv3_client_server_json( + State(services): State, +) -> Result { let server_url = match services.server.config.well_known.client.as_ref() { - Some(url) => url.to_string(), - None => match services.server.config.well_known.server.as_ref() { - Some(url) => url.to_string(), - None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")), + | Some(url) => url.to_string(), + | None => match services.server.config.well_known.server.as_ref() { + | Some(url) => url.to_string(), + | None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")), }, }; diff --git a/src/api/router.rs b/src/api/router.rs index 99e066e4e..1b38670d7 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -190,7 +190,10 @@ pub fn build(router: Router, server: &Server) -> Router { router = router .ruma_route(&server::get_server_version_route) .route("/_matrix/key/v2/server", get(server::get_server_keys_route)) - .route("/_matrix/key/v2/server/:key_id", get(server::get_server_keys_deprecated_route)) + .route( + "/_matrix/key/v2/server/:key_id", + get(server::get_server_keys_deprecated_route), + ) .ruma_route(&server::get_public_rooms_route) .ruma_route(&server::get_public_rooms_filtered_route) .ruma_route(&server::send_transaction_message_route) @@ -284,6 +287,10 @@ async fn redirect_legacy_preview(uri: Uri) -> impl IntoResponse { Redirect::temporary(&uri) } -async fn legacy_media_disabled() -> impl IntoResponse { err!(Request(Forbidden("Unauthenticated media is disabled."))) } +async fn legacy_media_disabled() -> impl IntoResponse { + err!(Request(Forbidden("Unauthenticated media is disabled."))) +} -async fn federation_disabled() -> impl IntoResponse { err!(Request(Forbidden("Federation is disabled."))) } +async fn federation_disabled() -> impl IntoResponse { + err!(Request(Forbidden("Federation is disabled."))) +} diff --git a/src/api/router/args.rs b/src/api/router/args.rs index f5666ed6c..582f0c56a 100644 --- a/src/api/router/args.rs +++ b/src/api/router/args.rs @@ -4,8 +4,8 @@ use axum::{async_trait, body::Body, extract::FromRequest}; use bytes::{BufMut, Bytes, BytesMut}; use conduwuit::{debug, debug_warn, err, trace, utils::string::EMPTY, Error, Result}; use ruma::{ - api::IncomingRequest, CanonicalJsonObject, CanonicalJsonValue, DeviceId, OwnedDeviceId, OwnedServerName, - OwnedUserId, ServerName, UserId, + api::IncomingRequest, CanonicalJsonObject, CanonicalJsonValue, DeviceId, OwnedDeviceId, + OwnedServerName, OwnedUserId, ServerName, UserId, }; use service::Services; @@ -43,7 +43,9 @@ where T: IncomingRequest + Send + Sync + 'static, { #[inline] - pub(crate) fn sender(&self) -> (&UserId, &DeviceId) { (self.sender_user(), self.sender_device()) } + pub(crate) fn sender(&self) -> (&UserId, &DeviceId) { + (self.sender_user(), self.sender_device()) + } #[inline] pub(crate) fn sender_user(&self) -> &UserId { @@ -83,7 +85,10 @@ where { type Rejection = Error; - async fn from_request(request: hyper::Request, services: &State) -> Result { + async fn from_request( + request: hyper::Request, + services: &State, + ) -> Result { let mut request = request::from(services, request).await?; let mut json_body = serde_json::from_slice::(&request.body).ok(); @@ -96,7 +101,10 @@ where && !request.parts.uri.path().contains("/media/") { trace!("json_body from_request: {:?}", json_body.clone()); - debug_warn!("received a POST request with an empty body, defaulting/assuming to {{}} like Synapse does"); + debug_warn!( + "received a POST request with an empty body, defaulting/assuming to {{}} like \ + Synapse does" + ); json_body = Some(CanonicalJsonValue::Object(CanonicalJsonObject::new())); } let auth = auth::auth(services, &mut request, json_body.as_ref(), &T::METADATA).await?; @@ -112,14 +120,18 @@ where } fn make_body( - services: &Services, request: &mut Request, json_body: Option<&mut CanonicalJsonValue>, auth: &Auth, + services: &Services, + request: &mut Request, + json_body: Option<&mut CanonicalJsonValue>, + auth: &Auth, ) -> Result where T: IncomingRequest, { let body = take_body(services, request, json_body, auth); let http_request = into_http_request(request, body); - T::try_from_http_request(http_request, &request.path).map_err(|e| err!(Request(BadJson(debug_warn!("{e}"))))) + T::try_from_http_request(http_request, &request.path) + .map_err(|e| err!(Request(BadJson(debug_warn!("{e}"))))) } fn into_http_request(request: &Request, body: Bytes) -> hyper::Request { @@ -141,7 +153,10 @@ fn into_http_request(request: &Request, body: Bytes) -> hyper::Request { #[allow(clippy::needless_pass_by_value)] fn take_body( - services: &Services, request: &mut Request, json_body: Option<&mut CanonicalJsonValue>, auth: &Auth, + services: &Services, + request: &mut Request, + json_body: Option<&mut CanonicalJsonValue>, + auth: &Auth, ) -> Bytes { let Some(CanonicalJsonValue::Object(json_body)) = json_body else { return mem::take(&mut request.body); diff --git a/src/api/router/auth.rs b/src/api/router/auth.rs index 243fd46b0..c5b040e07 100644 --- a/src/api/router/auth.rs +++ b/src/api/router/auth.rs @@ -10,7 +10,9 @@ use ruma::{ client::{ directory::get_public_rooms, error::ErrorKind, - profile::{get_avatar_url, get_display_name, get_profile, get_profile_key, get_timezone_key}, + profile::{ + get_avatar_url, get_display_name, get_profile, get_profile_key, get_timezone_key, + }, voip::get_turn_server_info, }, federation::openid::get_openid_userinfo, @@ -42,12 +44,15 @@ pub(super) struct Auth { } pub(super) async fn auth( - services: &Services, request: &mut Request, json_body: Option<&CanonicalJsonValue>, metadata: &Metadata, + services: &Services, + request: &mut Request, + json_body: Option<&CanonicalJsonValue>, + metadata: &Metadata, ) -> Result { let bearer: Option>> = request.parts.extract().await?; let token = match &bearer { - Some(TypedHeader(Authorization(bearer))) => Some(bearer.token()), - None => request.query.access_token.as_deref(), + | Some(TypedHeader(Authorization(bearer))) => Some(bearer.token()), + | None => request.query.access_token.as_deref(), }; let token = if let Some(token) = token { @@ -64,56 +69,64 @@ pub(super) async fn auth( if metadata.authentication == AuthScheme::None { match metadata { - &get_public_rooms::v3::Request::METADATA => { + | &get_public_rooms::v3::Request::METADATA => { if !services .globals .config .allow_public_room_directory_without_auth { match token { - Token::Appservice(_) | Token::User(_) => { + | Token::Appservice(_) | Token::User(_) => { // we should have validated the token above // already }, - Token::None | Token::Invalid => { - return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing or invalid access token.")); + | Token::None | Token::Invalid => { + return Err(Error::BadRequest( + ErrorKind::MissingToken, + "Missing or invalid access token.", + )); }, } } }, - &get_profile::v3::Request::METADATA + | &get_profile::v3::Request::METADATA | &get_profile_key::unstable::Request::METADATA | &get_display_name::v3::Request::METADATA | &get_avatar_url::v3::Request::METADATA | &get_timezone_key::unstable::Request::METADATA => { if services.globals.config.require_auth_for_profile_requests { match token { - Token::Appservice(_) | Token::User(_) => { + | Token::Appservice(_) | Token::User(_) => { // we should have validated the token above // already }, - Token::None | Token::Invalid => { - return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing or invalid access token.")); + | Token::None | Token::Invalid => { + return Err(Error::BadRequest( + ErrorKind::MissingToken, + "Missing or invalid access token.", + )); }, } } }, - _ => {}, + | _ => {}, }; } match (metadata.authentication, token) { - (AuthScheme::AccessToken, Token::Appservice(info)) => Ok(auth_appservice(services, request, info).await?), - (AuthScheme::None | AuthScheme::AccessTokenOptional | AuthScheme::AppserviceToken, Token::Appservice(info)) => { - Ok(Auth { - origin: None, - sender_user: None, - sender_device: None, - appservice_info: Some(*info), - }) - }, - (AuthScheme::AccessToken, Token::None) => match metadata { - &get_turn_server_info::v3::Request::METADATA => { + | (AuthScheme::AccessToken, Token::Appservice(info)) => + Ok(auth_appservice(services, request, info).await?), + | ( + AuthScheme::None | AuthScheme::AccessTokenOptional | AuthScheme::AppserviceToken, + Token::Appservice(info), + ) => Ok(Auth { + origin: None, + sender_user: None, + sender_device: None, + appservice_info: Some(*info), + }), + | (AuthScheme::AccessToken, Token::None) => match metadata { + | &get_turn_server_info::v3::Request::METADATA => { if services.globals.config.turn_allow_guests { Ok(Auth { origin: None, @@ -125,9 +138,9 @@ pub(super) async fn auth( Err(Error::BadRequest(ErrorKind::MissingToken, "Missing access token.")) } }, - _ => Err(Error::BadRequest(ErrorKind::MissingToken, "Missing access token.")), + | _ => Err(Error::BadRequest(ErrorKind::MissingToken, "Missing access token.")), }, - ( + | ( AuthScheme::AccessToken | AuthScheme::AccessTokenOptional | AuthScheme::None, Token::User((user_id, device_id)), ) => Ok(Auth { @@ -136,26 +149,33 @@ pub(super) async fn auth( sender_device: Some(device_id), appservice_info: None, }), - (AuthScheme::ServerSignatures, Token::None) => Ok(auth_server(services, request, json_body).await?), - (AuthScheme::None | AuthScheme::AppserviceToken | AuthScheme::AccessTokenOptional, Token::None) => Ok(Auth { + | (AuthScheme::ServerSignatures, Token::None) => + Ok(auth_server(services, request, json_body).await?), + | ( + AuthScheme::None | AuthScheme::AppserviceToken | AuthScheme::AccessTokenOptional, + Token::None, + ) => Ok(Auth { sender_user: None, sender_device: None, origin: None, appservice_info: None, }), - (AuthScheme::ServerSignatures, Token::Appservice(_) | Token::User(_)) => Err(Error::BadRequest( - ErrorKind::Unauthorized, - "Only server signatures should be used on this endpoint.", - )), - (AuthScheme::AppserviceToken, Token::User(_)) => Err(Error::BadRequest( + | (AuthScheme::ServerSignatures, Token::Appservice(_) | Token::User(_)) => + Err(Error::BadRequest( + ErrorKind::Unauthorized, + "Only server signatures should be used on this endpoint.", + )), + | (AuthScheme::AppserviceToken, Token::User(_)) => Err(Error::BadRequest( ErrorKind::Unauthorized, "Only appservice access tokens should be used on this endpoint.", )), - (AuthScheme::None, Token::Invalid) => { + | (AuthScheme::None, Token::Invalid) => { // OpenID federation endpoint uses a query param with the same name, drop this // once query params for user auth are removed from the spec. This is // required to make integration manager work. - if request.query.access_token.is_some() && metadata == &get_openid_userinfo::v1::Request::METADATA { + if request.query.access_token.is_some() + && metadata == &get_openid_userinfo::v1::Request::METADATA + { Ok(Auth { origin: None, sender_user: None, @@ -164,25 +184,29 @@ pub(super) async fn auth( }) } else { Err(Error::BadRequest( - ErrorKind::UnknownToken { - soft_logout: false, - }, + ErrorKind::UnknownToken { soft_logout: false }, "Unknown access token.", )) } }, - (_, Token::Invalid) => Err(Error::BadRequest( - ErrorKind::UnknownToken { - soft_logout: false, - }, + | (_, Token::Invalid) => Err(Error::BadRequest( + ErrorKind::UnknownToken { soft_logout: false }, "Unknown access token.", )), } } -async fn auth_appservice(services: &Services, request: &Request, info: Box) -> Result { - let user_id_default = - || UserId::parse_with_server_name(info.registration.sender_localpart.as_str(), services.globals.server_name()); +async fn auth_appservice( + services: &Services, + request: &Request, + info: Box, +) -> Result { + let user_id_default = || { + UserId::parse_with_server_name( + info.registration.sender_localpart.as_str(), + services.globals.server_name(), + ) + }; let Ok(user_id) = request .query @@ -205,7 +229,11 @@ async fn auth_appservice(services: &Services, request: &Request, info: Box) -> Result { +async fn auth_server( + services: &Services, + request: &mut Request, + body: Option<&CanonicalJsonValue>, +) -> Result { type Member = (String, CanonicalJsonValue); type Object = CanonicalJsonObject; type Value = CanonicalJsonValue; @@ -222,7 +250,8 @@ async fn auth_server(services: &Services, request: &mut Request, body: Option<&C .expect("all requests have a path") .to_string(); - let signature: [Member; 1] = [(x_matrix.key.as_str().into(), Value::String(x_matrix.sig.to_string()))]; + let signature: [Member; 1] = + [(x_matrix.key.as_str().into(), Value::String(x_matrix.sig.to_string()))]; let signatures: [Member; 1] = [(origin.as_str().into(), Value::Object(signature.into()))]; @@ -261,8 +290,8 @@ async fn auth_server(services: &Services, request: &mut Request, body: Option<&C debug_error!("Failed to verify federation request from {origin}: {e}"); if request.parts.uri.to_string().contains('@') { warn!( - "Request uri contained '@' character. Make sure your reverse proxy gives conduwuit the raw uri \ - (apache: use nocanon)" + "Request uri contained '@' character. Make sure your reverse proxy gives \ + conduwuit the raw uri (apache: use nocanon)" ); } @@ -294,7 +323,9 @@ fn auth_server_checks(services: &Services, x_matrix: &XMatrix) -> Result<()> { .forbidden_remote_server_names .contains(origin) { - return Err!(Request(Forbidden(debug_warn!("Federation requests from {origin} denied.")))); + return Err!(Request(Forbidden(debug_warn!( + "Federation requests from {origin} denied." + )))); } Ok(()) @@ -307,9 +338,9 @@ async fn parse_x_matrix(request: &mut Request) -> Result { .await .map_err(|e| { let msg = match e.reason() { - TypedHeaderRejectionReason::Missing => "Missing Authorization header.", - TypedHeaderRejectionReason::Error(_) => "Invalid X-Matrix signatures.", - _ => "Unknown header-related error", + | TypedHeaderRejectionReason::Missing => "Missing Authorization header.", + | TypedHeaderRejectionReason::Error(_) => "Invalid X-Matrix signatures.", + | _ => "Unknown header-related error", }; err!(Request(Forbidden(warn!("{msg}: {e}")))) diff --git a/src/api/router/handler.rs b/src/api/router/handler.rs index 246dc843c..cfb8fb6ef 100644 --- a/src/api/router/handler.rs +++ b/src/api/router/handler.rs @@ -66,14 +66,14 @@ ruma_handler!(T1, T2, T3, T4); const fn method_to_filter(method: &Method) -> MethodFilter { match *method { - Method::DELETE => MethodFilter::DELETE, - Method::GET => MethodFilter::GET, - Method::HEAD => MethodFilter::HEAD, - Method::OPTIONS => MethodFilter::OPTIONS, - Method::PATCH => MethodFilter::PATCH, - Method::POST => MethodFilter::POST, - Method::PUT => MethodFilter::PUT, - Method::TRACE => MethodFilter::TRACE, - _ => panic!("Unsupported HTTP method"), + | Method::DELETE => MethodFilter::DELETE, + | Method::GET => MethodFilter::GET, + | Method::HEAD => MethodFilter::HEAD, + | Method::OPTIONS => MethodFilter::OPTIONS, + | Method::PATCH => MethodFilter::PATCH, + | Method::POST => MethodFilter::POST, + | Method::PUT => MethodFilter::PUT, + | Method::TRACE => MethodFilter::TRACE, + | _ => panic!("Unsupported HTTP method"), } } diff --git a/src/api/router/request.rs b/src/api/router/request.rs index fd57d8410..627abd30a 100644 --- a/src/api/router/request.rs +++ b/src/api/router/request.rs @@ -20,14 +20,17 @@ pub(super) struct Request { pub(super) parts: Parts, } -pub(super) async fn from(services: &Services, request: hyper::Request) -> Result { +pub(super) async fn from( + services: &Services, + request: hyper::Request, +) -> Result { let limited = request.with_limited_body(); let (mut parts, body) = limited.into_parts(); let path: Path> = parts.extract().await?; let query = parts.uri.query().unwrap_or_default(); - let query = - serde_html_form::from_str(query).map_err(|e| err!(Request(Unknown("Failed to read query parameters: {e}"))))?; + let query = serde_html_form::from_str(query) + .map_err(|e| err!(Request(Unknown("Failed to read query parameters: {e}"))))?; let max_body_size = services.globals.config.max_request_size; @@ -35,10 +38,5 @@ pub(super) async fn from(services: &Services, request: hyper::Request) -> (State, Guard) { services: Arc::into_raw(services.clone()), }; - let guard = Guard { - services, - }; + let guard = Guard { services }; (state, guard) } diff --git a/src/api/server/backfill.rs b/src/api/server/backfill.rs index 22fb6a8e2..fac0e5405 100644 --- a/src/api/server/backfill.rs +++ b/src/api/server/backfill.rs @@ -16,7 +16,8 @@ use crate::Ruma; /// Retrieves events from before the sender joined the room, if the room's /// history visibility allows. pub(crate) async fn get_backfill_route( - State(services): State, ref body: Ruma, + State(services): State, + ref body: Ruma, ) -> Result { AccessCheck { services: &services, diff --git a/src/api/server/event.rs b/src/api/server/event.rs index cbd9100b4..629dd6a29 100644 --- a/src/api/server/event.rs +++ b/src/api/server/event.rs @@ -12,7 +12,8 @@ use crate::Ruma; /// - Only works if a user of this server is currently invited or joined the /// room pub(crate) async fn get_event_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let event = services .rooms diff --git a/src/api/server/event_auth.rs b/src/api/server/event_auth.rs index 2d0893eb2..93e867a02 100644 --- a/src/api/server/event_auth.rs +++ b/src/api/server/event_auth.rs @@ -17,7 +17,8 @@ use crate::Ruma; /// /// - This does not include the event itself pub(crate) async fn get_event_authorization_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { AccessCheck { services: &services, @@ -40,8 +41,8 @@ pub(crate) async fn get_event_authorization_route( .and_then(|val| val.as_str()) .ok_or_else(|| Error::bad_database("Invalid event in database."))?; - let room_id = - <&RoomId>::try_from(room_id_str).map_err(|_| Error::bad_database("Invalid room_id in event in database."))?; + let room_id = <&RoomId>::try_from(room_id_str) + .map_err(|_| Error::bad_database("Invalid room_id in event in database."))?; let auth_chain = services .rooms @@ -53,7 +54,5 @@ pub(crate) async fn get_event_authorization_route( .collect() .await; - Ok(get_event_authorization::v1::Response { - auth_chain, - }) + Ok(get_event_authorization::v1::Response { auth_chain }) } diff --git a/src/api/server/get_missing_events.rs b/src/api/server/get_missing_events.rs index a07a1a379..ea06015aa 100644 --- a/src/api/server/get_missing_events.rs +++ b/src/api/server/get_missing_events.rs @@ -12,7 +12,8 @@ use crate::Ruma; /// /// Retrieves events that the sender is missing. pub(crate) async fn get_missing_events_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { AccessCheck { services: &services, @@ -87,7 +88,5 @@ pub(crate) async fn get_missing_events_route( i = i.saturating_add(1); } - Ok(get_missing_events::v1::Response { - events, - }) + Ok(get_missing_events::v1::Response { events }) } diff --git a/src/api/server/hierarchy.rs b/src/api/server/hierarchy.rs index e3ce71084..a10df6ac7 100644 --- a/src/api/server/hierarchy.rs +++ b/src/api/server/hierarchy.rs @@ -8,7 +8,8 @@ use crate::{Error, Result, Ruma}; /// Gets the space tree in a depth-first manner to locate child rooms of a given /// space. pub(crate) async fn get_hierarchy_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if services.rooms.metadata.exists(&body.room_id).await { services diff --git a/src/api/server/invite.rs b/src/api/server/invite.rs index f76573c70..a5b4a11c9 100644 --- a/src/api/server/invite.rs +++ b/src/api/server/invite.rs @@ -16,7 +16,8 @@ use crate::Ruma; /// Invites a remote user to a room. #[tracing::instrument(skip_all, fields(%client), name = "invite")] pub(crate) async fn create_invite_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { // ACL check origin @@ -28,9 +29,7 @@ pub(crate) async fn create_invite_route( if !services.server.supported_room_version(&body.room_version) { return Err(Error::BadRequest( - ErrorKind::IncompatibleRoomVersion { - room_version: body.room_version.clone(), - }, + ErrorKind::IncompatibleRoomVersion { room_version: body.room_version.clone() }, "Server does not support this room version.", )); } @@ -102,11 +101,14 @@ pub(crate) async fn create_invite_route( .try_into() .map_err(|e| err!(Request(InvalidParam("Invalid sender property: {e}"))))?; - if services.rooms.metadata.is_banned(&body.room_id).await && !services.users.is_admin(&invited_user).await { + if services.rooms.metadata.is_banned(&body.room_id).await + && !services.users.is_admin(&invited_user).await + { return Err!(Request(Forbidden("This room is banned on this homeserver."))); } - if services.globals.block_non_admin_invites() && !services.users.is_admin(&invited_user).await { + if services.globals.block_non_admin_invites() && !services.users.is_admin(&invited_user).await + { return Err!(Request(Forbidden("This server does not allow room invites."))); } diff --git a/src/api/server/key.rs b/src/api/server/key.rs index fea798976..75801a7a6 100644 --- a/src/api/server/key.rs +++ b/src/api/server/key.rs @@ -22,7 +22,9 @@ use ruma::{ /// this will be valid forever. // Response type for this endpoint is Json because we need to calculate a // signature for the response -pub(crate) async fn get_server_keys_route(State(services): State) -> Result { +pub(crate) async fn get_server_keys_route( + State(services): State, +) -> Result { let server_name = services.globals.server_name(); let active_key_id = services.server_keys.active_key_id(); let mut all_keys = services.server_keys.verify_keys_for(server_name).await; @@ -72,6 +74,8 @@ fn expires_ts() -> MilliSecondsSinceUnixEpoch { /// /// - Matrix does not support invalidating public keys, so the key returned by /// this will be valid forever. -pub(crate) async fn get_server_keys_deprecated_route(State(services): State) -> impl IntoResponse { +pub(crate) async fn get_server_keys_deprecated_route( + State(services): State, +) -> impl IntoResponse { get_server_keys_route(State(services)).await } diff --git a/src/api/server/make_join.rs b/src/api/server/make_join.rs index 3f62fbbea..3900c4188 100644 --- a/src/api/server/make_join.rs +++ b/src/api/server/make_join.rs @@ -23,7 +23,8 @@ use crate::{ /// /// Creates a join template. pub(crate) async fn create_join_event_template_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.rooms.metadata.exists(&body.room_id).await { return Err!(Request(NotFound("Room is unknown to this server."))); @@ -47,8 +48,8 @@ pub(crate) async fn create_join_event_template_route( .contains(body.origin()) { warn!( - "Server {} for remote user {} tried joining room ID {} which has a server name that is globally \ - forbidden. Rejecting.", + "Server {} for remote user {} tried joining room ID {} which has a server name that \ + is globally forbidden. Rejecting.", body.origin(), &body.user_id, &body.room_id, @@ -72,9 +73,7 @@ pub(crate) async fn create_join_event_template_route( let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?; if !body.ver.contains(&room_version_id) { return Err(Error::BadRequest( - ErrorKind::IncompatibleRoomVersion { - room_version: room_version_id, - }, + ErrorKind::IncompatibleRoomVersion { room_version: room_version_id }, "Room version not supported.", )); } @@ -86,16 +85,25 @@ pub(crate) async fn create_join_event_template_route( if matches!(room_version_id, V1 | V2 | V3 | V4 | V5 | V6 | V7) { // room version does not support restricted join rules None - } else if user_can_perform_restricted_join(&services, &body.user_id, &body.room_id, &room_version_id).await? { + } else if user_can_perform_restricted_join( + &services, + &body.user_id, + &body.room_id, + &room_version_id, + ) + .await? + { let Some(auth_user) = services .rooms .state_cache .local_users_in_room(&body.room_id) .filter(|user| { - services - .rooms - .state_accessor - .user_can_invite(&body.room_id, user, &body.user_id, &state_lock) + services.rooms.state_accessor.user_can_invite( + &body.room_id, + user, + &body.user_id, + &state_lock, + ) }) .boxed() .next() @@ -116,13 +124,10 @@ pub(crate) async fn create_join_event_template_route( .rooms .timeline .create_hash_and_sign_event( - PduBuilder::state( - body.user_id.to_string(), - &RoomMemberEventContent { - join_authorized_via_users_server, - ..RoomMemberEventContent::new(MembershipState::Join) - }, - ), + PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent { + join_authorized_via_users_server, + ..RoomMemberEventContent::new(MembershipState::Join) + }), &body.user_id, &body.room_id, &state_lock, @@ -142,7 +147,10 @@ pub(crate) async fn create_join_event_template_route( /// Checks whether the given user can join the given room via a restricted join. pub(crate) async fn user_can_perform_restricted_join( - services: &Services, user_id: &UserId, room_id: &RoomId, room_version_id: &RoomVersionId, + services: &Services, + user_id: &UserId, + room_id: &RoomId, + room_version_id: &RoomVersionId, ) -> Result { use RoomVersionId::*; @@ -159,13 +167,19 @@ pub(crate) async fn user_can_perform_restricted_join( let Ok(join_rules_event_content) = services .rooms .state_accessor - .room_state_get_content::(room_id, &StateEventType::RoomJoinRules, "") + .room_state_get_content::( + room_id, + &StateEventType::RoomJoinRules, + "", + ) .await else { return Ok(false); }; - let (JoinRule::Restricted(r) | JoinRule::KnockRestricted(r)) = join_rules_event_content.join_rule else { + let (JoinRule::Restricted(r) | JoinRule::KnockRestricted(r)) = + join_rules_event_content.join_rule + else { return Ok(false); }; @@ -195,12 +209,15 @@ pub(crate) async fn user_can_perform_restricted_join( } } -pub(crate) fn maybe_strip_event_id(pdu_json: &mut CanonicalJsonObject, room_version_id: &RoomVersionId) -> Result { +pub(crate) fn maybe_strip_event_id( + pdu_json: &mut CanonicalJsonObject, + room_version_id: &RoomVersionId, +) -> Result { use RoomVersionId::*; match room_version_id { - V1 | V2 => Ok(()), - _ => { + | V1 | V2 => Ok(()), + | _ => { pdu_json.remove("event_id"); Ok(()) }, diff --git a/src/api/server/make_leave.rs b/src/api/server/make_leave.rs index 2895d3bf1..746a48588 100644 --- a/src/api/server/make_leave.rs +++ b/src/api/server/make_leave.rs @@ -13,7 +13,8 @@ use crate::{service::pdu::PduBuilder, Ruma}; /// /// Creates a leave template. pub(crate) async fn create_leave_event_template_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.rooms.metadata.exists(&body.room_id).await { return Err!(Request(NotFound("Room is unknown to this server."))); @@ -37,7 +38,10 @@ pub(crate) async fn create_leave_event_template_route( .rooms .timeline .create_hash_and_sign_event( - PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent::new(MembershipState::Leave)), + PduBuilder::state( + body.user_id.to_string(), + &RoomMemberEventContent::new(MembershipState::Leave), + ), &body.user_id, &body.room_id, &state_lock, diff --git a/src/api/server/media.rs b/src/api/server/media.rs index 8c3ff4351..03ec7b519 100644 --- a/src/api/server/media.rs +++ b/src/api/server/media.rs @@ -16,7 +16,8 @@ use crate::Ruma; /// Load media from our server. #[tracing::instrument(skip_all, fields(%client), name = "media_get")] pub(crate) async fn get_content_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let mxc = Mxc { @@ -33,7 +34,8 @@ pub(crate) async fn get_content_route( return Err!(Request(NotFound("Media not found."))); }; - let content_disposition = make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); + let content_disposition = + make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); let content = Content { file: content.expect("entire file contents"), content_type: content_type.map(Into::into), @@ -51,7 +53,8 @@ pub(crate) async fn get_content_route( /// Load media thumbnail from our server. #[tracing::instrument(skip_all, fields(%client), name = "media_thumbnail_get")] pub(crate) async fn get_content_thumbnail_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { let dim = Dim::from_ruma(body.width, body.height, body.method.clone())?; @@ -69,7 +72,8 @@ pub(crate) async fn get_content_thumbnail_route( return Err!(Request(NotFound("Media not found."))); }; - let content_disposition = make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); + let content_disposition = + make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None); let content = Content { file: content.expect("entire file contents"), content_type: content_type.map(Into::into), diff --git a/src/api/server/openid.rs b/src/api/server/openid.rs index 9b54807a6..4833fbe11 100644 --- a/src/api/server/openid.rs +++ b/src/api/server/openid.rs @@ -7,7 +7,8 @@ use crate::{Result, Ruma}; /// /// Get information about the user that generated the OpenID token. pub(crate) async fn get_openid_userinfo_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { Ok(get_openid_userinfo::v1::Response::new( services diff --git a/src/api/server/publicrooms.rs b/src/api/server/publicrooms.rs index f6c418592..77cde15f4 100644 --- a/src/api/server/publicrooms.rs +++ b/src/api/server/publicrooms.rs @@ -15,7 +15,8 @@ use crate::{Error, Result, Ruma}; /// Lists the public rooms on this server. #[tracing::instrument(skip_all, fields(%client), name = "publicrooms")] pub(crate) async fn get_public_rooms_filtered_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { if !services @@ -35,7 +36,9 @@ pub(crate) async fn get_public_rooms_filtered_route( &body.room_network, ) .await - .map_err(|_| Error::BadRequest(ErrorKind::Unknown, "Failed to return this server's public room list."))?; + .map_err(|_| { + Error::BadRequest(ErrorKind::Unknown, "Failed to return this server's public room list.") + })?; Ok(get_public_rooms_filtered::v1::Response { chunk: response.chunk, @@ -50,7 +53,8 @@ pub(crate) async fn get_public_rooms_filtered_route( /// Lists the public rooms on this server. #[tracing::instrument(skip_all, fields(%client), "publicrooms")] pub(crate) async fn get_public_rooms_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { if !services @@ -69,7 +73,9 @@ pub(crate) async fn get_public_rooms_route( &body.room_network, ) .await - .map_err(|_| Error::BadRequest(ErrorKind::Unknown, "Failed to return this server's public room list."))?; + .map_err(|_| { + Error::BadRequest(ErrorKind::Unknown, "Failed to return this server's public room list.") + })?; Ok(get_public_rooms::v1::Response { chunk: response.chunk, diff --git a/src/api/server/query.rs b/src/api/server/query.rs index 6536bb205..0e5f7e567 100644 --- a/src/api/server/query.rs +++ b/src/api/server/query.rs @@ -19,7 +19,8 @@ use crate::Ruma; /// /// Resolve a room alias to a room id. pub(crate) async fn get_room_information_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { let room_id = services .rooms @@ -50,10 +51,7 @@ pub(crate) async fn get_room_information_route( servers.insert(0, services.globals.server_name().to_owned()); } - Ok(get_room_information::v1::Response { - room_id, - servers, - }) + Ok(get_room_information::v1::Response { room_id, servers }) } /// # `GET /_matrix/federation/v1/query/profile` @@ -61,7 +59,8 @@ pub(crate) async fn get_room_information_route( /// /// Gets information on a profile. pub(crate) async fn get_profile_information_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services .globals @@ -88,14 +87,14 @@ pub(crate) async fn get_profile_information_route( let mut custom_profile_fields = BTreeMap::new(); match &body.field { - Some(ProfileField::DisplayName) => { + | Some(ProfileField::DisplayName) => { displayname = services.users.displayname(&body.user_id).await.ok(); }, - Some(ProfileField::AvatarUrl) => { + | Some(ProfileField::AvatarUrl) => { avatar_url = services.users.avatar_url(&body.user_id).await.ok(); blurhash = services.users.blurhash(&body.user_id).await.ok(); }, - Some(custom_field) => { + | Some(custom_field) => { if let Ok(value) = services .users .profile_key(&body.user_id, custom_field.as_str()) @@ -104,7 +103,7 @@ pub(crate) async fn get_profile_information_route( custom_profile_fields.insert(custom_field.to_string(), value); } }, - None => { + | None => { displayname = services.users.displayname(&body.user_id).await.ok(); avatar_url = services.users.avatar_url(&body.user_id).await.ok(); blurhash = services.users.blurhash(&body.user_id).await.ok(); diff --git a/src/api/server/send.rs b/src/api/server/send.rs index 960c79b07..c5fc7118a 100644 --- a/src/api/server/send.rs +++ b/src/api/server/send.rs @@ -2,15 +2,18 @@ use std::{collections::BTreeMap, net::IpAddr, time::Instant}; use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduwuit::{debug, debug_warn, err, error, result::LogErr, trace, utils::ReadyExt, warn, Err, Error, Result}; +use conduwuit::{ + debug, debug_warn, err, error, result::LogErr, trace, utils::ReadyExt, warn, Err, Error, + Result, +}; use futures::StreamExt; use ruma::{ api::{ client::error::ErrorKind, federation::transactions::{ edu::{ - DeviceListUpdateContent, DirectDeviceContent, Edu, PresenceContent, ReceiptContent, - SigningKeyUpdateContent, TypingContent, + DeviceListUpdateContent, DirectDeviceContent, Edu, PresenceContent, + ReceiptContent, SigningKeyUpdateContent, TypingContent, }, send_transaction_message, }, @@ -38,7 +41,8 @@ type ResolvedMap = BTreeMap>; /// Push EDUs and PDUs to this server. #[tracing::instrument(skip_all, fields(%client, origin = body.origin().as_str()), name = "send")] pub(crate) async fn send_transaction_message_route( - State(services): State, InsecureClientIp(client): InsecureClientIp, + State(services): State, + InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { if body.origin() != body.body.origin { @@ -69,7 +73,8 @@ pub(crate) async fn send_transaction_message_route( "Starting txn", ); - let resolved_map = handle_pdus(&services, &client, &body.pdus, body.origin(), &txn_start_time).await?; + let resolved_map = + handle_pdus(&services, &client, &body.pdus, body.origin(), &txn_start_time).await?; handle_edus(&services, &client, &body.edus, body.origin()).await; debug!( @@ -90,13 +95,17 @@ pub(crate) async fn send_transaction_message_route( } async fn handle_pdus( - services: &Services, _client: &IpAddr, pdus: &[Box], origin: &ServerName, txn_start_time: &Instant, + services: &Services, + _client: &IpAddr, + pdus: &[Box], + origin: &ServerName, + txn_start_time: &Instant, ) -> Result { let mut parsed_pdus = Vec::with_capacity(pdus.len()); for pdu in pdus { parsed_pdus.push(match services.rooms.event_handler.parse_incoming_pdu(pdu).await { - Ok(t) => t, - Err(e) => { + | Ok(t) => t, + | Err(e) => { debug_warn!("Could not parse PDU: {e}"); continue; }, @@ -145,26 +154,45 @@ async fn handle_pdus( Ok(resolved_map) } -async fn handle_edus(services: &Services, client: &IpAddr, edus: &[Raw], origin: &ServerName) { +async fn handle_edus( + services: &Services, + client: &IpAddr, + edus: &[Raw], + origin: &ServerName, +) { for edu in edus .iter() .filter_map(|edu| serde_json::from_str::(edu.json().get()).ok()) { match edu { - Edu::Presence(presence) => handle_edu_presence(services, client, origin, presence).await, - Edu::Receipt(receipt) => handle_edu_receipt(services, client, origin, receipt).await, - Edu::Typing(typing) => handle_edu_typing(services, client, origin, typing).await, - Edu::DeviceListUpdate(content) => handle_edu_device_list_update(services, client, origin, content).await, - Edu::DirectToDevice(content) => handle_edu_direct_to_device(services, client, origin, content).await, - Edu::SigningKeyUpdate(content) => handle_edu_signing_key_update(services, client, origin, content).await, - Edu::_Custom(ref _custom) => { + | Edu::Presence(presence) => { + handle_edu_presence(services, client, origin, presence).await; + }, + | Edu::Receipt(receipt) => + handle_edu_receipt(services, client, origin, receipt).await, + | Edu::Typing(typing) => handle_edu_typing(services, client, origin, typing).await, + | Edu::DeviceListUpdate(content) => { + handle_edu_device_list_update(services, client, origin, content).await; + }, + | Edu::DirectToDevice(content) => { + handle_edu_direct_to_device(services, client, origin, content).await; + }, + | Edu::SigningKeyUpdate(content) => { + handle_edu_signing_key_update(services, client, origin, content).await; + }, + | Edu::_Custom(ref _custom) => { debug_warn!(?edus, "received custom/unknown EDU"); }, } } } -async fn handle_edu_presence(services: &Services, _client: &IpAddr, origin: &ServerName, presence: PresenceContent) { +async fn handle_edu_presence( + services: &Services, + _client: &IpAddr, + origin: &ServerName, + presence: PresenceContent, +) { if !services.globals.allow_incoming_presence() { return; } @@ -193,7 +221,12 @@ async fn handle_edu_presence(services: &Services, _client: &IpAddr, origin: &Ser } } -async fn handle_edu_receipt(services: &Services, _client: &IpAddr, origin: &ServerName, receipt: ReceiptContent) { +async fn handle_edu_receipt( + services: &Services, + _client: &IpAddr, + origin: &ServerName, + receipt: ReceiptContent, +) { if !services.globals.allow_incoming_read_receipts() { return; } @@ -230,7 +263,8 @@ async fn handle_edu_receipt(services: &Services, _client: &IpAddr, origin: &Serv .await { for event_id in &user_updates.event_ids { - let user_receipts = BTreeMap::from([(user_id.clone(), user_updates.data.clone())]); + let user_receipts = + BTreeMap::from([(user_id.clone(), user_updates.data.clone())]); let receipts = BTreeMap::from([(ReceiptType::Read, user_receipts)]); let receipt_content = BTreeMap::from([(event_id.to_owned(), receipts)]); let event = ReceiptEvent { @@ -255,7 +289,12 @@ async fn handle_edu_receipt(services: &Services, _client: &IpAddr, origin: &Serv } } -async fn handle_edu_typing(services: &Services, _client: &IpAddr, origin: &ServerName, typing: TypingContent) { +async fn handle_edu_typing( + services: &Services, + _client: &IpAddr, + origin: &ServerName, + typing: TypingContent, +) { if !services.globals.config.allow_incoming_typing { return; } @@ -321,12 +360,12 @@ async fn handle_edu_typing(services: &Services, _client: &IpAddr, origin: &Serve } async fn handle_edu_device_list_update( - services: &Services, _client: &IpAddr, origin: &ServerName, content: DeviceListUpdateContent, + services: &Services, + _client: &IpAddr, + origin: &ServerName, + content: DeviceListUpdateContent, ) { - let DeviceListUpdateContent { - user_id, - .. - } = content; + let DeviceListUpdateContent { user_id, .. } = content; if user_id.server_name() != origin { debug_warn!( @@ -340,14 +379,12 @@ async fn handle_edu_device_list_update( } async fn handle_edu_direct_to_device( - services: &Services, _client: &IpAddr, origin: &ServerName, content: DirectDeviceContent, + services: &Services, + _client: &IpAddr, + origin: &ServerName, + content: DirectDeviceContent, ) { - let DirectDeviceContent { - sender, - ev_type, - message_id, - messages, - } = content; + let DirectDeviceContent { sender, ev_type, message_id, messages } = content; if sender.server_name() != origin { debug_warn!( @@ -369,23 +406,28 @@ async fn handle_edu_direct_to_device( for (target_user_id, map) in &messages { for (target_device_id_maybe, event) in map { - let Ok(event) = event - .deserialize_as() - .map_err(|e| err!(Request(InvalidParam(error!("To-Device event is invalid: {e}"))))) - else { + let Ok(event) = event.deserialize_as().map_err(|e| { + err!(Request(InvalidParam(error!("To-Device event is invalid: {e}")))) + }) else { continue; }; let ev_type = ev_type.to_string(); match target_device_id_maybe { - DeviceIdOrAllDevices::DeviceId(target_device_id) => { + | DeviceIdOrAllDevices::DeviceId(target_device_id) => { services .users - .add_to_device_event(&sender, target_user_id, target_device_id, &ev_type, event) + .add_to_device_event( + &sender, + target_user_id, + target_device_id, + &ev_type, + event, + ) .await; }, - DeviceIdOrAllDevices::AllDevices => { + | DeviceIdOrAllDevices::AllDevices => { let (sender, ev_type, event) = (&sender, &ev_type, &event); services .users @@ -412,13 +454,12 @@ async fn handle_edu_direct_to_device( } async fn handle_edu_signing_key_update( - services: &Services, _client: &IpAddr, origin: &ServerName, content: SigningKeyUpdateContent, + services: &Services, + _client: &IpAddr, + origin: &ServerName, + content: SigningKeyUpdateContent, ) { - let SigningKeyUpdateContent { - user_id, - master_key, - self_signing_key, - } = content; + let SigningKeyUpdateContent { user_id, master_key, self_signing_key } = content; if user_id.server_name() != origin { debug_warn!( diff --git a/src/api/server/send_join.rs b/src/api/server/send_join.rs index 9c72de2c7..6ac849072 100644 --- a/src/api/server/send_join.rs +++ b/src/api/server/send_join.rs @@ -16,7 +16,8 @@ use ruma::{ room::member::{MembershipState, RoomMemberEventContent}, StateEventType, }, - CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, ServerName, + CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, + ServerName, }; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use service::Services; @@ -25,7 +26,10 @@ use crate::Ruma; /// helper method for /send_join v1 and v2 async fn create_join_event( - services: &Services, origin: &ServerName, room_id: &RoomId, pdu: &RawJsonValue, + services: &Services, + origin: &ServerName, + room_id: &RoomId, + pdu: &RawJsonValue, ) -> Result { if !services.rooms.metadata.exists(room_id).await { return Err!(Request(NotFound("Room is unknown to this server."))); @@ -146,7 +150,8 @@ async fn create_join_event( if !services.globals.user_is_local(&authorising_user) { return Err!(Request(InvalidParam( - "Cannot authorise membership event through {authorising_user} as they do not belong to this homeserver" + "Cannot authorise membership event through {authorising_user} as they do not \ + belong to this homeserver" ))); } @@ -157,12 +162,19 @@ async fn create_join_event( .await { return Err!(Request(InvalidParam( - "Authorising user {authorising_user} is not in the room you are trying to join, they cannot authorise \ - your join." + "Authorising user {authorising_user} is not in the room you are trying to join, \ + they cannot authorise your join." ))); } - if !super::user_can_perform_restricted_join(services, &state_key, room_id, &room_version_id).await? { + if !super::user_can_perform_restricted_join( + services, + &state_key, + room_id, + &room_version_id, + ) + .await? + { return Err!(Request(UnableToAuthorizeJoin( "Joining user did not pass restricted room's rules." ))); @@ -228,7 +240,9 @@ async fn create_join_event( .event_ids_iter(room_id, starting_events) .await? .map(Ok) - .broad_and_then(|event_id| async move { services.rooms.timeline.get_pdu_json(&event_id).await }) + .broad_and_then(|event_id| async move { + services.rooms.timeline.get_pdu_json(&event_id).await + }) .broad_and_then(|pdu| { services .sending @@ -252,7 +266,8 @@ async fn create_join_event( /// /// Submits a signed join event. pub(crate) async fn create_join_event_v1_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if services .globals @@ -261,8 +276,8 @@ pub(crate) async fn create_join_event_v1_route( .contains(body.origin()) { warn!( - "Server {} tried joining room ID {} through us who has a server name that is globally forbidden. \ - Rejecting.", + "Server {} tried joining room ID {} through us who has a server name that is \ + globally forbidden. Rejecting.", body.origin(), &body.room_id, ); @@ -277,8 +292,8 @@ pub(crate) async fn create_join_event_v1_route( .contains(&server.to_owned()) { warn!( - "Server {} tried joining room ID {} through us which has a server name that is globally forbidden. \ - Rejecting.", + "Server {} tried joining room ID {} through us which has a server name that is \ + globally forbidden. Rejecting.", body.origin(), &body.room_id, ); @@ -292,16 +307,15 @@ pub(crate) async fn create_join_event_v1_route( .boxed() .await?; - Ok(create_join_event::v1::Response { - room_state, - }) + Ok(create_join_event::v1::Response { room_state }) } /// # `PUT /_matrix/federation/v2/send_join/{roomId}/{eventId}` /// /// Submits a signed join event. pub(crate) async fn create_join_event_v2_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if services .globals @@ -320,8 +334,8 @@ pub(crate) async fn create_join_event_v2_route( .contains(&server.to_owned()) { warn!( - "Server {} tried joining room ID {} through us which has a server name that is globally forbidden. \ - Rejecting.", + "Server {} tried joining room ID {} through us which has a server name that is \ + globally forbidden. Rejecting.", body.origin(), &body.room_id, ); @@ -331,13 +345,10 @@ pub(crate) async fn create_join_event_v2_route( } } - let create_join_event::v1::RoomState { - auth_chain, - state, - event, - } = create_join_event(&services, body.origin(), &body.room_id, &body.pdu) - .boxed() - .await?; + let create_join_event::v1::RoomState { auth_chain, state, event } = + create_join_event(&services, body.origin(), &body.room_id, &body.pdu) + .boxed() + .await?; let room_state = create_join_event::v2::RoomState { members_omitted: false, auth_chain, @@ -346,7 +357,5 @@ pub(crate) async fn create_join_event_v2_route( servers_in_room: None, }; - Ok(create_join_event::v2::Response { - room_state, - }) + Ok(create_join_event::v2::Response { room_state }) } diff --git a/src/api/server/send_leave.rs b/src/api/server/send_leave.rs index b58bae7e0..016ed7fa1 100644 --- a/src/api/server/send_leave.rs +++ b/src/api/server/send_leave.rs @@ -21,7 +21,8 @@ use crate::{ /// /// Submits a signed leave event. pub(crate) async fn create_leave_event_v1_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { create_leave_event(&services, body.origin(), &body.room_id, &body.pdu).await?; @@ -32,14 +33,20 @@ pub(crate) async fn create_leave_event_v1_route( /// /// Submits a signed leave event. pub(crate) async fn create_leave_event_v2_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { create_leave_event(&services, body.origin(), &body.room_id, &body.pdu).await?; Ok(create_leave_event::v2::Response::new()) } -async fn create_leave_event(services: &Services, origin: &ServerName, room_id: &RoomId, pdu: &RawJsonValue) -> Result { +async fn create_leave_event( + services: &Services, + origin: &ServerName, + room_id: &RoomId, + pdu: &RawJsonValue, +) -> Result { if !services.rooms.metadata.exists(room_id).await { return Err!(Request(NotFound("Room is unknown to this server."))); } diff --git a/src/api/server/state.rs b/src/api/server/state.rs index ba1c400f4..42f7e5383 100644 --- a/src/api/server/state.rs +++ b/src/api/server/state.rs @@ -12,7 +12,8 @@ use crate::Ruma; /// /// Retrieves a snapshot of a room's state at a given event. pub(crate) async fn get_room_state_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { AccessCheck { services: &services, @@ -69,8 +70,5 @@ pub(crate) async fn get_room_state_route( .try_collect() .await?; - Ok(get_room_state::v1::Response { - auth_chain, - pdus, - }) + Ok(get_room_state::v1::Response { auth_chain, pdus }) } diff --git a/src/api/server/state_ids.rs b/src/api/server/state_ids.rs index 503104df9..186ef3990 100644 --- a/src/api/server/state_ids.rs +++ b/src/api/server/state_ids.rs @@ -13,7 +13,8 @@ use crate::Ruma; /// Retrieves a snapshot of a room's state at a given event, in the form of /// event IDs. pub(crate) async fn get_room_state_ids_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { AccessCheck { services: &services, @@ -49,8 +50,5 @@ pub(crate) async fn get_room_state_ids_route( .collect() .await; - Ok(get_room_state_ids::v1::Response { - auth_chain_ids, - pdu_ids, - }) + Ok(get_room_state_ids::v1::Response { auth_chain_ids, pdu_ids }) } diff --git a/src/api/server/user.rs b/src/api/server/user.rs index 5072ed2f8..321d0b66f 100644 --- a/src/api/server/user.rs +++ b/src/api/server/user.rs @@ -18,7 +18,8 @@ use crate::{ /// /// Gets information on all devices of the user. pub(crate) async fn get_devices_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if !services.globals.user_is_local(&body.user_id) { return Err(Error::BadRequest( @@ -52,11 +53,7 @@ pub(crate) async fn get_devices_route( services .users .get_device_keys(user_id, &device_id_clone) - .map_ok(|keys| UserDevice { - device_id, - keys, - device_display_name, - }) + .map_ok(|keys| UserDevice { device_id, keys, device_display_name }) .map(Result::ok) .await }) @@ -79,7 +76,8 @@ pub(crate) async fn get_devices_route( /// /// Gets devices and identity keys for the given users. pub(crate) async fn get_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if body .device_keys @@ -112,7 +110,8 @@ pub(crate) async fn get_keys_route( /// /// Claims one-time keys. pub(crate) async fn claim_keys_route( - State(services): State, body: Ruma, + State(services): State, + body: Ruma, ) -> Result { if body .one_time_keys @@ -127,7 +126,5 @@ pub(crate) async fn claim_keys_route( let result = claim_keys_helper(&services, &body.one_time_keys).await?; - Ok(claim_keys::v1::Response { - one_time_keys: result.one_time_keys, - }) + Ok(claim_keys::v1::Response { one_time_keys: result.one_time_keys }) } diff --git a/src/api/server/utils.rs b/src/api/server/utils.rs index 3e7685131..112cf858a 100644 --- a/src/api/server/utils.rs +++ b/src/api/server/utils.rs @@ -34,10 +34,11 @@ pub(super) async fn check(&self) -> Result { let server_can_see: OptionFuture<_> = self .event_id .map(|event_id| { - self.services - .rooms - .state_accessor - .server_can_see_event(self.origin, self.room_id, event_id) + self.services.rooms.state_accessor.server_can_see_event( + self.origin, + self.room_id, + event_id, + ) }) .into(); diff --git a/src/api/server/well_known.rs b/src/api/server/well_known.rs index e6145aeaa..48caa7d6c 100644 --- a/src/api/server/well_known.rs +++ b/src/api/server/well_known.rs @@ -7,12 +7,13 @@ use crate::{Error, Result, Ruma}; /// /// Returns the .well-known URL if it is configured, otherwise returns 404. pub(crate) async fn well_known_server( - State(services): State, _body: Ruma, + State(services): State, + _body: Ruma, ) -> Result { Ok(discover_homeserver::Response { server: match services.server.config.well_known.server.as_ref() { - Some(server_name) => server_name.to_owned(), - None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")), + | Some(server_name) => server_name.to_owned(), + | None => return Err(Error::BadRequest(ErrorKind::NotFound, "Not found.")), }, }) } diff --git a/src/core/alloc/je.rs b/src/core/alloc/je.rs index a3a7acc01..423f5408a 100644 --- a/src/core/alloc/je.rs +++ b/src/core/alloc/je.rs @@ -29,8 +29,9 @@ pub fn memory_usage() -> Option { let resident = mibs(stats::resident::read()); let retained = mibs(stats::retained::read()); Some(format!( - "allocated: {allocated:.2} MiB\nactive: {active:.2} MiB\nmapped: {mapped:.2} MiB\nmetadata: {metadata:.2} \ - MiB\nresident: {resident:.2} MiB\nretained: {retained:.2} MiB\n" + "allocated: {allocated:.2} MiB\nactive: {active:.2} MiB\nmapped: {mapped:.2} \ + MiB\nmetadata: {metadata:.2} MiB\nresident: {resident:.2} MiB\nretained: {retained:.2} \ + MiB\n" )) } diff --git a/src/core/alloc/mod.rs b/src/core/alloc/mod.rs index 7941a99c8..31eb033cc 100644 --- a/src/core/alloc/mod.rs +++ b/src/core/alloc/mod.rs @@ -8,10 +8,20 @@ pub use je::{memory_stats, memory_usage}; #[cfg(all(not(target_env = "msvc"), feature = "hardened_malloc", not(feature = "jemalloc")))] pub mod hardened; -#[cfg(all(not(target_env = "msvc"), feature = "hardened_malloc", not(feature = "jemalloc")))] +#[cfg(all( + not(target_env = "msvc"), + feature = "hardened_malloc", + not(feature = "jemalloc") +))] pub use hardened::{memory_stats, memory_usage}; -#[cfg(any(target_env = "msvc", all(not(feature = "hardened_malloc"), not(feature = "jemalloc"))))] +#[cfg(any( + target_env = "msvc", + all(not(feature = "hardened_malloc"), not(feature = "jemalloc")) +))] pub mod default; -#[cfg(any(target_env = "msvc", all(not(feature = "hardened_malloc"), not(feature = "jemalloc"))))] +#[cfg(any( + target_env = "msvc", + all(not(feature = "hardened_malloc"), not(feature = "jemalloc")) +))] pub use default::{memory_stats, memory_usage}; diff --git a/src/core/config/check.rs b/src/core/config/check.rs index b8415281b..c242e2fdd 100644 --- a/src/core/config/check.rs +++ b/src/core/config/check.rs @@ -16,18 +16,24 @@ pub fn check(config: &Config) -> Result<()> { warn_unknown_key(config); if config.sentry && config.sentry_endpoint.is_none() { - return Err!(Config("sentry_endpoint", "Sentry cannot be enabled without an endpoint set")); + return Err!(Config( + "sentry_endpoint", + "Sentry cannot be enabled without an endpoint set" + )); } if cfg!(all(feature = "hardened_malloc", feature = "jemalloc")) { - info!("hardened_malloc and jemalloc compile-time features are both enabled, this causes jemalloc to be used."); + info!( + "hardened_malloc and jemalloc compile-time features are both enabled, this causes \ + jemalloc to be used." + ); } if cfg!(not(unix)) && config.unix_socket_path.is_some() { return Err!(Config( "unix_socket_path", - "UNIX socket support is only available on *nix platforms. Please remove 'unix_socket_path' from your \ - config." + "UNIX socket support is only available on *nix platforms. Please remove \ + 'unix_socket_path' from your config." )); } @@ -44,30 +50,36 @@ pub fn check(config: &Config) -> Result<()> { use std::path::Path; if addr.ip().is_loopback() { - debug_info!("Found loopback listening address {addr}, running checks if we're in a container."); + debug_info!( + "Found loopback listening address {addr}, running checks if we're in a \ + container." + ); if Path::new("/proc/vz").exists() /* Guest */ && !Path::new("/proc/bz").exists() /* Host */ { error!( - "You are detected using OpenVZ with a loopback/localhost listening address of {addr}. If you \ - are using OpenVZ for containers and you use NAT-based networking to communicate with the \ - host and guest, this will NOT work. Please change this to \"0.0.0.0\". If this is expected, \ - you can ignore.", + "You are detected using OpenVZ with a loopback/localhost listening \ + address of {addr}. If you are using OpenVZ for containers and you use \ + NAT-based networking to communicate with the host and guest, this will \ + NOT work. Please change this to \"0.0.0.0\". If this is expected, you \ + can ignore.", ); } else if Path::new("/.dockerenv").exists() { error!( - "You are detected using Docker with a loopback/localhost listening address of {addr}. If you \ - are using a reverse proxy on the host and require communication to conduwuit in the Docker \ - container via NAT-based networking, this will NOT work. Please change this to \"0.0.0.0\". \ - If this is expected, you can ignore.", + "You are detected using Docker with a loopback/localhost listening \ + address of {addr}. If you are using a reverse proxy on the host and \ + require communication to conduwuit in the Docker container via \ + NAT-based networking, this will NOT work. Please change this to \ + \"0.0.0.0\". If this is expected, you can ignore.", ); } else if Path::new("/run/.containerenv").exists() { error!( - "You are detected using Podman with a loopback/localhost listening address of {addr}. If you \ - are using a reverse proxy on the host and require communication to conduwuit in the Podman \ - container via NAT-based networking, this will NOT work. Please change this to \"0.0.0.0\". \ - If this is expected, you can ignore.", + "You are detected using Podman with a loopback/localhost listening \ + address of {addr}. If you are using a reverse proxy on the host and \ + require communication to conduwuit in the Podman container via \ + NAT-based networking, this will NOT work. Please change this to \ + \"0.0.0.0\". If this is expected, you can ignore.", ); } } @@ -93,7 +105,8 @@ pub fn check(config: &Config) -> Result<()> { if config.emergency_password == Some(String::from("F670$2CP@Hw8mG7RY1$%!#Ic7YA")) { return Err!(Config( "emergency_password", - "The public example emergency password is being used, this is insecure. Please change this." + "The public example emergency password is being used, this is insecure. Please \ + change this." )); } @@ -124,7 +137,8 @@ pub fn check(config: &Config) -> Result<()> { if config.max_request_size < 10_000_000 { return Err!(Config( "max_request_size", - "Max request size is less than 10MB. Please increase it as this is too low for operable federation." + "Max request size is less than 10MB. Please increase it as this is too low for \ + operable federation." )); } @@ -145,11 +159,12 @@ pub fn check(config: &Config) -> Result<()> { { return Err!(Config( "registration_token", - "!! You have `allow_registration` enabled without a token configured in your config which means you are \ - allowing ANYONE to register on your conduwuit instance without any 2nd-step (e.g. registration token). \ - If this is not the intended behaviour, please set a registration token. For security and safety reasons, \ - conduwuit will shut down. If you are extra sure this is the desired behaviour you want, please set the \ - following config option to true: + "!! You have `allow_registration` enabled without a token configured in your config \ + which means you are allowing ANYONE to register on your conduwuit instance without \ + any 2nd-step (e.g. registration token). If this is not the intended behaviour, \ + please set a registration token. For security and safety reasons, conduwuit will \ + shut down. If you are extra sure this is the desired behaviour you want, please \ + set the following config option to true: `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`" )); } @@ -161,17 +176,18 @@ pub fn check(config: &Config) -> Result<()> { { warn!( "Open registration is enabled via setting \ - `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` and `allow_registration` to \ - true without a registration token configured. You are expected to be aware of the risks now. If this is \ - not the desired behaviour, please set a registration token." + `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` and \ + `allow_registration` to true without a registration token configured. You are \ + expected to be aware of the risks now. If this is not the desired behaviour, \ + please set a registration token." ); } if config.allow_outgoing_presence && !config.allow_local_presence { return Err!(Config( "allow_local_presence", - "Outgoing presence requires allowing local presence. Please enable 'allow_local_presence' or disable \ - outgoing presence." + "Outgoing presence requires allowing local presence. Please enable \ + 'allow_local_presence' or disable outgoing presence." )); } @@ -180,9 +196,10 @@ pub fn check(config: &Config) -> Result<()> { .contains(&"*".to_owned()) { warn!( - "All URLs are allowed for URL previews via setting \"url_preview_domain_contains_allowlist\" to \"*\". \ - This opens up significant attack surface to your server. You are expected to be aware of the risks by \ - doing this." + "All URLs are allowed for URL previews via setting \ + \"url_preview_domain_contains_allowlist\" to \"*\". This opens up significant \ + attack surface to your server. You are expected to be aware of the risks by doing \ + this." ); } if config @@ -190,9 +207,10 @@ pub fn check(config: &Config) -> Result<()> { .contains(&"*".to_owned()) { warn!( - "All URLs are allowed for URL previews via setting \"url_preview_domain_explicit_allowlist\" to \"*\". \ - This opens up significant attack surface to your server. You are expected to be aware of the risks by \ - doing this." + "All URLs are allowed for URL previews via setting \ + \"url_preview_domain_explicit_allowlist\" to \"*\". This opens up significant \ + attack surface to your server. You are expected to be aware of the risks by doing \ + this." ); } if config @@ -200,9 +218,9 @@ pub fn check(config: &Config) -> Result<()> { .contains(&"*".to_owned()) { warn!( - "All URLs are allowed for URL previews via setting \"url_preview_url_contains_allowlist\" to \"*\". This \ - opens up significant attack surface to your server. You are expected to be aware of the risks by doing \ - this." + "All URLs are allowed for URL previews via setting \ + \"url_preview_url_contains_allowlist\" to \"*\". This opens up significant attack \ + surface to your server. You are expected to be aware of the risks by doing this." ); } @@ -260,7 +278,8 @@ pub(super) fn is_dual_listening(raw_config: &Figment) -> Result<()> { let contains_unix_socket = raw_config.contains("unix_socket_path"); if contains_address && contains_unix_socket { return Err!( - "TOML keys \"address\" and \"unix_socket_path\" were both defined. Please specify only one option." + "TOML keys \"address\" and \"unix_socket_path\" were both defined. Please specify \ + only one option." ); } diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index a34514de1..44b66f41d 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -18,8 +18,8 @@ pub use figment::{value::Value as FigmentValue, Figment}; use itertools::Itertools; use regex::RegexSet; use ruma::{ - api::client::discovery::discover_support::ContactRole, OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, - RoomVersionId, + api::client::discovery::discover_support::ContactRole, OwnedRoomOrAliasId, OwnedServerName, + OwnedUserId, RoomVersionId, }; use serde::{de::IgnoredAny, Deserialize}; use url::Url; @@ -181,7 +181,10 @@ pub struct Config { /// are scaled by your CPU core count. /// /// default: 1.0 - #[serde(default = "default_cache_capacity_modifier", alias = "conduit_cache_capacity_modifier")] + #[serde( + default = "default_cache_capacity_modifier", + alias = "conduit_cache_capacity_modifier" + )] pub cache_capacity_modifier: f64, /// default: varies by system @@ -1555,7 +1558,8 @@ pub struct Config { pub db_pool_queue_size: usize, #[serde(flatten)] - #[allow(clippy::zero_sized_map_values)] // this is a catchall, the map shouldn't be zero at runtime + #[allow(clippy::zero_sized_map_values)] + // this is a catchall, the map shouldn't be zero at runtime catchall: BTreeMap, } @@ -1676,15 +1680,15 @@ impl Config { fn get_bind_hosts(&self) -> Vec { match &self.address.addrs { - Left(addr) => vec![*addr], - Right(addrs) => addrs.clone(), + | Left(addr) => vec![*addr], + | Right(addrs) => addrs.clone(), } } fn get_bind_ports(&self) -> Vec { match &self.port.ports { - Left(port) => vec![*port], - Right(ports) => ports.clone(), + | Left(port) => vec![*port], + | Right(ports) => ports.clone(), } } @@ -1756,9 +1760,13 @@ impl fmt::Display for Config { line("Allow registration", &self.allow_registration.to_string()); line( "Registration token", - if self.registration_token.is_none() && self.registration_token_file.is_none() && self.allow_registration { + if self.registration_token.is_none() + && self.registration_token_file.is_none() + && self.allow_registration + { "not set (⚠️ open registration!)" - } else if self.registration_token.is_none() && self.registration_token_file.is_none() { + } else if self.registration_token.is_none() && self.registration_token_file.is_none() + { "not set" } else { "set" @@ -1811,7 +1819,8 @@ impl fmt::Display for Config { &self.allow_outgoing_read_receipts.to_string(), ); line( - "Block non-admin room invites (local and remote, admins can still send and receive invites)", + "Block non-admin room invites (local and remote, admins can still send and receive \ + invites)", &self.block_non_admin_invites.to_string(), ); line("Enable admin escape commands", &self.admin_escape_commands.to_string()); @@ -1859,13 +1868,10 @@ impl fmt::Display for Config { "Lockdown public room directory (only allow admins to publish)", &self.lockdown_public_room_directory.to_string(), ); - line( - "JWT secret", - match self.jwt_secret { - Some(_) => "set", - None => "not set", - }, - ); + line("JWT secret", match self.jwt_secret { + | Some(_) => "set", + | None => "not set", + }); line( "Trusted key servers", &self @@ -1979,7 +1985,8 @@ impl fmt::Display for Config { &lst.join(", ") }); line("Forbidden Remote Room Directory Server Names", { - let mut lst = Vec::with_capacity(self.forbidden_remote_room_directory_server_names.len()); + let mut lst = + Vec::with_capacity(self.forbidden_remote_room_directory_server_names.len()); for domain in &self.forbidden_remote_room_directory_server_names { lst.push(domain.host()); } @@ -2099,11 +2106,7 @@ fn default_address() -> ListeningAddr { } } -fn default_port() -> ListeningPort { - ListeningPort { - ports: Left(8008), - } -} +fn default_port() -> ListeningPort { ListeningPort { ports: Left(8008) } } fn default_unix_socket_perms() -> u32 { 660 } @@ -2115,19 +2118,33 @@ fn default_pdu_cache_capacity() -> u32 { parallelism_scaled_u32(10_000).saturati fn default_cache_capacity_modifier() -> f64 { 1.0 } -fn default_auth_chain_cache_capacity() -> u32 { parallelism_scaled_u32(10_000).saturating_add(100_000) } +fn default_auth_chain_cache_capacity() -> u32 { + parallelism_scaled_u32(10_000).saturating_add(100_000) +} -fn default_shorteventid_cache_capacity() -> u32 { parallelism_scaled_u32(50_000).saturating_add(100_000) } +fn default_shorteventid_cache_capacity() -> u32 { + parallelism_scaled_u32(50_000).saturating_add(100_000) +} -fn default_eventidshort_cache_capacity() -> u32 { parallelism_scaled_u32(25_000).saturating_add(100_000) } +fn default_eventidshort_cache_capacity() -> u32 { + parallelism_scaled_u32(25_000).saturating_add(100_000) +} -fn default_eventid_pdu_cache_capacity() -> u32 { parallelism_scaled_u32(25_000).saturating_add(100_000) } +fn default_eventid_pdu_cache_capacity() -> u32 { + parallelism_scaled_u32(25_000).saturating_add(100_000) +} -fn default_shortstatekey_cache_capacity() -> u32 { parallelism_scaled_u32(10_000).saturating_add(100_000) } +fn default_shortstatekey_cache_capacity() -> u32 { + parallelism_scaled_u32(10_000).saturating_add(100_000) +} -fn default_statekeyshort_cache_capacity() -> u32 { parallelism_scaled_u32(10_000).saturating_add(100_000) } +fn default_statekeyshort_cache_capacity() -> u32 { + parallelism_scaled_u32(10_000).saturating_add(100_000) +} -fn default_servernameevent_data_cache_capacity() -> u32 { parallelism_scaled_u32(100_000).saturating_add(500_000) } +fn default_servernameevent_data_cache_capacity() -> u32 { + parallelism_scaled_u32(100_000).saturating_add(500_000) +} fn default_server_visibility_cache_capacity() -> u32 { parallelism_scaled_u32(500) } @@ -2203,7 +2220,9 @@ fn default_jaeger_filter() -> String { fn default_tracing_flame_output_path() -> String { "./tracing.folded".to_owned() } -fn default_trusted_servers() -> Vec { vec![OwnedServerName::try_from("matrix.org").unwrap()] } +fn default_trusted_servers() -> Vec { + vec![OwnedServerName::try_from("matrix.org").unwrap()] +} /// do debug logging by default for debug builds #[must_use] @@ -2332,4 +2351,6 @@ fn default_trusted_server_batch_size() -> usize { 256 } fn default_db_pool_workers() -> usize { sys::available_parallelism().saturating_mul(4).max(32) } -fn default_db_pool_queue_size() -> usize { sys::available_parallelism().saturating_mul(8).max(256) } +fn default_db_pool_queue_size() -> usize { + sys::available_parallelism().saturating_mul(8).max(256) +} diff --git a/src/core/config/proxy.rs b/src/core/config/proxy.rs index 48f883c6a..ea388f24c 100644 --- a/src/core/config/proxy.rs +++ b/src/core/config/proxy.rs @@ -42,11 +42,9 @@ pub enum ProxyConfig { impl ProxyConfig { pub fn to_proxy(&self) -> Result> { Ok(match self.clone() { - Self::None => None, - Self::Global { - url, - } => Some(Proxy::all(url)?), - Self::ByDomain(proxies) => Some(Proxy::custom(move |url| { + | Self::None => None, + | Self::Global { url } => Some(Proxy::all(url)?), + | Self::ByDomain(proxies) => Some(Proxy::custom(move |url| { // first matching proxy proxies.iter().find_map(|proxy| proxy.for_url(url)).cloned() })), @@ -76,24 +74,26 @@ impl PartialProxyConfig { for wc_domain in &self.include { if wc_domain.matches(domain) { match included_because { - Some(prev) if !wc_domain.more_specific_than(prev) => (), - _ => included_because = Some(wc_domain), + | Some(prev) if !wc_domain.more_specific_than(prev) => (), + | _ => included_because = Some(wc_domain), } } } for wc_domain in &self.exclude { if wc_domain.matches(domain) { match excluded_because { - Some(prev) if !wc_domain.more_specific_than(prev) => (), - _ => excluded_because = Some(wc_domain), + | Some(prev) if !wc_domain.more_specific_than(prev) => (), + | _ => excluded_because = Some(wc_domain), } } } match (included_because, excluded_because) { - (Some(a), Some(b)) if a.more_specific_than(b) => Some(&self.url), /* included for a more specific reason */ + | (Some(a), Some(b)) if a.more_specific_than(b) => Some(&self.url), /* included for + * a more specific + * reason */ // than excluded - (Some(_), None) => Some(&self.url), - _ => None, + | (Some(_), None) => Some(&self.url), + | _ => None, } } } @@ -108,19 +108,19 @@ enum WildCardedDomain { impl WildCardedDomain { fn matches(&self, domain: &str) -> bool { match self { - Self::WildCard => true, - Self::WildCarded(d) => domain.ends_with(d), - Self::Exact(d) => domain == d, + | Self::WildCard => true, + | Self::WildCarded(d) => domain.ends_with(d), + | Self::Exact(d) => domain == d, } } fn more_specific_than(&self, other: &Self) -> bool { match (self, other) { - (Self::WildCard, Self::WildCard) => false, - (_, Self::WildCard) => true, - (Self::Exact(a), Self::WildCarded(_)) => other.matches(a), - (Self::WildCarded(a), Self::WildCarded(b)) => a != b && a.ends_with(b), - _ => false, + | (Self::WildCard, Self::WildCard) => false, + | (_, Self::WildCard) => true, + | (Self::Exact(a), Self::WildCarded(_)) => other.matches(a), + | (Self::WildCarded(a), Self::WildCarded(b)) => a != b && a.ends_with(b), + | _ => false, } } } diff --git a/src/core/debug.rs b/src/core/debug.rs index e19802341..123cf8203 100644 --- a/src/core/debug.rs +++ b/src/core/debug.rs @@ -84,7 +84,9 @@ pub fn trap() { } #[must_use] -pub fn panic_str(p: &Box) -> &'static str { p.downcast_ref::<&str>().copied().unwrap_or_default() } +pub fn panic_str(p: &Box) -> &'static str { + p.downcast_ref::<&str>().copied().unwrap_or_default() +} #[inline(always)] #[must_use] @@ -96,4 +98,6 @@ pub fn type_name() -> &'static str { std::any::type_name::() } #[must_use] #[inline] -pub const fn logging() -> bool { cfg!(debug_assertions) && cfg!(not(feature = "dev_release_log_level")) } +pub const fn logging() -> bool { + cfg!(debug_assertions) && cfg!(not(feature = "dev_release_log_level")) +} diff --git a/src/core/error/err.rs b/src/core/error/err.rs index a24441e00..60fa5bffa 100644 --- a/src/core/error/err.rs +++ b/src/core/error/err.rs @@ -184,7 +184,12 @@ impl Visit for Visitor<'_> { } } -pub fn visit(out: &mut String, level: Level, __callsite: &'static DefaultCallsite, vs: &mut ValueSet<'_>) { +pub fn visit( + out: &mut String, + level: Level, + __callsite: &'static DefaultCallsite, + vs: &mut ValueSet<'_>, +) { let meta = __callsite.metadata(); let enabled = level_enabled!(level) && { let interest = __callsite.interest(); diff --git a/src/core/error/log.rs b/src/core/error/log.rs index 60bd70140..18c3a680a 100644 --- a/src/core/error/log.rs +++ b/src/core/error/log.rs @@ -68,18 +68,20 @@ where pub fn inspect_log(error: &E) { inspect_log_level(error, Level::ERROR); } #[inline] -pub fn inspect_debug_log(error: &E) { inspect_debug_log_level(error, Level::ERROR); } +pub fn inspect_debug_log(error: &E) { + inspect_debug_log_level(error, Level::ERROR); +} #[inline] pub fn inspect_log_level(error: &E, level: Level) { use crate::{debug, error, info, trace, warn}; match level { - Level::ERROR => error!("{error}"), - Level::WARN => warn!("{error}"), - Level::INFO => info!("{error}"), - Level::DEBUG => debug!("{error}"), - Level::TRACE => trace!("{error}"), + | Level::ERROR => error!("{error}"), + | Level::WARN => warn!("{error}"), + | Level::INFO => info!("{error}"), + | Level::DEBUG => debug!("{error}"), + | Level::TRACE => trace!("{error}"), } } @@ -88,10 +90,10 @@ pub fn inspect_debug_log_level(error: &E, level: Level) { use crate::{debug, debug_error, debug_info, debug_warn, trace}; match level { - Level::ERROR => debug_error!("{error:?}"), - Level::WARN => debug_warn!("{error:?}"), - Level::INFO => debug_info!("{error:?}"), - Level::DEBUG => debug!("{error:?}"), - Level::TRACE => trace!("{error:?}"), + | Level::ERROR => debug_error!("{error:?}"), + | Level::WARN => debug_warn!("{error:?}"), + | Level::INFO => debug_info!("{error:?}"), + | Level::DEBUG => debug!("{error:?}"), + | Level::TRACE => trace!("{error:?}"), } } diff --git a/src/core/error/mod.rs b/src/core/error/mod.rs index b84f1b466..12ba07972 100644 --- a/src/core/error/mod.rs +++ b/src/core/error/mod.rs @@ -128,23 +128,25 @@ pub enum Error { impl Error { //#[deprecated] - pub fn bad_database(message: &'static str) -> Self { crate::err!(Database(error!("{message}"))) } + pub fn bad_database(message: &'static str) -> Self { + crate::err!(Database(error!("{message}"))) + } /// Sanitizes public-facing errors that can leak sensitive information. pub fn sanitized_message(&self) -> String { match self { - Self::Database(..) => String::from("Database error occurred."), - Self::Io(..) => String::from("I/O error occurred."), - _ => self.message(), + | Self::Database(..) => String::from("Database error occurred."), + | Self::Io(..) => String::from("I/O error occurred."), + | _ => self.message(), } } /// Generate the error message string. pub fn message(&self) -> String { match self { - Self::Federation(ref origin, ref error) => format!("Answer from {origin}: {error}"), - Self::Ruma(ref error) => response::ruma_error_message(error), - _ => format!("{self}"), + | Self::Federation(ref origin, ref error) => format!("Answer from {origin}: {error}"), + | Self::Ruma(ref error) => response::ruma_error_message(error), + | _ => format!("{self}"), } } @@ -154,9 +156,10 @@ impl Error { use ruma::api::client::error::ErrorKind::Unknown; match self { - Self::Federation(_, error) | Self::Ruma(error) => response::ruma_error_kind(error).clone(), - Self::BadRequest(kind, ..) | Self::Request(kind, ..) => kind.clone(), - _ => Unknown, + | Self::Federation(_, error) | Self::Ruma(error) => + response::ruma_error_kind(error).clone(), + | Self::BadRequest(kind, ..) | Self::Request(kind, ..) => kind.clone(), + | _ => Unknown, } } @@ -166,12 +169,12 @@ impl Error { use http::StatusCode; match self { - Self::Federation(_, error) | Self::Ruma(error) => error.status_code, - Self::Request(kind, _, code) => response::status_code(kind, *code), - Self::BadRequest(kind, ..) => response::bad_request_code(kind), - Self::Reqwest(error) => error.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), - Self::Conflict(_) => StatusCode::CONFLICT, - _ => StatusCode::INTERNAL_SERVER_ERROR, + | Self::Federation(_, error) | Self::Ruma(error) => error.status_code, + | Self::Request(kind, _, code) => response::status_code(kind, *code), + | Self::BadRequest(kind, ..) => response::bad_request_code(kind), + | Self::Reqwest(error) => error.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), + | Self::Conflict(_) => StatusCode::CONFLICT, + | _ => StatusCode::INTERNAL_SERVER_ERROR, } } diff --git a/src/core/error/panic.rs b/src/core/error/panic.rs index bec25132d..c6a83ae05 100644 --- a/src/core/error/panic.rs +++ b/src/core/error/panic.rs @@ -20,9 +20,9 @@ impl Error { #[inline] pub fn into_panic(self) -> Box { match self { - Self::Panic(_, e) | Self::PanicAny(e) => e, - Self::JoinError(e) => e.into_panic(), - _ => Box::new(self), + | Self::Panic(_, e) | Self::PanicAny(e) => e, + | Self::JoinError(e) => e.into_panic(), + | _ => Box::new(self), } } @@ -37,9 +37,9 @@ impl Error { #[inline] pub fn is_panic(&self) -> bool { match &self { - Self::Panic(..) | Self::PanicAny(..) => true, - Self::JoinError(e) => e.is_panic(), - _ => false, + | Self::Panic(..) | Self::PanicAny(..) => true, + | Self::JoinError(e) => e.is_panic(), + | _ => false, } } } diff --git a/src/core/error/response.rs b/src/core/error/response.rs index 21fbdcf22..568238c37 100644 --- a/src/core/error/response.rs +++ b/src/core/error/response.rs @@ -57,49 +57,35 @@ pub(super) fn bad_request_code(kind: &ErrorKind) -> StatusCode { match kind { // 429 - LimitExceeded { - .. - } => StatusCode::TOO_MANY_REQUESTS, + | LimitExceeded { .. } => StatusCode::TOO_MANY_REQUESTS, // 413 - TooLarge => StatusCode::PAYLOAD_TOO_LARGE, + | TooLarge => StatusCode::PAYLOAD_TOO_LARGE, // 405 - Unrecognized => StatusCode::METHOD_NOT_ALLOWED, + | Unrecognized => StatusCode::METHOD_NOT_ALLOWED, // 404 - NotFound => StatusCode::NOT_FOUND, + | NotFound => StatusCode::NOT_FOUND, // 403 - GuestAccessForbidden + | GuestAccessForbidden | ThreepidAuthFailed | UserDeactivated | ThreepidDenied - | WrongRoomKeysVersion { - .. - } - | Forbidden { - .. - } => StatusCode::FORBIDDEN, + | WrongRoomKeysVersion { .. } + | Forbidden { .. } => StatusCode::FORBIDDEN, // 401 - UnknownToken { - .. - } - | MissingToken - | Unauthorized => StatusCode::UNAUTHORIZED, + | UnknownToken { .. } | MissingToken | Unauthorized => StatusCode::UNAUTHORIZED, // 400 - _ => StatusCode::BAD_REQUEST, + | _ => StatusCode::BAD_REQUEST, } } pub(super) fn ruma_error_message(error: &ruma::api::client::error::Error) -> String { - if let ErrorBody::Standard { - message, - .. - } = &error.body - { + if let ErrorBody::Standard { message, .. } = &error.body { return message.to_string(); } diff --git a/src/core/info/cargo.rs b/src/core/info/cargo.rs index 735ccee60..c5a1d1674 100644 --- a/src/core/info/cargo.rs +++ b/src/core/info/cargo.rs @@ -41,17 +41,22 @@ static FEATURES: OnceLock> = OnceLock::new(); static DEPENDENCIES: OnceLock = OnceLock::new(); #[must_use] -pub fn dependencies_names() -> Vec<&'static str> { dependencies().keys().map(String::as_str).collect() } +pub fn dependencies_names() -> Vec<&'static str> { + dependencies().keys().map(String::as_str).collect() +} pub fn dependencies() -> &'static DepsSet { - DEPENDENCIES - .get_or_init(|| init_dependencies().unwrap_or_else(|e| panic!("Failed to initialize dependencies: {e}"))) + DEPENDENCIES.get_or_init(|| { + init_dependencies().unwrap_or_else(|e| panic!("Failed to initialize dependencies: {e}")) + }) } /// List of all possible features for the project. For *enabled* features in /// this build see the companion function in info::rustc. pub fn features() -> &'static Vec { - FEATURES.get_or_init(|| init_features().unwrap_or_else(|e| panic!("Failed initialize features: {e}"))) + FEATURES.get_or_init(|| { + init_features().unwrap_or_else(|e| panic!("Failed initialize features: {e}")) + }) } fn init_features() -> Result> { diff --git a/src/core/info/room_version.rs b/src/core/info/room_version.rs index 59685b5f9..40f0cf0a4 100644 --- a/src/core/info/room_version.rs +++ b/src/core/info/room_version.rs @@ -34,7 +34,9 @@ impl crate::Server { } #[inline] - pub fn available_room_versions(&self) -> impl Iterator { + pub fn available_room_versions( + &self, + ) -> impl Iterator { available_room_versions() } diff --git a/src/core/log/capture/layer.rs b/src/core/log/capture/layer.rs index 674bc3790..241b384de 100644 --- a/src/core/log/capture/layer.rs +++ b/src/core/log/capture/layer.rs @@ -22,11 +22,7 @@ type ScopeNames = ArrayVec<&'static str, 32>; impl Layer { #[inline] - pub fn new(state: &Arc) -> Self { - Self { - state: state.clone(), - } - } + pub fn new(state: &Arc) -> Self { Self { state: state.clone() } } } impl fmt::Debug for Layer { @@ -56,9 +52,7 @@ where S: Subscriber + for<'a> LookupSpan<'a>, { let names = ScopeNames::new(); - let mut visitor = Visitor { - values: Values::new(), - }; + let mut visitor = Visitor { values: Values::new() }; event.record(&mut visitor); let mut closure = capture.closure.lock().expect("exclusive lock"); @@ -95,7 +89,9 @@ where } impl Visit for Visitor { - fn record_debug(&mut self, f: &Field, v: &dyn fmt::Debug) { self.values.push((f.name(), format!("{v:?}"))); } + fn record_debug(&mut self, f: &Field, v: &dyn fmt::Debug) { + self.values.push((f.name(), format!("{v:?}"))); + } fn record_str(&mut self, f: &Field, v: &str) { self.values.push((f.name(), v.to_owned())); } } diff --git a/src/core/log/capture/mod.rs b/src/core/log/capture/mod.rs index c0fcd31ef..20f700913 100644 --- a/src/core/log/capture/mod.rs +++ b/src/core/log/capture/mod.rs @@ -41,9 +41,7 @@ impl Capture { #[must_use] pub fn start(self: &Arc) -> Guard { self.state.add(self); - Guard { - capture: self.clone(), - } + Guard { capture: self.clone() } } pub fn stop(self: &Arc) { self.state.del(self); } diff --git a/src/core/log/capture/state.rs b/src/core/log/capture/state.rs index f2c401cd9..dad6c8d85 100644 --- a/src/core/log/capture/state.rs +++ b/src/core/log/capture/state.rs @@ -13,11 +13,7 @@ impl Default for State { impl State { #[must_use] - pub fn new() -> Self { - Self { - active: RwLock::new(Vec::new()), - } - } + pub fn new() -> Self { Self { active: RwLock::new(Vec::new()) } } pub(super) fn add(&self, capture: &Arc) { self.active diff --git a/src/core/log/color.rs b/src/core/log/color.rs index 9baa99c27..23905d143 100644 --- a/src/core/log/color.rs +++ b/src/core/log/color.rs @@ -5,11 +5,11 @@ use super::Level; #[must_use] pub fn html(level: &Level) -> (&'static str, &'static str) { match *level { - Level::TRACE => ("#000000", "#A0A0A0"), - Level::DEBUG => ("#000000", "#FFFFFF"), - Level::ERROR => ("#000000", "#FF0000"), - Level::WARN => ("#000000", "#FFFF00"), - Level::INFO => ("#FFFFFF", "#008E00"), + | Level::TRACE => ("#000000", "#A0A0A0"), + | Level::DEBUG => ("#000000", "#FFFFFF"), + | Level::ERROR => ("#000000", "#FF0000"), + | Level::WARN => ("#000000", "#FFFF00"), + | Level::INFO => ("#FFFFFF", "#008E00"), } } @@ -18,10 +18,10 @@ pub fn html(level: &Level) -> (&'static str, &'static str) { #[must_use] pub fn code_tag(level: &Level) -> &'static str { match *level { - Level::TRACE => "#888888", - Level::DEBUG => "#C8C8C8", - Level::ERROR => "#FF0000", - Level::WARN => "#FFFF00", - Level::INFO => "#00FF00", + | Level::TRACE => "#888888", + | Level::DEBUG => "#C8C8C8", + | Level::ERROR => "#FF0000", + | Level::WARN => "#FFFF00", + | Level::INFO => "#00FF00", } } diff --git a/src/core/log/fmt.rs b/src/core/log/fmt.rs index 8766eb8d5..353d44426 100644 --- a/src/core/log/fmt.rs +++ b/src/core/log/fmt.rs @@ -11,7 +11,8 @@ where let level = level.as_str().to_uppercase(); write!( out, - "{level:>5} {span:^12} {msg}
" + "{level:>5} {span:^12} \ + {msg}
" )?; Ok(()) diff --git a/src/core/log/fmt_span.rs b/src/core/log/fmt_span.rs index 5a340d0fa..7ba86c4c7 100644 --- a/src/core/log/fmt_span.rs +++ b/src/core/log/fmt_span.rs @@ -5,13 +5,13 @@ use crate::Result; #[inline] pub fn from_str(str: &str) -> Result { match str.to_uppercase().as_str() { - "ENTER" => Ok(FmtSpan::ENTER), - "EXIT" => Ok(FmtSpan::EXIT), - "NEW" => Ok(FmtSpan::NEW), - "CLOSE" => Ok(FmtSpan::CLOSE), - "ACTIVE" => Ok(FmtSpan::ACTIVE), - "FULL" => Ok(FmtSpan::FULL), - "NONE" => Ok(FmtSpan::NONE), - _ => Err(FmtSpan::NONE), + | "ENTER" => Ok(FmtSpan::ENTER), + | "EXIT" => Ok(FmtSpan::EXIT), + | "NEW" => Ok(FmtSpan::NEW), + | "CLOSE" => Ok(FmtSpan::CLOSE), + | "ACTIVE" => Ok(FmtSpan::ACTIVE), + | "FULL" => Ok(FmtSpan::FULL), + | "NONE" => Ok(FmtSpan::NONE), + | _ => Err(FmtSpan::NONE), } } diff --git a/src/core/log/suppress.rs b/src/core/log/suppress.rs index b13ee99ef..55428d15e 100644 --- a/src/core/log/suppress.rs +++ b/src/core/log/suppress.rs @@ -25,10 +25,7 @@ impl Suppress { .reload(&suppress, Some(&[handle])) .expect("log filter reloaded"); - Self { - server: server.clone(), - restore, - } + Self { server: server.clone(), restore } } } diff --git a/src/core/metrics/mod.rs b/src/core/metrics/mod.rs index 3ae139a86..d5f937d7e 100644 --- a/src/core/metrics/mod.rs +++ b/src/core/metrics/mod.rs @@ -68,5 +68,7 @@ impl Metrics { pub fn task_root(&self) -> Option<&TaskMonitor> { self.task_monitor.as_ref() } - pub fn runtime_metrics(&self) -> Option<&runtime::RuntimeMetrics> { self.runtime_metrics.as_ref() } + pub fn runtime_metrics(&self) -> Option<&runtime::RuntimeMetrics> { + self.runtime_metrics.as_ref() + } } diff --git a/src/core/pdu/builder.rs b/src/core/pdu/builder.rs index 80ff07130..db3bb20a3 100644 --- a/src/core/pdu/builder.rs +++ b/src/core/pdu/builder.rs @@ -35,7 +35,8 @@ impl Builder { { Self { event_type: content.event_type().into(), - content: to_raw_value(content).expect("Builder failed to serialize state event content to RawValue"), + content: to_raw_value(content) + .expect("Builder failed to serialize state event content to RawValue"), state_key: Some(state_key), ..Self::default() } @@ -47,7 +48,8 @@ impl Builder { { Self { event_type: content.event_type().into(), - content: to_raw_value(content).expect("Builder failed to serialize timeline event content to RawValue"), + content: to_raw_value(content) + .expect("Builder failed to serialize timeline event content to RawValue"), ..Self::default() } } diff --git a/src/core/pdu/count.rs b/src/core/pdu/count.rs index 852223825..0135cf283 100644 --- a/src/core/pdu/count.rs +++ b/src/core/pdu/count.rs @@ -21,8 +21,8 @@ impl Count { #[must_use] pub fn from_signed(signed: i64) -> Self { match signed { - i64::MIN..=0 => Self::Backfilled(signed), - _ => Self::Normal(signed as u64), + | i64::MIN..=0 => Self::Backfilled(signed), + | _ => Self::Normal(signed as u64), } } @@ -31,8 +31,8 @@ impl Count { pub fn into_unsigned(self) -> u64 { self.debug_assert_valid(); match self { - Self::Normal(i) => i, - Self::Backfilled(i) => i as u64, + | Self::Normal(i) => i, + | Self::Backfilled(i) => i as u64, } } @@ -41,8 +41,8 @@ impl Count { pub fn into_signed(self) -> i64 { self.debug_assert_valid(); match self { - Self::Normal(i) => i as i64, - Self::Backfilled(i) => i, + | Self::Normal(i) => i as i64, + | Self::Backfilled(i) => i, } } @@ -51,27 +51,27 @@ impl Count { pub fn into_normal(self) -> Self { self.debug_assert_valid(); match self { - Self::Normal(i) => Self::Normal(i), - Self::Backfilled(_) => Self::Normal(0), + | Self::Normal(i) => Self::Normal(i), + | Self::Backfilled(_) => Self::Normal(0), } } #[inline] pub fn checked_inc(self, dir: Direction) -> Result { match dir { - Direction::Forward => self.checked_add(1), - Direction::Backward => self.checked_sub(1), + | Direction::Forward => self.checked_add(1), + | Direction::Backward => self.checked_sub(1), } } #[inline] pub fn checked_add(self, add: u64) -> Result { Ok(match self { - Self::Normal(i) => Self::Normal( + | Self::Normal(i) => Self::Normal( i.checked_add(add) .ok_or_else(|| err!(Arithmetic("Count::Normal overflow")))?, ), - Self::Backfilled(i) => Self::Backfilled( + | Self::Backfilled(i) => Self::Backfilled( i.checked_add(add as i64) .ok_or_else(|| err!(Arithmetic("Count::Backfilled overflow")))?, ), @@ -81,11 +81,11 @@ impl Count { #[inline] pub fn checked_sub(self, sub: u64) -> Result { Ok(match self { - Self::Normal(i) => Self::Normal( + | Self::Normal(i) => Self::Normal( i.checked_sub(sub) .ok_or_else(|| err!(Arithmetic("Count::Normal underflow")))?, ), - Self::Backfilled(i) => Self::Backfilled( + | Self::Backfilled(i) => Self::Backfilled( i.checked_sub(sub as i64) .ok_or_else(|| err!(Arithmetic("Count::Backfilled underflow")))?, ), @@ -96,8 +96,8 @@ impl Count { #[must_use] pub fn saturating_inc(self, dir: Direction) -> Self { match dir { - Direction::Forward => self.saturating_add(1), - Direction::Backward => self.saturating_sub(1), + | Direction::Forward => self.saturating_add(1), + | Direction::Backward => self.saturating_sub(1), } } @@ -105,8 +105,8 @@ impl Count { #[must_use] pub fn saturating_add(self, add: u64) -> Self { match self { - Self::Normal(i) => Self::Normal(i.saturating_add(add)), - Self::Backfilled(i) => Self::Backfilled(i.saturating_add(add as i64)), + | Self::Normal(i) => Self::Normal(i.saturating_add(add)), + | Self::Backfilled(i) => Self::Backfilled(i.saturating_add(add as i64)), } } @@ -114,8 +114,8 @@ impl Count { #[must_use] pub fn saturating_sub(self, sub: u64) -> Self { match self { - Self::Normal(i) => Self::Normal(i.saturating_sub(sub)), - Self::Backfilled(i) => Self::Backfilled(i.saturating_sub(sub as i64)), + | Self::Normal(i) => Self::Normal(i.saturating_sub(sub)), + | Self::Backfilled(i) => Self::Backfilled(i.saturating_sub(sub as i64)), } } @@ -139,8 +139,8 @@ impl Display for Count { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { self.debug_assert_valid(); match self { - Self::Normal(i) => write!(f, "{i}"), - Self::Backfilled(i) => write!(f, "{i}"), + | Self::Normal(i) => write!(f, "{i}"), + | Self::Backfilled(i) => write!(f, "{i}"), } } } diff --git a/src/core/pdu/event.rs b/src/core/pdu/event.rs index 96a1e4ba3..fb98d6860 100644 --- a/src/core/pdu/event.rs +++ b/src/core/pdu/event.rs @@ -19,13 +19,19 @@ impl Event for Pdu { fn content(&self) -> &RawJsonValue { &self.content } - fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch { MilliSecondsSinceUnixEpoch(self.origin_server_ts) } + 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 prev_events(&self) -> impl DoubleEndedIterator + Send + '_ { + self.prev_events.iter() + } - fn auth_events(&self) -> impl DoubleEndedIterator + Send + '_ { self.auth_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/pdu/event_id.rs b/src/core/pdu/event_id.rs index ae5b85f9a..09b33edcf 100644 --- a/src/core/pdu/event_id.rs +++ b/src/core/pdu/event_id.rs @@ -8,7 +8,8 @@ use crate::{err, Result}; /// Returns a tuple of the new `EventId` and the PDU as a `BTreeMap`. pub fn gen_event_id_canonical_json( - pdu: &RawJsonValue, room_version_id: &RoomVersionId, + pdu: &RawJsonValue, + room_version_id: &RoomVersionId, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()) .map_err(|e| err!(BadServerResponse(warn!("Error parsing incoming event: {e:?}"))))?; @@ -19,7 +20,10 @@ pub fn gen_event_id_canonical_json( } /// Generates a correct eventId for the incoming pdu. -pub fn gen_event_id(value: &CanonicalJsonObject, room_version_id: &RoomVersionId) -> Result { +pub fn gen_event_id( + value: &CanonicalJsonObject, + room_version_id: &RoomVersionId, +) -> Result { let reference_hash = ruma::signatures::reference_hash(value, room_version_id)?; let event_id: OwnedEventId = format!("${reference_hash}").try_into()?; diff --git a/src/core/pdu/filter.rs b/src/core/pdu/filter.rs index c7c7316d1..aabf13db7 100644 --- a/src/core/pdu/filter.rs +++ b/src/core/pdu/filter.rs @@ -84,7 +84,7 @@ fn matches_url(&self, filter: &RoomEventFilter) -> bool { .is_some_and(Value::is_string); match url_filter { - UrlFilter::EventsWithUrl => url, - UrlFilter::EventsWithoutUrl => !url, + | UrlFilter::EventsWithUrl => url, + | UrlFilter::EventsWithoutUrl => !url, } } diff --git a/src/core/pdu/mod.rs b/src/core/pdu/mod.rs index 2aa60ed1e..c90e174ef 100644 --- a/src/core/pdu/mod.rs +++ b/src/core/pdu/mod.rs @@ -15,7 +15,8 @@ mod unsigned; use std::{cmp::Ordering, sync::Arc}; use ruma::{ - events::TimelineEventType, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedRoomId, OwnedUserId, UInt, + events::TimelineEventType, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedRoomId, + OwnedUserId, UInt, }; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue as RawJsonValue; diff --git a/src/core/pdu/raw_id.rs b/src/core/pdu/raw_id.rs index ef8502f68..e1fd2381e 100644 --- a/src/core/pdu/raw_id.rs +++ b/src/core/pdu/raw_id.rs @@ -29,10 +29,10 @@ impl RawId { #[must_use] pub fn shortroomid(self) -> [u8; INT_LEN] { match self { - Self::Normal(raw) => raw[0..INT_LEN] + | Self::Normal(raw) => raw[0..INT_LEN] .try_into() .expect("normal raw shortroomid array from slice"), - Self::Backfilled(raw) => raw[0..INT_LEN] + | Self::Backfilled(raw) => raw[0..INT_LEN] .try_into() .expect("backfilled raw shortroomid array from slice"), } @@ -42,10 +42,10 @@ impl RawId { #[must_use] pub fn shorteventid(self) -> [u8; INT_LEN] { match self { - Self::Normal(raw) => raw[INT_LEN..INT_LEN * 2] + | Self::Normal(raw) => raw[INT_LEN..INT_LEN * 2] .try_into() .expect("normal raw shorteventid array from slice"), - Self::Backfilled(raw) => raw[INT_LEN * 2..INT_LEN * 3] + | Self::Backfilled(raw) => raw[INT_LEN * 2..INT_LEN * 3] .try_into() .expect("backfilled raw shorteventid array from slice"), } @@ -55,8 +55,8 @@ impl RawId { #[must_use] pub fn as_bytes(&self) -> &[u8] { match self { - Self::Normal(ref raw) => raw, - Self::Backfilled(ref raw) => raw, + | Self::Normal(ref raw) => raw, + | Self::Backfilled(ref raw) => raw, } } } @@ -70,17 +70,17 @@ impl From<&[u8]> for RawId { #[inline] fn from(id: &[u8]) -> Self { match id.len() { - Self::NORMAL_LEN => Self::Normal( + | Self::NORMAL_LEN => Self::Normal( id[0..Self::NORMAL_LEN] .try_into() .expect("normal RawId from [u8]"), ), - Self::BACKFILLED_LEN => Self::Backfilled( + | Self::BACKFILLED_LEN => Self::Backfilled( id[0..Self::BACKFILLED_LEN] .try_into() .expect("backfilled RawId from [u8]"), ), - _ => unimplemented!("unrecognized RawId length"), + | _ => unimplemented!("unrecognized RawId length"), } } } @@ -95,11 +95,11 @@ impl From for RawId { vec.extend(id.shortroomid.to_be_bytes()); id.shorteventid.debug_assert_valid(); match id.shorteventid { - Count::Normal(shorteventid) => { + | Count::Normal(shorteventid) => { vec.extend(shorteventid.to_be_bytes()); Self::Normal(vec.as_ref().try_into().expect("RawVec into RawId::Normal")) }, - Count::Backfilled(shorteventid) => { + | Count::Backfilled(shorteventid) => { vec.extend(0_u64.to_be_bytes()); vec.extend(shorteventid.to_be_bytes()); Self::Backfilled( diff --git a/src/core/pdu/redact.rs b/src/core/pdu/redact.rs index 01d9147cc..dc97bfa82 100644 --- a/src/core/pdu/redact.rs +++ b/src/core/pdu/redact.rs @@ -22,8 +22,8 @@ struct ExtractRedactedBecause { pub fn redact(&mut self, room_version_id: &RoomVersionId, reason: &Self) -> Result { self.unsigned = None; - let mut content = - serde_json::from_str(self.content.get()).map_err(|_| Error::bad_database("PDU in db has invalid content."))?; + let mut content = serde_json::from_str(self.content.get()) + .map_err(|_| Error::bad_database("PDU in db has invalid content."))?; redact_content_in_place(&mut content, room_version_id, self.kind.to_string()) .map_err(|e| Error::Redaction(self.sender.server_name().to_owned(), e))?; @@ -75,7 +75,9 @@ pub fn is_redacted(&self) -> bool { #[must_use] pub fn copy_redacts(&self) -> (Option>, Box) { if self.kind == TimelineEventType::RoomRedaction { - if let Ok(mut content) = serde_json::from_str::(self.content.get()) { + if let Ok(mut content) = + serde_json::from_str::(self.content.get()) + { if let Some(redacts) = content.redacts { return (Some(redacts.into()), self.content.clone()); } else if let Some(redacts) = self.redacts.clone() { diff --git a/src/core/pdu/strip.rs b/src/core/pdu/strip.rs index 594577494..8e1045db7 100644 --- a/src/core/pdu/strip.rs +++ b/src/core/pdu/strip.rs @@ -1,8 +1,8 @@ use ruma::{ events::{ - room::member::RoomMemberEventContent, space::child::HierarchySpaceChildEvent, AnyEphemeralRoomEvent, - AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent, - AnyTimelineEvent, StateEvent, + room::member::RoomMemberEventContent, space::child::HierarchySpaceChildEvent, + AnyEphemeralRoomEvent, AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent, + AnySyncStateEvent, AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, }, serde::Raw, }; diff --git a/src/core/pdu/unsigned.rs b/src/core/pdu/unsigned.rs index 6f3e44016..fa305d711 100644 --- a/src/core/pdu/unsigned.rs +++ b/src/core/pdu/unsigned.rs @@ -13,8 +13,8 @@ pub fn remove_transaction_id(&mut self) -> Result { return Ok(()); }; - let mut unsigned: BTreeMap> = - serde_json::from_str(unsigned.get()).map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?; + let mut unsigned: BTreeMap> = serde_json::from_str(unsigned.get()) + .map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?; unsigned.remove("transaction_id"); self.unsigned = to_raw_value(&unsigned) @@ -97,7 +97,9 @@ where #[implement(Pdu)] #[must_use] -pub fn get_unsigned_as_value(&self) -> JsonValue { self.get_unsigned::().unwrap_or_default() } +pub fn get_unsigned_as_value(&self) -> JsonValue { + self.get_unsigned::().unwrap_or_default() +} #[implement(Pdu)] pub fn get_unsigned(&self) -> Result { diff --git a/src/core/server.rs b/src/core/server.rs index 1e7215176..2a70ae4be 100644 --- a/src/core/server.rs +++ b/src/core/server.rs @@ -79,8 +79,9 @@ impl Server { return Err!("Restart already in progress"); } - self.shutdown() - .inspect_err(|_| self.restarting.store(false, Ordering::Release)) + self.shutdown().inspect_err(|_| { + self.restarting.store(false, Ordering::Release); + }) } pub fn shutdown(&self) -> Result<()> { @@ -88,8 +89,9 @@ impl Server { return Err!("Shutdown already in progress"); } - self.signal("SIGTERM") - .inspect_err(|_| self.stopping.store(false, Ordering::Release)) + self.signal("SIGTERM").inspect_err(|_| { + self.stopping.store(false, Ordering::Release); + }) } pub fn signal(&self, sig: &'static str) -> Result<()> { diff --git a/src/core/utils/bool.rs b/src/core/utils/bool.rs index e9f399d49..b4192daf0 100644 --- a/src/core/utils/bool.rs +++ b/src/core/utils/bool.rs @@ -66,19 +66,25 @@ impl BoolExt for bool { } #[inline] - fn map_ok_or T>(self, err: E, f: F) -> Result { self.ok_or(err).map(|()| f()) } + fn map_ok_or T>(self, err: E, f: F) -> Result { + self.ok_or(err).map(|()| f()) + } #[inline] fn map_or T>(self, err: T, f: F) -> T { self.then(f).unwrap_or(err) } #[inline] - fn map_or_else T>(self, err: F, f: F) -> T { self.then(f).unwrap_or_else(err) } + fn map_or_else T>(self, err: F, f: F) -> T { + self.then(f).unwrap_or_else(err) + } #[inline] fn ok_or(self, err: E) -> Result<(), E> { self.into_option().ok_or(err) } #[inline] - fn ok_or_else E>(self, err: F) -> Result<(), E> { self.into_option().ok_or_else(err) } + fn ok_or_else E>(self, err: F) -> Result<(), E> { + self.into_option().ok_or_else(err) + } #[inline] fn or T>(self, f: F) -> Option { (!self).then(f) } diff --git a/src/core/utils/bytes.rs b/src/core/utils/bytes.rs index 441ba422a..403164408 100644 --- a/src/core/utils/bytes.rs +++ b/src/core/utils/bytes.rs @@ -39,7 +39,9 @@ pub fn increment(old: Option<&[u8]>) -> [u8; 8] { /// Parses 8 big-endian bytes into an u64; panic on invalid argument #[inline] #[must_use] -pub fn u64_from_u8(bytes: &[u8]) -> u64 { u64_from_bytes(bytes).expect("must slice at least 8 bytes") } +pub fn u64_from_u8(bytes: &[u8]) -> u64 { + u64_from_bytes(bytes).expect("must slice at least 8 bytes") +} /// Parses the big-endian bytes into an u64. #[inline] diff --git a/src/core/utils/content_disposition.rs b/src/core/utils/content_disposition.rs index 3a264a74f..82f11732e 100644 --- a/src/core/utils/content_disposition.rs +++ b/src/core/utils/content_disposition.rs @@ -71,13 +71,10 @@ pub fn content_disposition_type(content_type: Option<&str>) -> ContentDispositio /// `sanitize_filename` crate #[tracing::instrument(level = "debug")] pub fn sanitise_filename(filename: &str) -> String { - sanitize_filename::sanitize_with_options( - filename, - sanitize_filename::Options { - truncate: false, - ..Default::default() - }, - ) + sanitize_filename::sanitize_with_options(filename, sanitize_filename::Options { + truncate: false, + ..Default::default() + }) } /// creates the final Content-Disposition based on whether the filename exists @@ -89,11 +86,16 @@ pub fn sanitise_filename(filename: &str) -> String { /// /// else: `Content-Disposition: attachment/inline` pub fn make_content_disposition( - content_disposition: Option<&ContentDisposition>, content_type: Option<&str>, filename: Option<&str>, + content_disposition: Option<&ContentDisposition>, + content_type: Option<&str>, + filename: Option<&str>, ) -> ContentDisposition { ContentDisposition::new(content_disposition_type(content_type)).with_filename( filename - .or_else(|| content_disposition.and_then(|content_disposition| content_disposition.filename.as_deref())) + .or_else(|| { + content_disposition + .and_then(|content_disposition| content_disposition.filename.as_deref()) + }) .map(sanitise_filename), ) } @@ -102,8 +104,8 @@ pub fn make_content_disposition( mod tests { #[test] fn string_sanitisation() { - const SAMPLE: &str = - "🏳️‍⚧️this\\r\\n įs \r\\n ä \\r\nstrïng 🥴that\n\r ../../../../../../../may be\r\n malicious🏳️‍⚧️"; + const SAMPLE: &str = "🏳️‍⚧️this\\r\\n įs \r\\n ä \\r\nstrïng 🥴that\n\r \ + ../../../../../../../may be\r\n malicious🏳️‍⚧️"; const SANITISED: &str = "🏳️‍⚧️thisrn įs n ä rstrïng 🥴that ..............may be malicious🏳️‍⚧️"; let options = sanitize_filename::Options { @@ -125,14 +127,12 @@ mod tests { fn empty_sanitisation() { use crate::utils::string::EMPTY; - let result = sanitize_filename::sanitize_with_options( - EMPTY, - sanitize_filename::Options { + let result = + sanitize_filename::sanitize_with_options(EMPTY, sanitize_filename::Options { windows: true, truncate: true, replacement: "", - }, - ); + }); assert_eq!(EMPTY, result); } diff --git a/src/core/utils/debug.rs b/src/core/utils/debug.rs index cb9d7bab0..b16ae7541 100644 --- a/src/core/utils/debug.rs +++ b/src/core/utils/debug.rs @@ -31,10 +31,8 @@ impl fmt::Debug for TruncatedSlice<'_, T> { /// fn bar(foos: &[&str]); /// ``` pub fn slice_truncated( - slice: &[T], max_len: usize, + slice: &[T], + max_len: usize, ) -> tracing::field::DebugValue> { - tracing::field::debug(TruncatedSlice { - inner: slice, - max_len, - }) + tracing::field::debug(TruncatedSlice { inner: slice, max_len }) } diff --git a/src/core/utils/defer.rs b/src/core/utils/defer.rs index 29199700b..60243e97d 100644 --- a/src/core/utils/defer.rs +++ b/src/core/utils/defer.rs @@ -9,9 +9,7 @@ macro_rules! defer { fn drop(&mut self) { (self.closure)(); } } - let _defer_ = _Defer_ { - closure: || $body, - }; + let _defer_ = _Defer_ { closure: || $body }; }; ($body:expr) => { diff --git a/src/core/utils/future/try_ext_ext.rs b/src/core/utils/future/try_ext_ext.rs index 977f74d2e..19761309c 100644 --- a/src/core/utils/future/try_ext_ext.rs +++ b/src/core/utils/future/try_ext_ext.rs @@ -14,17 +14,23 @@ pub trait TryExtExt where Self: TryFuture + Send, { - fn is_err(self) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> + fn is_err( + self, + ) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> where Self: Sized; #[allow(clippy::wrong_self_convention)] - fn is_ok(self) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> + fn is_ok( + self, + ) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> where Self: Sized; fn map_ok_or( - self, default: U, f: F, + self, + default: U, + f: F, ) -> MapOkOrElse U, impl FnOnce(Self::Error) -> U> where F: FnOnce(Self::Ok) -> U, @@ -32,11 +38,18 @@ where fn ok( self, - ) -> MapOkOrElse Option, impl FnOnce(Self::Error) -> Option> + ) -> MapOkOrElse< + Self, + impl FnOnce(Self::Ok) -> Option, + impl FnOnce(Self::Error) -> Option, + > where Self: Sized; - fn unwrap_or(self, default: Self::Ok) -> UnwrapOrElse Self::Ok> + fn unwrap_or( + self, + default: Self::Ok, + ) -> UnwrapOrElse Self::Ok> where Self: Sized; @@ -51,7 +64,9 @@ where Fut: TryFuture + Send, { #[inline] - fn is_err(self) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> + fn is_err( + self, + ) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> where Self: Sized, { @@ -59,7 +74,9 @@ where } #[inline] - fn is_ok(self) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> + fn is_ok( + self, + ) -> MapOkOrElse bool, impl FnOnce(Self::Error) -> bool> where Self: Sized, { @@ -68,7 +85,9 @@ where #[inline] fn map_ok_or( - self, default: U, f: F, + self, + default: U, + f: F, ) -> MapOkOrElse U, impl FnOnce(Self::Error) -> U> where F: FnOnce(Self::Ok) -> U, @@ -80,7 +99,11 @@ where #[inline] fn ok( self, - ) -> MapOkOrElse Option, impl FnOnce(Self::Error) -> Option> + ) -> MapOkOrElse< + Self, + impl FnOnce(Self::Ok) -> Option, + impl FnOnce(Self::Error) -> Option, + > where Self: Sized, { @@ -88,7 +111,10 @@ where } #[inline] - fn unwrap_or(self, default: Self::Ok) -> UnwrapOrElse Self::Ok> + fn unwrap_or( + self, + default: Self::Ok, + ) -> UnwrapOrElse Self::Ok> where Self: Sized, { diff --git a/src/core/utils/hash/argon.rs b/src/core/utils/hash/argon.rs index 0a1e1e14f..18146b473 100644 --- a/src/core/utils/hash/argon.rs +++ b/src/core/utils/hash/argon.rs @@ -1,8 +1,8 @@ use std::sync::OnceLock; use argon2::{ - password_hash, password_hash::SaltString, Algorithm, Argon2, Params, PasswordHash, PasswordHasher, - PasswordVerifier, Version, + password_hash, password_hash::SaltString, Algorithm, Argon2, Params, PasswordHash, + PasswordHasher, PasswordVerifier, Version, }; use crate::{err, Error, Result}; diff --git a/src/core/utils/html.rs b/src/core/utils/html.rs index fe07b2dd7..f2b6d861a 100644 --- a/src/core/utils/html.rs +++ b/src/core/utils/html.rs @@ -16,12 +16,12 @@ impl fmt::Display for Escape<'_> { let mut last = 0; for (i, ch) in s.char_indices() { let s = match ch { - '>' => ">", - '<' => "<", - '&' => "&", - '\'' => "'", - '"' => """, - _ => continue, + | '>' => ">", + | '<' => "<", + | '&' => "&", + | '\'' => "'", + | '"' => """, + | _ => continue, }; fmt.write_str(&pile_o_bits[last..i])?; fmt.write_str(s)?; diff --git a/src/core/utils/json.rs b/src/core/utils/json.rs index a9adad546..4a3fec8f9 100644 --- a/src/core/utils/json.rs +++ b/src/core/utils/json.rs @@ -8,16 +8,24 @@ use crate::Result; /// `CanonicalJsonObject`. /// /// `value` must serialize to an `serde_json::Value::Object`. -pub fn to_canonical_object(value: T) -> Result { +pub fn to_canonical_object( + value: T, +) -> Result { use serde::ser::Error; match serde_json::to_value(value).map_err(CanonicalJsonError::SerDe)? { - serde_json::Value::Object(map) => try_from_json_map(map), - _ => Err(CanonicalJsonError::SerDe(serde_json::Error::custom("Value must be an object"))), + | serde_json::Value::Object(map) => try_from_json_map(map), + | _ => + Err(CanonicalJsonError::SerDe(serde_json::Error::custom("Value must be an object"))), } } -pub fn deserialize_from_str<'de, D: serde::de::Deserializer<'de>, T: FromStr, E: fmt::Display>( +pub fn deserialize_from_str< + 'de, + D: serde::de::Deserializer<'de>, + T: FromStr, + E: fmt::Display, +>( deserializer: D, ) -> Result { struct Visitor, E>(std::marker::PhantomData); diff --git a/src/core/utils/math.rs b/src/core/utils/math.rs index ccff6400d..da2357d53 100644 --- a/src/core/utils/math.rs +++ b/src/core/utils/math.rs @@ -56,7 +56,12 @@ macro_rules! validated { /// Returns false if the exponential backoff has expired based on the inputs #[inline] #[must_use] -pub fn continue_exponential_backoff_secs(min: u64, max: u64, elapsed: Duration, tries: u32) -> bool { +pub fn continue_exponential_backoff_secs( + min: u64, + max: u64, + elapsed: Duration, + tries: u32, +) -> bool { let min = Duration::from_secs(min); let max = Duration::from_secs(max); continue_exponential_backoff(min, max, elapsed, tries) @@ -65,7 +70,12 @@ pub fn continue_exponential_backoff_secs(min: u64, max: u64, elapsed: Duration, /// Returns false if the exponential backoff has expired based on the inputs #[inline] #[must_use] -pub fn continue_exponential_backoff(min: Duration, max: Duration, elapsed: Duration, tries: u32) -> bool { +pub fn continue_exponential_backoff( + min: Duration, + max: Duration, + elapsed: Duration, + tries: u32, +) -> bool { let min = min.saturating_mul(tries).saturating_mul(tries); let min = cmp::min(min, max); elapsed < min diff --git a/src/core/utils/mod.rs b/src/core/utils/mod.rs index ad53bc424..a9b73fb64 100644 --- a/src/core/utils/mod.rs +++ b/src/core/utils/mod.rs @@ -47,8 +47,8 @@ pub fn exchange(state: &mut T, source: T) -> T { std::mem::replace(state, sou macro_rules! extract_variant { ($e:expr, $variant:path) => { match $e { - $variant(value) => Some(value), - _ => None, + | $variant(value) => Some(value), + | _ => None, } }; } diff --git a/src/core/utils/mutex_map.rs b/src/core/utils/mutex_map.rs index c3c51798c..152a75d16 100644 --- a/src/core/utils/mutex_map.rs +++ b/src/core/utils/mutex_map.rs @@ -70,10 +70,9 @@ where impl Drop for Guard { fn drop(&mut self) { if Arc::strong_count(Omg::mutex(&self.val)) <= 2 { - self.map - .lock() - .expect("locked") - .retain(|_, val| !Arc::ptr_eq(val, Omg::mutex(&self.val)) || Arc::strong_count(val) > 2); + self.map.lock().expect("locked").retain(|_, val| { + !Arc::ptr_eq(val, Omg::mutex(&self.val)) || Arc::strong_count(val) > 2 + }); } } } diff --git a/src/core/utils/result.rs b/src/core/utils/result.rs index 6b11ea66f..1ad5371bb 100644 --- a/src/core/utils/result.rs +++ b/src/core/utils/result.rs @@ -10,9 +10,9 @@ mod unwrap_infallible; mod unwrap_or_err; pub use self::{ - debug_inspect::DebugInspect, filter::Filter, flat_ok::FlatOk, into_is_ok::IntoIsOk, log_debug_err::LogDebugErr, - log_err::LogErr, map_expect::MapExpect, not_found::NotFound, unwrap_infallible::UnwrapInfallible, - unwrap_or_err::UnwrapOrErr, + debug_inspect::DebugInspect, filter::Filter, flat_ok::FlatOk, into_is_ok::IntoIsOk, + log_debug_err::LogDebugErr, log_err::LogErr, map_expect::MapExpect, not_found::NotFound, + unwrap_infallible::UnwrapInfallible, unwrap_or_err::UnwrapOrErr, }; pub type Result = std::result::Result; diff --git a/src/core/utils/result/flat_ok.rs b/src/core/utils/result/flat_ok.rs index e378e5d05..8e7bb968f 100644 --- a/src/core/utils/result/flat_ok.rs +++ b/src/core/utils/result/flat_ok.rs @@ -19,7 +19,9 @@ impl FlatOk for Option> { fn flat_ok_or(self, err: Ep) -> Result { self.flat_ok().ok_or(err) } #[inline] - fn flat_ok_or_else Ep>(self, err: F) -> Result { self.flat_ok().ok_or_else(err) } + fn flat_ok_or_else Ep>(self, err: F) -> Result { + self.flat_ok().ok_or_else(err) + } } impl FlatOk for Result, E> { @@ -30,5 +32,7 @@ impl FlatOk for Result, E> { fn flat_ok_or(self, err: Ep) -> Result { self.flat_ok().ok_or(err) } #[inline] - fn flat_ok_or_else Ep>(self, err: F) -> Result { self.flat_ok().ok_or_else(err) } + fn flat_ok_or_else Ep>(self, err: F) -> Result { + self.flat_ok().ok_or_else(err) + } } diff --git a/src/core/utils/result/log_err.rs b/src/core/utils/result/log_err.rs index 374a5e596..a1ce891f6 100644 --- a/src/core/utils/result/log_err.rs +++ b/src/core/utils/result/log_err.rs @@ -20,5 +20,7 @@ pub trait LogErr { impl LogErr for Result { #[inline] - fn err_log(self, level: Level) -> Self { self.inspect_err(|error| error::inspect_log_level(&error, level)) } + fn err_log(self, level: Level) -> Self { + self.inspect_err(|error| error::inspect_log_level(&error, level)) + } } diff --git a/src/core/utils/set.rs b/src/core/utils/set.rs index ddcf05ffc..8eac7157f 100644 --- a/src/core/utils/set.rs +++ b/src/core/utils/set.rs @@ -32,7 +32,9 @@ where /// Intersection of sets /// /// Outputs the set of elements common to all input sets. Inputs must be sorted. -pub fn intersection_sorted(mut input: Iters) -> impl Iterator + Send +pub fn intersection_sorted( + mut input: Iters, +) -> impl Iterator + Send where Iters: Iterator + Clone + Send, Iter: Iterator + Send, diff --git a/src/core/utils/stream/expect.rs b/src/core/utils/stream/expect.rs index 68ac24ced..3509bb838 100644 --- a/src/core/utils/stream/expect.rs +++ b/src/core/utils/stream/expect.rs @@ -14,9 +14,13 @@ where Item: 'a, { #[inline] - fn expect_ok(self: T) -> impl Stream + Send + 'a { self.map_expect("stream expectation failure") } + fn expect_ok(self: T) -> impl Stream + Send + 'a { + self.map_expect("stream expectation failure") + } //TODO: move to impl MapExpect #[inline] - fn map_expect(self, msg: &'a str) -> impl Stream + Send + 'a { self.map(|res| res.expect(msg)) } + fn map_expect(self, msg: &'a str) -> impl Stream + Send + 'a { + self.map(|res| res.expect(msg)) + } } diff --git a/src/core/utils/stream/ignore.rs b/src/core/utils/stream/ignore.rs index 4e426557d..9baa00f3d 100644 --- a/src/core/utils/stream/ignore.rs +++ b/src/core/utils/stream/ignore.rs @@ -23,8 +23,12 @@ where #[cfg(not(debug_assertions))] #[inline] - fn ignore_err(self: T) -> impl Stream + Send + 'a { self.filter_map(|res| ready(res.ok())) } + fn ignore_err(self: T) -> impl Stream + Send + 'a { + self.filter_map(|res| ready(res.ok())) + } #[inline] - fn ignore_ok(self: T) -> impl Stream + Send + 'a { self.filter_map(|res| ready(res.err())) } + fn ignore_ok(self: T) -> impl Stream + Send + 'a { + self.filter_map(|res| ready(res.err())) + } } diff --git a/src/core/utils/stream/iter_stream.rs b/src/core/utils/stream/iter_stream.rs index 2face4b05..9077deac0 100644 --- a/src/core/utils/stream/iter_stream.rs +++ b/src/core/utils/stream/iter_stream.rs @@ -13,7 +13,11 @@ pub trait IterStream { /// Convert an Iterator into a TryStream fn try_stream( self, - ) -> impl TryStream::Item, Error = Error, Item = Result<::Item, Error>> + Send; + ) -> impl TryStream< + Ok = ::Item, + Error = Error, + Item = Result<::Item, Error>, + > + Send; } impl IterStream for I @@ -27,8 +31,11 @@ where #[inline] fn try_stream( self, - ) -> impl TryStream::Item, Error = Error, Item = Result<::Item, Error>> + Send - { + ) -> impl TryStream< + Ok = ::Item, + Error = Error, + Item = Result<::Item, Error>, + > + Send { self.stream().map(Ok) } } diff --git a/src/core/utils/stream/ready.rs b/src/core/utils/stream/ready.rs index 9bba589e4..d93187e9d 100644 --- a/src/core/utils/stream/ready.rs +++ b/src/core/utils/stream/ready.rs @@ -3,7 +3,9 @@ use futures::{ future::{ready, Ready}, - stream::{All, Any, Filter, FilterMap, Fold, ForEach, Scan, SkipWhile, Stream, StreamExt, TakeWhile}, + stream::{ + All, Any, Filter, FilterMap, Fold, ForEach, Scan, SkipWhile, Stream, StreamExt, TakeWhile, + }, }; /// Synchronous combinators to augment futures::StreamExt. Most Stream @@ -24,19 +26,32 @@ where where F: Fn(Item) -> bool; - fn ready_filter<'a, F>(self, f: F) -> Filter, impl FnMut(&Item) -> Ready + 'a> + fn ready_filter<'a, F>( + self, + f: F, + ) -> Filter, impl FnMut(&Item) -> Ready + 'a> where F: Fn(&Item) -> bool + 'a; - fn ready_filter_map(self, f: F) -> FilterMap>, impl FnMut(Item) -> Ready>> + fn ready_filter_map( + self, + f: F, + ) -> FilterMap>, impl FnMut(Item) -> Ready>> where F: Fn(Item) -> Option; - fn ready_fold(self, init: T, f: F) -> Fold, T, impl FnMut(T, Item) -> Ready> + fn ready_fold( + self, + init: T, + f: F, + ) -> Fold, T, impl FnMut(T, Item) -> Ready> where F: Fn(T, Item) -> T; - fn ready_fold_default(self, f: F) -> Fold, T, impl FnMut(T, Item) -> Ready> + fn ready_fold_default( + self, + f: F, + ) -> Fold, T, impl FnMut(T, Item) -> Ready> where F: Fn(T, Item) -> T, T: Default; @@ -45,23 +60,33 @@ where where F: FnMut(Item); - fn ready_take_while<'a, F>(self, f: F) -> TakeWhile, impl FnMut(&Item) -> Ready + 'a> + fn ready_take_while<'a, F>( + self, + f: F, + ) -> TakeWhile, impl FnMut(&Item) -> Ready + 'a> where F: Fn(&Item) -> bool + 'a; fn ready_scan( - self, init: T, f: F, + self, + init: T, + f: F, ) -> Scan>, impl FnMut(&mut T, Item) -> Ready>> where F: Fn(&mut T, Item) -> Option; fn ready_scan_each( - self, init: T, f: F, + self, + init: T, + f: F, ) -> Scan>, impl FnMut(&mut T, Item) -> Ready>> where F: Fn(&mut T, &Item); - fn ready_skip_while<'a, F>(self, f: F) -> SkipWhile, impl FnMut(&Item) -> Ready + 'a> + fn ready_skip_while<'a, F>( + self, + f: F, + ) -> SkipWhile, impl FnMut(&Item) -> Ready + 'a> where F: Fn(&Item) -> bool + 'a; } @@ -87,7 +112,10 @@ where } #[inline] - fn ready_filter<'a, F>(self, f: F) -> Filter, impl FnMut(&Item) -> Ready + 'a> + fn ready_filter<'a, F>( + self, + f: F, + ) -> Filter, impl FnMut(&Item) -> Ready + 'a> where F: Fn(&Item) -> bool + 'a, { @@ -95,7 +123,10 @@ where } #[inline] - fn ready_filter_map(self, f: F) -> FilterMap>, impl FnMut(Item) -> Ready>> + fn ready_filter_map( + self, + f: F, + ) -> FilterMap>, impl FnMut(Item) -> Ready>> where F: Fn(Item) -> Option, { @@ -103,7 +134,11 @@ where } #[inline] - fn ready_fold(self, init: T, f: F) -> Fold, T, impl FnMut(T, Item) -> Ready> + fn ready_fold( + self, + init: T, + f: F, + ) -> Fold, T, impl FnMut(T, Item) -> Ready> where F: Fn(T, Item) -> T, { @@ -111,7 +146,10 @@ where } #[inline] - fn ready_fold_default(self, f: F) -> Fold, T, impl FnMut(T, Item) -> Ready> + fn ready_fold_default( + self, + f: F, + ) -> Fold, T, impl FnMut(T, Item) -> Ready> where F: Fn(T, Item) -> T, T: Default, @@ -121,7 +159,10 @@ where #[inline] #[allow(clippy::unit_arg)] - fn ready_for_each(self, mut f: F) -> ForEach, impl FnMut(Item) -> Ready<()>> + fn ready_for_each( + self, + mut f: F, + ) -> ForEach, impl FnMut(Item) -> Ready<()>> where F: FnMut(Item), { @@ -129,7 +170,10 @@ where } #[inline] - fn ready_take_while<'a, F>(self, f: F) -> TakeWhile, impl FnMut(&Item) -> Ready + 'a> + fn ready_take_while<'a, F>( + self, + f: F, + ) -> TakeWhile, impl FnMut(&Item) -> Ready + 'a> where F: Fn(&Item) -> bool + 'a, { @@ -138,7 +182,9 @@ where #[inline] fn ready_scan( - self, init: T, f: F, + self, + init: T, + f: F, ) -> Scan>, impl FnMut(&mut T, Item) -> Ready>> where F: Fn(&mut T, Item) -> Option, @@ -148,7 +194,9 @@ where #[inline] fn ready_scan_each( - self, init: T, f: F, + self, + init: T, + f: F, ) -> Scan>, impl FnMut(&mut T, Item) -> Ready>> where F: Fn(&mut T, &Item), @@ -160,7 +208,10 @@ where } #[inline] - fn ready_skip_while<'a, F>(self, f: F) -> SkipWhile, impl FnMut(&Item) -> Ready + 'a> + fn ready_skip_while<'a, F>( + self, + f: F, + ) -> SkipWhile, impl FnMut(&Item) -> Ready + 'a> where F: Fn(&Item) -> bool + 'a, { diff --git a/src/core/utils/stream/tools.rs b/src/core/utils/stream/tools.rs index b5b036ccc..7b24642e3 100644 --- a/src/core/utils/stream/tools.rs +++ b/src/core/utils/stream/tools.rs @@ -24,12 +24,17 @@ where F: Fn(Item) -> K + Send, K: Eq + Hash + Send; - fn counts_by_with_cap(self, f: F) -> impl Future> + Send + fn counts_by_with_cap( + self, + f: F, + ) -> impl Future> + Send where F: Fn(Item) -> K + Send, K: Eq + Hash + Send; - fn counts_with_cap(self) -> impl Future> + Send + fn counts_with_cap( + self, + ) -> impl Future> + Send where ::Item: Eq + Hash; @@ -63,7 +68,10 @@ where } #[inline] - fn counts_by_with_cap(self, f: F) -> impl Future> + Send + fn counts_by_with_cap( + self, + f: F, + ) -> impl Future> + Send where F: Fn(Item) -> K + Send, K: Eq + Hash + Send, @@ -72,7 +80,9 @@ where } #[inline] - fn counts_with_cap(self) -> impl Future> + Send + fn counts_with_cap( + self, + ) -> impl Future> + Send where ::Item: Eq + Hash, { diff --git a/src/core/utils/stream/try_broadband.rs b/src/core/utils/stream/try_broadband.rs index 59c488e0f..d12131743 100644 --- a/src/core/utils/stream/try_broadband.rs +++ b/src/core/utils/stream/try_broadband.rs @@ -12,13 +12,20 @@ pub trait TryBroadbandExt where Self: TryStream> + Send + Sized, { - fn broadn_and_then(self, n: N, f: F) -> impl TryStream> + Send + fn broadn_and_then( + self, + n: N, + f: F, + ) -> impl TryStream> + Send where N: Into>, F: Fn(Self::Ok) -> Fut + Send + Sync, Fut: TryFuture> + Send; - fn broad_and_then(self, f: F) -> impl TryStream> + Send + fn broad_and_then( + self, + f: F, + ) -> impl TryStream> + Send where F: Fn(Self::Ok) -> Fut + Send + Sync, Fut: TryFuture> + Send, @@ -31,7 +38,11 @@ impl TryBroadbandExt for S where S: TryStream> + Send + Sized, { - fn broadn_and_then(self, n: N, f: F) -> impl TryStream> + Send + fn broadn_and_then( + self, + n: N, + f: F, + ) -> impl TryStream> + Send where N: Into>, F: Fn(Self::Ok) -> Fut + Send + Sync, diff --git a/src/core/utils/stream/try_ready.rs b/src/core/utils/stream/try_ready.rs index b0a2b6c53..d8da04ecb 100644 --- a/src/core/utils/stream/try_ready.rs +++ b/src/core/utils/stream/try_ready.rs @@ -16,31 +16,43 @@ where S: TryStream> + Send + ?Sized, Self: TryStream + Send + Sized, { - fn ready_and_then(self, f: F) -> AndThen>, impl FnMut(S::Ok) -> Ready>> + fn ready_and_then( + self, + f: F, + ) -> AndThen>, impl FnMut(S::Ok) -> Ready>> where F: Fn(S::Ok) -> Result; fn ready_try_filter_map( - self, f: F, - ) -> TryFilterMap, E>>, impl FnMut(S::Ok) -> Ready, E>>> + self, + f: F, + ) -> TryFilterMap< + Self, + Ready, E>>, + impl FnMut(S::Ok) -> Ready, E>>, + > where F: Fn(S::Ok) -> Result, E>; fn ready_try_fold( - self, init: U, f: F, + self, + init: U, + f: F, ) -> TryFold>, U, impl FnMut(U, S::Ok) -> Ready>> where F: Fn(U, S::Ok) -> Result; fn ready_try_fold_default( - self, f: F, + self, + f: F, ) -> TryFold>, U, impl FnMut(U, S::Ok) -> Ready>> where F: Fn(U, S::Ok) -> Result, U: Default; fn ready_try_for_each( - self, f: F, + self, + f: F, ) -> TryForEach>, impl FnMut(S::Ok) -> Ready>> where F: FnMut(S::Ok) -> Result<(), E>; @@ -52,7 +64,10 @@ where Self: TryStream + Send + Sized, { #[inline] - fn ready_and_then(self, f: F) -> AndThen>, impl FnMut(S::Ok) -> Ready>> + fn ready_and_then( + self, + f: F, + ) -> AndThen>, impl FnMut(S::Ok) -> Ready>> where F: Fn(S::Ok) -> Result, { @@ -60,8 +75,13 @@ where } fn ready_try_filter_map( - self, f: F, - ) -> TryFilterMap, E>>, impl FnMut(S::Ok) -> Ready, E>>> + self, + f: F, + ) -> TryFilterMap< + Self, + Ready, E>>, + impl FnMut(S::Ok) -> Ready, E>>, + > where F: Fn(S::Ok) -> Result, E>, { @@ -70,7 +90,9 @@ where #[inline] fn ready_try_fold( - self, init: U, f: F, + self, + init: U, + f: F, ) -> TryFold>, U, impl FnMut(U, S::Ok) -> Ready>> where F: Fn(U, S::Ok) -> Result, @@ -80,7 +102,8 @@ where #[inline] fn ready_try_fold_default( - self, f: F, + self, + f: F, ) -> TryFold>, U, impl FnMut(U, S::Ok) -> Ready>> where F: Fn(U, S::Ok) -> Result, @@ -91,7 +114,8 @@ where #[inline] fn ready_try_for_each( - self, mut f: F, + self, + mut f: F, ) -> TryForEach>, impl FnMut(S::Ok) -> Ready>> where F: FnMut(S::Ok) -> Result<(), E>, diff --git a/src/core/utils/string/between.rs b/src/core/utils/string/between.rs index 209a9dabb..05c137b43 100644 --- a/src/core/utils/string/between.rs +++ b/src/core/utils/string/between.rs @@ -15,7 +15,9 @@ pub trait Between<'a> { impl<'a> Between<'a> for &'a str { #[inline] - fn between_infallible(&self, delim: Delim<'_>) -> &'a str { self.between(delim).unwrap_or(self) } + fn between_infallible(&self, delim: Delim<'_>) -> &'a str { + self.between(delim).unwrap_or(self) + } #[inline] fn between(&self, delim: Delim<'_>) -> Option<&'a str> { diff --git a/src/core/utils/string/split.rs b/src/core/utils/string/split.rs index 96de28dff..e643f51bd 100644 --- a/src/core/utils/string/split.rs +++ b/src/core/utils/string/split.rs @@ -15,8 +15,12 @@ pub trait SplitInfallible<'a> { impl<'a> SplitInfallible<'a> for &'a str { #[inline] - fn rsplit_once_infallible(&self, delim: &str) -> Pair<'a> { self.rsplit_once(delim).unwrap_or((self, EMPTY)) } + fn rsplit_once_infallible(&self, delim: &str) -> Pair<'a> { + self.rsplit_once(delim).unwrap_or((self, EMPTY)) + } #[inline] - fn split_once_infallible(&self, delim: &str) -> Pair<'a> { self.split_once(delim).unwrap_or((self, EMPTY)) } + fn split_once_infallible(&self, delim: &str) -> Pair<'a> { + self.split_once(delim).unwrap_or((self, EMPTY)) + } } diff --git a/src/core/utils/string/unquote.rs b/src/core/utils/string/unquote.rs index eeded610a..ea7ddbf96 100644 --- a/src/core/utils/string/unquote.rs +++ b/src/core/utils/string/unquote.rs @@ -26,7 +26,9 @@ impl<'a> Unquote<'a> for &'a str { } #[inline] - fn unquote(&self) -> Option<&'a str> { self.strip_prefix(QUOTE).and_then(|s| s.strip_suffix(QUOTE)) } + fn unquote(&self) -> Option<&'a str> { + self.strip_prefix(QUOTE).and_then(|s| s.strip_suffix(QUOTE)) + } #[inline] fn is_quoted(&self) -> bool { self.starts_with(QUOTE) && self.ends_with(QUOTE) } diff --git a/src/core/utils/sys.rs b/src/core/utils/sys.rs index f3ff08b6a..05ef12ca3 100644 --- a/src/core/utils/sys.rs +++ b/src/core/utils/sys.rs @@ -45,8 +45,8 @@ pub unsafe fn current_exe() -> Result { let exe = std::env::current_exe()?; match exe.to_str() { - None => Ok(exe), - Some(str) => Ok(str + | None => Ok(exe), + | Some(str) => Ok(str .strip_suffix(" (deleted)") .map(PathBuf::from) .unwrap_or(exe)), @@ -58,5 +58,6 @@ pub unsafe fn current_exe() -> Result { /// accurate on all platforms; defaults to false. #[must_use] pub fn current_exe_deleted() -> bool { - std::env::current_exe().is_ok_and(|exe| exe.to_str().is_some_and(|exe| exe.ends_with(" (deleted)"))) + std::env::current_exe() + .is_ok_and(|exe| exe.to_str().is_some_and(|exe| exe.ends_with(" (deleted)"))) } diff --git a/src/core/utils/time.rs b/src/core/utils/time.rs index f96a27d00..d65eb2d46 100644 --- a/src/core/utils/time.rs +++ b/src/core/utils/time.rs @@ -13,7 +13,9 @@ pub fn now_millis() -> u64 { } #[inline] -pub fn parse_timepoint_ago(ago: &str) -> Result { timepoint_ago(parse_duration(ago)?) } +pub fn parse_timepoint_ago(ago: &str) -> Result { + timepoint_ago(parse_duration(ago)?) +} #[inline] pub fn timepoint_ago(duration: Duration) -> Result { @@ -61,13 +63,13 @@ pub fn pretty(d: Duration) -> String { let gen64 = |w, f, u| fmt(w, (f * 100.0) as u32, u); let gen128 = |w, f, u| gen64(u64::try_from(w).expect("u128 to u64"), f, u); match whole_and_frac(d) { - (Days(whole), frac) => gen64(whole, frac, "days"), - (Hours(whole), frac) => gen64(whole, frac, "hours"), - (Mins(whole), frac) => gen64(whole, frac, "minutes"), - (Secs(whole), frac) => gen64(whole, frac, "seconds"), - (Millis(whole), frac) => gen128(whole, frac, "milliseconds"), - (Micros(whole), frac) => gen128(whole, frac, "microseconds"), - (Nanos(whole), frac) => gen128(whole, frac, "nanoseconds"), + | (Days(whole), frac) => gen64(whole, frac, "days"), + | (Hours(whole), frac) => gen64(whole, frac, "hours"), + | (Mins(whole), frac) => gen64(whole, frac, "minutes"), + | (Secs(whole), frac) => gen64(whole, frac, "seconds"), + | (Millis(whole), frac) => gen128(whole, frac, "milliseconds"), + | (Micros(whole), frac) => gen128(whole, frac, "microseconds"), + | (Nanos(whole), frac) => gen128(whole, frac, "nanoseconds"), } } @@ -80,18 +82,15 @@ pub fn whole_and_frac(d: Duration) -> (Unit, f64) { use Unit::*; let whole = whole_unit(d); - ( - whole, - match whole { - Days(_) => (d.as_secs() % 86_400) as f64 / 86_400.0, - Hours(_) => (d.as_secs() % 3_600) as f64 / 3_600.0, - Mins(_) => (d.as_secs() % 60) as f64 / 60.0, - Secs(_) => f64::from(d.subsec_millis()) / 1000.0, - Millis(_) => f64::from(d.subsec_micros()) / 1000.0, - Micros(_) => f64::from(d.subsec_nanos()) / 1000.0, - Nanos(_) => 0.0, - }, - ) + (whole, match whole { + | Days(_) => (d.as_secs() % 86_400) as f64 / 86_400.0, + | Hours(_) => (d.as_secs() % 3_600) as f64 / 3_600.0, + | Mins(_) => (d.as_secs() % 60) as f64 / 60.0, + | Secs(_) => f64::from(d.subsec_millis()) / 1000.0, + | Millis(_) => f64::from(d.subsec_micros()) / 1000.0, + | Micros(_) => f64::from(d.subsec_nanos()) / 1000.0, + | Nanos(_) => 0.0, + }) } /// Return the largest Unit which represents the duration. The value is @@ -101,18 +100,18 @@ pub fn whole_unit(d: Duration) -> Unit { use Unit::*; match d.as_secs() { - 86_400.. => Days(d.as_secs() / 86_400), - 3_600..=86_399 => Hours(d.as_secs() / 3_600), - 60..=3_599 => Mins(d.as_secs() / 60), + | 86_400.. => Days(d.as_secs() / 86_400), + | 3_600..=86_399 => Hours(d.as_secs() / 3_600), + | 60..=3_599 => Mins(d.as_secs() / 60), - _ => match d.as_micros() { - 1_000_000.. => Secs(d.as_secs()), - 1_000..=999_999 => Millis(d.subsec_millis().into()), + | _ => match d.as_micros() { + | 1_000_000.. => Secs(d.as_secs()), + | 1_000..=999_999 => Millis(d.subsec_millis().into()), - _ => match d.as_nanos() { - 1_000.. => Micros(d.subsec_micros().into()), + | _ => match d.as_nanos() { + | 1_000.. => Micros(d.subsec_micros().into()), - _ => Nanos(d.subsec_nanos().into()), + | _ => Nanos(d.subsec_nanos().into()), }, }, } diff --git a/src/database/cork.rs b/src/database/cork.rs index 5fe5fd7ab..11b6efd7b 100644 --- a/src/database/cork.rs +++ b/src/database/cork.rs @@ -26,11 +26,7 @@ impl Cork { #[inline] pub(super) fn new(db: &Arc, flush: bool, sync: bool) -> Self { db.cork(); - Self { - db: db.clone(), - flush, - sync, - } + Self { db: db.clone(), flush, sync } } } diff --git a/src/database/database.rs b/src/database/database.rs index bd8dcb1ab..83d2c2010 100644 --- a/src/database/database.rs +++ b/src/database/database.rs @@ -17,10 +17,7 @@ impl Database { /// Load an existing database or create a new one. pub async fn open(server: &Arc) -> Result> { let db = Engine::open(server).await?; - Ok(Arc::new(Self { - db: db.clone(), - maps: maps::open(&db)?, - })) + Ok(Arc::new(Self { db: db.clone(), maps: maps::open(&db)? })) } #[inline] @@ -31,7 +28,9 @@ impl Database { } #[inline] - pub fn iter(&self) -> impl Iterator + Send + '_ { self.maps.iter() } + pub fn iter(&self) -> impl Iterator + Send + '_ { + self.maps.iter() + } #[inline] pub fn keys(&self) -> impl Iterator + Send + '_ { self.maps.keys() } diff --git a/src/database/de.rs b/src/database/de.rs index ac8c021f4..f648b89a0 100644 --- a/src/database/de.rs +++ b/src/database/de.rs @@ -13,11 +13,7 @@ pub(crate) fn from_slice<'a, T>(buf: &'a [u8]) -> Result where T: Deserialize<'a>, { - let mut deserializer = Deserializer { - buf, - pos: 0, - seq: false, - }; + let mut deserializer = Deserializer { buf, pos: 0, seq: false }; T::deserialize(&mut deserializer).debug_inspect(|_| { deserializer @@ -169,7 +165,12 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { visitor.visit_seq(self) } - fn deserialize_tuple_struct(self, _name: &'static str, _len: usize, visitor: V) -> Result + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result where V: Visitor<'de>, { @@ -186,7 +187,12 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { d.deserialize_map(visitor).map_err(Into::into) } - fn deserialize_struct(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result where V: Visitor<'de>, { @@ -201,9 +207,9 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { V: Visitor<'de>, { match name { - "Ignore" => self.record_ignore(), - "IgnoreAll" => self.record_ignore_all(), - _ => unhandled!("Unrecognized deserialization Directive {name:?}"), + | "Ignore" => self.record_ignore(), + | "IgnoreAll" => self.record_ignore_all(), + | _ => unhandled!("Unrecognized deserialization Directive {name:?}"), }; visitor.visit_unit() @@ -214,13 +220,16 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { V: Visitor<'de>, { match name { - "$serde_json::private::RawValue" => visitor.visit_map(self), - _ => visitor.visit_newtype_struct(self), + | "$serde_json::private::RawValue" => visitor.visit_map(self), + | _ => visitor.visit_newtype_struct(self), } } fn deserialize_enum( - self, _name: &'static str, _variants: &'static [&'static str], _visitor: V, + self, + _name: &'static str, + _variants: &'static [&'static str], + _visitor: V, ) -> Result where V: Visitor<'de>, @@ -260,7 +269,10 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_u8>(self, _visitor: V) -> Result { - unhandled!("deserialize u8 not implemented; try dereferencing the Handle for [u8] access instead") + unhandled!( + "deserialize u8 not implemented; try dereferencing the Handle for [u8] access \ + instead" + ) } fn deserialize_u16>(self, _visitor: V) -> Result { @@ -338,8 +350,8 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { ); match self.record_peek_byte() { - Some(b'{') => self.deserialize_map(visitor), - _ => self.deserialize_str(visitor), + | Some(b'{') => self.deserialize_map(visitor), + | _ => self.deserialize_str(visitor), } } } diff --git a/src/database/engine.rs b/src/database/engine.rs index 72fe11e62..63a6087d9 100644 --- a/src/database/engine.rs +++ b/src/database/engine.rs @@ -6,12 +6,14 @@ use std::{ sync::{atomic::AtomicU32, Arc, Mutex, RwLock}, }; -use conduwuit::{debug, error, info, utils::time::rfc2822_from_seconds, warn, Err, Result, Server}; +use conduwuit::{ + debug, error, info, utils::time::rfc2822_from_seconds, warn, Err, Result, Server, +}; use rocksdb::{ backup::{BackupEngine, BackupEngineOptions}, perf::get_memory_usage_stats, - AsColumnFamilyRef, BoundColumnFamily, Cache, ColumnFamilyDescriptor, DBCommon, DBWithThreadMode, Env, LogLevel, - MultiThreaded, Options, + AsColumnFamilyRef, BoundColumnFamily, Cache, ColumnFamilyDescriptor, DBCommon, + DBWithThreadMode, Env, LogLevel, MultiThreaded, Options, }; use crate::{ @@ -169,11 +171,13 @@ impl Engine { pub fn memory_usage(&self) -> Result { let mut res = String::new(); - let stats = get_memory_usage_stats(Some(&[&self.db]), Some(&[&self.row_cache])).or_else(or_else)?; + let stats = get_memory_usage_stats(Some(&[&self.db]), Some(&[&self.row_cache])) + .or_else(or_else)?; let mibs = |input| f64::from(u32::try_from(input / 1024).unwrap_or(0)) / 1024.0; writeln!( res, - "Memory buffers: {:.2} MiB\nPending write: {:.2} MiB\nTable readers: {:.2} MiB\nRow cache: {:.2} MiB", + "Memory buffers: {:.2} MiB\nPending write: {:.2} MiB\nTable readers: {:.2} MiB\nRow \ + cache: {:.2} MiB", mibs(stats.mem_table_total), mibs(stats.mem_table_unflushed), mibs(stats.mem_table_readers_total), @@ -202,7 +206,8 @@ impl Engine { return Ok(()); } - let options = BackupEngineOptions::new(path.expect("valid database backup path")).map_err(map_err)?; + let options = BackupEngineOptions::new(path.expect("valid database backup path")) + .map_err(map_err)?; let mut engine = BackupEngine::open(&options, &self.env).map_err(map_err)?; if config.database_backups_to_keep > 0 { let flush = !self.is_read_only(); @@ -232,13 +237,14 @@ impl Engine { let config = &self.server.config; let path = config.database_backup_path.as_ref(); if path.is_none() || path.is_some_and(|path| path.as_os_str().is_empty()) { - return Ok( - "Configure database_backup_path to enable backups, or the path specified is not valid".to_owned(), - ); + return Ok("Configure database_backup_path to enable backups, or the path \ + specified is not valid" + .to_owned()); } let mut res = String::new(); - let options = BackupEngineOptions::new(path.expect("valid database backup path")).or_else(or_else)?; + let options = BackupEngineOptions::new(path.expect("valid database backup path")) + .or_else(or_else)?; let engine = BackupEngine::open(&options, &self.env).or_else(or_else)?; for info in engine.get_backup_info() { writeln!( @@ -256,8 +262,8 @@ impl Engine { pub fn file_list(&self) -> Result { match self.db.live_files() { - Err(e) => Ok(String::from(e)), - Ok(files) => { + | Err(e) => Ok(String::from(e)), + | Ok(files) => { let mut res = String::new(); writeln!(res, "| lev | sst | keys | dels | size | column |")?; writeln!(res, "| ---: | :--- | ---: | ---: | ---: | :--- |")?; @@ -265,7 +271,12 @@ impl Engine { writeln!( res, "| {} | {:<13} | {:7}+ | {:4}- | {:9} | {} |", - file.level, file.name, file.num_entries, file.num_deletions, file.size, file.column_family_name, + file.level, + file.name, + file.num_entries, + file.num_deletions, + file.size, + file.column_family_name, )?; } @@ -277,7 +288,11 @@ impl Engine { /// Query for database property by null-terminated name which is expected to /// have a result with an integer representation. This is intended for /// low-overhead programmatic use. - pub(crate) fn property_integer(&self, cf: &impl AsColumnFamilyRef, name: &CStr) -> Result { + pub(crate) fn property_integer( + &self, + cf: &impl AsColumnFamilyRef, + name: &CStr, + ) -> Result { result(self.db.property_int_value_cf(cf, name)) .and_then(|val| val.map_or_else(|| Err!("Property {name:?} not found."), Ok)) } @@ -300,8 +315,8 @@ impl Engine { pub(crate) fn repair(db_opts: &Options, path: &PathBuf) -> Result<()> { warn!("Starting database repair. This may take a long time..."); match Db::repair(db_opts, path) { - Ok(()) => info!("Database repair successful."), - Err(e) => return Err!("Repair failed: {e:?}"), + | Ok(()) => info!("Database repair successful."), + | Err(e) => return Err!("Repair failed: {e:?}"), } Ok(()) @@ -320,10 +335,10 @@ pub(crate) fn handle_log(level: LogLevel, msg: &str) { } match level { - LogLevel::Header | LogLevel::Debug => debug!("{msg}"), - LogLevel::Error | LogLevel::Fatal => error!("{msg}"), - LogLevel::Info => debug!("{msg}"), - LogLevel::Warn => warn!("{msg}"), + | LogLevel::Header | LogLevel::Debug => debug!("{msg}"), + | LogLevel::Error | LogLevel::Fatal => error!("{msg}"), + | LogLevel::Info => debug!("{msg}"), + | LogLevel::Warn => warn!("{msg}"), }; } diff --git a/src/database/handle.rs b/src/database/handle.rs index b4d34b85c..43b57839b 100644 --- a/src/database/handle.rs +++ b/src/database/handle.rs @@ -11,11 +11,7 @@ pub struct Handle<'a> { } impl<'a> From> for Handle<'a> { - fn from(val: DBPinnableSlice<'a>) -> Self { - Self { - val, - } - } + fn from(val: DBPinnableSlice<'a>) -> Self { Self { val } } } impl Debug for Handle<'_> { diff --git a/src/database/map.rs b/src/database/map.rs index 09721b2a7..af22a43c8 100644 --- a/src/database/map.rs +++ b/src/database/map.rs @@ -56,7 +56,10 @@ impl Map { } #[inline] - pub fn watch_prefix<'a, K>(&'a self, prefix: &K) -> Pin + Send + 'a>> + pub fn watch_prefix<'a, K>( + &'a self, + prefix: &K, + ) -> Pin + Send + 'a>> where K: AsRef<[u8]> + ?Sized + Debug, { @@ -64,7 +67,9 @@ impl Map { } #[inline] - pub fn property_integer(&self, name: &CStr) -> Result { self.db.property_integer(&self.cf(), name) } + pub fn property_integer(&self, name: &CStr) -> Result { + self.db.property_integer(&self.cf(), name) + } #[inline] pub fn property(&self, name: &str) -> Result { self.db.property(&self.cf(), name) } @@ -76,7 +81,9 @@ impl Map { } impl Debug for Map { - fn fmt(&self, out: &mut fmt::Formatter<'_>) -> fmt::Result { write!(out, "Map {{name: {0}}}", self.name) } + fn fmt(&self, out: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(out, "Map {{name: {0}}}", self.name) + } } impl Display for Map { diff --git a/src/database/map/contains.rs b/src/database/map/contains.rs index aa3ea676f..424f89704 100644 --- a/src/database/map/contains.rs +++ b/src/database/map/contains.rs @@ -29,7 +29,10 @@ where /// - harder errors will panic #[inline] #[implement(super::Map)] -pub fn acontains(self: &Arc, key: &K) -> impl Future + Send + '_ +pub fn acontains( + self: &Arc, + key: &K, +) -> impl Future + Send + '_ where K: Serialize + ?Sized + Debug, { @@ -42,7 +45,11 @@ where /// - harder errors will panic #[implement(super::Map)] #[tracing::instrument(skip(self, buf), fields(%self), level = "trace")] -pub fn bcontains(self: &Arc, key: &K, buf: &mut B) -> impl Future + Send + '_ +pub fn bcontains( + self: &Arc, + key: &K, + buf: &mut B, +) -> impl Future + Send + '_ where K: Serialize + ?Sized + Debug, B: Write + AsRef<[u8]>, diff --git a/src/database/map/count.rs b/src/database/map/count.rs index 7b632bb36..b9b34613f 100644 --- a/src/database/map/count.rs +++ b/src/database/map/count.rs @@ -26,7 +26,10 @@ where /// - From is a raw #[implement(super::Map)] #[inline] -pub fn raw_count_from<'a, P>(self: &'a Arc, from: &'a P) -> impl Future + Send + 'a +pub fn raw_count_from<'a, P>( + self: &'a Arc, + from: &'a P, +) -> impl Future + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, { @@ -38,7 +41,10 @@ where /// - Prefix is structured key #[implement(super::Map)] #[inline] -pub fn count_prefix<'a, P>(self: &'a Arc, prefix: &P) -> impl Future + Send + 'a +pub fn count_prefix<'a, P>( + self: &'a Arc, + prefix: &P, +) -> impl Future + Send + 'a where P: Serialize + ?Sized + Debug + 'a, { @@ -50,7 +56,10 @@ where /// - Prefix is raw #[implement(super::Map)] #[inline] -pub fn raw_count_prefix<'a, P>(self: &'a Arc, prefix: &'a P) -> impl Future + Send + 'a +pub fn raw_count_prefix<'a, P>( + self: &'a Arc, + prefix: &'a P, +) -> impl Future + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, { diff --git a/src/database/map/get.rs b/src/database/map/get.rs index 88023b1ce..94a6b727d 100644 --- a/src/database/map/get.rs +++ b/src/database/map/get.rs @@ -31,7 +31,10 @@ where /// the query. The maximum size is supplied as const generic parameter. #[implement(super::Map)] #[inline] -pub fn aqry(self: &Arc, key: &K) -> impl Future>> + Send +pub fn aqry( + self: &Arc, + key: &K, +) -> impl Future>> + Send where K: Serialize + ?Sized + Debug, { @@ -43,7 +46,11 @@ where /// asynchronously. The key is serialized into a user-supplied Writer. #[implement(super::Map)] #[tracing::instrument(skip(self, buf), level = "trace")] -pub fn bqry(self: &Arc, key: &K, buf: &mut B) -> impl Future>> + Send +pub fn bqry( + self: &Arc, + key: &K, + buf: &mut B, +) -> impl Future>> + Send where K: Serialize + ?Sized + Debug, B: Write + AsRef<[u8]>, @@ -110,15 +117,15 @@ where match res { // cache hit; not found - Ok(None) => Err!(Request(NotFound("Not found in database"))), + | Ok(None) => Err!(Request(NotFound("Not found in database"))), // cache hit; value found - Ok(Some(res)) => Ok(Some(Handle::from(res))), + | Ok(Some(res)) => Ok(Some(Handle::from(res))), // cache miss; unknown - Err(e) if is_incomplete(&e) => Ok(None), + | Err(e) if is_incomplete(&e) => Ok(None), // some other error occurred - Err(e) => or_else(e), + | Err(e) => or_else(e), } } diff --git a/src/database/map/get_batch.rs b/src/database/map/get_batch.rs index 5f444cce2..49cd5920b 100644 --- a/src/database/map/get_batch.rs +++ b/src/database/map/get_batch.rs @@ -9,7 +9,8 @@ use crate::{util::map_err, Handle}; #[implement(super::Map)] #[tracing::instrument(skip(self, keys), level = "trace")] pub fn aqry_batch<'b, 'a: 'b, const MAX: usize, I, K>( - self: &'a Arc, keys: I, + self: &'a Arc, + keys: I, ) -> impl Stream>> + Send + 'a where I: Iterator + Send + 'a, @@ -22,7 +23,10 @@ where #[implement(super::Map)] #[tracing::instrument(skip(self, keys), level = "trace")] -pub fn get_batch<'a, I, K>(self: &'a Arc, keys: I) -> impl Stream>> + Send + 'a +pub fn get_batch<'a, I, K>( + self: &'a Arc, + keys: I, +) -> impl Stream>> + Send + 'a where I: Iterator + Debug + Send + 'a, K: AsRef<[u8]> + Debug + Send + ?Sized + Sync + 'a, @@ -34,7 +38,10 @@ where #[implement(super::Map)] #[tracing::instrument(name = "batch_blocking", level = "trace", skip_all)] -pub(crate) fn get_batch_blocking<'a, I, K>(&self, keys: I) -> impl Iterator>> + Send +pub(crate) fn get_batch_blocking<'a, I, K>( + &self, + keys: I, +) -> impl Iterator>> + Send where I: Iterator + ExactSizeIterator + Debug + Send, K: AsRef<[u8]> + Debug + Send + ?Sized + Sync + 'a, diff --git a/src/database/map/keys_from.rs b/src/database/map/keys_from.rs index 2f6d20206..2ffc68df0 100644 --- a/src/database/map/keys_from.rs +++ b/src/database/map/keys_from.rs @@ -11,7 +11,10 @@ use crate::{ }; #[implement(super::Map)] -pub fn keys_from<'a, K, P>(self: &'a Arc, from: &P) -> impl Stream>> + Send +pub fn keys_from<'a, K, P>( + self: &'a Arc, + from: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, K: Deserialize<'a> + Send, @@ -30,7 +33,10 @@ where } #[implement(super::Map)] -pub fn keys_raw_from<'a, K, P>(self: &'a Arc, from: &P) -> impl Stream>> + Send +pub fn keys_raw_from<'a, K, P>( + self: &'a Arc, + from: &P, +) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug + Sync, K: Deserialize<'a> + Send, diff --git a/src/database/map/keys_prefix.rs b/src/database/map/keys_prefix.rs index 24112ac12..32a1f04c1 100644 --- a/src/database/map/keys_prefix.rs +++ b/src/database/map/keys_prefix.rs @@ -11,7 +11,10 @@ use serde::{Deserialize, Serialize}; use crate::keyval::{result_deserialize_key, serialize_key, Key}; #[implement(super::Map)] -pub fn keys_prefix<'a, K, P>(self: &'a Arc, prefix: &P) -> impl Stream>> + Send +pub fn keys_prefix<'a, K, P>( + self: &'a Arc, + prefix: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, K: Deserialize<'a> + Send, @@ -22,7 +25,10 @@ where #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn keys_prefix_raw

(self: &Arc, prefix: &P) -> impl Stream>> + Send +pub fn keys_prefix_raw

( + self: &Arc, + prefix: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -33,7 +39,8 @@ where #[implement(super::Map)] pub fn keys_raw_prefix<'a, K, P>( - self: &'a Arc, prefix: &'a P, + self: &'a Arc, + prefix: &'a P, ) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, @@ -44,7 +51,10 @@ where } #[implement(super::Map)] -pub fn raw_keys_prefix<'a, P>(self: &'a Arc, prefix: &'a P) -> impl Stream>> + Send + 'a +pub fn raw_keys_prefix<'a, P>( + self: &'a Arc, + prefix: &'a P, +) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, { diff --git a/src/database/map/rev_keys_from.rs b/src/database/map/rev_keys_from.rs index c895105cd..a398f3159 100644 --- a/src/database/map/rev_keys_from.rs +++ b/src/database/map/rev_keys_from.rs @@ -11,7 +11,10 @@ use crate::{ }; #[implement(super::Map)] -pub fn rev_keys_from<'a, K, P>(self: &'a Arc, from: &P) -> impl Stream>> + Send +pub fn rev_keys_from<'a, K, P>( + self: &'a Arc, + from: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, K: Deserialize<'a> + Send, @@ -22,7 +25,10 @@ where #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn rev_keys_from_raw

(self: &Arc, from: &P) -> impl Stream>> + Send +pub fn rev_keys_from_raw

( + self: &Arc, + from: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -31,7 +37,10 @@ where } #[implement(super::Map)] -pub fn rev_keys_raw_from<'a, K, P>(self: &'a Arc, from: &P) -> impl Stream>> + Send +pub fn rev_keys_raw_from<'a, K, P>( + self: &'a Arc, + from: &P, +) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug + Sync, K: Deserialize<'a> + Send, @@ -42,7 +51,10 @@ where #[implement(super::Map)] #[tracing::instrument(skip(self, from), fields(%self), level = "trace")] -pub fn rev_raw_keys_from

(self: &Arc, from: &P) -> impl Stream>> + Send +pub fn rev_raw_keys_from

( + self: &Arc, + from: &P, +) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug, { diff --git a/src/database/map/rev_keys_prefix.rs b/src/database/map/rev_keys_prefix.rs index a5ed35ec2..9fda49a07 100644 --- a/src/database/map/rev_keys_prefix.rs +++ b/src/database/map/rev_keys_prefix.rs @@ -11,7 +11,10 @@ use serde::{Deserialize, Serialize}; use crate::keyval::{result_deserialize_key, serialize_key, Key}; #[implement(super::Map)] -pub fn rev_keys_prefix<'a, K, P>(self: &'a Arc, prefix: &P) -> impl Stream>> + Send +pub fn rev_keys_prefix<'a, K, P>( + self: &'a Arc, + prefix: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, K: Deserialize<'a> + Send, @@ -22,7 +25,10 @@ where #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn rev_keys_prefix_raw

(self: &Arc, prefix: &P) -> impl Stream>> + Send +pub fn rev_keys_prefix_raw

( + self: &Arc, + prefix: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -33,7 +39,8 @@ where #[implement(super::Map)] pub fn rev_keys_raw_prefix<'a, K, P>( - self: &'a Arc, prefix: &'a P, + self: &'a Arc, + prefix: &'a P, ) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, @@ -44,7 +51,10 @@ where } #[implement(super::Map)] -pub fn rev_raw_keys_prefix<'a, P>(self: &'a Arc, prefix: &'a P) -> impl Stream>> + Send + 'a +pub fn rev_raw_keys_prefix<'a, P>( + self: &'a Arc, + prefix: &'a P, +) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, { diff --git a/src/database/map/rev_stream_from.rs b/src/database/map/rev_stream_from.rs index 2d6a76b79..6ddb9bc74 100644 --- a/src/database/map/rev_stream_from.rs +++ b/src/database/map/rev_stream_from.rs @@ -19,7 +19,8 @@ use crate::{ /// - Result is deserialized #[implement(super::Map)] pub fn rev_stream_from<'a, K, V, P>( - self: &'a Arc, from: &P, + self: &'a Arc, + from: &P, ) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, @@ -36,7 +37,10 @@ where /// - Result is raw #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn rev_stream_from_raw

(self: &Arc, from: &P) -> impl Stream>> + Send +pub fn rev_stream_from_raw

( + self: &Arc, + from: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -50,7 +54,8 @@ where /// - Result is deserialized #[implement(super::Map)] pub fn rev_stream_raw_from<'a, K, V, P>( - self: &'a Arc, from: &P, + self: &'a Arc, + from: &P, ) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug + Sync, @@ -67,7 +72,10 @@ where /// - Result is raw #[implement(super::Map)] #[tracing::instrument(skip(self, from), fields(%self), level = "trace")] -pub fn rev_raw_stream_from

(self: &Arc, from: &P) -> impl Stream>> + Send +pub fn rev_raw_stream_from

( + self: &Arc, + from: &P, +) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug, { diff --git a/src/database/map/rev_stream_prefix.rs b/src/database/map/rev_stream_prefix.rs index 13aa40f26..857aa3a5d 100644 --- a/src/database/map/rev_stream_prefix.rs +++ b/src/database/map/rev_stream_prefix.rs @@ -16,7 +16,8 @@ use crate::keyval::{result_deserialize, serialize_key, KeyVal}; /// - Result is deserialized #[implement(super::Map)] pub fn rev_stream_prefix<'a, K, V, P>( - self: &'a Arc, prefix: &P, + self: &'a Arc, + prefix: &P, ) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, @@ -33,7 +34,10 @@ where /// - Result is raw #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn rev_stream_prefix_raw

(self: &Arc, prefix: &P) -> impl Stream>> + Send +pub fn rev_stream_prefix_raw

( + self: &Arc, + prefix: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -48,7 +52,8 @@ where /// - Result is deserialized #[implement(super::Map)] pub fn rev_stream_raw_prefix<'a, K, V, P>( - self: &'a Arc, prefix: &'a P, + self: &'a Arc, + prefix: &'a P, ) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, @@ -65,7 +70,8 @@ where /// - Result is raw #[implement(super::Map)] pub fn rev_raw_stream_prefix<'a, P>( - self: &'a Arc, prefix: &'a P, + self: &'a Arc, + prefix: &'a P, ) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, diff --git a/src/database/map/stream_from.rs b/src/database/map/stream_from.rs index c6fe439a8..1dae9d78a 100644 --- a/src/database/map/stream_from.rs +++ b/src/database/map/stream_from.rs @@ -18,7 +18,10 @@ use crate::{ /// - Query is serialized /// - Result is deserialized #[implement(super::Map)] -pub fn stream_from<'a, K, V, P>(self: &'a Arc, from: &P) -> impl Stream>> + Send +pub fn stream_from<'a, K, V, P>( + self: &'a Arc, + from: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, K: Deserialize<'a> + Send, @@ -33,7 +36,10 @@ where /// - Result is raw #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn stream_from_raw

(self: &Arc, from: &P) -> impl Stream>> + Send +pub fn stream_from_raw

( + self: &Arc, + from: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -47,7 +53,8 @@ where /// - Result is deserialized #[implement(super::Map)] pub fn stream_raw_from<'a, K, V, P>( - self: &'a Arc, from: &P, + self: &'a Arc, + from: &P, ) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug + Sync, @@ -63,7 +70,10 @@ where /// - Result is raw #[implement(super::Map)] #[tracing::instrument(skip(self, from), fields(%self), level = "trace")] -pub fn raw_stream_from

(self: &Arc, from: &P) -> impl Stream>> + Send +pub fn raw_stream_from

( + self: &Arc, + from: &P, +) -> impl Stream>> + Send where P: AsRef<[u8]> + ?Sized + Debug, { diff --git a/src/database/map/stream_prefix.rs b/src/database/map/stream_prefix.rs index e7dad2114..a05e2fc5c 100644 --- a/src/database/map/stream_prefix.rs +++ b/src/database/map/stream_prefix.rs @@ -16,7 +16,8 @@ use crate::keyval::{result_deserialize, serialize_key, KeyVal}; /// - Result is deserialized #[implement(super::Map)] pub fn stream_prefix<'a, K, V, P>( - self: &'a Arc, prefix: &P, + self: &'a Arc, + prefix: &P, ) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, @@ -33,7 +34,10 @@ where /// - Result is raw #[implement(super::Map)] #[tracing::instrument(skip(self), level = "trace")] -pub fn stream_prefix_raw

(self: &Arc, prefix: &P) -> impl Stream>> + Send +pub fn stream_prefix_raw

( + self: &Arc, + prefix: &P, +) -> impl Stream>> + Send where P: Serialize + ?Sized + Debug, { @@ -48,7 +52,8 @@ where /// - Result is deserialized #[implement(super::Map)] pub fn stream_raw_prefix<'a, K, V, P>( - self: &'a Arc, prefix: &'a P, + self: &'a Arc, + prefix: &'a P, ) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, @@ -65,7 +70,8 @@ where /// - Result is raw #[implement(super::Map)] pub fn raw_stream_prefix<'a, P>( - self: &'a Arc, prefix: &'a P, + self: &'a Arc, + prefix: &'a P, ) -> impl Stream>> + Send + 'a where P: AsRef<[u8]> + ?Sized + Debug + Sync + 'a, diff --git a/src/database/opts.rs b/src/database/opts.rs index 52ed48189..933830bd8 100644 --- a/src/database/opts.rs +++ b/src/database/opts.rs @@ -2,8 +2,9 @@ use std::{cmp, collections::HashMap, convert::TryFrom}; use conduwuit::{err, utils, Config, Result}; use rocksdb::{ - statistics::StatsLevel, BlockBasedOptions, Cache, DBCompactionStyle, DBCompressionType, DBRecoveryMode, Env, - LogLevel, LruCacheOptions, Options, UniversalCompactOptions, UniversalCompactionStopStyle, + statistics::StatsLevel, BlockBasedOptions, Cache, DBCompactionStyle, DBCompressionType, + DBRecoveryMode, Env, LogLevel, LruCacheOptions, Options, UniversalCompactOptions, + UniversalCompactionStopStyle, }; /// Create database-wide options suitable for opening the database. This also @@ -11,7 +12,12 @@ use rocksdb::{ /// resulting value. Note that we require special per-column options on some /// columns, therefor columns should only be opened after passing this result /// through cf_options(). -pub(crate) fn db_options(config: &Config, env: &mut Env, row_cache: &Cache, col_cache: &Cache) -> Result { +pub(crate) fn db_options( + config: &Config, + env: &mut Env, + row_cache: &Cache, + col_cache: &Cache, +) -> Result { const DEFAULT_STATS_LEVEL: StatsLevel = if cfg!(debug_assertions) { StatsLevel::ExceptDetailedTimers } else { @@ -73,13 +79,13 @@ pub(crate) fn db_options(config: &Config, env: &mut Env, row_cache: &Cache, col_ opts.set_disable_auto_compactions(!config.rocksdb_compaction); opts.set_statistics_level(match config.rocksdb_stats_level { - 0 => StatsLevel::DisableAll, - 1 => DEFAULT_STATS_LEVEL, - 2 => StatsLevel::ExceptHistogramOrTimers, - 3 => StatsLevel::ExceptTimers, - 4 => StatsLevel::ExceptDetailedTimers, - 5 => StatsLevel::ExceptTimeForMutex, - 6_u8..=u8::MAX => StatsLevel::All, + | 0 => StatsLevel::DisableAll, + | 1 => DEFAULT_STATS_LEVEL, + | 2 => StatsLevel::ExceptHistogramOrTimers, + | 3 => StatsLevel::ExceptTimers, + | 4 => StatsLevel::ExceptDetailedTimers, + | 5 => StatsLevel::ExceptTimeForMutex, + | 6_u8..=u8::MAX => StatsLevel::All, }); // Default: https://github.com/facebook/rocksdb/wiki/WAL-Recovery-Modes#ktoleratecorruptedtailrecords @@ -88,11 +94,11 @@ pub(crate) fn db_options(config: &Config, env: &mut Env, row_cache: &Cache, col_ // recovered in this manner as it's likely any lost information will be // restored via federation. opts.set_wal_recovery_mode(match config.rocksdb_recovery_mode { - 0 => DBRecoveryMode::AbsoluteConsistency, - 1 => DBRecoveryMode::TolerateCorruptedTailRecords, - 2 => DBRecoveryMode::PointInTime, - 3 => DBRecoveryMode::SkipAnyCorruptedRecord, - 4_u8..=u8::MAX => unimplemented!(), + | 0 => DBRecoveryMode::AbsoluteConsistency, + | 1 => DBRecoveryMode::TolerateCorruptedTailRecords, + | 2 => DBRecoveryMode::PointInTime, + | 3 => DBRecoveryMode::SkipAnyCorruptedRecord, + | 4_u8..=u8::MAX => unimplemented!(), }); // @@ -111,11 +117,14 @@ pub(crate) fn db_options(config: &Config, env: &mut Env, row_cache: &Cache, col_ /// db_options() as the argument to this function and use the return value in /// the arguments to open the specific column. pub(crate) fn cf_options( - cfg: &Config, name: &str, mut opts: Options, cache: &mut HashMap, + cfg: &Config, + name: &str, + mut opts: Options, + cache: &mut HashMap, ) -> Result { // Columns with non-default compaction options match name { - "backupid_algorithm" + | "backupid_algorithm" | "backupid_etag" | "backupkeyid_backup" | "roomid_shortroomid" @@ -125,12 +134,12 @@ pub(crate) fn cf_options( | "shortstatehash_statediff" | "userdevicetxnid_response" | "userfilterid_filter" => set_for_sequential_small_uc(&mut opts, cfg), - &_ => {}, + | &_ => {}, } // Columns with non-default table/cache configs match name { - "shorteventid_eventid" => set_table_with_new_cache( + | "shorteventid_eventid" => set_table_with_new_cache( &mut opts, cfg, cache, @@ -138,7 +147,7 @@ pub(crate) fn cf_options( cache_size(cfg, cfg.shorteventid_cache_capacity, 64)?, ), - "eventid_shorteventid" => set_table_with_new_cache( + | "eventid_shorteventid" => set_table_with_new_cache( &mut opts, cfg, cache, @@ -146,7 +155,7 @@ pub(crate) fn cf_options( cache_size(cfg, cfg.eventidshort_cache_capacity, 64)?, ), - "eventid_pduid" => set_table_with_new_cache( + | "eventid_pduid" => set_table_with_new_cache( &mut opts, cfg, cache, @@ -154,7 +163,7 @@ pub(crate) fn cf_options( cache_size(cfg, cfg.eventid_pdu_cache_capacity, 64)?, ), - "shorteventid_authchain" => { + | "shorteventid_authchain" => { set_table_with_new_cache( &mut opts, cfg, @@ -164,7 +173,7 @@ pub(crate) fn cf_options( ); }, - "shortstatekey_statekey" => set_table_with_new_cache( + | "shortstatekey_statekey" => set_table_with_new_cache( &mut opts, cfg, cache, @@ -172,7 +181,7 @@ pub(crate) fn cf_options( cache_size(cfg, cfg.shortstatekey_cache_capacity, 1024)?, ), - "statekey_shortstatekey" => set_table_with_new_cache( + | "statekey_shortstatekey" => set_table_with_new_cache( &mut opts, cfg, cache, @@ -180,22 +189,32 @@ pub(crate) fn cf_options( cache_size(cfg, cfg.statekeyshort_cache_capacity, 1024)?, ), - "servernameevent_data" => set_table_with_new_cache( + | "servernameevent_data" => set_table_with_new_cache( &mut opts, cfg, cache, name, - cache_size(cfg, cfg.servernameevent_data_cache_capacity, 128)?, /* Raw average value size = 102, key + cache_size(cfg, cfg.servernameevent_data_cache_capacity, 128)?, /* Raw average + * value size = + * 102, key * size = 34 */ ), - "eventid_outlierpdu" => { - set_table_with_new_cache(&mut opts, cfg, cache, name, cache_size(cfg, cfg.pdu_cache_capacity, 1536)?); + | "eventid_outlierpdu" => { + set_table_with_new_cache( + &mut opts, + cfg, + cache, + name, + cache_size(cfg, cfg.pdu_cache_capacity, 1536)?, + ); }, - "pduid_pdu" => set_table_with_shared_cache(&mut opts, cfg, cache, name, "eventid_outlierpdu"), + | "pduid_pdu" => { + set_table_with_shared_cache(&mut opts, cfg, cache, name, "eventid_outlierpdu"); + }, - &_ => {}, + | &_ => {}, } Ok(opts) @@ -203,11 +222,11 @@ pub(crate) fn cf_options( fn set_logging_defaults(opts: &mut Options, config: &Config) { let rocksdb_log_level = match config.rocksdb_log_level.as_ref() { - "debug" => LogLevel::Debug, - "info" => LogLevel::Info, - "warn" => LogLevel::Warn, - "fatal" => LogLevel::Fatal, - _ => LogLevel::Error, + | "debug" => LogLevel::Debug, + | "info" => LogLevel::Info, + | "warn" => LogLevel::Warn, + | "fatal" => LogLevel::Fatal, + | _ => LogLevel::Error, }; opts.set_log_level(rocksdb_log_level); @@ -225,13 +244,13 @@ fn set_logging_defaults(opts: &mut Options, config: &Config) { fn set_compression_defaults(opts: &mut Options, config: &Config) { let rocksdb_compression_algo = match config.rocksdb_compression_algo.as_ref() { - "snappy" => DBCompressionType::Snappy, - "zlib" => DBCompressionType::Zlib, - "bz2" => DBCompressionType::Bz2, - "lz4" => DBCompressionType::Lz4, - "lz4hc" => DBCompressionType::Lz4hc, - "none" => DBCompressionType::None, - _ => DBCompressionType::Zstd, + | "snappy" => DBCompressionType::Snappy, + | "zlib" => DBCompressionType::Zlib, + | "bz2" => DBCompressionType::Bz2, + | "lz4" => DBCompressionType::Lz4, + | "lz4hc" => DBCompressionType::Lz4hc, + | "none" => DBCompressionType::None, + | _ => DBCompressionType::Zstd, }; if config.rocksdb_bottommost_compression { @@ -239,7 +258,13 @@ fn set_compression_defaults(opts: &mut Options, config: &Config) { opts.set_bottommost_zstd_max_train_bytes(0, true); // -14 w_bits is only read by zlib. - opts.set_bottommost_compression_options(-14, config.rocksdb_bottommost_compression_level, 0, 0, true); + opts.set_bottommost_compression_options( + -14, + config.rocksdb_bottommost_compression_level, + 0, + 0, + true, + ); } // -14 w_bits is only read by zlib. @@ -338,7 +363,11 @@ fn uc_options(_config: &Config) -> UniversalCompactOptions { } fn set_table_with_new_cache( - opts: &mut Options, config: &Config, caches: &mut HashMap, name: &str, size: usize, + opts: &mut Options, + config: &Config, + caches: &mut HashMap, + name: &str, + size: usize, ) { let mut cache_opts = LruCacheOptions::default(); cache_opts.set_capacity(size); @@ -351,7 +380,11 @@ fn set_table_with_new_cache( } fn set_table_with_shared_cache( - opts: &mut Options, config: &Config, cache: &HashMap, _name: &str, cache_name: &str, + opts: &mut Options, + config: &Config, + cache: &HashMap, + _name: &str, + cache_name: &str, ) { let mut table = table_options(config); table.set_block_cache( diff --git a/src/database/pool.rs b/src/database/pool.rs index 3301b821a..e4d78897d 100644 --- a/src/database/pool.rs +++ b/src/database/pool.rs @@ -230,8 +230,8 @@ fn worker_wait(&self, recv: &Receiver) -> Result { #[implement(Pool)] fn worker_handle(&self, cmd: Cmd) { match cmd { - Cmd::Get(cmd) => self.handle_get(cmd), - Cmd::Iter(cmd) => self.handle_iter(cmd), + | Cmd::Get(cmd) => self.handle_get(cmd), + | Cmd::Iter(cmd) => self.handle_iter(cmd), } } @@ -251,8 +251,8 @@ fn handle_iter(&self, mut cmd: Seek) { let from = cmd.key.as_deref().map(Into::into); let result = match cmd.dir { - Direction::Forward => cmd.state.init_fwd(from), - Direction::Reverse => cmd.state.init_rev(from), + | Direction::Forward => cmd.state.init_fwd(from), + | Direction::Reverse => cmd.state.init_rev(from), }; let chan_result = chan.send(into_send_seek(result)); @@ -274,8 +274,8 @@ fn _handle_seek(&self, mut cmd: Seek) { } match cmd.dir { - Direction::Forward => cmd.state.seek_fwd(), - Direction::Reverse => cmd.state.seek_rev(), + | Direction::Forward => cmd.state.seek_fwd(), + | Direction::Reverse => cmd.state.seek_rev(), }; let chan_result = chan.send(into_send_seek(cmd.state)); diff --git a/src/database/ser.rs b/src/database/ser.rs index 8abe55218..878319fe8 100644 --- a/src/database/ser.rs +++ b/src/database/ser.rs @@ -6,7 +6,9 @@ use serde::{ser, Serialize}; use crate::util::unhandled; #[inline] -pub fn serialize_to_vec(val: T) -> Result> { serialize_to::, T>(val) } +pub fn serialize_to_vec(val: T) -> Result> { + serialize_to::, T>(val) +} #[inline] pub fn serialize_to(val: T) -> Result @@ -26,17 +28,15 @@ where W: Write + AsRef<[u8]> + 'a, T: Serialize, { - let mut serializer = Serializer { - out, - depth: 0, - sep: false, - fin: false, - }; + let mut serializer = Serializer { out, depth: 0, sep: false, fin: false }; val.serialize(&mut serializer) .map_err(|error| err!(SerdeSer("{error}"))) .debug_inspect(|()| { - debug_assert_eq!(serializer.depth, 0, "Serialization completed at non-zero recursion level"); + debug_assert_eq!( + serializer.depth, 0, + "Serialization completed at non-zero recursion level" + ); })?; Ok((*out).as_ref()) @@ -132,29 +132,45 @@ impl ser::Serializer for &mut Serializer<'_, W> { Ok(self) } - fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { self.tuple_start(); Ok(self) } fn serialize_tuple_variant( - self, _name: &'static str, _idx: u32, _var: &'static str, _len: usize, + self, + _name: &'static str, + _idx: u32, + _var: &'static str, + _len: usize, ) -> Result { unhandled!("serialize Tuple Variant not implemented") } fn serialize_map(self, _len: Option) -> Result { - unhandled!("serialize Map not implemented; did you mean to use database::Json() around your serde_json::Value?") + unhandled!( + "serialize Map not implemented; did you mean to use database::Json() around your \ + serde_json::Value?" + ) } fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { unhandled!( - "serialize Struct not implemented at this time; did you mean to use database::Json() around your struct?" + "serialize Struct not implemented at this time; did you mean to use \ + database::Json() around your struct?" ) } fn serialize_struct_variant( - self, _name: &'static str, _idx: u32, _var: &'static str, _len: usize, + self, + _name: &'static str, + _idx: u32, + _var: &'static str, + _len: usize, ) -> Result { unhandled!("serialize Struct Variant not implemented") } @@ -170,36 +186,47 @@ impl ser::Serializer for &mut Serializer<'_, W> { ); match name { - "Json" => serde_json::to_writer(&mut self.out, value).map_err(Into::into), - _ => unhandled!("Unrecognized serialization Newtype {name:?}"), + | "Json" => serde_json::to_writer(&mut self.out, value).map_err(Into::into), + | _ => unhandled!("Unrecognized serialization Newtype {name:?}"), } } fn serialize_newtype_variant( - self, _name: &'static str, _idx: u32, _var: &'static str, _value: &T, + self, + _name: &'static str, + _idx: u32, + _var: &'static str, + _value: &T, ) -> Result { unhandled!("serialize Newtype Variant not implemented") } fn serialize_unit_struct(self, name: &'static str) -> Result { match name { - "Interfix" => { + | "Interfix" => { self.set_finalized(); }, - "Separator" => { + | "Separator" => { self.separator()?; }, - _ => unhandled!("Unrecognized serialization directive: {name:?}"), + | _ => unhandled!("Unrecognized serialization directive: {name:?}"), }; Ok(()) } - fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _var: &'static str) -> Result { + fn serialize_unit_variant( + self, + _name: &'static str, + _idx: u32, + _var: &'static str, + ) -> Result { unhandled!("serialize Unit Variant not implemented") } - fn serialize_some(self, val: &T) -> Result { val.serialize(self) } + fn serialize_some(self, val: &T) -> Result { + val.serialize(self) + } fn serialize_none(self) -> Result { Ok(()) } @@ -226,27 +253,39 @@ impl ser::Serializer for &mut Serializer<'_, W> { self.write(v) } - fn serialize_f64(self, _v: f64) -> Result { unhandled!("serialize f64 not implemented") } + fn serialize_f64(self, _v: f64) -> Result { + unhandled!("serialize f64 not implemented") + } - fn serialize_f32(self, _v: f32) -> Result { unhandled!("serialize f32 not implemented") } + fn serialize_f32(self, _v: f32) -> Result { + unhandled!("serialize f32 not implemented") + } fn serialize_i64(self, v: i64) -> Result { self.write(&v.to_be_bytes()) } fn serialize_i32(self, v: i32) -> Result { self.write(&v.to_be_bytes()) } - fn serialize_i16(self, _v: i16) -> Result { unhandled!("serialize i16 not implemented") } + fn serialize_i16(self, _v: i16) -> Result { + unhandled!("serialize i16 not implemented") + } - fn serialize_i8(self, _v: i8) -> Result { unhandled!("serialize i8 not implemented") } + fn serialize_i8(self, _v: i8) -> Result { + unhandled!("serialize i8 not implemented") + } fn serialize_u64(self, v: u64) -> Result { self.write(&v.to_be_bytes()) } fn serialize_u32(self, v: u32) -> Result { self.write(&v.to_be_bytes()) } - fn serialize_u16(self, _v: u16) -> Result { unhandled!("serialize u16 not implemented") } + fn serialize_u16(self, _v: u16) -> Result { + unhandled!("serialize u16 not implemented") + } fn serialize_u8(self, v: u8) -> Result { self.write(&[v]) } - fn serialize_bool(self, _v: bool) -> Result { unhandled!("serialize bool not implemented") } + fn serialize_bool(self, _v: bool) -> Result { + unhandled!("serialize bool not implemented") + } fn serialize_unit(self) -> Result { unhandled!("serialize unit not implemented") } } @@ -255,7 +294,9 @@ impl ser::SerializeSeq for &mut Serializer<'_, W> { type Error = Error; type Ok = (); - fn serialize_element(&mut self, val: &T) -> Result { val.serialize(&mut **self) } + fn serialize_element(&mut self, val: &T) -> Result { + val.serialize(&mut **self) + } fn end(self) -> Result { self.sequence_end() } } @@ -315,7 +356,11 @@ impl ser::SerializeStruct for &mut Serializer<'_, W> { type Error = Error; type Ok = (); - fn serialize_field(&mut self, _key: &'static str, _val: &T) -> Result { + fn serialize_field( + &mut self, + _key: &'static str, + _val: &T, + ) -> Result { unhandled!("serialize Struct Field not implemented") } @@ -326,9 +371,15 @@ impl ser::SerializeStructVariant for &mut Serializer<'_, W> { type Error = Error; type Ok = (); - fn serialize_field(&mut self, _key: &'static str, _val: &T) -> Result { + fn serialize_field( + &mut self, + _key: &'static str, + _val: &T, + ) -> Result { unhandled!("serialize Struct Variant Field not implemented") } - fn end(self) -> Result { unhandled!("serialize Struct Variant End not implemented") } + fn end(self) -> Result { + unhandled!("serialize Struct Variant End not implemented") + } } diff --git a/src/database/stream/items.rs b/src/database/stream/items.rs index 06cb6de98..2a38d97ea 100644 --- a/src/database/stream/items.rs +++ b/src/database/stream/items.rs @@ -17,18 +17,12 @@ pub(crate) struct Items<'a> { impl<'a> Items<'a> { pub(crate) fn new(db: &'a Arc, cf: &'a Arc, opts: ReadOptions) -> Self { - Self { - state: State::new(db, cf, opts), - } + Self { state: State::new(db, cf, opts) } } } impl<'a> convert::From> for Items<'a> { - fn from(state: State<'a>) -> Self { - Self { - state, - } - } + fn from(state: State<'a>) -> Self { Self { state } } } impl<'a> Cursor<'a, KeyVal<'a>> for Items<'a> { @@ -40,11 +34,7 @@ impl<'a> Cursor<'a, KeyVal<'a>> for Items<'a> { fn seek(&mut self) { self.state.seek_fwd(); } #[inline] - fn init(self, from: From<'a>) -> Self { - Self { - state: self.state.init_fwd(from), - } - } + fn init(self, from: From<'a>) -> Self { Self { state: self.state.init_fwd(from) } } } impl<'a> Stream for Items<'a> { diff --git a/src/database/stream/items_rev.rs b/src/database/stream/items_rev.rs index 2d0c46391..c3a6cc7f3 100644 --- a/src/database/stream/items_rev.rs +++ b/src/database/stream/items_rev.rs @@ -17,18 +17,12 @@ pub(crate) struct ItemsRev<'a> { impl<'a> ItemsRev<'a> { pub(crate) fn new(db: &'a Arc, cf: &'a Arc, opts: ReadOptions) -> Self { - Self { - state: State::new(db, cf, opts), - } + Self { state: State::new(db, cf, opts) } } } impl<'a> convert::From> for ItemsRev<'a> { - fn from(state: State<'a>) -> Self { - Self { - state, - } - } + fn from(state: State<'a>) -> Self { Self { state } } } impl<'a> Cursor<'a, KeyVal<'a>> for ItemsRev<'a> { @@ -40,11 +34,7 @@ impl<'a> Cursor<'a, KeyVal<'a>> for ItemsRev<'a> { fn seek(&mut self) { self.state.seek_rev(); } #[inline] - fn init(self, from: From<'a>) -> Self { - Self { - state: self.state.init_rev(from), - } - } + fn init(self, from: From<'a>) -> Self { Self { state: self.state.init_rev(from) } } } impl<'a> Stream for ItemsRev<'a> { diff --git a/src/database/stream/keys.rs b/src/database/stream/keys.rs index a901b3421..0696781db 100644 --- a/src/database/stream/keys.rs +++ b/src/database/stream/keys.rs @@ -17,18 +17,12 @@ pub(crate) struct Keys<'a> { impl<'a> Keys<'a> { pub(crate) fn new(db: &'a Arc, cf: &'a Arc, opts: ReadOptions) -> Self { - Self { - state: State::new(db, cf, opts), - } + Self { state: State::new(db, cf, opts) } } } impl<'a> convert::From> for Keys<'a> { - fn from(state: State<'a>) -> Self { - Self { - state, - } - } + fn from(state: State<'a>) -> Self { Self { state } } } impl<'a> Cursor<'a, Key<'a>> for Keys<'a> { @@ -41,11 +35,7 @@ impl<'a> Cursor<'a, Key<'a>> for Keys<'a> { fn seek(&mut self) { self.state.seek_fwd(); } #[inline] - fn init(self, from: From<'a>) -> Self { - Self { - state: self.state.init_fwd(from), - } - } + fn init(self, from: From<'a>) -> Self { Self { state: self.state.init_fwd(from) } } } impl<'a> Stream for Keys<'a> { diff --git a/src/database/stream/keys_rev.rs b/src/database/stream/keys_rev.rs index 73758a857..42706d9f9 100644 --- a/src/database/stream/keys_rev.rs +++ b/src/database/stream/keys_rev.rs @@ -17,18 +17,12 @@ pub(crate) struct KeysRev<'a> { impl<'a> KeysRev<'a> { pub(crate) fn new(db: &'a Arc, cf: &'a Arc, opts: ReadOptions) -> Self { - Self { - state: State::new(db, cf, opts), - } + Self { state: State::new(db, cf, opts) } } } impl<'a> convert::From> for KeysRev<'a> { - fn from(state: State<'a>) -> Self { - Self { - state, - } - } + fn from(state: State<'a>) -> Self { Self { state } } } impl<'a> Cursor<'a, Key<'a>> for KeysRev<'a> { @@ -41,11 +35,7 @@ impl<'a> Cursor<'a, Key<'a>> for KeysRev<'a> { fn seek(&mut self) { self.state.seek_rev(); } #[inline] - fn init(self, from: From<'a>) -> Self { - Self { - state: self.state.init_rev(from), - } - } + fn init(self, from: From<'a>) -> Self { Self { state: self.state.init_rev(from) } } } impl<'a> Stream for KeysRev<'a> { diff --git a/src/database/tests.rs b/src/database/tests.rs index 7f486966a..3d41a544d 100644 --- a/src/database/tests.rs +++ b/src/database/tests.rs @@ -66,10 +66,7 @@ fn ser_complex() { media_id: "AbCdEfGhIjK", }; - let dim = Dim { - width: 123, - height: 456, - }; + let dim = Dim { width: 123, height: 456 }; let mut a = Vec::new(); a.extend_from_slice(b"mxc://"); @@ -128,9 +125,7 @@ fn ser_json_macro() { foo: String, } - let content = Foo { - foo: "bar".to_owned(), - }; + let content = Foo { foo: "bar".to_owned() }; let content = serde_json::to_value(content).expect("failed to serialize content"); let sender: &UserId = "@foo:example.com".try_into().unwrap(); let serialized = serialize_to_vec(Json(json!({ @@ -153,7 +148,8 @@ fn ser_json_raw() { ..Default::default() }; - let value = serde_json::value::to_raw_value(&filter).expect("failed to serialize to raw value"); + let value = + serde_json::value::to_raw_value(&filter).expect("failed to serialize to raw value"); let a = serialize_to_vec(value.get()).expect("failed to serialize raw value"); let s = String::from_utf8_lossy(&a); assert_eq!(&s, r#"{"event_fields":["content.body"]}"#); @@ -169,7 +165,8 @@ fn ser_json_raw_json() { ..Default::default() }; - let value = serde_json::value::to_raw_value(&filter).expect("failed to serialize to raw value"); + let value = + serde_json::value::to_raw_value(&filter).expect("failed to serialize to raw value"); let a = serialize_to_vec(Json(value)).expect("failed to serialize json value"); let s = String::from_utf8_lossy(&a); assert_eq!(&s, r#"{"event_fields":["content.body"]}"#); @@ -241,7 +238,8 @@ fn de_tuple_ignore() { let room_id: &RoomId = "!room:example.com".try_into().unwrap(); let raw: &[u8] = b"@user:example.com\xFF@user2:example.net\xFF!room:example.com"; - let (a, _, c): (&UserId, Ignore, &RoomId) = de::from_slice(raw).expect("failed to deserialize"); + let (a, _, c): (&UserId, Ignore, &RoomId) = + de::from_slice(raw).expect("failed to deserialize"); assert_eq!(a, user_id, "deserialized user_id does not match"); assert_eq!(c, room_id, "deserialized room_id does not match"); @@ -254,7 +252,8 @@ fn de_json_array() { let b: Raw>> = de::from_slice(&s).expect("failed to deserialize"); - let d: Vec = serde_json::from_str(b.json().get()).expect("failed to deserialize JSON"); + let d: Vec = + serde_json::from_str(b.json().get()).expect("failed to deserialize JSON"); for (i, a) in a.iter().enumerate() { assert_eq!(*a, d[i]); @@ -268,7 +267,8 @@ fn de_json_raw_array() { let b: Raw>> = de::from_slice(&s).expect("failed to deserialize"); - let c: Vec> = serde_json::from_str(b.json().get()).expect("failed to deserialize JSON"); + let c: Vec> = + serde_json::from_str(b.json().get()).expect("failed to deserialize JSON"); for (i, a) in a.iter().enumerate() { let c = serde_json::to_value(c[i].json()).expect("failed to deserialize JSON to string"); diff --git a/src/database/util.rs b/src/database/util.rs index 0fca3b68e..c2a020e3e 100644 --- a/src/database/util.rs +++ b/src/database/util.rs @@ -30,13 +30,15 @@ pub(crate) fn _into_direction(mode: &IteratorMode<'_>) -> Direction { use IteratorMode::{End, From, Start}; match mode { - Start | From(_, Forward) => Forward, - End | From(_, Reverse) => Reverse, + | Start | From(_, Forward) => Forward, + | End | From(_, Reverse) => Reverse, } } #[inline] -pub(crate) fn result(r: std::result::Result) -> Result { +pub(crate) fn result( + r: std::result::Result, +) -> Result { r.map_or_else(or_else, and_then) } diff --git a/src/database/watchers.rs b/src/database/watchers.rs index 93c82b442..9ce6f74c9 100644 --- a/src/database/watchers.rs +++ b/src/database/watchers.rs @@ -15,10 +15,13 @@ pub(crate) struct Watchers { } impl Watchers { - pub(crate) fn watch<'a>(&'a self, prefix: &[u8]) -> Pin + Send + 'a>> { + pub(crate) fn watch<'a>( + &'a self, + prefix: &[u8], + ) -> Pin + Send + 'a>> { let mut rx = match self.watchers.write().unwrap().entry(prefix.to_vec()) { - hash_map::Entry::Occupied(o) => o.get().1.clone(), - hash_map::Entry::Vacant(v) => { + | hash_map::Entry::Occupied(o) => o.get().1.clone(), + | hash_map::Entry::Vacant(v) => { let (tx, rx) = watch::channel(()); v.insert((tx, rx.clone())); rx diff --git a/src/macros/admin.rs b/src/macros/admin.rs index b0dc19560..e98e914cf 100644 --- a/src/macros/admin.rs +++ b/src/macros/admin.rs @@ -42,14 +42,14 @@ fn dispatch_arm(v: &Variant) -> Result { let target = camel_to_snake_string(&format!("{name}")); let handler = Ident::new(&target, Span::call_site().into()); let res = match &v.fields { - Fields::Named(fields) => { + | Fields::Named(fields) => { let field = fields.named.iter().filter_map(|f| f.ident.as_ref()); let arg = field.clone(); quote! { #name { #( #field ),* } => Box::pin(context.#handler(#( #arg ),*)).await?, } }, - Fields::Unnamed(fields) => { + | Fields::Unnamed(fields) => { let Some(ref field) = fields.unnamed.first() else { return Err(Error::new(Span::call_site().into(), "One unnamed field required")); }; @@ -57,7 +57,7 @@ fn dispatch_arm(v: &Variant) -> Result { #name ( #field ) => Box::pin(#handler::process(#field, context)).await?, } }, - Fields::Unit => { + | Fields::Unit => { quote! { #name => Box::pin(context.#handler()).await?, } diff --git a/src/macros/config.rs b/src/macros/config.rs index 2934a0b20..eb269e1e2 100644 --- a/src/macros/config.rs +++ b/src/macros/config.rs @@ -4,8 +4,8 @@ use proc_macro::TokenStream; use proc_macro2::Span; use quote::ToTokens; use syn::{ - parse::Parser, punctuated::Punctuated, spanned::Spanned, Error, Expr, ExprLit, Field, Fields, FieldsNamed, - ItemStruct, Lit, Meta, MetaList, MetaNameValue, Type, TypePath, + parse::Parser, punctuated::Punctuated, spanned::Spanned, Error, Expr, ExprLit, Field, Fields, + FieldsNamed, ItemStruct, Lit, Meta, MetaList, MetaNameValue, Type, TypePath, }; use crate::{ @@ -29,9 +29,9 @@ pub(super) fn example_generator(input: ItemStruct, args: &[Meta]) -> Result Result<()> { let settings = get_simple_settings(args); - let filename = settings - .get("filename") - .ok_or_else(|| Error::new(args[0].span(), "missing required 'filename' attribute argument"))?; + let filename = settings.get("filename").ok_or_else(|| { + Error::new(args[0].span(), "missing required 'filename' attribute argument") + })?; let undocumented = settings .get("undocumented") @@ -43,9 +43,9 @@ fn generate_example(input: &ItemStruct, args: &[Meta]) -> Result<()> { .split(' ') .collect(); - let section = settings - .get("section") - .ok_or_else(|| Error::new(args[0].span(), "missing required 'section' attribute argument"))?; + let section = settings.get("section").ok_or_else(|| { + Error::new(args[0].span(), "missing required 'section' attribute argument") + })?; let mut file = OpenOptions::new() .write(true) @@ -53,7 +53,12 @@ fn generate_example(input: &ItemStruct, args: &[Meta]) -> Result<()> { .truncate(section == "global") .append(section != "global") .open(filename) - .map_err(|e| Error::new(Span::call_site(), format!("Failed to open config file for generation: {e}")))?; + .map_err(|e| { + Error::new( + Span::call_site(), + format!("Failed to open config file for generation: {e}"), + ) + })?; if let Some(header) = settings.get("header") { file.write_all(header.as_bytes()) @@ -63,11 +68,7 @@ fn generate_example(input: &ItemStruct, args: &[Meta]) -> Result<()> { file.write_fmt(format_args!("\n[{section}]\n")) .expect("written to config file"); - if let Fields::Named(FieldsNamed { - named, - .. - }) = &input.fields - { + if let Fields::Named(FieldsNamed { named, .. }) = &input.fields { for field in named { let Some(ident) = &field.ident else { continue; @@ -120,12 +121,7 @@ fn generate_example(input: &ItemStruct, args: &[Meta]) -> Result<()> { fn get_default(field: &Field) -> Option { for attr in &field.attrs { - let Meta::List(MetaList { - path, - tokens, - .. - }) = &attr.meta - else { + let Meta::List(MetaList { path, tokens, .. }) = &attr.meta else { continue; }; @@ -149,23 +145,18 @@ fn get_default(field: &Field) -> Option { }; match arg { - Meta::NameValue(MetaNameValue { - value: Expr::Lit(ExprLit { - lit: Lit::Str(str), - .. - }), + | Meta::NameValue(MetaNameValue { + value: Expr::Lit(ExprLit { lit: Lit::Str(str), .. }), .. }) => { match str.value().as_str() { - "HashSet::new" | "Vec::new" | "RegexSet::empty" => Some("[]".to_owned()), - "true_fn" => return Some("true".to_owned()), - _ => return None, + | "HashSet::new" | "Vec::new" | "RegexSet::empty" => Some("[]".to_owned()), + | "true_fn" => return Some("true".to_owned()), + | _ => return None, }; }, - Meta::Path { - .. - } => return Some("false".to_owned()), - _ => return None, + | Meta::Path { .. } => return Some("false".to_owned()), + | _ => return None, }; } @@ -174,12 +165,7 @@ fn get_default(field: &Field) -> Option { fn get_doc_default(field: &Field) -> Option { for attr in &field.attrs { - let Meta::NameValue(MetaNameValue { - path, - value, - .. - }) = &attr.meta - else { + let Meta::NameValue(MetaNameValue { path, value, .. }) = &attr.meta else { continue; }; @@ -187,11 +173,7 @@ fn get_doc_default(field: &Field) -> Option { continue; } - let Expr::Lit(ExprLit { - lit, - .. - }) = &value - else { + let Expr::Lit(ExprLit { lit, .. }) = &value else { continue; }; @@ -217,12 +199,7 @@ fn get_doc_default(field: &Field) -> Option { fn get_doc_comment(field: &Field) -> Option { let mut out = String::new(); for attr in &field.attrs { - let Meta::NameValue(MetaNameValue { - path, - value, - .. - }) = &attr.meta - else { + let Meta::NameValue(MetaNameValue { path, value, .. }) = &attr.meta else { continue; }; @@ -230,11 +207,7 @@ fn get_doc_comment(field: &Field) -> Option { continue; } - let Expr::Lit(ExprLit { - lit, - .. - }) = &value - else { + let Expr::Lit(ExprLit { lit, .. }) = &value else { continue; }; @@ -254,11 +227,7 @@ fn get_doc_comment(field: &Field) -> Option { } fn get_type_name(field: &Field) -> Option { - let Type::Path(TypePath { - path, - .. - }) = &field.ty - else { + let Type::Path(TypePath { path, .. }) = &field.ty else { return None; }; diff --git a/src/macros/implement.rs b/src/macros/implement.rs index b798bae5b..8d18f2430 100644 --- a/src/macros/implement.rs +++ b/src/macros/implement.rs @@ -20,12 +20,15 @@ pub(super) fn implement(item: ItemFn, args: &[Meta]) -> Result { } fn get_receiver(args: &[Meta]) -> Result { - let receiver = &args - .first() - .ok_or_else(|| Error::new(Span::call_site().into(), "Missing required argument to receiver"))?; + let receiver = &args.first().ok_or_else(|| { + Error::new(Span::call_site().into(), "Missing required argument to receiver") + })?; let Meta::Path(receiver) = receiver else { - return Err(Error::new(Span::call_site().into(), "First argument is not path to receiver")); + return Err(Error::new( + Span::call_site().into(), + "First argument is not path to receiver", + )); }; Ok(receiver.clone()) diff --git a/src/macros/refutable.rs b/src/macros/refutable.rs index facb4729d..66e0ebc32 100644 --- a/src/macros/refutable.rs +++ b/src/macros/refutable.rs @@ -9,11 +9,7 @@ pub(super) fn refutable(mut item: ItemFn, _args: &[Meta]) -> Result let stmt = &mut item.block.stmts; let sig = &mut item.sig; for (i, input) in inputs.iter().enumerate() { - let Typed(PatType { - pat, - .. - }) = input - else { + let Typed(PatType { pat, .. }) = input else { continue; }; @@ -24,11 +20,7 @@ pub(super) fn refutable(mut item: ItemFn, _args: &[Meta]) -> Result let variant = &pat.path; let fields = &pat.fields; - let Some(Typed(PatType { - ref mut pat, - .. - })) = sig.inputs.get_mut(i) - else { + let Some(Typed(PatType { ref mut pat, .. })) = sig.inputs.get_mut(i) else { continue; }; diff --git a/src/macros/rustc.rs b/src/macros/rustc.rs index f484e5f50..1220c8d4e 100644 --- a/src/macros/rustc.rs +++ b/src/macros/rustc.rs @@ -4,8 +4,8 @@ use quote::quote; pub(super) fn flags_capture(args: TokenStream) -> TokenStream { let cargo_crate_name = std::env::var("CARGO_CRATE_NAME"); let crate_name = match cargo_crate_name.as_ref() { - Err(_) => return args, - Ok(crate_name) => crate_name.trim_start_matches("conduwuit_"), + | Err(_) => return args, + | Ok(crate_name) => crate_name.trim_start_matches("conduwuit_"), }; let flag = std::env::args().collect::>(); diff --git a/src/macros/utils.rs b/src/macros/utils.rs index 23c4c16f9..9f799f7b1 100644 --- a/src/macros/utils.rs +++ b/src/macros/utils.rs @@ -6,23 +6,11 @@ use crate::Result; pub(crate) fn get_simple_settings(args: &[Meta]) -> HashMap { args.iter().fold(HashMap::new(), |mut map, arg| { - let Meta::NameValue(MetaNameValue { - path, - value, - .. - }) = arg - else { + let Meta::NameValue(MetaNameValue { path, value, .. }) = arg else { return map; }; - let Expr::Lit( - ExprLit { - lit: Lit::Str(str), - .. - }, - .., - ) = value - else { + let Expr::Lit(ExprLit { lit: Lit::Str(str), .. }, ..) = value else { return map; }; diff --git a/src/main/logging.rs b/src/main/logging.rs index 999265e77..e8a18b10c 100644 --- a/src/main/logging.rs +++ b/src/main/logging.rs @@ -10,12 +10,15 @@ use conduwuit::{ use tracing_subscriber::{layer::SubscriberExt, reload, EnvFilter, Layer, Registry}; #[cfg(feature = "perf_measurements")] -pub(crate) type TracingFlameGuard = Option>>; +pub(crate) type TracingFlameGuard = + Option>>; #[cfg(not(feature = "perf_measurements"))] pub(crate) type TracingFlameGuard = (); #[allow(clippy::redundant_clone)] -pub(crate) fn init(config: &Config) -> Result<(LogLevelReloadHandles, TracingFlameGuard, Arc)> { +pub(crate) fn init( + config: &Config, +) -> Result<(LogLevelReloadHandles, TracingFlameGuard, Arc)> { let reload_handles = LogLevelReloadHandles::default(); let console_span_events = fmt_span::from_str(&config.log_span_events).unwrap_or_err(); @@ -27,7 +30,8 @@ pub(crate) fn init(config: &Config) -> Result<(LogLevelReloadHandles, TracingFla .with_ansi(config.log_colors) .with_span_events(console_span_events) .with_thread_ids(config.log_thread_ids); - let (console_reload_filter, console_reload_handle) = reload::Layer::new(console_filter.clone()); + let (console_reload_filter, console_reload_handle) = + reload::Layer::new(console_filter.clone()); reload_handles.add("console", Box::new(console_reload_handle)); let cap_state = Arc::new(capture::State::new()); @@ -39,8 +43,8 @@ pub(crate) fn init(config: &Config) -> Result<(LogLevelReloadHandles, TracingFla #[cfg(feature = "sentry_telemetry")] let subscriber = { - let sentry_filter = - EnvFilter::try_new(&config.sentry_filter).map_err(|e| err!(Config("sentry_filter", "{e}.")))?; + let sentry_filter = EnvFilter::try_new(&config.sentry_filter) + .map_err(|e| err!(Config("sentry_filter", "{e}.")))?; let sentry_layer = sentry_tracing::layer(); let (sentry_reload_filter, sentry_reload_handle) = reload::Layer::new(sentry_filter); reload_handles.add("sentry", Box::new(sentry_reload_handle)); @@ -52,8 +56,9 @@ pub(crate) fn init(config: &Config) -> Result<(LogLevelReloadHandles, TracingFla let (flame_layer, flame_guard) = if config.tracing_flame { let flame_filter = EnvFilter::try_new(&config.tracing_flame_filter) .map_err(|e| err!(Config("tracing_flame_filter", "{e}.")))?; - let (flame_layer, flame_guard) = tracing_flame::FlameLayer::with_file(&config.tracing_flame_output_path) - .map_err(|e| err!(Config("tracing_flame_output_path", "{e}.")))?; + let (flame_layer, flame_guard) = + tracing_flame::FlameLayer::with_file(&config.tracing_flame_output_path) + .map_err(|e| err!(Config("tracing_flame_output_path", "{e}.")))?; let flame_layer = flame_layer .with_empty_samples(false) .with_filter(flame_filter); @@ -62,17 +67,20 @@ pub(crate) fn init(config: &Config) -> Result<(LogLevelReloadHandles, TracingFla (None, None) }; - let jaeger_filter = - EnvFilter::try_new(&config.jaeger_filter).map_err(|e| err!(Config("jaeger_filter", "{e}.")))?; + let jaeger_filter = EnvFilter::try_new(&config.jaeger_filter) + .map_err(|e| err!(Config("jaeger_filter", "{e}.")))?; let jaeger_layer = config.allow_jaeger.then(|| { - opentelemetry::global::set_text_map_propagator(opentelemetry_jaeger::Propagator::new()); + opentelemetry::global::set_text_map_propagator( + opentelemetry_jaeger::Propagator::new(), + ); let tracer = opentelemetry_jaeger::new_agent_pipeline() .with_auto_split_batch(true) .with_service_name("conduwuit") .install_batch(opentelemetry_sdk::runtime::Tokio) .expect("jaeger agent pipeline"); let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); - let (jaeger_reload_filter, jaeger_reload_handle) = reload::Layer::new(jaeger_filter.clone()); + let (jaeger_reload_filter, jaeger_reload_handle) = + reload::Layer::new(jaeger_filter.clone()); reload_handles.add("jaeger", Box::new(jaeger_reload_handle)); Some(telemetry.with_filter(jaeger_reload_filter)) }); diff --git a/src/main/main.rs b/src/main/main.rs index 5c0665847..0946e8359 100644 --- a/src/main/main.rs +++ b/src/main/main.rs @@ -68,8 +68,8 @@ async fn async_main(server: &Arc) -> Result<(), Error> { extern crate conduwuit_router as router; match router::start(&server.server).await { - Ok(services) => server.services.lock().await.insert(services), - Err(error) => { + | Ok(services) => server.services.lock().await.insert(services), + | Err(error) => { error!("Critical error starting server: {error}"); return Err(error); }, diff --git a/src/main/mods.rs b/src/main/mods.rs index ca984a641..ca799b90f 100644 --- a/src/main/mods.rs +++ b/src/main/mods.rs @@ -44,8 +44,8 @@ pub(crate) async fn run(server: &Arc, starts: bool) -> Result<(bool, boo if starts { let start = main_mod.get::("start")?; match start(&server.server).await { - Ok(services) => server.services.lock().await.insert(services), - Err(error) => { + | Ok(services) => server.services.lock().await.insert(services), + | Err(error) => { error!("Starting server: {error}"); return Err(error); }, diff --git a/src/main/server.rs b/src/main/server.rs index 7c3eec1f7..00c7a6cc8 100644 --- a/src/main/server.rs +++ b/src/main/server.rs @@ -23,7 +23,10 @@ pub(crate) struct Server { } impl Server { - pub(crate) fn build(args: &Args, runtime: Option<&runtime::Handle>) -> Result, Error> { + pub(crate) fn build( + args: &Args, + runtime: Option<&runtime::Handle>, + ) -> Result, Error> { let _runtime_guard = runtime.map(runtime::Handle::enter); let raw_config = Config::load(args.config.as_deref())?; @@ -33,12 +36,14 @@ impl Server { #[cfg(feature = "sentry_telemetry")] let sentry_guard = crate::sentry::init(&config); - let (tracing_reload_handle, tracing_flame_guard, capture) = crate::logging::init(&config)?; + let (tracing_reload_handle, tracing_flame_guard, capture) = + crate::logging::init(&config)?; config.check()?; #[cfg(unix)] - sys::maximize_fd_limit().expect("Unable to increase maximum soft and hard file descriptor limit"); + sys::maximize_fd_limit() + .expect("Unable to increase maximum soft and hard file descriptor limit"); info!( server_name = %config.server_name, @@ -49,14 +54,10 @@ impl Server { ); Ok(Arc::new(Self { - server: Arc::new(conduwuit::Server::new( - config, - runtime.cloned(), - Log { - reload: tracing_reload_handle, - capture, - }, - )), + server: Arc::new(conduwuit::Server::new(config, runtime.cloned(), Log { + reload: tracing_reload_handle, + capture, + })), services: None.into(), diff --git a/src/router/layers.rs b/src/router/layers.rs index 1c5beacec..96bca4fd4 100644 --- a/src/router/layers.rs +++ b/src/router/layers.rs @@ -41,7 +41,11 @@ pub(crate) fn build(services: &Arc) -> Result<(Router, Guard)> { #[cfg(feature = "sentry_telemetry")] let layers = layers.layer(sentry_tower::NewSentryLayer::>::new_from_top()); - #[cfg(any(feature = "zstd_compression", feature = "gzip_compression", feature = "brotli_compression"))] + #[cfg(any( + feature = "zstd_compression", + feature = "gzip_compression", + feature = "brotli_compression" + ))] let layers = layers.layer(compression_layer(server)); let layers = layers @@ -88,7 +92,11 @@ pub(crate) fn build(services: &Arc) -> Result<(Router, Guard)> { Ok((router.layer(layers), guard)) } -#[cfg(any(feature = "zstd_compression", feature = "gzip_compression", feature = "brotli_compression"))] +#[cfg(any( + feature = "zstd_compression", + feature = "gzip_compression", + feature = "brotli_compression" +))] fn compression_layer(server: &Server) -> tower_http::compression::CompressionLayer { let mut compression_layer = tower_http::compression::CompressionLayer::new(); @@ -148,11 +156,15 @@ fn cors_layer(_server: &Server) -> CorsLayer { .max_age(Duration::from_secs(86400)) } -fn body_limit_layer(server: &Server) -> DefaultBodyLimit { DefaultBodyLimit::max(server.config.max_request_size) } +fn body_limit_layer(server: &Server) -> DefaultBodyLimit { + DefaultBodyLimit::max(server.config.max_request_size) +} #[tracing::instrument(name = "panic", level = "error", skip_all)] #[allow(clippy::needless_pass_by_value)] -fn catch_panic(err: Box) -> http::Response> { +fn catch_panic( + err: Box, +) -> http::Response> { //TODO: XXX /* conduwuit_service::services() diff --git a/src/router/mod.rs b/src/router/mod.rs index aab0b1850..f64dcb676 100644 --- a/src/router/mod.rs +++ b/src/router/mod.rs @@ -17,7 +17,9 @@ conduwuit::mod_dtor! {} conduwuit::rustc_flags_capture! {} #[unsafe(no_mangle)] -pub extern "Rust" fn start(server: &Arc) -> Pin>> + Send>> { +pub extern "Rust" fn start( + server: &Arc, +) -> Pin>> + Send>> { AssertUnwindSafe(run::start(server.clone())) .catch_unwind() .map_err(Error::from_panic) @@ -26,7 +28,9 @@ pub extern "Rust" fn start(server: &Arc) -> Pin) -> Pin> + Send>> { +pub extern "Rust" fn stop( + services: Arc, +) -> Pin> + Send>> { AssertUnwindSafe(run::stop(services)) .catch_unwind() .map_err(Error::from_panic) @@ -35,7 +39,9 @@ pub extern "Rust" fn stop(services: Arc) -> Pin) -> Pin> + Send>> { +pub extern "Rust" fn run( + services: &Arc, +) -> Pin> + Send>> { AssertUnwindSafe(run::run(services.clone())) .catch_unwind() .map_err(Error::from_panic) diff --git a/src/router/request.rs b/src/router/request.rs index b17e9c4fd..559c7f88a 100644 --- a/src/router/request.rs +++ b/src/router/request.rs @@ -14,7 +14,9 @@ use http::{Method, StatusCode, Uri}; skip_all, )] pub(crate) async fn spawn( - State(services): State>, req: http::Request, next: axum::middleware::Next, + State(services): State>, + req: http::Request, + next: axum::middleware::Next, ) -> Result { let server = &services.server; if !server.running() { @@ -40,7 +42,9 @@ pub(crate) async fn spawn( #[tracing::instrument(level = "debug", skip_all)] pub(crate) async fn handle( - State(services): State>, req: http::Request, next: axum::middleware::Next, + State(services): State>, + req: http::Request, + next: axum::middleware::Next, ) -> Result { let server = &services.server; if !server.running() { diff --git a/src/router/run.rs b/src/router/run.rs index 6d5c8923c..248f70525 100644 --- a/src/router/run.rs +++ b/src/router/run.rs @@ -33,9 +33,10 @@ pub(crate) async fn run(services: Arc) -> Result<()> { .runtime() .spawn(signal(server.clone(), tx.clone(), handle.clone())); - let mut listener = server - .runtime() - .spawn(serve::serve(services.clone(), handle.clone(), tx.subscribe())); + let mut listener = + server + .runtime() + .spawn(serve::serve(services.clone(), handle.clone(), tx.subscribe())); // Focal point debug!("Running"); @@ -63,7 +64,8 @@ pub(crate) async fn start(server: Arc) -> Result> { let services = Services::build(server).await?.start().await?; #[cfg(feature = "systemd")] - sd_notify::notify(true, &[sd_notify::NotifyState::Ready]).expect("failed to notify systemd of ready state"); + sd_notify::notify(true, &[sd_notify::NotifyState::Ready]) + .expect("failed to notify systemd of ready state"); debug!("Started"); Ok(services) @@ -98,7 +100,8 @@ pub(crate) async fn stop(services: Arc) -> Result<()> { } #[cfg(feature = "systemd")] - sd_notify::notify(true, &[sd_notify::NotifyState::Stopping]).expect("failed to notify systemd of stopping state"); + sd_notify::notify(true, &[sd_notify::NotifyState::Stopping]) + .expect("failed to notify systemd of stopping state"); info!("Shutdown complete."); Ok(()) @@ -121,7 +124,12 @@ async fn signal(server: Arc, tx: Sender<()>, handle: axum_server::Handle } } -async fn handle_shutdown(server: &Arc, tx: &Sender<()>, handle: &axum_server::Handle, sig: &str) { +async fn handle_shutdown( + server: &Arc, + tx: &Sender<()>, + handle: &axum_server::Handle, + sig: &str, +) { debug!("Received signal {sig}"); if let Err(e) = tx.send(()) { error!("failed sending shutdown transaction to channel: {e}"); @@ -139,7 +147,9 @@ async fn handle_shutdown(server: &Arc, tx: &Sender<()>, handle: &axum_se } async fn handle_services_poll( - server: &Arc, result: Result<()>, listener: JoinHandle>, + server: &Arc, + result: Result<()>, + listener: JoinHandle>, ) -> Result<()> { debug!("Service manager finished: {result:?}"); diff --git a/src/router/serve/mod.rs b/src/router/serve/mod.rs index 357923595..f6262202f 100644 --- a/src/router/serve/mod.rs +++ b/src/router/serve/mod.rs @@ -14,7 +14,9 @@ use super::layers; /// Serve clients pub(super) async fn serve( - services: Arc, handle: ServerHandle, shutdown: broadcast::Receiver<()>, + services: Arc, + handle: ServerHandle, + shutdown: broadcast::Receiver<()>, ) -> Result<()> { let server = &services.server; let config = &server.config; diff --git a/src/router/serve/plain.rs b/src/router/serve/plain.rs index f6b6fba43..0e971f3ce 100644 --- a/src/router/serve/plain.rs +++ b/src/router/serve/plain.rs @@ -9,12 +9,16 @@ use conduwuit::{debug_info, info, Result, Server}; use tokio::task::JoinSet; pub(super) async fn serve( - server: &Arc, app: Router, handle: ServerHandle, addrs: Vec, + server: &Arc, + app: Router, + handle: ServerHandle, + addrs: Vec, ) -> Result<()> { let app = app.into_make_service_with_connect_info::(); let mut join_set = JoinSet::new(); for addr in &addrs { - join_set.spawn_on(bind(*addr).handle(handle.clone()).serve(app.clone()), server.runtime()); + join_set + .spawn_on(bind(*addr).handle(handle.clone()).serve(app.clone()), server.runtime()); } info!("Listening on {addrs:?}"); diff --git a/src/router/serve/tls.rs b/src/router/serve/tls.rs index 7f54cfccc..9d3fbd3bd 100644 --- a/src/router/serve/tls.rs +++ b/src/router/serve/tls.rs @@ -10,7 +10,12 @@ use conduwuit::{err, Result, Server}; use tokio::task::JoinSet; use tracing::{debug, info, warn}; -pub(super) async fn serve(server: &Arc, app: Router, handle: ServerHandle, addrs: Vec) -> Result { +pub(super) async fn serve( + server: &Arc, + app: Router, + handle: ServerHandle, + addrs: Vec, +) -> Result { let tls = &server.config.tls; let certs = tls .certs @@ -29,7 +34,8 @@ pub(super) async fn serve(server: &Arc, app: Router, handle: ServerHandl debug!("Using direct TLS. Certificate path {certs} and certificate private key path {key}",); info!( - "Note: It is strongly recommended that you use a reverse proxy instead of running conduwuit directly with TLS." + "Note: It is strongly recommended that you use a reverse proxy instead of running \ + conduwuit directly with TLS." ); let conf = RustlsConfig::from_pem_file(certs, key).await?; @@ -58,8 +64,8 @@ pub(super) async fn serve(server: &Arc, app: Router, handle: ServerHandl if tls.dual_protocol { warn!( - "Listening on {addrs:?} with TLS certificate {certs} and supporting plain text (HTTP) connections too \ - (insecure!)", + "Listening on {addrs:?} with TLS certificate {certs} and supporting plain text \ + (HTTP) connections too (insecure!)", ); } else { info!("Listening on {addrs:?} with TLS certificate {certs}"); diff --git a/src/router/serve/unix.rs b/src/router/serve/unix.rs index fb37e125f..bee3c8c7a 100644 --- a/src/router/serve/unix.rs +++ b/src/router/serve/unix.rs @@ -10,7 +10,9 @@ use axum::{ extract::{connect_info::IntoMakeServiceWithConnectInfo, Request}, Router, }; -use conduwuit::{debug, debug_error, info, result::UnwrapInfallible, trace, warn, Err, Result, Server}; +use conduwuit::{ + debug, debug_error, info, result::UnwrapInfallible, trace, warn, Err, Result, Server, +}; use hyper::{body::Incoming, service::service_fn}; use hyper_util::{ rt::{TokioExecutor, TokioIo}, @@ -31,7 +33,11 @@ const NULL_ADDR: net::SocketAddr = net::SocketAddr::new(IpAddr::V4(Ipv4Addr::new const FINI_POLL_INTERVAL: Duration = Duration::from_millis(750); #[tracing::instrument(skip_all, level = "debug")] -pub(super) async fn serve(server: &Arc, app: Router, mut shutdown: broadcast::Receiver<()>) -> Result<()> { +pub(super) async fn serve( + server: &Arc, + app: Router, + mut shutdown: broadcast::Receiver<()>, +) -> Result<()> { let mut tasks = JoinSet::<()>::new(); let executor = TokioExecutor::new(); let app = app.into_make_service_with_connect_info::(); @@ -55,8 +61,12 @@ pub(super) async fn serve(server: &Arc, app: Router, mut shutdown: broad } async fn accept( - server: &Arc, listener: &UnixListener, tasks: &mut JoinSet<()>, mut app: MakeService, - builder: server::conn::auto::Builder, conn: (UnixStream, SocketAddr), + server: &Arc, + listener: &UnixListener, + tasks: &mut JoinSet<()>, + mut app: MakeService, + builder: server::conn::auto::Builder, + conn: (UnixStream, SocketAddr), ) { let (socket, remote) = conn; let socket = TokioIo::new(socket); @@ -103,7 +113,8 @@ async fn init(server: &Arc) -> Result { } let socket_perms = config.unix_socket_perms.to_string(); - let octal_perms = u32::from_str_radix(&socket_perms, 8).expect("failed to convert octal permissions"); + let octal_perms = + u32::from_str_radix(&socket_perms, 8).expect("failed to convert octal permissions"); let perms = std::fs::Permissions::from_mode(octal_perms); if let Err(e) = fs::set_permissions(&path, perms).await { return Err!("Failed to set socket {path:?} permissions: {e}"); diff --git a/src/service/account_data/mod.rs b/src/service/account_data/mod.rs index 536a24e86..ddbc15a4c 100644 --- a/src/service/account_data/mod.rs +++ b/src/service/account_data/mod.rs @@ -9,8 +9,8 @@ use database::{Deserialized, Handle, Interfix, Json, Map}; use futures::{Stream, StreamExt, TryFutureExt}; use ruma::{ events::{ - AnyGlobalAccountDataEvent, AnyRawAccountDataEvent, AnyRoomAccountDataEvent, GlobalAccountDataEventType, - RoomAccountDataEventType, + AnyGlobalAccountDataEvent, AnyRawAccountDataEvent, AnyRoomAccountDataEvent, + GlobalAccountDataEventType, RoomAccountDataEventType, }, serde::Raw, RoomId, UserId, @@ -54,7 +54,11 @@ impl crate::Service for Service { #[allow(clippy::needless_pass_by_value)] #[implement(Service)] pub async fn update( - &self, room_id: Option<&RoomId>, user_id: &UserId, event_type: RoomAccountDataEventType, data: &serde_json::Value, + &self, + room_id: Option<&RoomId>, + user_id: &UserId, + event_type: RoomAccountDataEventType, + data: &serde_json::Value, ) -> Result<()> { if data.get("type").is_none() || data.get("content").is_none() { return Err!(Request(InvalidParam("Account data doesn't have all required fields."))); @@ -91,7 +95,12 @@ where /// Searches the global account data for a specific kind. #[implement(Service)] -pub async fn get_room(&self, room_id: &RoomId, user_id: &UserId, kind: RoomAccountDataEventType) -> Result +pub async fn get_room( + &self, + room_id: &RoomId, + user_id: &UserId, + kind: RoomAccountDataEventType, +) -> Result where T: for<'de> Deserialize<'de>, { @@ -101,7 +110,12 @@ where } #[implement(Service)] -pub async fn get_raw(&self, room_id: Option<&RoomId>, user_id: &UserId, kind: &str) -> Result> { +pub async fn get_raw( + &self, + room_id: Option<&RoomId>, + user_id: &UserId, + kind: &str, +) -> Result> { let key = (room_id, user_id, kind.to_owned()); self.db .roomusertype_roomuserdataid @@ -113,7 +127,10 @@ pub async fn get_raw(&self, room_id: Option<&RoomId>, user_id: &UserId, kind: &s /// Returns all changes to the account data that happened after `since`. #[implement(Service)] pub fn changes_since<'a>( - &'a self, room_id: Option<&'a RoomId>, user_id: &'a UserId, since: u64, + &'a self, + room_id: Option<&'a RoomId>, + user_id: &'a UserId, + since: u64, ) -> impl Stream + Send + 'a { let prefix = (room_id, user_id, Interfix); let prefix = database::serialize_key(prefix).expect("failed to serialize prefix"); @@ -128,8 +145,10 @@ pub fn changes_since<'a>( .ready_take_while(move |(k, _)| k.starts_with(&prefix)) .map(move |(_, v)| { match room_id { - Some(_) => serde_json::from_slice::>(v).map(AnyRawAccountDataEvent::Room), - None => serde_json::from_slice::>(v).map(AnyRawAccountDataEvent::Global), + | Some(_) => serde_json::from_slice::>(v) + .map(AnyRawAccountDataEvent::Room), + | None => serde_json::from_slice::>(v) + .map(AnyRawAccountDataEvent::Global), } .map_err(|e| err!(Database("Database contains invalid account data: {e}"))) .log_err() diff --git a/src/service/admin/console.rs b/src/service/admin/console.rs index c25eb6c69..0edcd2f30 100644 --- a/src/service/admin/console.rs +++ b/src/service/admin/console.rs @@ -94,15 +94,16 @@ impl Console { debug!("session starting"); while self.server.running() { match self.readline().await { - Ok(event) => match event { - ReadlineEvent::Line(string) => self.clone().handle(string).await, - ReadlineEvent::Interrupted => continue, - ReadlineEvent::Eof => break, - ReadlineEvent::Quit => self.server.shutdown().unwrap_or_else(error::default_log), + | Ok(event) => match event { + | ReadlineEvent::Line(string) => self.clone().handle(string).await, + | ReadlineEvent::Interrupted => continue, + | ReadlineEvent::Eof => break, + | ReadlineEvent::Quit => + self.server.shutdown().unwrap_or_else(error::default_log), }, - Err(error) => match error { - ReadlineError::Closed => break, - ReadlineError::IO(error) => { + | Err(error) => match error { + | ReadlineError::Closed => break, + | ReadlineError::IO(error) => { error!("console I/O: {error:?}"); break; }, @@ -158,9 +159,9 @@ impl Console { async fn process(self: Arc, line: String) { match self.admin.command_in_place(line, None).await { - Ok(Some(ref content)) => self.output(content), - Err(ref content) => self.output_err(content), - _ => unreachable!(), + | Ok(Some(ref content)) => self.output(content), + | Err(ref content) => self.output_err(content), + | _ => unreachable!(), } } diff --git a/src/service/admin/create.rs b/src/service/admin/create.rs index 971fdf671..7b691fb1f 100644 --- a/src/service/admin/create.rs +++ b/src/service/admin/create.rs @@ -42,8 +42,9 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { let create_content = { use RoomVersionId::*; match room_version { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => RoomCreateEventContent::new_v1(server_user.clone()), - _ => RoomCreateEventContent::new_v11(), + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => + RoomCreateEventContent::new_v1(server_user.clone()), + | _ => RoomCreateEventContent::new_v11(), } }; @@ -52,15 +53,12 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomCreateEventContent { - federate: true, - predecessor: None, - room_version: room_version.clone(), - ..create_content - }, - ), + PduBuilder::state(String::new(), &RoomCreateEventContent { + federate: true, + predecessor: None, + room_version: room_version.clone(), + ..create_content + }), server_user, &room_id, &state_lock, @@ -72,7 +70,10 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state(server_user.to_string(), &RoomMemberEventContent::new(MembershipState::Join)), + PduBuilder::state( + server_user.to_string(), + &RoomMemberEventContent::new(MembershipState::Join), + ), server_user, &room_id, &state_lock, @@ -86,13 +87,10 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomPowerLevelsEventContent { - users, - ..Default::default() - }, - ), + PduBuilder::state(String::new(), &RoomPowerLevelsEventContent { + users, + ..Default::default() + }), server_user, &room_id, &state_lock, @@ -131,7 +129,10 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state(String::new(), &RoomGuestAccessEventContent::new(GuestAccess::Forbidden)), + PduBuilder::state( + String::new(), + &RoomGuestAccessEventContent::new(GuestAccess::Forbidden), + ), server_user, &room_id, &state_lock, @@ -155,12 +156,9 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomTopicEventContent { - topic: format!("Manage {}", services.globals.server_name()), - }, - ), + PduBuilder::state(String::new(), &RoomTopicEventContent { + topic: format!("Manage {}", services.globals.server_name()), + }), server_user, &room_id, &state_lock, @@ -174,13 +172,10 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomCanonicalAliasEventContent { - alias: Some(alias.clone()), - alt_aliases: Vec::new(), - }, - ), + PduBuilder::state(String::new(), &RoomCanonicalAliasEventContent { + alias: Some(alias.clone()), + alt_aliases: Vec::new(), + }), server_user, &room_id, &state_lock, @@ -197,12 +192,7 @@ pub async fn create_admin_room(services: &Services) -> Result<()> { .rooms .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomPreviewUrlsEventContent { - disabled: true, - }, - ), + PduBuilder::state(String::new(), &RoomPreviewUrlsEventContent { disabled: true }), server_user, &room_id, &state_lock, diff --git a/src/service/admin/grant.rs b/src/service/admin/grant.rs index 2b05bfc78..3ad9283fb 100644 --- a/src/service/admin/grant.rs +++ b/src/service/admin/grant.rs @@ -34,7 +34,10 @@ pub async fn make_user_admin(&self, user_id: &UserId) -> Result<()> { self.services .timeline .build_and_append_pdu( - PduBuilder::state(user_id.to_string(), &RoomMemberEventContent::new(MembershipState::Invite)), + PduBuilder::state( + user_id.to_string(), + &RoomMemberEventContent::new(MembershipState::Invite), + ), server_user, &room_id, &state_lock, @@ -43,7 +46,10 @@ pub async fn make_user_admin(&self, user_id: &UserId) -> Result<()> { self.services .timeline .build_and_append_pdu( - PduBuilder::state(user_id.to_string(), &RoomMemberEventContent::new(MembershipState::Join)), + PduBuilder::state( + user_id.to_string(), + &RoomMemberEventContent::new(MembershipState::Join), + ), user_id, &room_id, &state_lock, @@ -51,18 +57,18 @@ pub async fn make_user_admin(&self, user_id: &UserId) -> Result<()> { .await?; // Set power level - let users = BTreeMap::from_iter([(server_user.clone(), 100.into()), (user_id.to_owned(), 100.into())]); + let users = BTreeMap::from_iter([ + (server_user.clone(), 100.into()), + (user_id.to_owned(), 100.into()), + ]); self.services .timeline .build_and_append_pdu( - PduBuilder::state( - String::new(), - &RoomPowerLevelsEventContent { - users, - ..Default::default() - }, - ), + PduBuilder::state(String::new(), &RoomPowerLevelsEventContent { + users, + ..Default::default() + }), server_user, &room_id, &state_lock, @@ -103,9 +109,7 @@ async fn set_room_tag(&self, room_id: &RoomId, user_id: &UserId, tag: &str) -> R .get_room(room_id, user_id, RoomAccountDataEventType::Tag) .await .unwrap_or_else(|_| TagEvent { - content: TagEventContent { - tags: BTreeMap::new(), - }, + content: TagEventContent { tags: BTreeMap::new() }, }); event diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index c4783565a..59639e582 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -10,7 +10,9 @@ use std::{ }; use async_trait::async_trait; -use conduwuit::{debug, err, error, error::default_log, pdu::PduBuilder, Error, PduEvent, Result, Server}; +use conduwuit::{ + debug, err, error, error::default_log, pdu::PduBuilder, Error, PduEvent, Result, Server, +}; pub use create::create_admin_room; use futures::{FutureExt, TryFutureExt}; use loole::{Receiver, Sender}; @@ -158,21 +160,19 @@ impl Service { /// the queue is full. pub fn command(&self, command: String, reply_id: Option) -> Result<()> { self.sender - .send(CommandInput { - command, - reply_id, - }) + .send(CommandInput { command, reply_id }) .map_err(|e| err!("Failed to enqueue admin command: {e:?}")) } /// Dispatches a comamnd to the processor on the current task and waits for /// completion. - pub async fn command_in_place(&self, command: String, reply_id: Option) -> ProcessorResult { - self.process_command(CommandInput { - command, - reply_id, - }) - .await + pub async fn command_in_place( + &self, + command: String, + reply_id: Option, + ) -> ProcessorResult { + self.process_command(CommandInput { command, reply_id }) + .await } /// Invokes the tab-completer to complete the command. When unavailable, @@ -191,8 +191,8 @@ impl Service { async fn handle_command(&self, command: CommandInput) { match self.process_command(command).await { - Ok(None) => debug!("Command successful with no response"), - Ok(Some(output)) | Err(output) => self + | Ok(None) => debug!("Command successful with no response"), + | Ok(Some(output)) | Err(output) => self .handle_response(output) .await .unwrap_or_else(default_log), @@ -250,10 +250,7 @@ impl Service { } async fn handle_response(&self, content: RoomMessageEventContent) -> Result<()> { - let Some(Relation::Reply { - in_reply_to, - }) = content.relates_to.as_ref() - else { + let Some(Relation::Reply { in_reply_to }) = content.relates_to.as_ref() else { return Ok(()); }; @@ -277,7 +274,10 @@ impl Service { } async fn respond_to_room( - &self, content: RoomMessageEventContent, room_id: &RoomId, user_id: &UserId, + &self, + content: RoomMessageEventContent, + room_id: &RoomId, + user_id: &UserId, ) -> Result<()> { assert!(self.user_is_admin(user_id).await, "sender is not admin"); @@ -298,12 +298,16 @@ impl Service { } async fn handle_response_error( - &self, e: Error, room_id: &RoomId, user_id: &UserId, state_lock: &RoomMutexGuard, + &self, + e: Error, + room_id: &RoomId, + user_id: &UserId, + state_lock: &RoomMutexGuard, ) -> Result<()> { error!("Failed to build and append admin room response PDU: \"{e}\""); let content = RoomMessageEventContent::text_plain(format!( - "Failed to build and append admin room PDU: \"{e}\"\n\nThe original admin command may have finished \ - successfully, but we could not return the output." + "Failed to build and append admin room PDU: \"{e}\"\n\nThe original admin command \ + may have finished successfully, but we could not return the output." )); self.services @@ -321,7 +325,8 @@ impl Service { // Admin command with public echo (in admin room) let server_user = &self.services.globals.server_user; - let is_public_prefix = body.starts_with("!admin") || body.starts_with(server_user.as_str()); + let is_public_prefix = + body.starts_with("!admin") || body.starts_with(server_user.as_str()); // Expected backward branch if !is_public_escape && !is_public_prefix { diff --git a/src/service/admin/startup.rs b/src/service/admin/startup.rs index 68ad4be1c..582e863d0 100644 --- a/src/service/admin/startup.rs +++ b/src/service/admin/startup.rs @@ -65,9 +65,9 @@ async fn startup_execute_command(&self, i: usize, command: String) -> Result<()> debug!("Startup command #{i}: executing {command:?}"); match self.command_in_place(command, None).await { - Ok(Some(output)) => Self::startup_command_output(i, &output), - Err(output) => Self::startup_command_error(i, &output), - Ok(None) => { + | Ok(Some(output)) => Self::startup_command_output(i, &output), + | Err(output) => Self::startup_command_error(i, &output), + | Ok(None) => { info!("Startup command #{i} completed (no output)."); Ok(()) }, diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index cf2921a72..2a54ee093 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -61,7 +61,11 @@ impl crate::Service for Service { impl Service { /// Registers an appservice and returns the ID to the caller - pub async fn register_appservice(&self, registration: &Registration, appservice_config_body: &str) -> Result { + pub async fn register_appservice( + &self, + registration: &Registration, + appservice_config_body: &str, + ) -> Result { //TODO: Check for collisions between exclusive appservice namespaces self.registration_info .write() @@ -152,7 +156,10 @@ impl Service { .any(|info| info.rooms.is_exclusive_match(room_id.as_str())) } - pub fn read(&self) -> impl Future>> { + pub fn read( + &self, + ) -> impl Future>> + { self.registration_info.read() } diff --git a/src/service/appservice/registration_info.rs b/src/service/appservice/registration_info.rs index 612933be0..9758e186b 100644 --- a/src/service/appservice/registration_info.rs +++ b/src/service/appservice/registration_info.rs @@ -15,13 +15,15 @@ pub struct RegistrationInfo { impl RegistrationInfo { #[must_use] pub fn is_user_match(&self, user_id: &UserId) -> bool { - self.users.is_match(user_id.as_str()) || self.registration.sender_localpart == user_id.localpart() + self.users.is_match(user_id.as_str()) + || self.registration.sender_localpart == user_id.localpart() } #[inline] #[must_use] pub fn is_exclusive_user_match(&self, user_id: &UserId) -> bool { - self.users.is_exclusive_match(user_id.as_str()) || self.registration.sender_localpart == user_id.localpart() + self.users.is_exclusive_match(user_id.as_str()) + || self.registration.sender_localpart == user_id.localpart() } } diff --git a/src/service/client/mod.rs b/src/service/client/mod.rs index f2bc82561..f63d78b82 100644 --- a/src/service/client/mod.rs +++ b/src/service/client/mod.rs @@ -42,7 +42,9 @@ impl crate::Service for Service { .build()?, url_preview: base(config) - .and_then(|builder| builder_interface(builder, url_preview_bind_iface.as_deref()))? + .and_then(|builder| { + builder_interface(builder, url_preview_bind_iface.as_deref()) + })? .local_address(url_preview_bind_addr) .dns_resolver(resolver.resolver.clone()) .redirect(redirect::Policy::limited(3)) @@ -178,7 +180,10 @@ fn base(config: &Config) -> Result { } #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -fn builder_interface(builder: reqwest::ClientBuilder, config: Option<&str>) -> Result { +fn builder_interface( + builder: reqwest::ClientBuilder, + config: Option<&str>, +) -> Result { if let Some(iface) = config { Ok(builder.interface(iface)) } else { @@ -187,7 +192,10 @@ fn builder_interface(builder: reqwest::ClientBuilder, config: Option<&str>) -> R } #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))] -fn builder_interface(builder: reqwest::ClientBuilder, config: Option<&str>) -> Result { +fn builder_interface( + builder: reqwest::ClientBuilder, + config: Option<&str>, +) -> Result { use conduwuit::Err; if let Some(iface) = config { diff --git a/src/service/emergency/mod.rs b/src/service/emergency/mod.rs index 5063fbd47..9b2e40254 100644 --- a/src/service/emergency/mod.rs +++ b/src/service/emergency/mod.rs @@ -3,7 +3,9 @@ use std::sync::Arc; use async_trait::async_trait; use conduwuit::{error, warn, Result}; use ruma::{ - events::{push_rules::PushRulesEventContent, GlobalAccountDataEvent, GlobalAccountDataEventType}, + events::{ + push_rules::PushRulesEventContent, GlobalAccountDataEvent, GlobalAccountDataEventType, + }, push::Ruleset, }; @@ -31,16 +33,14 @@ impl crate::Service for Service { })) } - async fn worker(self: Arc) -> Result<()> { + async fn worker(self: Arc) -> Result { if self.services.globals.is_read_only() { return Ok(()); } - self.set_emergency_access() - .await - .inspect_err(|e| error!("Could not set the configured emergency password for the server user: {e}"))?; - - Ok(()) + self.set_emergency_access().await.inspect_err(|e| { + error!("Could not set the configured emergency password for the server user: {e}"); + }) } fn name(&self) -> &str { crate::service::make_name(std::module_path!()) } @@ -49,7 +49,7 @@ impl crate::Service for Service { impl Service { /// Sets the emergency password and push rules for the server user account /// in case emergency password is set - async fn set_emergency_access(&self) -> Result { + async fn set_emergency_access(&self) -> Result { let server_user = &self.services.globals.server_user; self.services @@ -57,8 +57,8 @@ impl Service { .set_password(server_user, self.services.globals.emergency_password().as_deref())?; let (ruleset, pwd_set) = match self.services.globals.emergency_password() { - Some(_) => (Ruleset::server_default(server_user), true), - None => (Ruleset::new(), false), + | Some(_) => (Ruleset::server_default(server_user), true), + | None => (Ruleset::new(), false), }; self.services @@ -68,9 +68,7 @@ impl Service { server_user, GlobalAccountDataEventType::PushRules.to_string().into(), &serde_json::to_value(&GlobalAccountDataEvent { - content: PushRulesEventContent { - global: ruleset, - }, + content: PushRulesEventContent { global: ruleset }, }) .expect("to json value always works"), ) @@ -78,14 +76,14 @@ impl Service { if pwd_set { warn!( - "The server account emergency password is set! Please unset it as soon as you finish admin account \ - recovery! You will be logged out of the server service account when you finish." + "The server account emergency password is set! Please unset it as soon as you \ + finish admin account recovery! You will be logged out of the server service \ + account when you finish." ); + Ok(()) } else { // logs out any users still in the server service account and removes sessions - self.services.users.deactivate_account(server_user).await?; + self.services.users.deactivate_account(server_user).await } - - Ok(pwd_set) } } diff --git a/src/service/globals/data.rs b/src/service/globals/data.rs index 5edd1f30a..07b4ac2c8 100644 --- a/src/service/globals/data.rs +++ b/src/service/globals/data.rs @@ -16,7 +16,9 @@ impl Data { let db = &args.db; Self { global: db["global"].clone(), - counter: RwLock::new(Self::stored_count(&db["global"]).expect("initialized global counter")), + counter: RwLock::new( + Self::stored_count(&db["global"]).expect("initialized global counter"), + ), db: args.db.clone(), } } diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 2403b7033..88199f5fa 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -10,7 +10,9 @@ use std::{ use conduwuit::{error, Config, Result}; use data::Data; use regex::RegexSet; -use ruma::{OwnedEventId, OwnedRoomAliasId, OwnedServerName, OwnedUserId, RoomAliasId, ServerName, UserId}; +use ruma::{ + OwnedEventId, OwnedRoomAliasId, OwnedServerName, OwnedUserId, RoomAliasId, ServerName, UserId, +}; use tokio::sync::Mutex; use crate::service; @@ -40,31 +42,31 @@ impl crate::Service for Service { .as_ref() .map(|secret| jsonwebtoken::DecodingKey::from_secret(secret.as_bytes())); - let turn_secret = config - .turn_secret_file - .as_ref() - .map_or(config.turn_secret.clone(), |path| { - std::fs::read_to_string(path).unwrap_or_else(|e| { - error!("Failed to read the TURN secret file: {e}"); - - config.turn_secret.clone() - }) - }); - - let registration_token = + let turn_secret = config - .registration_token_file + .turn_secret_file .as_ref() - .map_or(config.registration_token.clone(), |path| { - let Ok(token) = std::fs::read_to_string(path).inspect_err(|e| { - error!("Failed to read the registration token file: {e}"); - }) else { - return config.registration_token.clone(); - }; - - Some(token) + .map_or(config.turn_secret.clone(), |path| { + std::fs::read_to_string(path).unwrap_or_else(|e| { + error!("Failed to read the TURN secret file: {e}"); + + config.turn_secret.clone() + }) }); + let registration_token = config.registration_token_file.as_ref().map_or( + config.registration_token.clone(), + |path| { + let Ok(token) = std::fs::read_to_string(path).inspect_err(|e| { + error!("Failed to read the registration token file: {e}"); + }) else { + return config.registration_token.clone(); + }; + + Some(token) + }, + ); + let mut s = Self { db, config: config.clone(), @@ -73,8 +75,11 @@ impl crate::Service for Service { stateres_mutex: Arc::new(Mutex::new(())), admin_alias: RoomAliasId::parse(format!("#admins:{}", &config.server_name)) .expect("#admins:server_name is valid alias name"), - server_user: UserId::parse_with_server_name(String::from("conduit"), &config.server_name) - .expect("@conduit:server_name is valid"), + server_user: UserId::parse_with_server_name( + String::from("conduit"), + &config.server_name, + ) + .expect("@conduit:server_name is valid"), turn_secret, registration_token, }; @@ -125,7 +130,9 @@ impl Service { pub fn allow_guest_registration(&self) -> bool { self.config.allow_guest_registration } - pub fn allow_guests_auto_join_rooms(&self) -> bool { self.config.allow_guests_auto_join_rooms } + pub fn allow_guests_auto_join_rooms(&self) -> bool { + self.config.allow_guests_auto_join_rooms + } pub fn log_guest_registrations(&self) -> bool { self.config.log_guest_registrations } @@ -137,17 +144,23 @@ impl Service { self.config.allow_public_room_directory_over_federation } - pub fn allow_device_name_federation(&self) -> bool { self.config.allow_device_name_federation } + pub fn allow_device_name_federation(&self) -> bool { + self.config.allow_device_name_federation + } pub fn allow_room_creation(&self) -> bool { self.config.allow_room_creation } - pub fn new_user_displayname_suffix(&self) -> &String { &self.config.new_user_displayname_suffix } + pub fn new_user_displayname_suffix(&self) -> &String { + &self.config.new_user_displayname_suffix + } pub fn allow_check_for_updates(&self) -> bool { self.config.allow_check_for_updates } pub fn trusted_servers(&self) -> &[OwnedServerName] { &self.config.trusted_servers } - pub fn jwt_decoding_key(&self) -> Option<&jsonwebtoken::DecodingKey> { self.jwt_decoding_key.as_ref() } + pub fn jwt_decoding_key(&self) -> Option<&jsonwebtoken::DecodingKey> { + self.jwt_decoding_key.as_ref() + } pub fn turn_password(&self) -> &String { &self.config.turn_password } @@ -173,11 +186,15 @@ impl Service { &self.config.url_preview_domain_explicit_denylist } - pub fn url_preview_url_contains_allowlist(&self) -> &Vec { &self.config.url_preview_url_contains_allowlist } + pub fn url_preview_url_contains_allowlist(&self) -> &Vec { + &self.config.url_preview_url_contains_allowlist + } pub fn url_preview_max_spider_size(&self) -> usize { self.config.url_preview_max_spider_size } - pub fn url_preview_check_root_domain(&self) -> bool { self.config.url_preview_check_root_domain } + pub fn url_preview_check_root_domain(&self) -> bool { + self.config.url_preview_check_root_domain + } pub fn forbidden_alias_names(&self) -> &RegexSet { &self.config.forbidden_alias_names } @@ -189,18 +206,26 @@ impl Service { pub fn allow_outgoing_presence(&self) -> bool { self.config.allow_outgoing_presence } - pub fn allow_incoming_read_receipts(&self) -> bool { self.config.allow_incoming_read_receipts } + pub fn allow_incoming_read_receipts(&self) -> bool { + self.config.allow_incoming_read_receipts + } - pub fn allow_outgoing_read_receipts(&self) -> bool { self.config.allow_outgoing_read_receipts } + pub fn allow_outgoing_read_receipts(&self) -> bool { + self.config.allow_outgoing_read_receipts + } pub fn block_non_admin_invites(&self) -> bool { self.config.block_non_admin_invites } /// checks if `user_id` is local to us via server_name comparison #[inline] - pub fn user_is_local(&self, user_id: &UserId) -> bool { self.server_is_ours(user_id.server_name()) } + pub fn user_is_local(&self, user_id: &UserId) -> bool { + self.server_is_ours(user_id.server_name()) + } #[inline] - pub fn server_is_ours(&self, server_name: &ServerName) -> bool { server_name == self.config.server_name } + pub fn server_is_ours(&self, server_name: &ServerName) -> bool { + server_name == self.config.server_name + } #[inline] pub fn is_read_only(&self) -> bool { self.db.db.is_read_only() } diff --git a/src/service/key_backups/mod.rs b/src/service/key_backups/mod.rs index 140fc7013..1165c3edf 100644 --- a/src/service/key_backups/mod.rs +++ b/src/service/key_backups/mod.rs @@ -48,7 +48,11 @@ impl crate::Service for Service { } #[implement(Service)] -pub fn create_backup(&self, user_id: &UserId, backup_metadata: &Raw) -> Result { +pub fn create_backup( + &self, + user_id: &UserId, + backup_metadata: &Raw, +) -> Result { let version = self.services.globals.next_count()?.to_string(); let count = self.services.globals.next_count()?; @@ -71,13 +75,18 @@ pub async fn delete_backup(&self, user_id: &UserId, version: &str) { .backupkeyid_backup .keys_prefix_raw(&key) .ignore_err() - .ready_for_each(|outdated_key| self.db.backupkeyid_backup.remove(outdated_key)) + .ready_for_each(|outdated_key| { + self.db.backupkeyid_backup.remove(outdated_key); + }) .await; } #[implement(Service)] pub async fn update_backup<'a>( - &self, user_id: &UserId, version: &'a str, backup_metadata: &Raw, + &self, + user_id: &UserId, + version: &'a str, + backup_metadata: &Raw, ) -> Result<&'a str> { let key = (user_id, version); if self.db.backupid_algorithm.qry(&key).await.is_err() { @@ -110,7 +119,10 @@ pub async fn get_latest_backup_version(&self, user_id: &UserId) -> Result Result<(String, Raw)> { +pub async fn get_latest_backup( + &self, + user_id: &UserId, +) -> Result<(String, Raw)> { type Key<'a> = (&'a UserId, &'a str); type KeyVal<'a> = (Key<'a>, Raw); @@ -134,7 +146,12 @@ pub async fn get_backup(&self, user_id: &UserId, version: &str) -> Result, + &self, + user_id: &UserId, + version: &str, + room_id: &RoomId, + session_id: &str, + key_data: &Raw, ) -> Result<()> { let key = (user_id, version); if self.db.backupid_algorithm.qry(&key).await.is_err() { @@ -176,14 +193,16 @@ pub async fn get_etag(&self, user_id: &UserId, version: &str) -> String { } #[implement(Service)] -pub async fn get_all(&self, user_id: &UserId, version: &str) -> BTreeMap { +pub async fn get_all( + &self, + user_id: &UserId, + version: &str, +) -> BTreeMap { type Key<'a> = (Ignore, Ignore, &'a RoomId, &'a str); type KeyVal<'a> = (Key<'a>, Raw); let mut rooms = BTreeMap::::new(); - let default = || RoomKeyBackup { - sessions: BTreeMap::new(), - }; + let default = || RoomKeyBackup { sessions: BTreeMap::new() }; let prefix = (user_id, version, Interfix); self.db @@ -204,7 +223,10 @@ pub async fn get_all(&self, user_id: &UserId, version: &str) -> BTreeMap BTreeMap> { type KeyVal<'a> = ((Ignore, Ignore, Ignore, &'a str), Raw); @@ -213,14 +235,20 @@ pub async fn get_room( .backupkeyid_backup .stream_prefix(&prefix) .ignore_err() - .map(|((.., session_id), key_backup_data): KeyVal<'_>| (session_id.to_owned(), key_backup_data)) + .map(|((.., session_id), key_backup_data): KeyVal<'_>| { + (session_id.to_owned(), key_backup_data) + }) .collect() .await } #[implement(Service)] pub async fn get_session( - &self, user_id: &UserId, version: &str, room_id: &RoomId, session_id: &str, + &self, + user_id: &UserId, + version: &str, + room_id: &RoomId, + session_id: &str, ) -> Result> { let key = (user_id, version, room_id, session_id); @@ -245,17 +273,27 @@ pub async fn delete_room_keys(&self, user_id: &UserId, version: &str, room_id: & .backupkeyid_backup .keys_prefix_raw(&key) .ignore_err() - .ready_for_each(|outdated_key| self.db.backupkeyid_backup.remove(outdated_key)) + .ready_for_each(|outdated_key| { + self.db.backupkeyid_backup.remove(outdated_key); + }) .await; } #[implement(Service)] -pub async fn delete_room_key(&self, user_id: &UserId, version: &str, room_id: &RoomId, session_id: &str) { +pub async fn delete_room_key( + &self, + user_id: &UserId, + version: &str, + room_id: &RoomId, + session_id: &str, +) { let key = (user_id, version, room_id, session_id); self.db .backupkeyid_backup .keys_prefix_raw(&key) .ignore_err() - .ready_for_each(|outdated_key| self.db.backupkeyid_backup.remove(outdated_key)) + .ready_for_each(|outdated_key| { + self.db.backupkeyid_backup.remove(outdated_key); + }) .await; } diff --git a/src/service/manager.rs b/src/service/manager.rs index 3ce2e0a53..ea33d285f 100644 --- a/src/service/manager.rs +++ b/src/service/manager.rs @@ -102,21 +102,32 @@ impl Manager { unimplemented!("unexpected worker task abort {error:?}"); } - async fn handle_result(&self, workers: &mut WorkersLocked<'_>, result: WorkerResult) -> Result<()> { + async fn handle_result( + &self, + workers: &mut WorkersLocked<'_>, + result: WorkerResult, + ) -> Result<()> { let (service, result) = result; match result { - Ok(()) => self.handle_finished(workers, &service).await, - Err(error) => self.handle_error(workers, &service, error).await, + | Ok(()) => self.handle_finished(workers, &service).await, + | Err(error) => self.handle_error(workers, &service, error).await, } } - async fn handle_finished(&self, _workers: &mut WorkersLocked<'_>, service: &Arc) -> Result<()> { + async fn handle_finished( + &self, + _workers: &mut WorkersLocked<'_>, + service: &Arc, + ) -> Result<()> { debug!("service {:?} worker finished", service.name()); Ok(()) } async fn handle_error( - &self, workers: &mut WorkersLocked<'_>, service: &Arc, error: Error, + &self, + workers: &mut WorkersLocked<'_>, + service: &Arc, + error: Error, ) -> Result<()> { let name = service.name(); error!("service {name:?} aborted: {error}"); @@ -138,9 +149,16 @@ impl Manager { } /// Start the worker in a task for the service. - async fn start_worker(&self, workers: &mut WorkersLocked<'_>, service: &Arc) -> Result<()> { + async fn start_worker( + &self, + workers: &mut WorkersLocked<'_>, + service: &Arc, + ) -> Result<()> { if !self.server.running() { - return Err!("Service {:?} worker not starting during server shutdown.", service.name()); + return Err!( + "Service {:?} worker not starting during server shutdown.", + service.name() + ); } debug!("Service {:?} worker starting...", service.name()); diff --git a/src/service/media/data.rs b/src/service/media/data.rs index 71fb1cdb3..433105159 100644 --- a/src/service/media/data.rs +++ b/src/service/media/data.rs @@ -34,7 +34,11 @@ impl Data { } pub(super) fn create_file_metadata( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, dim: &Dim, content_disposition: Option<&ContentDisposition>, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + dim: &Dim, + content_disposition: Option<&ContentDisposition>, content_type: Option<&str>, ) -> Result> { let dim: &[u32] = &[dim.width, dim.height]; @@ -63,7 +67,10 @@ impl Data { .stream_prefix_raw(&prefix) .ignore_err() .ready_for_each(|(key, val)| { - debug_assert!(key.starts_with(mxc.to_string().as_bytes()), "key should start with the mxc"); + debug_assert!( + key.starts_with(mxc.to_string().as_bytes()), + "key should start with the mxc" + ); let user = str_from_bytes(val).unwrap_or_default(); debug_info!("Deleting key {key:?} which was uploaded by user {user}"); @@ -95,7 +102,11 @@ impl Data { Ok(keys) } - pub(super) async fn search_file_metadata(&self, mxc: &Mxc<'_>, dim: &Dim) -> Result { + pub(super) async fn search_file_metadata( + &self, + mxc: &Mxc<'_>, + dim: &Dim, + ) -> Result { let dim: &[u32] = &[dim.width, dim.height]; let prefix = (mxc, dim, Interfix); @@ -113,8 +124,9 @@ impl Data { let content_type = parts .next() .map(|bytes| { - string_from_bytes(bytes) - .map_err(|_| Error::bad_database("Content type in mediaid_file is invalid unicode.")) + string_from_bytes(bytes).map_err(|_| { + Error::bad_database("Content type in mediaid_file is invalid unicode.") + }) }) .transpose()?; @@ -127,16 +139,16 @@ impl Data { } else { Some( string_from_bytes(content_disposition_bytes) - .map_err(|_| Error::bad_database("Content Disposition in mediaid_file is invalid unicode."))? + .map_err(|_| { + Error::bad_database( + "Content Disposition in mediaid_file is invalid unicode.", + ) + })? .parse()?, ) }; - Ok(Metadata { - content_disposition, - content_type, - key, - }) + Ok(Metadata { content_disposition, content_type, key }) } /// Gets all the MXCs associated with a user @@ -144,7 +156,9 @@ impl Data { self.mediaid_user .stream() .ignore_err() - .ready_filter_map(|(key, user): (&str, &UserId)| (user == user_id).then(|| key.into())) + .ready_filter_map(|(key, user): (&str, &UserId)| { + (user == user_id).then(|| key.into()) + }) .collect() .await } @@ -166,7 +180,12 @@ impl Data { Ok(()) } - pub(super) fn set_url_preview(&self, url: &str, data: &UrlPreviewData, timestamp: Duration) -> Result<()> { + pub(super) fn set_url_preview( + &self, + url: &str, + data: &UrlPreviewData, + timestamp: Duration, + ) -> Result<()> { let mut value = Vec::::new(); value.extend_from_slice(×tamp.as_secs().to_be_bytes()); value.push(0xFF); @@ -218,43 +237,43 @@ impl Data { .next() .and_then(|b| String::from_utf8(b.to_vec()).ok()) { - Some(s) if s.is_empty() => None, - x => x, + | Some(s) if s.is_empty() => None, + | x => x, }; let description = match values .next() .and_then(|b| String::from_utf8(b.to_vec()).ok()) { - Some(s) if s.is_empty() => None, - x => x, + | Some(s) if s.is_empty() => None, + | x => x, }; let image = match values .next() .and_then(|b| String::from_utf8(b.to_vec()).ok()) { - Some(s) if s.is_empty() => None, - x => x, + | Some(s) if s.is_empty() => None, + | x => x, }; let image_size = match values .next() .map(|b| usize::from_be_bytes(b.try_into().unwrap_or_default())) { - Some(0) => None, - x => x, + | Some(0) => None, + | x => x, }; let image_width = match values .next() .map(|b| u32::from_be_bytes(b.try_into().unwrap_or_default())) { - Some(0) => None, - x => x, + | Some(0) => None, + | x => x, }; let image_height = match values .next() .map(|b| u32::from_be_bytes(b.try_into().unwrap_or_default())) { - Some(0) => None, - x => x, + | Some(0) => None, + | x => x, }; Ok(UrlPreviewData { diff --git a/src/service/media/migrations.rs b/src/service/media/migrations.rs index 5932643bc..9555edd7b 100644 --- a/src/service/media/migrations.rs +++ b/src/service/media/migrations.rs @@ -83,7 +83,8 @@ pub(crate) async fn checkup_sha256_media(services: &Services) -> Result<()> { for key in media.db.get_all_media_keys().await { let new_path = media.get_media_file_sha256(&key).into_os_string(); let old_path = media.get_media_file_b64(&key).into_os_string(); - if let Err(e) = handle_media_check(&dbs, config, &files, &key, &new_path, &old_path).await { + if let Err(e) = handle_media_check(&dbs, config, &files, &key, &new_path, &old_path).await + { error!( media_id = ?encode_key(&key), ?new_path, ?old_path, "Failed to resolve media check failure: {e}" @@ -100,8 +101,12 @@ pub(crate) async fn checkup_sha256_media(services: &Services) -> Result<()> { } async fn handle_media_check( - dbs: &(&Arc, &Arc), config: &Config, files: &HashSet, key: &[u8], - new_path: &OsStr, old_path: &OsStr, + dbs: &(&Arc, &Arc), + config: &Config, + files: &HashSet, + key: &[u8], + new_path: &OsStr, + old_path: &OsStr, ) -> Result<()> { use crate::media::encode_key; diff --git a/src/service/media/mod.rs b/src/service/media/mod.rs index 989e1c27f..7e77090c7 100644 --- a/src/service/media/mod.rs +++ b/src/service/media/mod.rs @@ -80,13 +80,21 @@ impl crate::Service for Service { impl Service { /// Uploads a file. pub async fn create( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, content_disposition: Option<&ContentDisposition>, - content_type: Option<&str>, file: &[u8], + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + content_disposition: Option<&ContentDisposition>, + content_type: Option<&str>, + file: &[u8], ) -> Result<()> { // Width, Height = 0 if it's not a thumbnail - let key = self - .db - .create_file_metadata(mxc, user, &Dim::default(), content_disposition, content_type)?; + let key = self.db.create_file_metadata( + mxc, + user, + &Dim::default(), + content_disposition, + content_type, + )?; //TODO: Dangling metadata in database if creation fails let mut f = self.create_media_file(&key).await?; @@ -132,10 +140,10 @@ impl Service { debug_info!(%deletion_count, "Deleting MXC {mxc} by user {user} from database and filesystem"); match self.delete(&mxc).await { - Ok(()) => { + | Ok(()) => { deletion_count = deletion_count.saturating_add(1); }, - Err(e) => { + | Err(e) => { debug_error!(%deletion_count, "Failed to delete {mxc} from user {user}, ignoring error: {e}"); }, } @@ -146,11 +154,8 @@ impl Service { /// Downloads a file. pub async fn get(&self, mxc: &Mxc<'_>) -> Result> { - if let Ok(Metadata { - content_disposition, - content_type, - key, - }) = self.db.search_file_metadata(mxc, &Dim::default()).await + if let Ok(Metadata { content_disposition, content_type, key }) = + self.db.search_file_metadata(mxc, &Dim::default()).await { let mut content = Vec::new(); let path = self.get_media_file(&key); @@ -181,13 +186,19 @@ impl Service { let mxc = parts .next() .map(|bytes| { - utils::string_from_bytes(bytes) - .map_err(|e| err!(Database(error!("Failed to parse MXC unicode bytes from our database: {e}")))) + utils::string_from_bytes(bytes).map_err(|e| { + err!(Database(error!( + "Failed to parse MXC unicode bytes from our database: {e}" + ))) + }) }) .transpose()?; let Some(mxc_s) = mxc else { - debug_warn!(?mxc, "Parsed MXC URL unicode bytes from database but is still invalid"); + debug_warn!( + ?mxc, + "Parsed MXC URL unicode bytes from database but is still invalid" + ); continue; }; @@ -207,7 +218,11 @@ impl Service { /// Deletes all remote only media files in the given at or after /// time/duration. Returns a usize with the amount of media files deleted. pub async fn delete_all_remote_media_at_after_time( - &self, time: SystemTime, before: bool, after: bool, yes_i_want_to_delete_local_media: bool, + &self, + time: SystemTime, + before: bool, + after: bool, + yes_i_want_to_delete_local_media: bool, ) -> Result { let all_keys = self.db.get_all_media_keys().await; let mut remote_mxcs = Vec::with_capacity(all_keys.len()); @@ -218,19 +233,26 @@ impl Service { let mxc = parts .next() .map(|bytes| { - utils::string_from_bytes(bytes) - .map_err(|e| err!(Database(error!("Failed to parse MXC unicode bytes from our database: {e}")))) + utils::string_from_bytes(bytes).map_err(|e| { + err!(Database(error!( + "Failed to parse MXC unicode bytes from our database: {e}" + ))) + }) }) .transpose()?; let Some(mxc_s) = mxc else { - debug_warn!(?mxc, "Parsed MXC URL unicode bytes from database but is still invalid"); + debug_warn!( + ?mxc, + "Parsed MXC URL unicode bytes from database but is still invalid" + ); continue; }; trace!("Parsed MXC key to URL: {mxc_s}"); let mxc = OwnedMxcUri::from(mxc_s); - if (mxc.server_name() == Ok(self.services.globals.server_name()) && !yes_i_want_to_delete_local_media) + if (mxc.server_name() == Ok(self.services.globals.server_name()) + && !yes_i_want_to_delete_local_media) || !mxc.is_valid() { debug!("Ignoring local or broken media MXC: {mxc}"); @@ -240,9 +262,12 @@ impl Service { let path = self.get_media_file(&key); let file_metadata = match fs::metadata(path.clone()).await { - Ok(file_metadata) => file_metadata, - Err(e) => { - error!("Failed to obtain file metadata for MXC {mxc} at file path \"{path:?}\", skipping: {e}"); + | Ok(file_metadata) => file_metadata, + | Err(e) => { + error!( + "Failed to obtain file metadata for MXC {mxc} at file path \ + \"{path:?}\", skipping: {e}" + ); continue; }, }; @@ -250,12 +275,12 @@ impl Service { trace!(%mxc, ?path, "File metadata: {file_metadata:?}"); let file_created_at = match file_metadata.created() { - Ok(value) => value, - Err(err) if err.kind() == std::io::ErrorKind::Unsupported => { + | Ok(value) => value, + | Err(err) if err.kind() == std::io::ErrorKind::Unsupported => { debug!("btime is unsupported, using mtime instead"); file_metadata.modified()? }, - Err(err) => { + | Err(err) => { error!("Could not delete MXC {mxc} at path {path:?}: {err:?}. Skipping..."); continue; }, @@ -264,10 +289,16 @@ impl Service { debug!("File created at: {file_created_at:?}"); if file_created_at >= time && before { - debug!("File is within (before) user duration, pushing to list of file paths and keys to delete."); + debug!( + "File is within (before) user duration, pushing to list of file paths and \ + keys to delete." + ); remote_mxcs.push(mxc.to_string()); } else if file_created_at <= time && after { - debug!("File is not within (after) user duration, pushing to list of file paths and keys to delete."); + debug!( + "File is not within (after) user duration, pushing to list of file paths \ + and keys to delete." + ); remote_mxcs.push(mxc.to_string()); } } @@ -289,10 +320,10 @@ impl Service { debug_info!("Deleting MXC {mxc} from database and filesystem"); match self.delete(&mxc).await { - Ok(()) => { + | Ok(()) => { deletion_count = deletion_count.saturating_add(1); }, - Err(e) => { + | Err(e) => { warn!("Failed to delete {mxc}, ignoring error and skipping: {e}"); continue; }, diff --git a/src/service/media/preview.rs b/src/service/media/preview.rs index d571ac563..b1c533054 100644 --- a/src/service/media/preview.rs +++ b/src/service/media/preview.rs @@ -53,10 +53,10 @@ pub async fn download_image(&self, url: &str) -> Result { self.create(&mxc, None, None, None, &image).await?; let (width, height) = match ImgReader::new(Cursor::new(&image)).with_guessed_format() { - Err(_) => (None, None), - Ok(reader) => match reader.into_dimensions() { - Err(_) => (None, None), - Ok((width, height)) => (Some(width), Some(height)), + | Err(_) => (None, None), + | Ok(reader) => match reader.into_dimensions() { + | Err(_) => (None, None), + | Ok((width, height)) => (Some(width), Some(height)), }, }; @@ -79,8 +79,8 @@ pub async fn get_url_preview(&self, url: &Url) -> Result { let _request_lock = self.url_preview_mutex.lock(url.as_str()).await; match self.db.get_url_preview(url.as_str()).await { - Ok(preview) => Ok(preview), - Err(_) => self.request_url_preview(url).await, + | Ok(preview) => Ok(preview), + | Err(_) => self.request_url_preview(url).await, } } @@ -111,9 +111,9 @@ async fn request_url_preview(&self, url: &Url) -> Result { return Err!(Request(Unknown("Unknown Content-Type"))); }; let data = match content_type { - html if html.starts_with("text/html") => self.download_html(url.as_str()).await?, - img if img.starts_with("image/") => self.download_image(url.as_str()).await?, - _ => return Err!(Request(Unknown("Unsupported Content-Type"))), + | html if html.starts_with("text/html") => self.download_html(url.as_str()).await?, + | img if img.starts_with("image/") => self.download_image(url.as_str()).await?, + | _ => return Err!(Request(Unknown("Unsupported Content-Type"))), }; self.set_url_preview(url.as_str(), &data).await?; @@ -131,8 +131,9 @@ async fn download_html(&self, url: &str) -> Result { bytes.extend_from_slice(&chunk); if bytes.len() > self.services.globals.url_preview_max_spider_size() { debug!( - "Response body from URL {} exceeds url_preview_max_spider_size ({}), not processing the rest of the \ - response body and assuming our necessary data is in this range.", + "Response body from URL {} exceeds url_preview_max_spider_size ({}), not \ + processing the rest of the response body and assuming our necessary data is in \ + this range.", url, self.services.globals.url_preview_max_spider_size() ); @@ -145,8 +146,8 @@ async fn download_html(&self, url: &str) -> Result { }; let mut data = match html.opengraph.images.first() { - None => UrlPreviewData::default(), - Some(obj) => self.download_image(&obj.url).await?, + | None => UrlPreviewData::default(), + | Some(obj) => self.download_image(&obj.url).await?, }; let props = html.opengraph.properties; @@ -169,11 +170,11 @@ pub fn url_preview_allowed(&self, url: &Url) -> bool { } let host = match url.host_str() { - None => { + | None => { debug!("Ignoring URL preview for a URL that does not have a host (?): {}", url); return false; }, - Some(h) => h.to_owned(), + | Some(h) => h.to_owned(), }; let allowlist_domain_contains = self @@ -205,7 +206,10 @@ pub fn url_preview_allowed(&self, url: &Url) -> bool { } if allowlist_domain_explicit.contains(&host) { - debug!("Host {} is allowed by url_preview_domain_explicit_allowlist (check 2/4)", &host); + debug!( + "Host {} is allowed by url_preview_domain_explicit_allowlist (check 2/4)", + &host + ); return true; } @@ -213,7 +217,10 @@ pub fn url_preview_allowed(&self, url: &Url) -> bool { .iter() .any(|domain_s| domain_s.contains(&host.clone())) { - debug!("Host {} is allowed by url_preview_domain_contains_allowlist (check 3/4)", &host); + debug!( + "Host {} is allowed by url_preview_domain_contains_allowlist (check 3/4)", + &host + ); return true; } @@ -229,11 +236,12 @@ pub fn url_preview_allowed(&self, url: &Url) -> bool { if self.services.globals.url_preview_check_root_domain() { debug!("Checking root domain"); match host.split_once('.') { - None => return false, - Some((_, root_domain)) => { + | None => return false, + | Some((_, root_domain)) => { if denylist_domain_explicit.contains(&root_domain.to_owned()) { debug!( - "Root domain {} is not allowed by url_preview_domain_explicit_denylist (check 1/3)", + "Root domain {} is not allowed by \ + url_preview_domain_explicit_denylist (check 1/3)", &root_domain ); return true; @@ -241,7 +249,8 @@ pub fn url_preview_allowed(&self, url: &Url) -> bool { if allowlist_domain_explicit.contains(&root_domain.to_owned()) { debug!( - "Root domain {} is allowed by url_preview_domain_explicit_allowlist (check 2/3)", + "Root domain {} is allowed by url_preview_domain_explicit_allowlist \ + (check 2/3)", &root_domain ); return true; @@ -252,7 +261,8 @@ pub fn url_preview_allowed(&self, url: &Url) -> bool { .any(|domain_s| domain_s.contains(&root_domain.to_owned())) { debug!( - "Root domain {} is allowed by url_preview_domain_contains_allowlist (check 3/3)", + "Root domain {} is allowed by url_preview_domain_contains_allowlist \ + (check 3/3)", &root_domain ); return true; diff --git a/src/service/media/remote.rs b/src/service/media/remote.rs index 8ec917b76..d5ad5391d 100644 --- a/src/service/media/remote.rs +++ b/src/service/media/remote.rs @@ -1,6 +1,9 @@ use std::{fmt::Debug, time::Duration}; -use conduwuit::{debug_warn, err, implement, utils::content_disposition::make_content_disposition, Err, Error, Result}; +use conduwuit::{ + debug_warn, err, implement, utils::content_disposition::make_content_disposition, Err, Error, + Result, +}; use http::header::{HeaderValue, CONTENT_DISPOSITION, CONTENT_TYPE}; use ruma::{ api::{ @@ -19,7 +22,12 @@ use super::{Dim, FileMeta}; #[implement(super::Service)] pub async fn fetch_remote_thumbnail( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, timeout_ms: Duration, dim: &Dim, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + timeout_ms: Duration, + dim: &Dim, ) -> Result { self.check_fetch_authorized(mxc)?; @@ -38,7 +46,11 @@ pub async fn fetch_remote_thumbnail( #[implement(super::Service)] pub async fn fetch_remote_content( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, timeout_ms: Duration, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + timeout_ms: Duration, ) -> Result { self.check_fetch_authorized(mxc)?; @@ -57,7 +69,12 @@ pub async fn fetch_remote_content( #[implement(super::Service)] async fn fetch_thumbnail_authenticated( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, timeout_ms: Duration, dim: &Dim, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + timeout_ms: Duration, + dim: &Dim, ) -> Result { use federation::authenticated_media::get_content_thumbnail::v1::{Request, Response}; @@ -70,20 +87,22 @@ async fn fetch_thumbnail_authenticated( timeout_ms, }; - let Response { - content, - .. - } = self.federation_request(mxc, user, server, request).await?; + let Response { content, .. } = self.federation_request(mxc, user, server, request).await?; match content { - FileOrLocation::File(content) => self.handle_thumbnail_file(mxc, user, dim, content).await, - FileOrLocation::Location(location) => self.handle_location(mxc, user, &location).await, + | FileOrLocation::File(content) => + self.handle_thumbnail_file(mxc, user, dim, content).await, + | FileOrLocation::Location(location) => self.handle_location(mxc, user, &location).await, } } #[implement(super::Service)] async fn fetch_content_authenticated( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, timeout_ms: Duration, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + timeout_ms: Duration, ) -> Result { use federation::authenticated_media::get_content::v1::{Request, Response}; @@ -92,21 +111,23 @@ async fn fetch_content_authenticated( timeout_ms, }; - let Response { - content, - .. - } = self.federation_request(mxc, user, server, request).await?; + let Response { content, .. } = self.federation_request(mxc, user, server, request).await?; match content { - FileOrLocation::File(content) => self.handle_content_file(mxc, user, content).await, - FileOrLocation::Location(location) => self.handle_location(mxc, user, &location).await, + | FileOrLocation::File(content) => self.handle_content_file(mxc, user, content).await, + | FileOrLocation::Location(location) => self.handle_location(mxc, user, &location).await, } } #[allow(deprecated)] #[implement(super::Service)] async fn fetch_thumbnail_unauthenticated( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, timeout_ms: Duration, dim: &Dim, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + timeout_ms: Duration, + dim: &Dim, ) -> Result { use media::get_content_thumbnail::v3::{Request, Response}; @@ -123,17 +144,10 @@ async fn fetch_thumbnail_unauthenticated( }; let Response { - file, - content_type, - content_disposition, - .. + file, content_type, content_disposition, .. } = self.federation_request(mxc, user, server, request).await?; - let content = Content { - file, - content_type, - content_disposition, - }; + let content = Content { file, content_type, content_disposition }; self.handle_thumbnail_file(mxc, user, dim, content).await } @@ -141,7 +155,11 @@ async fn fetch_thumbnail_unauthenticated( #[allow(deprecated)] #[implement(super::Service)] async fn fetch_content_unauthenticated( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, timeout_ms: Duration, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + timeout_ms: Duration, ) -> Result { use media::get_content::v3::{Request, Response}; @@ -154,27 +172,27 @@ async fn fetch_content_unauthenticated( }; let Response { - file, - content_type, - content_disposition, - .. + file, content_type, content_disposition, .. } = self.federation_request(mxc, user, server, request).await?; - let content = Content { - file, - content_type, - content_disposition, - }; + let content = Content { file, content_type, content_disposition }; self.handle_content_file(mxc, user, content).await } #[implement(super::Service)] async fn handle_thumbnail_file( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, dim: &Dim, content: Content, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + dim: &Dim, + content: Content, ) -> Result { - let content_disposition = - make_content_disposition(content.content_disposition.as_ref(), content.content_type.as_deref(), None); + let content_disposition = make_content_disposition( + content.content_disposition.as_ref(), + content.content_type.as_deref(), + None, + ); self.upload_thumbnail( mxc, @@ -193,9 +211,17 @@ async fn handle_thumbnail_file( } #[implement(super::Service)] -async fn handle_content_file(&self, mxc: &Mxc<'_>, user: Option<&UserId>, content: Content) -> Result { - let content_disposition = - make_content_disposition(content.content_disposition.as_ref(), content.content_type.as_deref(), None); +async fn handle_content_file( + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + content: Content, +) -> Result { + let content_disposition = make_content_disposition( + content.content_disposition.as_ref(), + content.content_type.as_deref(), + None, + ); self.create( mxc, @@ -213,7 +239,12 @@ async fn handle_content_file(&self, mxc: &Mxc<'_>, user: Option<&UserId>, conten } #[implement(super::Service)] -async fn handle_location(&self, mxc: &Mxc<'_>, user: Option<&UserId>, location: &str) -> Result { +async fn handle_location( + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + location: &str, +) -> Result { self.location_request(location).await.map_err(|error| { err!(Request(NotFound( debug_warn!(%mxc, ?user, ?location, ?error, "Fetching media from location failed") @@ -263,7 +294,11 @@ async fn location_request(&self, location: &str) -> Result { #[implement(super::Service)] async fn federation_request( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, request: Request, + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + request: Request, ) -> Result where Request: OutgoingRequest + Send + Debug, @@ -277,7 +312,12 @@ where // Handles and adjusts the error for the caller to determine if they should // request the fallback endpoint or give up. -fn handle_federation_error(mxc: &Mxc<'_>, user: Option<&UserId>, server: Option<&ServerName>, error: Error) -> Error { +fn handle_federation_error( + mxc: &Mxc<'_>, + user: Option<&UserId>, + server: Option<&ServerName>, + error: Error, +) -> Error { let fallback = || { err!(Request(NotFound( debug_error!(%mxc, ?user, ?server, ?error, "Remote media not found") @@ -303,7 +343,8 @@ fn handle_federation_error(mxc: &Mxc<'_>, user: Option<&UserId>, server: Option< #[implement(super::Service)] #[allow(deprecated)] pub async fn fetch_remote_thumbnail_legacy( - &self, body: &media::get_content_thumbnail::v3::Request, + &self, + body: &media::get_content_thumbnail::v3::Request, ) -> Result { let mxc = Mxc { server_name: &body.server_name, @@ -315,20 +356,17 @@ pub async fn fetch_remote_thumbnail_legacy( let reponse = self .services .sending - .send_federation_request( - mxc.server_name, - media::get_content_thumbnail::v3::Request { - allow_remote: body.allow_remote, - height: body.height, - width: body.width, - method: body.method.clone(), - server_name: body.server_name.clone(), - media_id: body.media_id.clone(), - timeout_ms: body.timeout_ms, - allow_redirect: body.allow_redirect, - animated: body.animated, - }, - ) + .send_federation_request(mxc.server_name, media::get_content_thumbnail::v3::Request { + allow_remote: body.allow_remote, + height: body.height, + width: body.width, + method: body.method.clone(), + server_name: body.server_name.clone(), + media_id: body.media_id.clone(), + timeout_ms: body.timeout_ms, + allow_redirect: body.allow_redirect, + animated: body.animated, + }) .await?; let dim = Dim::from_ruma(body.width, body.height, body.method.clone())?; @@ -341,27 +379,30 @@ pub async fn fetch_remote_thumbnail_legacy( #[implement(super::Service)] #[allow(deprecated)] pub async fn fetch_remote_content_legacy( - &self, mxc: &Mxc<'_>, allow_redirect: bool, timeout_ms: Duration, + &self, + mxc: &Mxc<'_>, + allow_redirect: bool, + timeout_ms: Duration, ) -> Result { self.check_legacy_freeze()?; self.check_fetch_authorized(mxc)?; let response = self .services .sending - .send_federation_request( - mxc.server_name, - media::get_content::v3::Request { - allow_remote: true, - server_name: mxc.server_name.into(), - media_id: mxc.media_id.into(), - timeout_ms, - allow_redirect, - }, - ) + .send_federation_request(mxc.server_name, media::get_content::v3::Request { + allow_remote: true, + server_name: mxc.server_name.into(), + media_id: mxc.media_id.into(), + timeout_ms, + allow_redirect, + }) .await?; - let content_disposition = - make_content_disposition(response.content_disposition.as_ref(), response.content_type.as_deref(), None); + let content_disposition = make_content_disposition( + response.content_disposition.as_ref(), + response.content_type.as_deref(), + None, + ); self.create( mxc, diff --git a/src/service/media/tests.rs b/src/service/media/tests.rs index b2f31e6f3..1d6dce30b 100644 --- a/src/service/media/tests.rs +++ b/src/service/media/tests.rs @@ -13,7 +13,12 @@ async fn long_file_names_works() { impl Data for MockedKVDatabase { fn create_file_metadata( - &self, _sender_user: Option<&str>, mxc: String, width: u32, height: u32, content_disposition: Option<&str>, + &self, + _sender_user: Option<&str>, + mxc: String, + width: u32, + height: u32, + content_disposition: Option<&str>, content_type: Option<&str>, ) -> Result> { // copied from src/database/key_value/media.rs @@ -46,14 +51,22 @@ async fn long_file_names_works() { fn get_all_media_keys(&self) -> Vec> { todo!() } fn search_file_metadata( - &self, _mxc: String, _width: u32, _height: u32, + &self, + _mxc: String, + _width: u32, + _height: u32, ) -> Result<(Option, Option, Vec)> { todo!() } fn remove_url_preview(&self, _url: &str) -> Result<()> { todo!() } - fn set_url_preview(&self, _url: &str, _data: &UrlPreviewData, _timestamp: std::time::Duration) -> Result<()> { + fn set_url_preview( + &self, + _url: &str, + _data: &UrlPreviewData, + _timestamp: std::time::Duration, + ) -> Result<()> { todo!() } @@ -64,11 +77,18 @@ async fn long_file_names_works() { let mxc = "mxc://example.com/ascERGshawAWawugaAcauga".to_owned(); let width = 100; let height = 100; - let content_disposition = "attachment; filename=\"this is a very long file name with spaces and special \ - characters like äöüß and even emoji like 🦀.png\""; + let content_disposition = "attachment; filename=\"this is a very long file name with spaces \ + and special characters like äöüß and even emoji like 🦀.png\""; let content_type = "image/png"; let key = db - .create_file_metadata(None, mxc, width, height, Some(content_disposition), Some(content_type)) + .create_file_metadata( + None, + mxc, + width, + height, + Some(content_disposition), + Some(content_type), + ) .unwrap(); let mut r = PathBuf::from("/tmp/media"); // r.push(base64::encode_config(key, base64::URL_SAFE_NO_PAD)); diff --git a/src/service/media/thumbnail.rs b/src/service/media/thumbnail.rs index 42fc40e70..5c8063cbb 100644 --- a/src/service/media/thumbnail.rs +++ b/src/service/media/thumbnail.rs @@ -22,12 +22,17 @@ impl super::Service { /// Uploads or replaces a file thumbnail. #[allow(clippy::too_many_arguments)] pub async fn upload_thumbnail( - &self, mxc: &Mxc<'_>, user: Option<&UserId>, content_disposition: Option<&ContentDisposition>, - content_type: Option<&str>, dim: &Dim, file: &[u8], + &self, + mxc: &Mxc<'_>, + user: Option<&UserId>, + content_disposition: Option<&ContentDisposition>, + content_type: Option<&str>, + dim: &Dim, + file: &[u8], ) -> Result<()> { - let key = self - .db - .create_file_metadata(mxc, user, dim, content_disposition, content_type)?; + let key = + self.db + .create_file_metadata(mxc, user, dim, content_disposition, content_type)?; //TODO: Dangling metadata in database if creation fails let mut f = self.create_media_file(&key).await?; @@ -78,7 +83,12 @@ impl super::Service { /// Generate a thumbnail #[tracing::instrument(skip(self), name = "generate", level = "debug")] - async fn get_thumbnail_generate(&self, mxc: &Mxc<'_>, dim: &Dim, data: Metadata) -> Result> { + async fn get_thumbnail_generate( + &self, + mxc: &Mxc<'_>, + dim: &Dim, + data: Metadata, + ) -> Result> { let mut content = Vec::new(); let path = self.get_media_file(&data.key); fs::File::open(path) @@ -117,11 +127,7 @@ impl super::Service { fn thumbnail_generate(image: &DynamicImage, requested: &Dim) -> Result { let thumbnail = if !requested.crop() { - let Dim { - width, - height, - .. - } = requested.scaled(&Dim { + let Dim { width, height, .. } = requested.scaled(&Dim { width: image.width(), height: image.height(), ..Dim::default() @@ -202,12 +208,12 @@ impl Dim { #[must_use] pub fn normalized(&self) -> Self { match (self.width, self.height) { - (0..=32, 0..=32) => Self::new(32, 32, Some(Method::Crop)), - (0..=96, 0..=96) => Self::new(96, 96, Some(Method::Crop)), - (0..=320, 0..=240) => Self::new(320, 240, Some(Method::Scale)), - (0..=640, 0..=480) => Self::new(640, 480, Some(Method::Scale)), - (0..=800, 0..=600) => Self::new(800, 600, Some(Method::Scale)), - _ => Self::default(), + | (0..=32, 0..=32) => Self::new(32, 32, Some(Method::Crop)), + | (0..=96, 0..=96) => Self::new(96, 96, Some(Method::Crop)), + | (0..=320, 0..=240) => Self::new(320, 240, Some(Method::Scale)), + | (0..=640, 0..=480) => Self::new(640, 480, Some(Method::Scale)), + | (0..=800, 0..=600) => Self::new(800, 600, Some(Method::Scale)), + | _ => Self::default(), } } diff --git a/src/service/migrations.rs b/src/service/migrations.rs index 102ac7d4e..adf75c0b2 100644 --- a/src/service/migrations.rs +++ b/src/service/migrations.rs @@ -12,7 +12,9 @@ use conduwuit::{ use futures::{FutureExt, StreamExt}; use itertools::Itertools; use ruma::{ - events::{push_rules::PushRulesEvent, room::member::MembershipState, GlobalAccountDataEventType}, + events::{ + push_rules::PushRulesEvent, room::member::MembershipState, GlobalAccountDataEventType, + }, push::Ruleset, OwnedUserId, RoomId, UserId, }; @@ -45,7 +47,8 @@ pub(crate) async fn migrations(services: &Services) -> Result<()> { if !services.users.exists(server_user).await { error!("The {server_user} server user does not exist, and the database is not new."); return Err!(Database( - "Cannot reuse an existing database after changing the server name, please delete the old one first.", + "Cannot reuse an existing database after changing the server name, please \ + delete the old one first.", )); } } @@ -144,7 +147,8 @@ async fn migrate(services: &Services) -> Result<()> { assert!( version_match, - "Failed asserting local database version {} is equal to known latest conduwuit database version {}", + "Failed asserting local database version {} is equal to known latest conduwuit database \ + version {}", services.globals.db.database_version().await, DATABASE_VERSION, ); @@ -192,7 +196,8 @@ async fn migrate(services: &Services) -> Result<()> { let matches = patterns.matches(room_alias.alias()); if matches.matched_any() { warn!( - "Room with alias {} ({}) matches the following forbidden room name patterns: {}", + "Room with alias {} ({}) matches the following forbidden room \ + name patterns: {}", room_alias, &room_id, matches @@ -223,8 +228,8 @@ async fn db_lt_12(services: &Services) -> Result<()> { .await { let user = match UserId::parse_with_server_name(username.as_str(), &config.server_name) { - Ok(u) => u, - Err(e) => { + | Ok(u) => u, + | Err(e) => { warn!("Invalid username {username}: {e}"); continue; }, @@ -240,7 +245,8 @@ async fn db_lt_12(services: &Services) -> Result<()> { //content rule { - let content_rule_transformation = [".m.rules.contains_user_name", ".m.rule.contains_user_name"]; + let content_rule_transformation = + [".m.rules.contains_user_name", ".m.rule.contains_user_name"]; let rule = rules_list.content.get(content_rule_transformation[0]); if rule.is_some() { @@ -301,8 +307,8 @@ async fn db_lt_13(services: &Services) -> Result<()> { .await { let user = match UserId::parse_with_server_name(username.as_str(), &config.server_name) { - Ok(u) => u, - Err(e) => { + | Ok(u) => u, + | Err(e) => { warn!("Invalid username {username}: {e}"); continue; }, @@ -413,7 +419,9 @@ async fn retroactively_fix_bad_data_from_roomuserid_joined(services: &Services) .rooms .state_accessor .get_member(room_id, user_id) - .map(|member| member.is_ok_and(|member| member.membership == MembershipState::Join)) + .map(|member| { + member.is_ok_and(|member| member.membership == MembershipState::Join) + }) }) .collect::>() .await; @@ -426,7 +434,9 @@ async fn retroactively_fix_bad_data_from_roomuserid_joined(services: &Services) .rooms .state_accessor .get_member(room_id, user_id) - .map(|member| member.is_ok_and(|member| member.membership == MembershipState::Join)) + .map(|member| { + member.is_ok_and(|member| member.membership == MembershipState::Join) + }) }) .collect::>() .await; @@ -444,7 +454,8 @@ async fn retroactively_fix_bad_data_from_roomuserid_joined(services: &Services) for room_id in &room_ids { debug_info!( - "Updating joined count for room {room_id} to fix servers in room after correcting membership states" + "Updating joined count for room {room_id} to fix servers in room after correcting \ + membership states" ); services diff --git a/src/service/presence/data.rs b/src/service/presence/data.rs index dd0d8e726..3d6143339 100644 --- a/src/service/presence/data.rs +++ b/src/service/presence/data.rs @@ -53,18 +53,22 @@ impl Data { } pub(super) async fn set_presence( - &self, user_id: &UserId, presence_state: &PresenceState, currently_active: Option, - last_active_ago: Option, status_msg: Option, + &self, + user_id: &UserId, + presence_state: &PresenceState, + currently_active: Option, + last_active_ago: Option, + status_msg: Option, ) -> Result<()> { let last_presence = self.get_presence(user_id).await; let state_changed = match last_presence { - Err(_) => true, - Ok(ref presence) => presence.1.content.presence != *presence_state, + | Err(_) => true, + | Ok(ref presence) => presence.1.content.presence != *presence_state, }; let status_msg_changed = match last_presence { - Err(_) => true, - Ok(ref last_presence) => { + | Err(_) => true, + | Ok(ref last_presence) => { let old_msg = last_presence .1 .content @@ -80,18 +84,22 @@ impl Data { let now = utils::millis_since_unix_epoch(); let last_last_active_ts = match last_presence { - Err(_) => 0, - Ok((_, ref presence)) => now.saturating_sub(presence.content.last_active_ago.unwrap_or_default().into()), + | Err(_) => 0, + | Ok((_, ref presence)) => + now.saturating_sub(presence.content.last_active_ago.unwrap_or_default().into()), }; let last_active_ts = match last_active_ago { - None => now, - Some(last_active_ago) => now.saturating_sub(last_active_ago.into()), + | None => now, + | Some(last_active_ago) => now.saturating_sub(last_active_ago.into()), }; // TODO: tighten for state flicker? if !status_msg_changed && !state_changed && last_active_ts < last_last_active_ts { - debug_warn!("presence spam {user_id:?} last_active_ts:{last_active_ts:?} < {last_last_active_ts:?}",); + debug_warn!( + "presence spam {user_id:?} last_active_ts:{last_active_ts:?} < \ + {last_last_active_ts:?}", + ); return Ok(()); } @@ -138,7 +146,10 @@ impl Data { } #[inline] - pub(super) fn presence_since(&self, since: u64) -> impl Stream + Send + '_ { + pub(super) fn presence_since( + &self, + since: u64, + ) -> impl Stream + Send + '_ { self.presenceid_presence .raw_stream() .ignore_err() diff --git a/src/service/presence/mod.rs b/src/service/presence/mod.rs index 7e80e05ed..5f4d03a7b 100644 --- a/src/service/presence/mod.rs +++ b/src/service/presence/mod.rs @@ -99,13 +99,14 @@ impl Service { let last_presence = self.db.get_presence(user_id).await; let state_changed = match last_presence { - Err(_) => true, - Ok((_, ref presence)) => presence.content.presence != *new_state, + | Err(_) => true, + | Ok((_, ref presence)) => presence.content.presence != *new_state, }; let last_last_active_ago = match last_presence { - Err(_) => 0_u64, - Ok((_, ref presence)) => presence.content.last_active_ago.unwrap_or_default().into(), + | Err(_) => 0_u64, + | Ok((_, ref presence)) => + presence.content.last_active_ago.unwrap_or_default().into(), }; if !state_changed && last_last_active_ago < REFRESH_TIMEOUT { @@ -113,8 +114,8 @@ impl Service { } let status_msg = match last_presence { - Ok((_, ref presence)) => presence.content.status_msg.clone(), - Err(_) => Some(String::new()), + | Ok((_, ref presence)) => presence.content.status_msg.clone(), + | Err(_) => Some(String::new()), }; let last_active_ago = UInt::new(0); @@ -125,12 +126,16 @@ impl Service { /// Adds a presence event which will be saved until a new event replaces it. pub async fn set_presence( - &self, user_id: &UserId, state: &PresenceState, currently_active: Option, last_active_ago: Option, + &self, + user_id: &UserId, + state: &PresenceState, + currently_active: Option, + last_active_ago: Option, status_msg: Option, ) -> Result<()> { let presence_state = match state.as_str() { - "" => &PresenceState::Offline, // default an empty string to 'offline' - &_ => state, + | "" => &PresenceState::Offline, // default an empty string to 'offline' + | &_ => state, }; self.db @@ -141,8 +146,8 @@ impl Service { && user_id != self.services.globals.server_user { let timeout = match presence_state { - PresenceState::Online => self.services.server.config.presence_idle_timeout_s, - _ => self.services.server.config.presence_offline_timeout_s, + | PresenceState::Online => self.services.server.config.presence_idle_timeout_s, + | _ => self.services.server.config.presence_offline_timeout_s, }; self.timer_sender @@ -160,16 +165,25 @@ impl Service { /// /// TODO: Why is this not used? #[allow(dead_code)] - pub async fn remove_presence(&self, user_id: &UserId) { self.db.remove_presence(user_id).await } + pub async fn remove_presence(&self, user_id: &UserId) { + self.db.remove_presence(user_id).await + } /// Returns the most recent presence updates that happened after the event /// with id `since`. - pub fn presence_since(&self, since: u64) -> impl Stream + Send + '_ { + pub fn presence_since( + &self, + since: u64, + ) -> impl Stream + Send + '_ { self.db.presence_since(since) } #[inline] - pub async fn from_json_bytes_to_event(&self, bytes: &[u8], user_id: &UserId) -> Result { + pub async fn from_json_bytes_to_event( + &self, + bytes: &[u8], + user_id: &UserId, + ) -> Result { let presence = Presence::from_json_bytes(bytes)?; let event = presence .to_presence_event(user_id, &self.services.users) @@ -192,13 +206,16 @@ impl Service { } let new_state = match (&presence_state, last_active_ago.map(u64::from)) { - (PresenceState::Online, Some(ago)) if ago >= self.idle_timeout => Some(PresenceState::Unavailable), - (PresenceState::Unavailable, Some(ago)) if ago >= self.offline_timeout => Some(PresenceState::Offline), - _ => None, + | (PresenceState::Online, Some(ago)) if ago >= self.idle_timeout => + Some(PresenceState::Unavailable), + | (PresenceState::Unavailable, Some(ago)) if ago >= self.offline_timeout => + Some(PresenceState::Offline), + | _ => None, }; debug!( - "Processed presence timer for user '{user_id}': Old state = {presence_state}, New state = {new_state:?}" + "Processed presence timer for user '{user_id}': Old state = {presence_state}, New \ + state = {new_state:?}" ); if let Some(new_state) = new_state { diff --git a/src/service/presence/presence.rs b/src/service/presence/presence.rs index aed4a3f8c..b88a004b0 100644 --- a/src/service/presence/presence.rs +++ b/src/service/presence/presence.rs @@ -21,7 +21,10 @@ pub(super) struct Presence { impl Presence { #[must_use] pub(super) fn new( - state: PresenceState, currently_active: bool, last_active_ts: u64, status_msg: Option, + state: PresenceState, + currently_active: bool, + last_active_ts: u64, + status_msg: Option, ) -> Self { Self { state, @@ -32,11 +35,16 @@ impl Presence { } pub(super) fn from_json_bytes(bytes: &[u8]) -> Result { - serde_json::from_slice(bytes).map_err(|_| Error::bad_database("Invalid presence data in database")) + serde_json::from_slice(bytes) + .map_err(|_| Error::bad_database("Invalid presence data in database")) } /// Creates a PresenceEvent from available data. - pub(super) async fn to_presence_event(&self, user_id: &UserId, users: &users::Service) -> PresenceEvent { + pub(super) async fn to_presence_event( + &self, + user_id: &UserId, + users: &users::Service, + ) -> PresenceEvent { let now = utils::millis_since_unix_epoch(); let last_active_ago = if self.currently_active { None diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index ffe822b7a..cea3ba35e 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -19,9 +19,12 @@ use ruma::{ IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken, }, events::{ - room::power_levels::RoomPowerLevelsEventContent, AnySyncTimelineEvent, StateEventType, TimelineEventType, + room::power_levels::RoomPowerLevelsEventContent, AnySyncTimelineEvent, StateEventType, + TimelineEventType, + }, + push::{ + Action, PushConditionPowerLevelsCtx, PushConditionRoomCtx, PushFormat, Ruleset, Tweak, }, - push::{Action, PushConditionPowerLevelsCtx, PushConditionRoomCtx, PushFormat, Ruleset, Tweak}, serde::Raw, uint, RoomId, UInt, UserId, }; @@ -55,7 +58,8 @@ impl crate::Service for Service { services: Services { globals: args.depend::("globals"), client: args.depend::("client"), - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), state_cache: args.depend::("rooms::state_cache"), users: args.depend::("users"), sending: args.depend::("sending"), @@ -67,23 +71,31 @@ impl crate::Service for Service { } impl Service { - pub async fn set_pusher(&self, sender: &UserId, pusher: &set_pusher::v3::PusherAction) -> Result { + pub async fn set_pusher( + &self, + sender: &UserId, + pusher: &set_pusher::v3::PusherAction, + ) -> Result { match pusher { - set_pusher::v3::PusherAction::Post(data) => { + | set_pusher::v3::PusherAction::Post(data) => { let pushkey = data.pusher.ids.pushkey.as_str(); if pushkey.len() > 512 { - return Err!(Request(InvalidParam("Push key length cannot be greater than 512 bytes."))); + return Err!(Request(InvalidParam( + "Push key length cannot be greater than 512 bytes." + ))); } if data.pusher.ids.app_id.as_str().len() > 64 { - return Err!(Request(InvalidParam("App ID length cannot be greater than 64 bytes."))); + return Err!(Request(InvalidParam( + "App ID length cannot be greater than 64 bytes." + ))); } let key = (sender, data.pusher.ids.pushkey.as_str()); self.db.senderkey_pusher.put(key, Json(pusher)); }, - set_pusher::v3::PusherAction::Delete(ids) => { + | set_pusher::v3::PusherAction::Delete(ids) => { let key = (sender, ids.pushkey.as_str()); self.db.senderkey_pusher.del(key); @@ -118,7 +130,10 @@ impl Service { .await } - pub fn get_pushkeys<'a>(&'a self, sender: &'a UserId) -> impl Stream + Send + 'a { + pub fn get_pushkeys<'a>( + &'a self, + sender: &'a UserId, + ) -> impl Stream + Send + 'a { let prefix = (sender, Interfix); self.db .senderkey_pusher @@ -160,14 +175,16 @@ impl Service { let response = self.services.client.pusher.execute(reqwest_request).await; match response { - Ok(mut response) => { + | Ok(mut response) => { // reqwest::Response -> http::Response conversion trace!("Checking response destination's IP"); if let Some(remote_addr) = response.remote_addr() { if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { if !self.services.client.valid_cidr_range(&ip) { - return Err!(BadServerResponse("Not allowed to send requests to this IP")); + return Err!(BadServerResponse( + "Not allowed to send requests to this IP" + )); } } } @@ -197,10 +214,13 @@ impl Service { .body(body) .expect("reqwest body is valid http body"), ); - response - .map_err(|e| err!(BadServerResponse(warn!("Push gateway {dest} returned invalid response: {e}")))) + response.map_err(|e| { + err!(BadServerResponse(warn!( + "Push gateway {dest} returned invalid response: {e}" + ))) + }) }, - Err(e) => { + | Err(e) => { warn!("Could not send request to pusher {dest}: {e}"); Err(e.into()) }, @@ -209,7 +229,12 @@ impl Service { #[tracing::instrument(skip(self, user, unread, pusher, ruleset, pdu))] pub async fn send_push_notice( - &self, user: &UserId, unread: UInt, pusher: &Pusher, ruleset: Ruleset, pdu: &PduEvent, + &self, + user: &UserId, + unread: UInt, + pusher: &Pusher, + ruleset: Ruleset, + pdu: &PduEvent, ) -> Result<()> { let mut notify = None; let mut tweaks = Vec::new(); @@ -220,8 +245,9 @@ impl Service { .room_state_get(&pdu.room_id, &StateEventType::RoomPowerLevels, "") .await .and_then(|ev| { - serde_json::from_str(ev.content.get()) - .map_err(|e| err!(Database(error!("invalid m.room.power_levels event: {e:?}")))) + serde_json::from_str(ev.content.get()).map_err(|e| { + err!(Database(error!("invalid m.room.power_levels event: {e:?}"))) + }) }) .unwrap_or_default(); @@ -230,12 +256,12 @@ impl Service { .await { let n = match action { - Action::Notify => true, - Action::SetTweak(tweak) => { + | Action::Notify => true, + | Action::SetTweak(tweak) => { tweaks.push(tweak.clone()); continue; }, - _ => false, + | _ => false, }; if notify.is_some() { @@ -257,8 +283,12 @@ impl Service { #[tracing::instrument(skip(self, user, ruleset, pdu), level = "debug")] pub async fn get_actions<'a>( - &self, user: &UserId, ruleset: &'a Ruleset, power_levels: &RoomPowerLevelsEventContent, - pdu: &Raw, room_id: &RoomId, + &self, + user: &UserId, + ruleset: &'a Ruleset, + power_levels: &RoomPowerLevelsEventContent, + pdu: &Raw, + room_id: &RoomId, ) -> &'a [Action] { let power_levels = PushConditionPowerLevelsCtx { users: power_levels.users.clone(), @@ -294,14 +324,21 @@ impl Service { } #[tracing::instrument(skip(self, unread, pusher, tweaks, event))] - async fn send_notice(&self, unread: UInt, pusher: &Pusher, tweaks: Vec, event: &PduEvent) -> Result<()> { + async fn send_notice( + &self, + unread: UInt, + pusher: &Pusher, + tweaks: Vec, + event: &PduEvent, + ) -> Result<()> { // TODO: email match &pusher.kind { - PusherKind::Http(http) => { + | PusherKind::Http(http) => { // TODO (timo): can pusher/devices have conflicting formats let event_id_only = http.format == Some(PushFormat::EventIdOnly); - let mut device = Device::new(pusher.ids.app_id.clone(), pusher.ids.pushkey.clone()); + let mut device = + Device::new(pusher.ids.app_id.clone(), pusher.ids.pushkey.clone()); device.data.default_payload = http.default_payload.clone(); device.data.format.clone_from(&http.format); @@ -319,8 +356,11 @@ impl Service { notifi.counts = NotificationCounts::new(unread, uint!(0)); if event_id_only { - self.send_request(&http.url, send_event_notification::v1::Request::new(notifi)) - .await?; + self.send_request( + &http.url, + send_event_notification::v1::Request::new(notifi), + ) + .await?; } else { if event.kind == TimelineEventType::RoomEncrypted || tweaks @@ -336,10 +376,12 @@ impl Service { notifi.content = serde_json::value::to_raw_value(&event.content).ok(); if event.kind == TimelineEventType::RoomMember { - notifi.user_is_target = event.state_key.as_deref() == Some(event.sender.as_str()); + notifi.user_is_target = + event.state_key.as_deref() == Some(event.sender.as_str()); } - notifi.sender_display_name = self.services.users.displayname(&event.sender).await.ok(); + notifi.sender_display_name = + self.services.users.displayname(&event.sender).await.ok(); notifi.room_name = self .services @@ -355,15 +397,18 @@ impl Service { .await .ok(); - self.send_request(&http.url, send_event_notification::v1::Request::new(notifi)) - .await?; + self.send_request( + &http.url, + send_event_notification::v1::Request::new(notifi), + ) + .await?; } Ok(()) }, // TODO: Handle email //PusherKind::Email(_) => Ok(()), - _ => Ok(()), + | _ => Ok(()), } } } diff --git a/src/service/resolver/actual.rs b/src/service/resolver/actual.rs index 4d2da6958..63de6539c 100644 --- a/src/service/resolver/actual.rs +++ b/src/service/resolver/actual.rs @@ -35,17 +35,9 @@ impl super::Service { (self.resolve_actual_dest(server_name, true).await?, false) }; - let CachedDest { - dest, - host, - .. - } = result; + let CachedDest { dest, host, .. } = result; - Ok(ActualDest { - dest, - host, - cached, - }) + Ok(ActualDest { dest, host, cached }) } /// Returns: `actual_destination`, host header @@ -53,12 +45,16 @@ impl super::Service { /// Numbers in comments below refer to bullet points in linked section of /// specification #[tracing::instrument(skip_all, name = "actual")] - pub async fn resolve_actual_dest(&self, dest: &ServerName, cache: bool) -> Result { + pub async fn resolve_actual_dest( + &self, + dest: &ServerName, + cache: bool, + ) -> Result { trace!("Finding actual destination for {dest}"); let mut host = dest.as_str().to_owned(); let actual_dest = match get_ip_with_port(dest.as_str()) { - Some(host_port) => Self::actual_dest_1(host_port)?, - None => { + | Some(host_port) => Self::actual_dest_1(host_port)?, + | None => if let Some(pos) = dest.as_str().find(':') { self.actual_dest_2(dest, cache, pos).await? } else if let Some(delegated) = self.request_well_known(dest.as_str()).await? { @@ -67,8 +63,7 @@ impl super::Service { self.actual_dest_4(&host, cache, overrider).await? } else { self.actual_dest_5(dest, cache).await? - } - }, + }, }; // Can't use get_ip_with_port here because we don't want to add a port @@ -79,7 +74,10 @@ impl super::Service { FedDest::Named(addr.to_string(), FedDest::default_port()) } else if let Some(pos) = host.find(':') { let (host, port) = host.split_at(pos); - FedDest::Named(host.to_owned(), port.try_into().unwrap_or_else(|_| FedDest::default_port())) + FedDest::Named( + host.to_owned(), + port.try_into().unwrap_or_else(|_| FedDest::default_port()), + ) } else { FedDest::Named(host, FedDest::default_port()) }; @@ -100,20 +98,30 @@ impl super::Service { async fn actual_dest_2(&self, dest: &ServerName, cache: bool, pos: usize) -> Result { debug!("2: Hostname with included port"); let (host, port) = dest.as_str().split_at(pos); - self.conditional_query_and_cache_override(host, host, port.parse::().unwrap_or(8448), cache) - .await?; + self.conditional_query_and_cache_override( + host, + host, + port.parse::().unwrap_or(8448), + cache, + ) + .await?; Ok(FedDest::Named( host.to_owned(), port.try_into().unwrap_or_else(|_| FedDest::default_port()), )) } - async fn actual_dest_3(&self, host: &mut String, cache: bool, delegated: String) -> Result { + async fn actual_dest_3( + &self, + host: &mut String, + cache: bool, + delegated: String, + ) -> Result { debug!("3: A .well-known file is available"); *host = add_port_to_hostname(&delegated).uri_string(); match get_ip_with_port(&delegated) { - Some(host_and_port) => Self::actual_dest_3_1(host_and_port), - None => { + | Some(host_and_port) => Self::actual_dest_3_1(host_and_port), + | None => if let Some(pos) = delegated.find(':') { self.actual_dest_3_2(cache, delegated, pos).await } else { @@ -123,8 +131,7 @@ impl super::Service { } else { self.actual_dest_3_4(cache, delegated).await } - } - }, + }, } } @@ -133,22 +140,42 @@ impl super::Service { Ok(host_and_port) } - async fn actual_dest_3_2(&self, cache: bool, delegated: String, pos: usize) -> Result { + async fn actual_dest_3_2( + &self, + cache: bool, + delegated: String, + pos: usize, + ) -> Result { debug!("3.2: Hostname with port in .well-known file"); let (host, port) = delegated.split_at(pos); - self.conditional_query_and_cache_override(host, host, port.parse::().unwrap_or(8448), cache) - .await?; + self.conditional_query_and_cache_override( + host, + host, + port.parse::().unwrap_or(8448), + cache, + ) + .await?; Ok(FedDest::Named( host.to_owned(), port.try_into().unwrap_or_else(|_| FedDest::default_port()), )) } - async fn actual_dest_3_3(&self, cache: bool, delegated: String, overrider: FedDest) -> Result { + async fn actual_dest_3_3( + &self, + cache: bool, + delegated: String, + overrider: FedDest, + ) -> Result { debug!("3.3: SRV lookup successful"); let force_port = overrider.port(); - self.conditional_query_and_cache_override(&delegated, &overrider.hostname(), force_port.unwrap_or(8448), cache) - .await?; + self.conditional_query_and_cache_override( + &delegated, + &overrider.hostname(), + force_port.unwrap_or(8448), + cache, + ) + .await?; if let Some(port) = force_port { Ok(FedDest::Named( delegated, @@ -169,11 +196,21 @@ impl super::Service { Ok(add_port_to_hostname(&delegated)) } - async fn actual_dest_4(&self, host: &str, cache: bool, overrider: FedDest) -> Result { + async fn actual_dest_4( + &self, + host: &str, + cache: bool, + overrider: FedDest, + ) -> Result { debug!("4: No .well-known; SRV record found"); let force_port = overrider.port(); - self.conditional_query_and_cache_override(host, &overrider.hostname(), force_port.unwrap_or(8448), cache) - .await?; + self.conditional_query_and_cache_override( + host, + &overrider.hostname(), + force_port.unwrap_or(8448), + cache, + ) + .await?; if let Some(port) = force_port { let port = format!(":{port}"); Ok(FedDest::Named( @@ -245,7 +282,11 @@ impl super::Service { #[inline] async fn conditional_query_and_cache_override( - &self, overname: &str, hostname: &str, port: u16, cache: bool, + &self, + overname: &str, + hostname: &str, + port: u16, + cache: bool, ) -> Result<()> { if cache { self.query_and_cache_override(overname, hostname, port) @@ -256,22 +297,24 @@ impl super::Service { } #[tracing::instrument(skip_all, name = "ip")] - async fn query_and_cache_override(&self, overname: &'_ str, hostname: &'_ str, port: u16) -> Result<()> { + async fn query_and_cache_override( + &self, + overname: &'_ str, + hostname: &'_ str, + port: u16, + ) -> Result<()> { match self.resolver.resolver.lookup_ip(hostname.to_owned()).await { - Err(e) => Self::handle_resolve_error(&e, hostname), - Ok(override_ip) => { + | Err(e) => Self::handle_resolve_error(&e, hostname), + | Ok(override_ip) => { if hostname != overname { debug_info!("{overname:?} overriden by {hostname:?}"); } - self.set_cached_override( - overname, - CachedOverride { - ips: override_ip.into_iter().take(MAX_IPS).collect(), - port, - expire: CachedOverride::default_expire(), - }, - ); + self.set_cached_override(overname, CachedOverride { + ips: override_ip.into_iter().take(MAX_IPS).collect(), + port, + expire: CachedOverride::default_expire(), + }); Ok(()) }, @@ -280,14 +323,15 @@ impl super::Service { #[tracing::instrument(skip_all, name = "srv")] async fn query_srv_record(&self, hostname: &'_ str) -> Result> { - let hostnames = [format!("_matrix-fed._tcp.{hostname}."), format!("_matrix._tcp.{hostname}.")]; + let hostnames = + [format!("_matrix-fed._tcp.{hostname}."), format!("_matrix._tcp.{hostname}.")]; for hostname in hostnames { debug!("querying SRV for {hostname:?}"); let hostname = hostname.trim_end_matches('.'); match self.resolver.resolver.srv_lookup(hostname).await { - Err(e) => Self::handle_resolve_error(&e, hostname)?, - Ok(result) => { + | Err(e) => Self::handle_resolve_error(&e, hostname)?, + | Ok(result) => return Ok(result.iter().next().map(|result| { FedDest::Named( result.target().to_string().trim_end_matches('.').to_owned(), @@ -296,8 +340,7 @@ impl super::Service { .try_into() .unwrap_or_else(|_| FedDest::default_port()), ) - })) - }, + })), } } @@ -308,25 +351,24 @@ impl super::Service { use hickory_resolver::error::ResolveErrorKind; match *e.kind() { - ResolveErrorKind::NoRecordsFound { - .. - } => { + | ResolveErrorKind::NoRecordsFound { .. } => { // Raise to debug_warn if we can find out the result wasn't from cache debug!(%host, "No DNS records found: {e}"); Ok(()) }, - ResolveErrorKind::Timeout => { + | ResolveErrorKind::Timeout => { Err!(warn!(%host, "DNS {e}")) }, - ResolveErrorKind::NoConnections => { + | ResolveErrorKind::NoConnections => { error!( - "Your DNS server is overloaded and has ran out of connections. It is strongly recommended you \ - remediate this issue to ensure proper federation connectivity." + "Your DNS server is overloaded and has ran out of connections. It is \ + strongly recommended you remediate this issue to ensure proper federation \ + connectivity." ); Err!(error!(%host, "DNS error: {e}")) }, - _ => Err!(error!(%host, "DNS error: {e}")), + | _ => Err!(error!(%host, "DNS error: {e}")), } } @@ -349,8 +391,9 @@ impl super::Service { dest.is_ip_literal() || !IPAddress::is_valid(dest.host()), "Destination is not an IP literal." ); - let ip = IPAddress::parse(dest.host()) - .map_err(|e| err!(BadServerResponse(debug_error!("Failed to parse IP literal from string: {e}"))))?; + let ip = IPAddress::parse(dest.host()).map_err(|e| { + err!(BadServerResponse(debug_error!("Failed to parse IP literal from string: {e}"))) + })?; self.validate_ip(&ip)?; diff --git a/src/service/resolver/cache.rs b/src/service/resolver/cache.rs index ca65db353..3e961f4ce 100644 --- a/src/service/resolver/cache.rs +++ b/src/service/resolver/cache.rs @@ -46,7 +46,11 @@ impl Cache { } impl super::Service { - pub fn set_cached_destination(&self, name: OwnedServerName, dest: CachedDest) -> Option { + pub fn set_cached_destination( + &self, + name: OwnedServerName, + dest: CachedDest, + ) -> Option { trace!(?name, ?dest, "set cached destination"); self.cache .destinations @@ -65,7 +69,11 @@ impl super::Service { .cloned() } - pub fn set_cached_override(&self, name: &str, over: CachedOverride) -> Option { + pub fn set_cached_override( + &self, + name: &str, + over: CachedOverride, + ) -> Option { trace!(?name, ?over, "set cached override"); self.cache .overrides @@ -102,7 +110,9 @@ impl CachedDest { //pub fn valid(&self) -> bool { self.expire > SystemTime::now() } #[must_use] - pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 18..60 * 60 * 36) } + pub(crate) fn default_expire() -> SystemTime { + rand::timepoint_secs(60 * 60 * 18..60 * 60 * 36) + } } impl CachedOverride { @@ -113,5 +123,7 @@ impl CachedOverride { //pub fn valid(&self) -> bool { self.expire > SystemTime::now() } #[must_use] - pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 6..60 * 60 * 12) } + pub(crate) fn default_expire() -> SystemTime { + rand::timepoint_secs(60 * 60 * 6..60 * 60 * 12) + } } diff --git a/src/service/resolver/dns.rs b/src/service/resolver/dns.rs index 54905647c..633b397a5 100644 --- a/src/service/resolver/dns.rs +++ b/src/service/resolver/dns.rs @@ -60,27 +60,26 @@ impl Resolver { opts.shuffle_dns_servers = true; opts.rotate = true; opts.ip_strategy = match config.ip_lookup_strategy { - 1 => hickory_resolver::config::LookupIpStrategy::Ipv4Only, - 2 => hickory_resolver::config::LookupIpStrategy::Ipv6Only, - 3 => hickory_resolver::config::LookupIpStrategy::Ipv4AndIpv6, - 4 => hickory_resolver::config::LookupIpStrategy::Ipv6thenIpv4, - _ => hickory_resolver::config::LookupIpStrategy::Ipv4thenIpv6, + | 1 => hickory_resolver::config::LookupIpStrategy::Ipv4Only, + | 2 => hickory_resolver::config::LookupIpStrategy::Ipv6Only, + | 3 => hickory_resolver::config::LookupIpStrategy::Ipv4AndIpv6, + | 4 => hickory_resolver::config::LookupIpStrategy::Ipv6thenIpv4, + | _ => hickory_resolver::config::LookupIpStrategy::Ipv4thenIpv6, }; opts.authentic_data = false; let resolver = Arc::new(TokioAsyncResolver::tokio(conf, opts)); Ok(Arc::new(Self { resolver: resolver.clone(), - hooked: Arc::new(Hooked { - resolver, - cache, - }), + hooked: Arc::new(Hooked { resolver, cache }), })) } } impl Resolve for Resolver { - fn resolve(&self, name: Name) -> Resolving { resolve_to_reqwest(self.resolver.clone(), name).boxed() } + fn resolve(&self, name: Name) -> Resolving { + resolve_to_reqwest(self.resolver.clone(), name).boxed() + } } impl Resolve for Hooked { diff --git a/src/service/resolver/fed.rs b/src/service/resolver/fed.rs index 9c348b47e..3986db8e0 100644 --- a/src/service/resolver/fed.rs +++ b/src/service/resolver/fed.rs @@ -29,8 +29,8 @@ pub(crate) fn get_ip_with_port(dest_str: &str) -> Option { pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest { let (host, port) = match dest.find(':') { - None => (dest, DEFAULT_PORT), - Some(pos) => dest.split_at(pos), + | None => (dest, DEFAULT_PORT), + | Some(pos) => dest.split_at(pos), }; FedDest::Named( @@ -42,23 +42,23 @@ pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest { impl FedDest { pub(crate) fn https_string(&self) -> String { match self { - Self::Literal(addr) => format!("https://{addr}"), - Self::Named(host, port) => format!("https://{host}{port}"), + | Self::Literal(addr) => format!("https://{addr}"), + | Self::Named(host, port) => format!("https://{host}{port}"), } } pub(crate) fn uri_string(&self) -> String { match self { - Self::Literal(addr) => addr.to_string(), - Self::Named(host, port) => format!("{host}{port}"), + | Self::Literal(addr) => addr.to_string(), + | Self::Named(host, port) => format!("{host}{port}"), } } #[inline] pub(crate) fn hostname(&self) -> Cow<'_, str> { match &self { - Self::Literal(addr) => addr.ip().to_string().into(), - Self::Named(host, _) => host.into(), + | Self::Literal(addr) => addr.ip().to_string().into(), + | Self::Named(host, _) => host.into(), } } @@ -66,16 +66,20 @@ impl FedDest { #[allow(clippy::string_slice)] pub(crate) fn port(&self) -> Option { match &self { - Self::Literal(addr) => Some(addr.port()), - Self::Named(_, port) => port[1..].parse().ok(), + | Self::Literal(addr) => Some(addr.port()), + | Self::Named(_, port) => port[1..].parse().ok(), } } #[inline] #[must_use] - pub fn default_port() -> PortString { PortString::from(DEFAULT_PORT).expect("default port string") } + pub fn default_port() -> PortString { + PortString::from(DEFAULT_PORT).expect("default port string") + } } impl fmt::Display for FedDest { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.uri_string().as_str()) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.uri_string().as_str()) + } } diff --git a/src/service/rooms/alias/mod.rs b/src/service/rooms/alias/mod.rs index 57db0e157..0790c3765 100644 --- a/src/service/rooms/alias/mod.rs +++ b/src/service/rooms/alias/mod.rs @@ -52,7 +52,8 @@ impl crate::Service for Service { appservice: args.depend::("appservice"), globals: args.depend::("globals"), sending: args.depend::("sending"), - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), }, })) } @@ -62,8 +63,15 @@ impl crate::Service for Service { impl Service { #[tracing::instrument(skip(self))] - pub fn set_alias(&self, alias: &RoomAliasId, room_id: &RoomId, user_id: &UserId) -> Result<()> { - if alias == self.services.globals.admin_alias && user_id != self.services.globals.server_user { + pub fn set_alias( + &self, + alias: &RoomAliasId, + room_id: &RoomId, + user_id: &UserId, + ) -> Result<()> { + if alias == self.services.globals.admin_alias + && user_id != self.services.globals.server_user + { return Err(Error::BadRequest( ErrorKind::forbidden(), "Only the server user can set this alias", @@ -120,7 +128,9 @@ impl Service { } pub async fn resolve_with_servers( - &self, room: &RoomOrAliasId, servers: Option>, + &self, + room: &RoomOrAliasId, + servers: Option>, ) -> Result<(OwnedRoomId, Vec)> { if room.is_room_id() { let room_id = RoomId::parse(room).expect("valid RoomId"); @@ -133,14 +143,16 @@ impl Service { #[tracing::instrument(skip(self), name = "resolve")] pub async fn resolve_alias( - &self, room_alias: &RoomAliasId, servers: Option>, + &self, + room_alias: &RoomAliasId, + servers: Option>, ) -> Result<(OwnedRoomId, Vec)> { let server_name = room_alias.server_name(); let server_is_ours = self.services.globals.server_is_ours(server_name); let servers_contains_ours = || { - servers - .as_ref() - .is_some_and(|servers| servers.contains(&self.services.globals.config.server_name)) + servers.as_ref().is_some_and(|servers| { + servers.contains(&self.services.globals.config.server_name) + }) }; if !server_is_ours && !servers_contains_ours() { @@ -150,8 +162,8 @@ impl Service { } let room_id = match self.resolve_local_alias(room_alias).await { - Ok(r) => Some(r), - Err(_) => self.resolve_appservice_alias(room_alias).await?, + | Ok(r) => Some(r), + | Err(_) => self.resolve_appservice_alias(room_alias).await?, }; room_id.map_or_else( @@ -166,7 +178,10 @@ impl Service { } #[tracing::instrument(skip(self), level = "debug")] - pub fn local_aliases_for_room<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn local_aliases_for_room<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { let prefix = (room_id, Interfix); self.db .aliasid_alias @@ -208,10 +223,15 @@ impl Service { if let Ok(content) = self .services .state_accessor - .room_state_get_content::(&room_id, &StateEventType::RoomPowerLevels, "") + .room_state_get_content::( + &room_id, + &StateEventType::RoomPowerLevels, + "", + ) .await { - return Ok(RoomPowerLevels::from(content).user_can_send_state(user_id, StateEventType::RoomCanonicalAlias)); + return Ok(RoomPowerLevels::from(content) + .user_can_send_state(user_id, StateEventType::RoomCanonicalAlias)); } // If there is no power levels event, only the room creator can change @@ -232,7 +252,10 @@ impl Service { self.db.alias_userid.get(alias.alias()).await.deserialized() } - async fn resolve_appservice_alias(&self, room_alias: &RoomAliasId) -> Result> { + async fn resolve_appservice_alias( + &self, + room_alias: &RoomAliasId, + ) -> Result> { use ruma::api::appservice::query::query_room_alias; for appservice in self.services.appservice.read().await.values() { @@ -242,9 +265,7 @@ impl Service { .sending .send_appservice_request( appservice.registration.clone(), - query_room_alias::v1::Request { - room_alias: room_alias.to_owned(), - }, + query_room_alias::v1::Request { room_alias: room_alias.to_owned() }, ) .await, Ok(Some(_opt_result)) @@ -261,19 +282,27 @@ impl Service { } pub async fn appservice_checks( - &self, room_alias: &RoomAliasId, appservice_info: &Option, + &self, + room_alias: &RoomAliasId, + appservice_info: &Option, ) -> Result<()> { if !self .services .globals .server_is_ours(room_alias.server_name()) { - return Err(Error::BadRequest(ErrorKind::InvalidParam, "Alias is from another server.")); + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Alias is from another server.", + )); } if let Some(ref info) = appservice_info { if !info.aliases.is_match(room_alias.as_str()) { - return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace.")); + return Err(Error::BadRequest( + ErrorKind::Exclusive, + "Room alias is not in namespace.", + )); } } else if self .services @@ -281,7 +310,10 @@ impl Service { .is_exclusive_alias(room_alias) .await { - return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice.")); + return Err(Error::BadRequest( + ErrorKind::Exclusive, + "Room alias reserved by appservice.", + )); } Ok(()) diff --git a/src/service/rooms/alias/remote.rs b/src/service/rooms/alias/remote.rs index 00661da26..7744bee28 100644 --- a/src/service/rooms/alias/remote.rs +++ b/src/service/rooms/alias/remote.rs @@ -6,7 +6,9 @@ use ruma::{api::federation, OwnedRoomId, OwnedServerName, RoomAliasId, ServerNam #[implement(super::Service)] pub(super) async fn remote_resolve( - &self, room_alias: &RoomAliasId, servers: Vec, + &self, + room_alias: &RoomAliasId, + servers: Vec, ) -> Result<(OwnedRoomId, Vec)> { debug!(?room_alias, servers = ?servers, "resolve"); let servers = once(room_alias.server_name()) @@ -17,12 +19,12 @@ pub(super) async fn remote_resolve( let mut resolved_room_id: Option = None; for server in servers { match self.remote_request(room_alias, &server).await { - Err(e) => debug_error!("Failed to query for {room_alias:?} from {server}: {e}"), - Ok(Response { - room_id, - servers, - }) => { - debug!("Server {server} answered with {room_id:?} for {room_alias:?} servers: {servers:?}"); + | Err(e) => debug_error!("Failed to query for {room_alias:?} from {server}: {e}"), + | Ok(Response { room_id, servers }) => { + debug!( + "Server {server} answered with {room_id:?} for {room_alias:?} servers: \ + {servers:?}" + ); resolved_room_id.get_or_insert(room_id); add_server(&mut resolved_servers, server); @@ -37,16 +39,20 @@ pub(super) async fn remote_resolve( resolved_room_id .map(|room_id| (room_id, resolved_servers)) - .ok_or_else(|| err!(Request(NotFound("No servers could assist in resolving the room alias")))) + .ok_or_else(|| { + err!(Request(NotFound("No servers could assist in resolving the room alias"))) + }) } #[implement(super::Service)] -async fn remote_request(&self, room_alias: &RoomAliasId, server: &ServerName) -> Result { +async fn remote_request( + &self, + room_alias: &RoomAliasId, + server: &ServerName, +) -> Result { use federation::query::get_room_information::v1::Request; - let request = Request { - room_alias: room_alias.to_owned(), - }; + let request = Request { room_alias: room_alias.to_owned() }; self.services .sending diff --git a/src/service/rooms/auth_chain/data.rs b/src/service/rooms/auth_chain/data.rs index 1548cd550..af8ae3645 100644 --- a/src/service/rooms/auth_chain/data.rs +++ b/src/service/rooms/auth_chain/data.rs @@ -19,14 +19,18 @@ impl Data { let db = &args.db; let config = &args.server.config; let cache_size = f64::from(config.auth_chain_cache_capacity); - let cache_size = usize_from_f64(cache_size * config.cache_capacity_modifier).expect("valid cache size"); + let cache_size = usize_from_f64(cache_size * config.cache_capacity_modifier) + .expect("valid cache size"); Self { shorteventid_authchain: db["shorteventid_authchain"].clone(), auth_chain_cache: Mutex::new(LruCache::new(cache_size)), } } - pub(super) async fn get_cached_eventid_authchain(&self, key: &[u64]) -> Result> { + pub(super) async fn get_cached_eventid_authchain( + &self, + key: &[u64], + ) -> Result> { debug_assert!(!key.is_empty(), "auth_chain key must not be empty"); // Check RAM cache diff --git a/src/service/rooms/auth_chain/mod.rs b/src/service/rooms/auth_chain/mod.rs index b875bf9c9..87992f2d2 100644 --- a/src/service/rooms/auth_chain/mod.rs +++ b/src/service/rooms/auth_chain/mod.rs @@ -43,7 +43,9 @@ impl crate::Service for Service { impl Service { pub async fn event_ids_iter<'a, I>( - &'a self, room_id: &RoomId, starting_events: I, + &'a self, + room_id: &RoomId, + starting_events: I, ) -> Result> + Send + '_> where I: Iterator + Clone + Debug + ExactSizeIterator + Send + 'a, @@ -57,7 +59,11 @@ impl Service { Ok(stream) } - pub async fn get_event_ids<'a, I>(&'a self, room_id: &RoomId, starting_events: I) -> Result>> + pub async fn get_event_ids<'a, I>( + &'a self, + room_id: &RoomId, + starting_events: I, + ) -> Result>> where I: Iterator + Clone + Debug + ExactSizeIterator + Send + 'a, { @@ -74,7 +80,11 @@ impl Service { } #[tracing::instrument(skip_all, name = "auth_chain")] - pub async fn get_auth_chain<'a, I>(&'a self, room_id: &RoomId, starting_events: I) -> Result> + pub async fn get_auth_chain<'a, I>( + &'a self, + room_id: &RoomId, + starting_events: I, + ) -> Result> where I: Iterator + Clone + Debug + ExactSizeIterator + Send + 'a, { @@ -110,7 +120,8 @@ impl Service { continue; } - let chunk_key: Vec = chunk.iter().map(|(short, _)| short).copied().collect(); + let chunk_key: Vec = + chunk.iter().map(|(short, _)| short).copied().collect(); if let Ok(cached) = self.get_cached_eventid_authchain(&chunk_key).await { trace!("Found cache entry for whole chunk"); full_auth_chain.extend(cached.iter().copied()); @@ -169,7 +180,11 @@ impl Service { } #[tracing::instrument(skip(self, room_id))] - async fn get_auth_chain_inner(&self, room_id: &RoomId, event_id: &EventId) -> Result> { + async fn get_auth_chain_inner( + &self, + room_id: &RoomId, + event_id: &EventId, + ) -> Result> { let mut todo = vec![Arc::from(event_id)]; let mut found = HashSet::new(); @@ -177,8 +192,10 @@ impl Service { trace!(?event_id, "processing auth event"); match self.services.timeline.get_pdu(&event_id).await { - Err(e) => debug_error!(?event_id, ?e, "Could not find pdu mentioned in auth events"), - Ok(pdu) => { + | Err(e) => { + debug_error!(?event_id, ?e, "Could not find pdu mentioned in auth events"); + }, + | Ok(pdu) => { if pdu.room_id != room_id { return Err!(Request(Forbidden(error!( ?event_id, @@ -196,7 +213,11 @@ impl Service { .await; if found.insert(sauthevent) { - trace!(?event_id, ?auth_event, "adding auth event to processing queue"); + trace!( + ?event_id, + ?auth_event, + "adding auth event to processing queue" + ); todo.push(auth_event.clone()); } } diff --git a/src/service/rooms/directory/mod.rs b/src/service/rooms/directory/mod.rs index 3046a328f..039efca77 100644 --- a/src/service/rooms/directory/mod.rs +++ b/src/service/rooms/directory/mod.rs @@ -32,10 +32,14 @@ pub fn set_public(&self, room_id: &RoomId) { self.db.publicroomids.insert(room_i pub fn set_not_public(&self, room_id: &RoomId) { self.db.publicroomids.remove(room_id); } #[implement(Service)] -pub fn public_rooms(&self) -> impl Stream + Send { self.db.publicroomids.keys().ignore_err() } +pub fn public_rooms(&self) -> impl Stream + Send { + self.db.publicroomids.keys().ignore_err() +} #[implement(Service)] -pub async fn is_public_room(&self, room_id: &RoomId) -> bool { self.visibility(room_id).await == Visibility::Public } +pub async fn is_public_room(&self, room_id: &RoomId) -> bool { + self.visibility(room_id).await == Visibility::Public +} #[implement(Service)] pub async fn visibility(&self, room_id: &RoomId) -> Visibility { diff --git a/src/service/rooms/event_handler/fetch_and_handle_outliers.rs b/src/service/rooms/event_handler/fetch_and_handle_outliers.rs index 316a1722b..af0ef67d1 100644 --- a/src/service/rooms/event_handler/fetch_and_handle_outliers.rs +++ b/src/service/rooms/event_handler/fetch_and_handle_outliers.rs @@ -5,10 +5,14 @@ use std::{ }; use conduwuit::{ - debug, debug_error, implement, info, pdu, trace, utils::math::continue_exponential_backoff_secs, warn, PduEvent, + debug, debug_error, implement, info, pdu, trace, + utils::math::continue_exponential_backoff_secs, warn, PduEvent, }; use futures::TryFutureExt; -use ruma::{api::federation::event::get_event, CanonicalJsonValue, EventId, RoomId, RoomVersionId, ServerName}; +use ruma::{ + api::federation::event::get_event, CanonicalJsonValue, EventId, RoomId, RoomVersionId, + ServerName, +}; /// Find the event and auth it. Once the event is validated (steps 1 - 8) /// it is appended to the outliers Tree. @@ -21,7 +25,11 @@ use ruma::{api::federation::event::get_event, CanonicalJsonValue, EventId, RoomI /// d. TODO: Ask other servers over federation? #[implement(super::Service)] pub(super) async fn fetch_and_handle_outliers<'a>( - &self, origin: &'a ServerName, events: &'a [Arc], create_event: &'a PduEvent, room_id: &'a RoomId, + &self, + origin: &'a ServerName, + events: &'a [Arc], + create_event: &'a PduEvent, + room_id: &'a RoomId, room_version_id: &'a RoomVersionId, ) -> Vec<(Arc, Option>)> { let back_off = |id| match self @@ -32,10 +40,12 @@ pub(super) async fn fetch_and_handle_outliers<'a>( .expect("locked") .entry(id) { - hash_map::Entry::Vacant(e) => { + | hash_map::Entry::Vacant(e) => { e.insert((Instant::now(), 1)); }, - hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1.saturating_add(1)), + | hash_map::Entry::Occupied(mut e) => { + *e.get_mut() = (Instant::now(), e.get().1.saturating_add(1)); + }, }; let mut events_with_auth_events = Vec::with_capacity(events.len()); @@ -67,7 +77,12 @@ pub(super) async fn fetch_and_handle_outliers<'a>( // Exponential backoff const MIN_DURATION: u64 = 5 * 60; const MAX_DURATION: u64 = 60 * 60 * 24; - if continue_exponential_backoff_secs(MIN_DURATION, MAX_DURATION, time.elapsed(), *tries) { + if continue_exponential_backoff_secs( + MIN_DURATION, + MAX_DURATION, + time.elapsed(), + *tries, + ) { info!("Backing off from {next_id}"); continue; } @@ -86,18 +101,16 @@ pub(super) async fn fetch_and_handle_outliers<'a>( match self .services .sending - .send_federation_request( - origin, - get_event::v1::Request { - event_id: (*next_id).to_owned(), - include_unredacted_content: None, - }, - ) + .send_federation_request(origin, get_event::v1::Request { + event_id: (*next_id).to_owned(), + include_unredacted_content: None, + }) .await { - Ok(res) => { + | Ok(res) => { debug!("Got {next_id} over federation"); - let Ok((calculated_event_id, value)) = pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) + let Ok((calculated_event_id, value)) = + pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) else { back_off((*next_id).to_owned()); continue; @@ -105,15 +118,18 @@ pub(super) async fn fetch_and_handle_outliers<'a>( if calculated_event_id != *next_id { warn!( - "Server didn't return event id we requested: requested: {next_id}, we got \ - {calculated_event_id}. Event: {:?}", + "Server didn't return event id we requested: requested: {next_id}, \ + we got {calculated_event_id}. Event: {:?}", &res.pdu ); } - if let Some(auth_events) = value.get("auth_events").and_then(|c| c.as_array()) { + if let Some(auth_events) = value.get("auth_events").and_then(|c| c.as_array()) + { for auth_event in auth_events { - if let Ok(auth_event) = serde_json::from_value(auth_event.clone().into()) { + if let Ok(auth_event) = + serde_json::from_value(auth_event.clone().into()) + { let a: Arc = auth_event; todo_auth_events.push(a); } else { @@ -127,7 +143,7 @@ pub(super) async fn fetch_and_handle_outliers<'a>( events_in_reverse_order.push((next_id.clone(), value)); events_all.insert(next_id); }, - Err(e) => { + | Err(e) => { debug_error!("Failed to fetch event {next_id}: {e}"); back_off((*next_id).to_owned()); }, @@ -158,20 +174,32 @@ pub(super) async fn fetch_and_handle_outliers<'a>( // Exponential backoff const MIN_DURATION: u64 = 5 * 60; const MAX_DURATION: u64 = 60 * 60 * 24; - if continue_exponential_backoff_secs(MIN_DURATION, MAX_DURATION, time.elapsed(), *tries) { + if continue_exponential_backoff_secs( + MIN_DURATION, + MAX_DURATION, + time.elapsed(), + *tries, + ) { debug!("Backing off from {next_id}"); continue; } } - match Box::pin(self.handle_outlier_pdu(origin, create_event, &next_id, room_id, value.clone(), true)).await + match Box::pin(self.handle_outlier_pdu( + origin, + create_event, + &next_id, + room_id, + value.clone(), + true, + )) + .await { - Ok((pdu, json)) => { + | Ok((pdu, json)) => if next_id == *id { pdus.push((pdu, Some(json))); - } - }, - Err(e) => { + }, + | Err(e) => { warn!("Authentication of event {next_id} failed: {e:?}"); back_off(next_id.into()); }, diff --git a/src/service/rooms/event_handler/fetch_prev.rs b/src/service/rooms/event_handler/fetch_prev.rs index 577b3ff22..b271958fb 100644 --- a/src/service/rooms/event_handler/fetch_prev.rs +++ b/src/service/rooms/event_handler/fetch_prev.rs @@ -8,7 +8,8 @@ use futures::{future, FutureExt}; use ruma::{ int, state_res::{self}, - uint, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, RoomId, RoomVersionId, ServerName, + uint, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, RoomId, RoomVersionId, + ServerName, }; use super::check_room_id; @@ -17,7 +18,11 @@ use super::check_room_id; #[allow(clippy::type_complexity)] #[tracing::instrument(skip_all)] pub(super) async fn fetch_prev( - &self, origin: &ServerName, create_event: &PduEvent, room_id: &RoomId, room_version_id: &RoomVersionId, + &self, + origin: &ServerName, + create_event: &PduEvent, + room_id: &RoomId, + room_version_id: &RoomVersionId, initial_set: Vec>, ) -> Result<( Vec>, @@ -35,7 +40,13 @@ pub(super) async fn fetch_prev( self.services.server.check_running()?; if let Some((pdu, mut json_opt)) = self - .fetch_and_handle_outliers(origin, &[prev_event_id.clone()], create_event, room_id, room_version_id) + .fetch_and_handle_outliers( + origin, + &[prev_event_id.clone()], + create_event, + room_id, + room_version_id, + ) .boxed() .await .pop() @@ -67,7 +78,8 @@ pub(super) async fn fetch_prev( } } - graph.insert(prev_event_id.clone(), pdu.prev_events.iter().cloned().collect()); + graph + .insert(prev_event_id.clone(), pdu.prev_events.iter().cloned().collect()); } else { // Time based check failed graph.insert(prev_event_id.clone(), HashSet::new()); diff --git a/src/service/rooms/event_handler/fetch_state.rs b/src/service/rooms/event_handler/fetch_state.rs index 9c7bc65eb..9ea3e0813 100644 --- a/src/service/rooms/event_handler/fetch_state.rs +++ b/src/service/rooms/event_handler/fetch_state.rs @@ -6,7 +6,8 @@ use std::{ use conduwuit::{debug, implement, warn, Err, Error, PduEvent, Result}; use futures::FutureExt; use ruma::{ - api::federation::event::get_room_state_ids, events::StateEventType, EventId, RoomId, RoomVersionId, ServerName, + api::federation::event::get_room_state_ids, events::StateEventType, EventId, RoomId, + RoomVersionId, ServerName, }; /// Call /state_ids to find out what the state at this pdu is. We trust the @@ -15,20 +16,21 @@ use ruma::{ #[implement(super::Service)] #[tracing::instrument(skip(self, create_event, room_version_id))] pub(super) async fn fetch_state( - &self, origin: &ServerName, create_event: &PduEvent, room_id: &RoomId, room_version_id: &RoomVersionId, + &self, + origin: &ServerName, + create_event: &PduEvent, + room_id: &RoomId, + room_version_id: &RoomVersionId, event_id: &EventId, ) -> Result>>> { debug!("Fetching state ids"); let res = self .services .sending - .send_federation_request( - origin, - get_room_state_ids::v1::Request { - room_id: room_id.to_owned(), - event_id: (*event_id).to_owned(), - }, - ) + .send_federation_request(origin, get_room_state_ids::v1::Request { + room_id: room_id.to_owned(), + event_id: (*event_id).to_owned(), + }) .await .inspect_err(|e| warn!("Fetching state for event failed: {e}"))?; @@ -58,14 +60,13 @@ pub(super) async fn fetch_state( .await; match state.entry(shortstatekey) { - hash_map::Entry::Vacant(v) => { + | hash_map::Entry::Vacant(v) => { v.insert(Arc::from(&*pdu.event_id)); }, - hash_map::Entry::Occupied(_) => { + | hash_map::Entry::Occupied(_) => return Err(Error::bad_database( "State event's type and state_key combination exists multiple times.", - )) - }, + )), } } diff --git a/src/service/rooms/event_handler/handle_incoming_pdu.rs b/src/service/rooms/event_handler/handle_incoming_pdu.rs index d63f96f91..ca56228d0 100644 --- a/src/service/rooms/event_handler/handle_incoming_pdu.rs +++ b/src/service/rooms/event_handler/handle_incoming_pdu.rs @@ -7,7 +7,8 @@ use std::{ use conduwuit::{debug, err, implement, warn, Error, Result}; use futures::{FutureExt, TryFutureExt}; use ruma::{ - api::client::error::ErrorKind, events::StateEventType, CanonicalJsonValue, EventId, RoomId, ServerName, UserId, + api::client::error::ErrorKind, events::StateEventType, CanonicalJsonValue, EventId, RoomId, + ServerName, UserId, }; use super::{check_room_id, get_room_version_id}; @@ -43,8 +44,12 @@ use crate::rooms::timeline::RawPduId; #[implement(super::Service)] #[tracing::instrument(skip(self, origin, value, is_timeline_event), name = "pdu")] pub async fn handle_incoming_pdu<'a>( - &self, origin: &'a ServerName, room_id: &'a RoomId, event_id: &'a EventId, - value: BTreeMap, is_timeline_event: bool, + &self, + origin: &'a ServerName, + room_id: &'a RoomId, + event_id: &'a EventId, + value: BTreeMap, + is_timeline_event: bool, ) -> Result> { // 1. Skip the PDU if we already have it as a timeline event if let Ok(pdu_id) = self.services.timeline.get_pdu_id(event_id).await { @@ -144,10 +149,10 @@ pub async fn handle_incoming_pdu<'a>( .expect("locked") .entry(prev_id.into()) { - Entry::Vacant(e) => { + | Entry::Vacant(e) => { e.insert((now, 1)); }, - Entry::Occupied(mut e) => { + | Entry::Occupied(mut e) => { *e.get_mut() = (now, e.get().1.saturating_add(1)); }, }; diff --git a/src/service/rooms/event_handler/handle_outlier_pdu.rs b/src/service/rooms/event_handler/handle_outlier_pdu.rs index 9391ebf3d..59ef27ba0 100644 --- a/src/service/rooms/event_handler/handle_outlier_pdu.rs +++ b/src/service/rooms/event_handler/handle_outlier_pdu.rs @@ -17,8 +17,13 @@ use super::{check_room_id, get_room_version_id, to_room_version}; #[implement(super::Service)] #[allow(clippy::too_many_arguments)] pub(super) async fn handle_outlier_pdu<'a>( - &self, origin: &'a ServerName, create_event: &'a PduEvent, event_id: &'a EventId, room_id: &'a RoomId, - mut value: CanonicalJsonObject, auth_events_known: bool, + &self, + origin: &'a ServerName, + create_event: &'a PduEvent, + event_id: &'a EventId, + room_id: &'a RoomId, + mut value: CanonicalJsonObject, + auth_events_known: bool, ) -> Result<(Arc, BTreeMap)> { // 1. Remove unsigned field value.remove("unsigned"); @@ -34,8 +39,8 @@ pub(super) async fn handle_outlier_pdu<'a>( .verify_event(&value, Some(&room_version_id)) .await { - Ok(ruma::signatures::Verified::All) => value, - Ok(ruma::signatures::Verified::Signatures) => { + | Ok(ruma::signatures::Verified::All) => value, + | Ok(ruma::signatures::Verified::Signatures) => { // Redact debug_info!("Calculated hash does not match (redaction): {event_id}"); let Ok(obj) = ruma::canonical_json::redact(value, &room_version_id, None) else { @@ -44,24 +49,26 @@ pub(super) async fn handle_outlier_pdu<'a>( // Skip the PDU if it is redacted and we already have it as an outlier event if self.services.timeline.pdu_exists(event_id).await { - return Err!(Request(InvalidParam("Event was redacted and we already knew about it"))); + return Err!(Request(InvalidParam( + "Event was redacted and we already knew about it" + ))); } obj }, - Err(e) => { + | Err(e) => return Err!(Request(InvalidParam(debug_error!( "Signature verification failed for {event_id}: {e}" - )))) - }, + )))), }; // Now that we have checked the signature and hashes we can add the eventID and // convert to our PduEvent type val.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.as_str().to_owned())); - let incoming_pdu = - serde_json::from_value::(serde_json::to_value(&val).expect("CanonicalJsonObj is a valid JsonValue")) - .map_err(|_| Error::bad_database("Event is not a valid PDU."))?; + let incoming_pdu = serde_json::from_value::( + serde_json::to_value(&val).expect("CanonicalJsonObj is a valid JsonValue"), + ) + .map_err(|_| Error::bad_database("Event is not a valid PDU."))?; check_room_id(room_id, &incoming_pdu)?; @@ -108,10 +115,10 @@ pub(super) async fn handle_outlier_pdu<'a>( .clone() .expect("all auth events have state keys"), )) { - hash_map::Entry::Vacant(v) => { + | hash_map::Entry::Vacant(v) => { v.insert(auth_event); }, - hash_map::Entry::Occupied(_) => { + | hash_map::Entry::Occupied(_) => { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Auth event's type and state_key combination exists multiple times.", diff --git a/src/service/rooms/event_handler/handle_prev_pdu.rs b/src/service/rooms/event_handler/handle_prev_pdu.rs index 1b4e9fe28..becaeb176 100644 --- a/src/service/rooms/event_handler/handle_prev_pdu.rs +++ b/src/service/rooms/event_handler/handle_prev_pdu.rs @@ -4,7 +4,9 @@ use std::{ time::Instant, }; -use conduwuit::{debug, implement, utils::math::continue_exponential_backoff_secs, Error, PduEvent, Result}; +use conduwuit::{ + debug, implement, utils::math::continue_exponential_backoff_secs, Error, PduEvent, Result, +}; use ruma::{api::client::error::ErrorKind, CanonicalJsonValue, EventId, RoomId, ServerName}; #[implement(super::Service)] @@ -15,15 +17,23 @@ use ruma::{api::client::error::ErrorKind, CanonicalJsonValue, EventId, RoomId, S name = "prev" )] pub(super) async fn handle_prev_pdu<'a>( - &self, origin: &'a ServerName, event_id: &'a EventId, room_id: &'a RoomId, - eventid_info: &mut HashMap, (Arc, BTreeMap)>, - create_event: &Arc, first_pdu_in_room: &Arc, prev_id: &EventId, + &self, + origin: &'a ServerName, + event_id: &'a EventId, + room_id: &'a RoomId, + eventid_info: &mut HashMap< + Arc, + (Arc, BTreeMap), + >, + create_event: &Arc, + first_pdu_in_room: &Arc, + prev_id: &EventId, ) -> Result { // Check for disabled again because it might have changed if self.services.metadata.is_disabled(room_id).await { debug!( - "Federaton of room {room_id} is currently disabled on this server. Request by origin {origin} and event \ - ID {event_id}" + "Federaton of room {room_id} is currently disabled on this server. Request by \ + origin {origin} and event ID {event_id}" ); return Err(Error::BadRequest( ErrorKind::forbidden(), diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index de3d2f498..bfc5a0141 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -23,8 +23,8 @@ use conduwuit::{ }; use futures::TryFutureExt; use ruma::{ - events::room::create::RoomCreateEventContent, state_res::RoomVersion, EventId, OwnedEventId, OwnedRoomId, RoomId, - RoomVersionId, + events::room::create::RoomCreateEventContent, state_res::RoomVersion, EventId, OwnedEventId, + OwnedRoomId, RoomId, RoomVersionId, }; use crate::{globals, rooms, sending, server_keys, Dep}; @@ -69,8 +69,10 @@ impl crate::Service for Service { pdu_metadata: args.depend::("rooms::pdu_metadata"), short: args.depend::("rooms::short"), state: args.depend::("rooms::state"), - state_accessor: args.depend::("rooms::state_accessor"), - state_compressor: args.depend::("rooms::state_compressor"), + state_accessor: args + .depend::("rooms::state_accessor"), + state_compressor: args + .depend::("rooms::state_compressor"), timeline: args.depend::("rooms::timeline"), server: args.server.clone(), }, @@ -95,7 +97,9 @@ impl crate::Service for Service { } impl Service { - async fn event_exists(&self, event_id: Arc) -> bool { self.services.timeline.pdu_exists(&event_id).await } + async fn event_exists(&self, event_id: Arc) -> bool { + self.services.timeline.pdu_exists(&event_id).await + } async fn event_fetch(&self, event_id: Arc) -> Option> { self.services diff --git a/src/service/rooms/event_handler/parse_incoming_pdu.rs b/src/service/rooms/event_handler/parse_incoming_pdu.rs index 6c19f43f6..f3c75f36a 100644 --- a/src/service/rooms/event_handler/parse_incoming_pdu.rs +++ b/src/service/rooms/event_handler/parse_incoming_pdu.rs @@ -3,9 +3,13 @@ use ruma::{CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedRoomId, R use serde_json::value::RawValue as RawJsonValue; #[implement(super::Service)] -pub async fn parse_incoming_pdu(&self, pdu: &RawJsonValue) -> Result<(OwnedEventId, CanonicalJsonObject, OwnedRoomId)> { - let value = serde_json::from_str::(pdu.get()) - .map_err(|e| err!(BadServerResponse(debug_warn!("Error parsing incoming event {e:?}"))))?; +pub async fn parse_incoming_pdu( + &self, + pdu: &RawJsonValue, +) -> Result<(OwnedEventId, CanonicalJsonObject, OwnedRoomId)> { + let value = serde_json::from_str::(pdu.get()).map_err(|e| { + err!(BadServerResponse(debug_warn!("Error parsing incoming event {e:?}"))) + })?; let room_id: OwnedRoomId = value .get("room_id") @@ -20,8 +24,9 @@ pub async fn parse_incoming_pdu(&self, pdu: &RawJsonValue) -> Result<(OwnedEvent .await .map_err(|_| err!("Server is not in room {room_id}"))?; - let (event_id, value) = gen_event_id_canonical_json(pdu, &room_version_id) - .map_err(|e| err!(Request(InvalidParam("Could not convert event to canonical json: {e}"))))?; + let (event_id, value) = gen_event_id_canonical_json(pdu, &room_version_id).map_err(|e| { + err!(Request(InvalidParam("Could not convert event to canonical json: {e}"))) + })?; Ok((event_id, value, room_id)) } diff --git a/src/service/rooms/event_handler/resolve_state.rs b/src/service/rooms/event_handler/resolve_state.rs index 8ba4e4f43..d507c9c35 100644 --- a/src/service/rooms/event_handler/resolve_state.rs +++ b/src/service/rooms/event_handler/resolve_state.rs @@ -20,7 +20,10 @@ use crate::rooms::state_compressor::CompressedStateEvent; #[implement(super::Service)] #[tracing::instrument(skip_all, name = "resolve")] pub async fn resolve_state( - &self, room_id: &RoomId, room_version_id: &RoomVersionId, incoming_state: HashMap>, + &self, + room_id: &RoomId, + room_version_id: &RoomVersionId, + incoming_state: HashMap>, ) -> Result>> { debug!("Loading current room state ids"); let current_sstatehash = self @@ -76,10 +79,16 @@ pub async fn resolve_state( let event_fetch = |event_id| self.event_fetch(event_id); let event_exists = |event_id| self.event_exists(event_id); - let state = state_res::resolve(room_version_id, &fork_states, &auth_chain_sets, &event_fetch, &event_exists) - .boxed() - .await - .map_err(|e| err!(Database(error!("State resolution failed: {e:?}"))))?; + let state = state_res::resolve( + room_version_id, + &fork_states, + &auth_chain_sets, + &event_fetch, + &event_exists, + ) + .boxed() + .await + .map_err(|e| err!(Database(error!("State resolution failed: {e:?}"))))?; drop(lock); diff --git a/src/service/rooms/event_handler/state_at_incoming.rs b/src/service/rooms/event_handler/state_at_incoming.rs index 6c76d9b53..51879d0d4 100644 --- a/src/service/rooms/event_handler/state_at_incoming.rs +++ b/src/service/rooms/event_handler/state_at_incoming.rs @@ -21,7 +21,8 @@ use ruma::{ // request and build the state from a known point and resolve if > 1 prev_event #[tracing::instrument(skip_all, name = "state")] pub(super) async fn state_at_incoming_degree_one( - &self, incoming_pdu: &Arc, + &self, + incoming_pdu: &Arc, ) -> Result>>> { let prev_event = &*incoming_pdu.prev_events[0]; let Ok(prev_event_sstatehash) = self @@ -70,7 +71,10 @@ pub(super) async fn state_at_incoming_degree_one( #[implement(super::Service)] #[tracing::instrument(skip_all, name = "state")] pub(super) async fn state_at_incoming_resolved( - &self, incoming_pdu: &Arc, room_id: &RoomId, room_version_id: &RoomVersionId, + &self, + incoming_pdu: &Arc, + room_id: &RoomId, + room_version_id: &RoomVersionId, ) -> Result>>> { debug!("Calculating state at event using state res"); let mut extremity_sstatehashes = HashMap::with_capacity(incoming_pdu.prev_events.len()); @@ -157,10 +161,16 @@ pub(super) async fn state_at_incoming_resolved( let event_fetch = |event_id| self.event_fetch(event_id); let event_exists = |event_id| self.event_exists(event_id); - let result = state_res::resolve(room_version_id, &fork_states, &auth_chain_sets, &event_fetch, &event_exists) - .boxed() - .await - .map_err(|e| err!(Database(warn!(?e, "State resolution on prev events failed.")))); + let result = state_res::resolve( + room_version_id, + &fork_states, + &auth_chain_sets, + &event_fetch, + &event_exists, + ) + .boxed() + .await + .map_err(|e| err!(Database(warn!(?e, "State resolution on prev events failed.")))); drop(lock); diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 83267563d..aa484cd62 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -19,8 +19,12 @@ use crate::rooms::{state_compressor::HashSetCompressStateEvent, timeline::RawPdu #[implement(super::Service)] pub(super) async fn upgrade_outlier_to_timeline_pdu( - &self, incoming_pdu: Arc, val: BTreeMap, create_event: &PduEvent, - origin: &ServerName, room_id: &RoomId, + &self, + incoming_pdu: Arc, + val: BTreeMap, + create_event: &PduEvent, + origin: &ServerName, + room_id: &RoomId, ) -> Result> { // Skip the PDU if we already have it as a timeline event if let Ok(pduid) = self @@ -63,7 +67,8 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( .await?; } - let state_at_incoming_event = state_at_incoming_event.expect("we always set this to some above"); + let state_at_incoming_event = + state_at_incoming_event.expect("we always set this to some above"); let room_version = to_room_version(&room_version_id); debug!("Performing auth check"); @@ -124,24 +129,34 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( !auth_check || incoming_pdu.kind == TimelineEventType::RoomRedaction && match room_version_id { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { if let Some(redact_id) = &incoming_pdu.redacts { !self .services .state_accessor - .user_can_redact(redact_id, &incoming_pdu.sender, &incoming_pdu.room_id, true) + .user_can_redact( + redact_id, + &incoming_pdu.sender, + &incoming_pdu.room_id, + true, + ) .await? } else { false } }, - _ => { + | _ => { let content: RoomRedactionEventContent = incoming_pdu.get_content()?; if let Some(redact_id) = &content.redacts { !self .services .state_accessor - .user_can_redact(redact_id, &incoming_pdu.sender, &incoming_pdu.room_id, true) + .user_can_redact( + redact_id, + &incoming_pdu.sender, + &incoming_pdu.room_id, + true, + ) .await? } else { false @@ -229,11 +244,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( // Set the new room state to the resolved state debug!("Forcing new room state"); - let HashSetCompressStateEvent { - shortstatehash, - added, - removed, - } = self + let HashSetCompressStateEvent { shortstatehash, added, removed } = self .services .state_compressor .save_state(room_id, new_room_state) diff --git a/src/service/rooms/lazy_loading/mod.rs b/src/service/rooms/lazy_loading/mod.rs index a4bd4e8ff..c3c27b9ed 100644 --- a/src/service/rooms/lazy_loading/mod.rs +++ b/src/service/rooms/lazy_loading/mod.rs @@ -51,7 +51,11 @@ impl crate::Service for Service { #[tracing::instrument(skip(self), level = "debug")] #[inline] pub async fn lazy_load_was_sent_before( - &self, user_id: &UserId, device_id: &DeviceId, room_id: &RoomId, ll_user: &UserId, + &self, + user_id: &UserId, + device_id: &DeviceId, + room_id: &RoomId, + ll_user: &UserId, ) -> bool { let key = (user_id, device_id, room_id, ll_user); self.db.lazyloadedids.qry(&key).await.is_ok() @@ -60,7 +64,12 @@ pub async fn lazy_load_was_sent_before( #[implement(Service)] #[tracing::instrument(skip(self), level = "debug")] pub fn lazy_load_mark_sent( - &self, user_id: &UserId, device_id: &DeviceId, room_id: &RoomId, lazy_load: HashSet, count: PduCount, + &self, + user_id: &UserId, + device_id: &DeviceId, + room_id: &RoomId, + lazy_load: HashSet, + count: PduCount, ) { let key = (user_id.to_owned(), device_id.to_owned(), room_id.to_owned(), count); @@ -72,7 +81,13 @@ pub fn lazy_load_mark_sent( #[implement(Service)] #[tracing::instrument(skip(self), level = "debug")] -pub fn lazy_load_confirm_delivery(&self, user_id: &UserId, device_id: &DeviceId, room_id: &RoomId, since: PduCount) { +pub fn lazy_load_confirm_delivery( + &self, + user_id: &UserId, + device_id: &DeviceId, + room_id: &RoomId, + since: PduCount, +) { let key = (user_id.to_owned(), device_id.to_owned(), room_id.to_owned(), since); let Some(user_ids) = self.lazy_load_waiting.lock().expect("locked").remove(&key) else { diff --git a/src/service/rooms/metadata/mod.rs b/src/service/rooms/metadata/mod.rs index 8f65eec3f..6d5a85a0f 100644 --- a/src/service/rooms/metadata/mod.rs +++ b/src/service/rooms/metadata/mod.rs @@ -58,7 +58,9 @@ pub async fn exists(&self, room_id: &RoomId) -> bool { } #[implement(Service)] -pub fn iter_ids(&self) -> impl Stream + Send + '_ { self.db.roomid_shortroomid.keys().ignore_err() } +pub fn iter_ids(&self) -> impl Stream + Send + '_ { + self.db.roomid_shortroomid.keys().ignore_err() +} #[implement(Service)] #[inline] @@ -81,12 +83,18 @@ pub fn ban_room(&self, room_id: &RoomId, banned: bool) { } #[implement(Service)] -pub fn list_banned_rooms(&self) -> impl Stream + Send + '_ { self.db.bannedroomids.keys().ignore_err() } +pub fn list_banned_rooms(&self) -> impl Stream + Send + '_ { + self.db.bannedroomids.keys().ignore_err() +} #[implement(Service)] #[inline] -pub async fn is_disabled(&self, room_id: &RoomId) -> bool { self.db.disabledroomids.get(room_id).await.is_ok() } +pub async fn is_disabled(&self, room_id: &RoomId) -> bool { + self.db.disabledroomids.get(room_id).await.is_ok() +} #[implement(Service)] #[inline] -pub async fn is_banned(&self, room_id: &RoomId) -> bool { self.db.bannedroomids.get(room_id).await.is_ok() } +pub async fn is_banned(&self, room_id: &RoomId) -> bool { + self.db.bannedroomids.get(room_id).await.is_ok() +} diff --git a/src/service/rooms/pdu_metadata/data.rs b/src/service/rooms/pdu_metadata/data.rs index be9e4ba91..01950975e 100644 --- a/src/service/rooms/pdu_metadata/data.rs +++ b/src/service/rooms/pdu_metadata/data.rs @@ -56,26 +56,27 @@ impl Data { } pub(super) fn get_relations<'a>( - &'a self, user_id: &'a UserId, shortroomid: ShortRoomId, target: ShortEventId, from: PduCount, dir: Direction, + &'a self, + user_id: &'a UserId, + shortroomid: ShortRoomId, + target: ShortEventId, + from: PduCount, + dir: Direction, ) -> impl Stream + Send + '_ { let mut current = ArrayVec::::new(); current.extend(target.to_be_bytes()); current.extend(from.saturating_inc(dir).into_unsigned().to_be_bytes()); let current = current.as_slice(); match dir { - Direction::Forward => self.tofrom_relation.raw_keys_from(current).boxed(), - Direction::Backward => self.tofrom_relation.rev_raw_keys_from(current).boxed(), + | Direction::Forward => self.tofrom_relation.raw_keys_from(current).boxed(), + | Direction::Backward => self.tofrom_relation.rev_raw_keys_from(current).boxed(), } .ignore_err() .ready_take_while(move |key| key.starts_with(&target.to_be_bytes())) .map(|to_from| u64_from_u8(&to_from[8..16])) .map(PduCount::from_unsigned) .wide_filter_map(move |shorteventid| async move { - let pdu_id: RawPduId = PduId { - shortroomid, - shorteventid, - } - .into(); + let pdu_id: RawPduId = PduId { shortroomid, shorteventid }.into(); let mut pdu = self.services.timeline.get_pdu_from_id(&pdu_id).await.ok()?; @@ -99,7 +100,9 @@ impl Data { self.referencedevents.qry(&key).await.is_ok() } - pub(super) fn mark_event_soft_failed(&self, event_id: &EventId) { self.softfailedeventids.insert(event_id, []); } + pub(super) fn mark_event_soft_failed(&self, event_id: &EventId) { + self.softfailedeventids.insert(event_id, []); + } pub(super) async fn is_event_soft_failed(&self, event_id: &EventId) -> bool { self.softfailedeventids.get(event_id).await.is_ok() diff --git a/src/service/rooms/pdu_metadata/mod.rs b/src/service/rooms/pdu_metadata/mod.rs index 23c6d90b0..ac70dbc32 100644 --- a/src/service/rooms/pdu_metadata/mod.rs +++ b/src/service/rooms/pdu_metadata/mod.rs @@ -36,8 +36,8 @@ impl Service { #[tracing::instrument(skip(self, from, to), level = "debug")] pub fn add_relation(&self, from: PduCount, to: PduCount) { match (from, to) { - (PduCount::Normal(f), PduCount::Normal(t)) => self.db.add_relation(f, t), - _ => { + | (PduCount::Normal(f), PduCount::Normal(t)) => self.db.add_relation(f, t), + | _ => { // TODO: Relations with backfilled pdus }, } @@ -45,15 +45,21 @@ impl Service { #[allow(clippy::too_many_arguments)] pub async fn get_relations( - &self, user_id: &UserId, room_id: &RoomId, target: &EventId, from: PduCount, limit: usize, max_depth: u8, + &self, + user_id: &UserId, + room_id: &RoomId, + target: &EventId, + from: PduCount, + limit: usize, + max_depth: u8, dir: Direction, ) -> Vec { let room_id = self.services.short.get_or_create_shortroomid(room_id).await; let target = match self.services.timeline.get_pdu_count(target).await { - Ok(PduCount::Normal(c)) => c, + | Ok(PduCount::Normal(c)) => c, // TODO: Support backfilled relations - _ => 0, // This will result in an empty iterator + | _ => 0, // This will result in an empty iterator }; let mut pdus: Vec<_> = self @@ -66,9 +72,9 @@ impl Service { 'limit: while let Some(stack_pdu) = stack.pop() { let target = match stack_pdu.0 .0 { - PduCount::Normal(c) => c, + | PduCount::Normal(c) => c, // TODO: Support backfilled relations - PduCount::Backfilled(_) => 0, // This will result in an empty iterator + | PduCount::Backfilled(_) => 0, // This will result in an empty iterator }; let relations: Vec<_> = self @@ -106,7 +112,9 @@ impl Service { #[inline] #[tracing::instrument(skip(self), level = "debug")] - pub fn mark_event_soft_failed(&self, event_id: &EventId) { self.db.mark_event_soft_failed(event_id) } + pub fn mark_event_soft_failed(&self, event_id: &EventId) { + self.db.mark_event_soft_failed(event_id); + } #[inline] #[tracing::instrument(skip(self), level = "debug")] diff --git a/src/service/rooms/read_receipt/data.rs b/src/service/rooms/read_receipt/data.rs index 03d04b656..c21ad36c6 100644 --- a/src/service/rooms/read_receipt/data.rs +++ b/src/service/rooms/read_receipt/data.rs @@ -40,7 +40,12 @@ impl Data { } } - pub(super) async fn readreceipt_update(&self, user_id: &UserId, room_id: &RoomId, event: &ReceiptEvent) { + pub(super) async fn readreceipt_update( + &self, + user_id: &UserId, + room_id: &RoomId, + event: &ReceiptEvent, + ) { // Remove old entry let last_possible_key = (room_id, u64::MAX); self.readreceiptid_readreceipt @@ -57,7 +62,9 @@ impl Data { } pub(super) fn readreceipts_since<'a>( - &'a self, room_id: &'a RoomId, since: u64, + &'a self, + room_id: &'a RoomId, + since: u64, ) -> impl Stream> + Send + 'a { type Key<'a> = (&'a RoomId, u64, &'a UserId); type KeyVal<'a> = (Key<'a>, CanonicalJsonObject); @@ -87,12 +94,20 @@ impl Data { self.roomuserid_lastprivatereadupdate.put(key, next_count); } - pub(super) async fn private_read_get_count(&self, room_id: &RoomId, user_id: &UserId) -> Result { + pub(super) async fn private_read_get_count( + &self, + room_id: &RoomId, + user_id: &UserId, + ) -> Result { let key = (room_id, user_id); self.roomuserid_privateread.qry(&key).await.deserialized() } - pub(super) async fn last_privateread_update(&self, user_id: &UserId, room_id: &RoomId) -> u64 { + pub(super) async fn last_privateread_update( + &self, + user_id: &UserId, + room_id: &RoomId, + ) -> u64 { let key = (room_id, user_id); self.roomuserid_lastprivatereadupdate .qry(&key) diff --git a/src/service/rooms/read_receipt/mod.rs b/src/service/rooms/read_receipt/mod.rs index d92b9759d..53e64957d 100644 --- a/src/service/rooms/read_receipt/mod.rs +++ b/src/service/rooms/read_receipt/mod.rs @@ -44,7 +44,12 @@ impl crate::Service for Service { impl Service { /// Replaces the previous read receipt. - pub async fn readreceipt_update(&self, user_id: &UserId, room_id: &RoomId, event: &ReceiptEvent) { + pub async fn readreceipt_update( + &self, + user_id: &UserId, + room_id: &RoomId, + event: &ReceiptEvent, + ) { self.db.readreceipt_update(user_id, room_id, event).await; self.services .sending @@ -54,23 +59,21 @@ impl Service { } /// Gets the latest private read receipt from the user in the room - pub async fn private_read_get(&self, room_id: &RoomId, user_id: &UserId) -> Result> { - let pdu_count = self - .private_read_get_count(room_id, user_id) - .map_err(|e| err!(Database(warn!("No private read receipt was set in {room_id}: {e}")))); - let shortroomid = self - .services - .short - .get_shortroomid(room_id) - .map_err(|e| err!(Database(warn!("Short room ID does not exist in database for {room_id}: {e}")))); + pub async fn private_read_get( + &self, + room_id: &RoomId, + user_id: &UserId, + ) -> Result> { + let pdu_count = self.private_read_get_count(room_id, user_id).map_err(|e| { + err!(Database(warn!("No private read receipt was set in {room_id}: {e}"))) + }); + let shortroomid = self.services.short.get_shortroomid(room_id).map_err(|e| { + err!(Database(warn!("Short room ID does not exist in database for {room_id}: {e}"))) + }); let (pdu_count, shortroomid) = try_join!(pdu_count, shortroomid)?; let shorteventid = PduCount::Normal(pdu_count); - let pdu_id: RawPduId = PduId { - shortroomid, - shorteventid, - } - .into(); + let pdu_id: RawPduId = PduId { shortroomid, shorteventid }.into(); let pdu = self.services.timeline.get_pdu_from_id(&pdu_id).await?; @@ -80,21 +83,17 @@ impl Service { event_id, BTreeMap::from_iter([( ruma::events::receipt::ReceiptType::ReadPrivate, - BTreeMap::from_iter([( - user_id, - ruma::events::receipt::Receipt { - ts: None, // TODO: start storing the timestamp so we can return one - thread: ruma::events::receipt::ReceiptThread::Unthreaded, - }, - )]), + BTreeMap::from_iter([(user_id, ruma::events::receipt::Receipt { + ts: None, // TODO: start storing the timestamp so we can return one + thread: ruma::events::receipt::ReceiptThread::Unthreaded, + })]), )]), )]); let receipt_event_content = ReceiptEventContent(content); - let receipt_sync_event = SyncEphemeralRoomEvent { - content: receipt_event_content, - }; + let receipt_sync_event = SyncEphemeralRoomEvent { content: receipt_event_content }; - let event = serde_json::value::to_raw_value(&receipt_sync_event).expect("receipt created manually"); + let event = serde_json::value::to_raw_value(&receipt_sync_event) + .expect("receipt created manually"); Ok(Raw::from_json(event)) } @@ -104,7 +103,9 @@ impl Service { #[inline] #[tracing::instrument(skip(self), level = "debug")] pub fn readreceipts_since<'a>( - &'a self, room_id: &'a RoomId, since: u64, + &'a self, + room_id: &'a RoomId, + since: u64, ) -> impl Stream> + Send + 'a { self.db.readreceipts_since(room_id, since) } @@ -119,7 +120,11 @@ impl Service { /// Returns the private read marker PDU count. #[inline] #[tracing::instrument(skip(self), level = "debug")] - pub async fn private_read_get_count(&self, room_id: &RoomId, user_id: &UserId) -> Result { + pub async fn private_read_get_count( + &self, + room_id: &RoomId, + user_id: &UserId, + ) -> Result { self.db.private_read_get_count(room_id, user_id).await } @@ -137,7 +142,9 @@ where { let mut json = BTreeMap::new(); for value in receipts { - let receipt = serde_json::from_str::>(value.json().get()); + let receipt = serde_json::from_str::>( + value.json().get(), + ); if let Ok(value) = receipt { for (event, receipt) in value.content { json.insert(event, receipt); @@ -149,9 +156,7 @@ where let content = ReceiptEventContent::from_iter(json); Raw::from_json( - serde_json::value::to_raw_value(&SyncEphemeralRoomEvent { - content, - }) - .expect("received valid json"), + serde_json::value::to_raw_value(&SyncEphemeralRoomEvent { content }) + .expect("received valid json"), ) } diff --git a/src/service/rooms/search/mod.rs b/src/service/rooms/search/mod.rs index 025fc42a7..35cfd4448 100644 --- a/src/service/rooms/search/mod.rs +++ b/src/service/rooms/search/mod.rs @@ -49,18 +49,18 @@ pub struct RoomQuery<'a> { type TokenId = ArrayVec; -const TOKEN_ID_MAX_LEN: usize = size_of::() + WORD_MAX_LEN + 1 + size_of::(); +const TOKEN_ID_MAX_LEN: usize = + size_of::() + WORD_MAX_LEN + 1 + size_of::(); const WORD_MAX_LEN: usize = 50; impl crate::Service for Service { fn build(args: crate::Args<'_>) -> Result> { Ok(Arc::new(Self { - db: Data { - tokenids: args.db["tokenids"].clone(), - }, + db: Data { tokenids: args.db["tokenids"].clone() }, services: Services { short: args.depend::("rooms::short"), - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), timeline: args.depend::("rooms::timeline"), }, })) @@ -103,7 +103,8 @@ pub fn deindex_pdu(&self, shortroomid: ShortRoomId, pdu_id: &RawPduId, message_b #[implement(Service)] pub async fn search_pdus<'a>( - &'a self, query: &'a RoomQuery<'a>, + &'a self, + query: &'a RoomQuery<'a>, ) -> Result<(usize, impl Stream + Send + 'a)> { let pdu_ids: Vec<_> = self.search_pdu_ids(query).await?.collect().await; @@ -136,7 +137,10 @@ pub async fn search_pdus<'a>( // result is modeled as a stream such that callers don't have to be refactored // though an additional async/wrap still exists for now #[implement(Service)] -pub async fn search_pdu_ids(&self, query: &RoomQuery<'_>) -> Result + Send + '_> { +pub async fn search_pdu_ids( + &self, + query: &RoomQuery<'_>, +) -> Result + Send + '_> { let shortroomid = self.services.short.get_shortroomid(query.room_id).await?; let pdu_ids = self.search_pdu_ids_query_room(query, shortroomid).await; @@ -147,7 +151,11 @@ pub async fn search_pdu_ids(&self, query: &RoomQuery<'_>) -> Result, shortroomid: ShortRoomId) -> Vec> { +async fn search_pdu_ids_query_room( + &self, + query: &RoomQuery<'_>, + shortroomid: ShortRoomId, +) -> Vec> { tokenize(&query.criteria.search_term) .stream() .wide_then(|word| async move { @@ -162,7 +170,9 @@ async fn search_pdu_ids_query_room(&self, query: &RoomQuery<'_>, shortroomid: Sh /// Iterate over PduId's containing a word #[implement(Service)] fn search_pdu_ids_query_words<'a>( - &'a self, shortroomid: ShortRoomId, word: &'a str, + &'a self, + shortroomid: ShortRoomId, + word: &'a str, ) -> impl Stream + Send + '_ { self.search_pdu_ids_query_word(shortroomid, word) .map(move |key| -> RawPduId { @@ -173,7 +183,11 @@ fn search_pdu_ids_query_words<'a>( /// Iterate over raw database results for a word #[implement(Service)] -fn search_pdu_ids_query_word(&self, shortroomid: ShortRoomId, word: &str) -> impl Stream> + Send + '_ { +fn search_pdu_ids_query_word( + &self, + shortroomid: ShortRoomId, + word: &str, +) -> impl Stream> + Send + '_ { // rustc says const'ing this not yet stable let end_id: RawPduId = PduId { shortroomid, diff --git a/src/service/rooms/short/mod.rs b/src/service/rooms/short/mod.rs index 465ce1a95..f814411be 100644 --- a/src/service/rooms/short/mod.rs +++ b/src/service/rooms/short/mod.rs @@ -60,7 +60,10 @@ pub async fn get_or_create_shorteventid(&self, event_id: &EventId) -> ShortEvent } #[implement(Service)] -pub fn multi_get_or_create_shorteventid<'a, I>(&'a self, event_ids: I) -> impl Stream + Send + '_ +pub fn multi_get_or_create_shorteventid<'a, I>( + &'a self, + event_ids: I, +) -> impl Stream + Send + '_ where I: Iterator + Clone + Debug + ExactSizeIterator + Send + 'a, ::Item: AsRef<[u8]> + Send + Sync + 'a, @@ -72,8 +75,8 @@ where event_ids.next().map(|event_id| (event_id, result)) }) .map(|(event_id, result)| match result { - Ok(ref short) => utils::u64_from_u8(short), - Err(_) => self.create_shorteventid(event_id), + | Ok(ref short) => utils::u64_from_u8(short), + | Err(_) => self.create_shorteventid(event_id), }) } @@ -104,7 +107,11 @@ pub async fn get_shorteventid(&self, event_id: &EventId) -> Result } #[implement(Service)] -pub async fn get_or_create_shortstatekey(&self, event_type: &StateEventType, state_key: &str) -> ShortStateKey { +pub async fn get_or_create_shortstatekey( + &self, + event_type: &StateEventType, + state_key: &str, +) -> ShortStateKey { const BUFSIZE: usize = size_of::(); if let Ok(shortstatekey) = self.get_shortstatekey(event_type, state_key).await { @@ -127,7 +134,11 @@ pub async fn get_or_create_shortstatekey(&self, event_type: &StateEventType, sta } #[implement(Service)] -pub async fn get_shortstatekey(&self, event_type: &StateEventType, state_key: &str) -> Result { +pub async fn get_shortstatekey( + &self, + event_type: &StateEventType, + state_key: &str, +) -> Result { let key = (event_type, state_key); self.db .statekey_shortstatekey @@ -153,7 +164,10 @@ where } #[implement(Service)] -pub fn multi_get_eventid_from_short<'a, Id, I>(&'a self, shorteventid: I) -> impl Stream> + Send + 'a +pub fn multi_get_eventid_from_short<'a, Id, I>( + &'a self, + shorteventid: I, +) -> impl Stream> + Send + 'a where I: Iterator + Send + 'a, Id: for<'de> Deserialize<'de> + Sized + ToOwned + 'a, @@ -168,7 +182,10 @@ where } #[implement(Service)] -pub async fn get_statekey_from_short(&self, shortstatekey: ShortStateKey) -> Result<(StateEventType, String)> { +pub async fn get_statekey_from_short( + &self, + shortstatekey: ShortStateKey, +) -> Result<(StateEventType, String)> { const BUFSIZE: usize = size_of::(); self.db diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index aa5238716..d60c4c9e7 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -125,7 +125,8 @@ enum Identifier<'a> { pub struct Service { services: Services, - pub roomid_spacehierarchy_cache: Mutex>>, + pub roomid_spacehierarchy_cache: + Mutex>>, } struct Services { @@ -145,11 +146,13 @@ impl crate::Service for Service { let cache_size = cache_size * config.cache_capacity_modifier; Ok(Arc::new(Self { services: Services { - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), state_cache: args.depend::("rooms::state_cache"), state: args.depend::("rooms::state"), short: args.depend::("rooms::short"), - event_handler: args.depend::("rooms::event_handler"), + event_handler: args + .depend::("rooms::event_handler"), timeline: args.depend::("rooms::timeline"), sending: args.depend::("sending"), }, @@ -166,28 +169,37 @@ impl Service { /// Errors if the room does not exist, so a check if the room exists should /// be done pub async fn get_federation_hierarchy( - &self, room_id: &RoomId, server_name: &ServerName, suggested_only: bool, + &self, + room_id: &RoomId, + server_name: &ServerName, + suggested_only: bool, ) -> Result { match self - .get_summary_and_children_local(&room_id.to_owned(), Identifier::ServerName(server_name)) + .get_summary_and_children_local( + &room_id.to_owned(), + Identifier::ServerName(server_name), + ) .await? { - Some(SummaryAccessibility::Accessible(room)) => { + | Some(SummaryAccessibility::Accessible(room)) => { let mut children = Vec::new(); let mut inaccessible_children = Vec::new(); for (child, _via) in get_parent_children_via(&room, suggested_only) { match self - .get_summary_and_children_local(&child, Identifier::ServerName(server_name)) + .get_summary_and_children_local( + &child, + Identifier::ServerName(server_name), + ) .await? { - Some(SummaryAccessibility::Accessible(summary)) => { + | Some(SummaryAccessibility::Accessible(summary)) => { children.push((*summary).into()); }, - Some(SummaryAccessibility::Inaccessible) => { + | Some(SummaryAccessibility::Inaccessible) => { inaccessible_children.push(child); }, - None => (), + | None => (), } } @@ -197,16 +209,18 @@ impl Service { inaccessible_children, }) }, - Some(SummaryAccessibility::Inaccessible) => { - Err(Error::BadRequest(ErrorKind::NotFound, "The requested room is inaccessible")) - }, - None => Err(Error::BadRequest(ErrorKind::NotFound, "The requested room was not found")), + | Some(SummaryAccessibility::Inaccessible) => + Err(Error::BadRequest(ErrorKind::NotFound, "The requested room is inaccessible")), + | None => + Err(Error::BadRequest(ErrorKind::NotFound, "The requested room was not found")), } } /// Gets the summary of a space using solely local information async fn get_summary_and_children_local( - &self, current_room: &OwnedRoomId, identifier: Identifier<'_>, + &self, + current_room: &OwnedRoomId, + identifier: Identifier<'_>, ) -> Result> { if let Some(cached) = self .roomid_spacehierarchy_cache @@ -241,9 +255,7 @@ impl Service { if let Ok(summary) = summary { self.roomid_spacehierarchy_cache.lock().await.insert( current_room.clone(), - Some(CachedSpaceHierarchySummary { - summary: summary.clone(), - }), + Some(CachedSpaceHierarchySummary { summary: summary.clone() }), ); Ok(Some(SummaryAccessibility::Accessible(Box::new(summary)))) @@ -258,20 +270,21 @@ impl Service { /// Gets the summary of a space using solely federation #[tracing::instrument(skip(self))] async fn get_summary_and_children_federation( - &self, current_room: &OwnedRoomId, suggested_only: bool, user_id: &UserId, via: &[OwnedServerName], + &self, + current_room: &OwnedRoomId, + suggested_only: bool, + user_id: &UserId, + via: &[OwnedServerName], ) -> Result> { for server in via { debug_info!("Asking {server} for /hierarchy"); let Ok(response) = self .services .sending - .send_federation_request( - server, - federation::space::get_hierarchy::v1::Request { - room_id: current_room.to_owned(), - suggested_only, - }, - ) + .send_federation_request(server, federation::space::get_hierarchy::v1::Request { + room_id: current_room.to_owned(), + suggested_only, + }) .await else { continue; @@ -282,9 +295,7 @@ impl Service { self.roomid_spacehierarchy_cache.lock().await.insert( current_room.clone(), - Some(CachedSpaceHierarchySummary { - summary: summary.clone(), - }), + Some(CachedSpaceHierarchySummary { summary: summary.clone() }), ); for child in response.children { @@ -356,7 +367,11 @@ impl Service { /// Gets the summary of a space using either local or remote (federation) /// sources async fn get_summary_and_children_client( - &self, current_room: &OwnedRoomId, suggested_only: bool, user_id: &UserId, via: &[OwnedServerName], + &self, + current_room: &OwnedRoomId, + suggested_only: bool, + user_id: &UserId, + via: &[OwnedServerName], ) -> Result> { if let Ok(Some(response)) = self .get_summary_and_children_local(current_room, Identifier::UserId(user_id)) @@ -370,7 +385,9 @@ impl Service { } async fn get_room_summary( - &self, current_room: &OwnedRoomId, children_state: Vec>, + &self, + current_room: &OwnedRoomId, + children_state: Vec>, identifier: &Identifier<'_>, ) -> Result { let room_id: &RoomId = current_room; @@ -388,12 +405,20 @@ impl Service { .allowed_room_ids(join_rule.clone()); if !self - .is_accessible_child(current_room, &join_rule.clone().into(), identifier, &allowed_room_ids) + .is_accessible_child( + current_room, + &join_rule.clone().into(), + identifier, + &allowed_room_ids, + ) .await { debug_info!("User is not allowed to see room {room_id}"); // This error will be caught later - return Err(Error::BadRequest(ErrorKind::forbidden(), "User is not allowed to see the room")); + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "User is not allowed to see the room", + )); } Ok(SpaceHierarchyParentSummary { @@ -446,7 +471,12 @@ impl Service { } pub async fn get_client_hierarchy( - &self, sender_user: &UserId, room_id: &RoomId, limit: usize, short_room_ids: Vec, max_depth: u64, + &self, + sender_user: &UserId, + room_id: &RoomId, + limit: usize, + short_room_ids: Vec, + max_depth: u64, suggested_only: bool, ) -> Result { let mut parents = VecDeque::new(); @@ -454,27 +484,30 @@ impl Service { // Don't start populating the results if we have to start at a specific room. let mut populate_results = short_room_ids.is_empty(); - let mut stack = vec![vec![( - room_id.to_owned(), - match room_id.server_name() { - Some(server_name) => vec![server_name.into()], - None => vec![], - }, - )]]; + let mut stack = vec![vec![(room_id.to_owned(), match room_id.server_name() { + | Some(server_name) => vec![server_name.into()], + | None => vec![], + })]]; let mut results = Vec::with_capacity(limit); - while let Some((current_room, via)) = { next_room_to_traverse(&mut stack, &mut parents) } { + while let Some((current_room, via)) = { next_room_to_traverse(&mut stack, &mut parents) } + { if results.len() >= limit { break; } match ( - self.get_summary_and_children_client(¤t_room, suggested_only, sender_user, &via) - .await?, + self.get_summary_and_children_client( + ¤t_room, + suggested_only, + sender_user, + &via, + ) + .await?, current_room == room_id, ) { - (Some(SummaryAccessibility::Accessible(summary)), _) => { + | (Some(SummaryAccessibility::Accessible(summary)), _) => { let mut children: Vec<(OwnedRoomId, Vec)> = get_parent_children_via(&summary, suggested_only) .into_iter() @@ -493,7 +526,9 @@ impl Service { self.services .short .get_shortroomid(room) - .map_ok(|short| Some(&short) != short_room_ids.get(parents.len())) + .map_ok(|short| { + Some(&short) != short_room_ids.get(parents.len()) + }) .unwrap_or_else(|_| false) }) .map(Clone::clone) @@ -525,14 +560,20 @@ impl Service { // Root room in the space hierarchy, we return an error // if this one fails. }, - (Some(SummaryAccessibility::Inaccessible), true) => { - return Err(Error::BadRequest(ErrorKind::forbidden(), "The requested room is inaccessible")); + | (Some(SummaryAccessibility::Inaccessible), true) => { + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "The requested room is inaccessible", + )); }, - (None, true) => { - return Err(Error::BadRequest(ErrorKind::forbidden(), "The requested room was not found")); + | (None, true) => { + return Err(Error::BadRequest( + ErrorKind::forbidden(), + "The requested room was not found", + )); }, // Just ignore other unavailable rooms - (None | Some(SummaryAccessibility::Inaccessible), false) => (), + | (None | Some(SummaryAccessibility::Inaccessible), false) => (), } } @@ -544,15 +585,19 @@ impl Service { let short_room_ids: Vec<_> = parents .iter() .stream() - .filter_map(|room_id| async move { self.services.short.get_shortroomid(room_id).await.ok() }) + .filter_map(|room_id| async move { + self.services.short.get_shortroomid(room_id).await.ok() + }) .collect() .await; Some( PaginationToken { short_room_ids, - limit: UInt::new(max_depth).expect("When sent in request it must have been valid UInt"), - max_depth: UInt::new(max_depth).expect("When sent in request it must have been valid UInt"), + limit: UInt::new(max_depth) + .expect("When sent in request it must have been valid UInt"), + max_depth: UInt::new(max_depth) + .expect("When sent in request it must have been valid UInt"), suggested_only, } .to_string(), @@ -566,9 +611,12 @@ impl Service { /// Simply returns the stripped m.space.child events of a room async fn get_stripped_space_child_events( - &self, room_id: &RoomId, + &self, + room_id: &RoomId, ) -> Result>>, Error> { - let Ok(current_shortstatehash) = self.services.state.get_room_shortstatehash(room_id).await else { + let Ok(current_shortstatehash) = + self.services.state.get_room_shortstatehash(room_id).await + else { return Ok(None); }; @@ -581,18 +629,17 @@ impl Service { let mut children_pdus = Vec::with_capacity(state.len()); for (key, id) in state { - let (event_type, state_key) = self.services.short.get_statekey_from_short(key).await?; + let (event_type, state_key) = + self.services.short.get_statekey_from_short(key).await?; if event_type != StateEventType::SpaceChild { continue; } - let pdu = self - .services - .timeline - .get_pdu(&id) - .await - .map_err(|e| err!(Database("Event {id:?} in space state not found: {e:?}")))?; + let pdu = + self.services.timeline.get_pdu(&id).await.map_err(|e| { + err!(Database("Event {id:?} in space state not found: {e:?}")) + })?; if let Ok(content) = pdu.get_content::() { if content.via.is_empty() { @@ -610,11 +657,14 @@ impl Service { /// With the given identifier, checks if a room is accessable async fn is_accessible_child( - &self, current_room: &OwnedRoomId, join_rule: &SpaceRoomJoinRule, identifier: &Identifier<'_>, + &self, + current_room: &OwnedRoomId, + join_rule: &SpaceRoomJoinRule, + identifier: &Identifier<'_>, allowed_room_ids: &Vec, ) -> bool { match identifier { - Identifier::ServerName(server_name) => { + | Identifier::ServerName(server_name) => { // Checks if ACLs allow for the server to participate if self .services @@ -626,7 +676,7 @@ impl Service { return false; } }, - Identifier::UserId(user_id) => { + | Identifier::UserId(user_id) => { if self .services .state_cache @@ -642,16 +692,18 @@ impl Service { }, } match &join_rule { - SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Knock | SpaceRoomJoinRule::KnockRestricted => true, - SpaceRoomJoinRule::Restricted => { + | SpaceRoomJoinRule::Public + | SpaceRoomJoinRule::Knock + | SpaceRoomJoinRule::KnockRestricted => true, + | SpaceRoomJoinRule::Restricted => { for room in allowed_room_ids { match identifier { - Identifier::UserId(user) => { + | Identifier::UserId(user) => { if self.services.state_cache.is_joined(user, room).await { return true; } }, - Identifier::ServerName(server) => { + | Identifier::ServerName(server) => { if self.services.state_cache.server_in_room(server, room).await { return true; } @@ -661,7 +713,7 @@ impl Service { false }, // Invite only, Private, or Custom join rule - _ => false, + | _ => false, } } } @@ -737,7 +789,8 @@ fn summary_to_chunk(summary: SpaceHierarchyParentSummary) -> SpaceHierarchyRooms /// Returns the children of a SpaceHierarchyParentSummary, making use of the /// children_state field fn get_parent_children_via( - parent: &SpaceHierarchyParentSummary, suggested_only: bool, + parent: &SpaceHierarchyParentSummary, + suggested_only: bool, ) -> Vec<(OwnedRoomId, Vec)> { parent .children_state @@ -755,7 +808,8 @@ fn get_parent_children_via( } fn next_room_to_traverse( - stack: &mut Vec)>>, parents: &mut VecDeque, + stack: &mut Vec)>>, + parents: &mut VecDeque, ) -> Option<(OwnedRoomId, Vec)> { while stack.last().is_some_and(Vec::is_empty) { stack.pop(); diff --git a/src/service/rooms/spaces/tests.rs b/src/service/rooms/spaces/tests.rs index 71640035d..b4c387d7d 100644 --- a/src/service/rooms/spaces/tests.rs +++ b/src/service/rooms/spaces/tests.rs @@ -69,18 +69,15 @@ fn get_summary_children() { } .into(); - assert_eq!( - get_parent_children_via(&summary, false), - vec![ - (owned_room_id!("!foo:example.org"), vec![owned_server_name!("example.org")]), - (owned_room_id!("!bar:example.org"), vec![owned_server_name!("example.org")]), - (owned_room_id!("!baz:example.org"), vec![owned_server_name!("example.org")]) - ] - ); - assert_eq!( - get_parent_children_via(&summary, true), - vec![(owned_room_id!("!bar:example.org"), vec![owned_server_name!("example.org")])] - ); + assert_eq!(get_parent_children_via(&summary, false), vec![ + (owned_room_id!("!foo:example.org"), vec![owned_server_name!("example.org")]), + (owned_room_id!("!bar:example.org"), vec![owned_server_name!("example.org")]), + (owned_room_id!("!baz:example.org"), vec![owned_server_name!("example.org")]) + ]); + assert_eq!(get_parent_children_via(&summary, true), vec![( + owned_room_id!("!bar:example.org"), + vec![owned_server_name!("example.org")] + )]); } #[test] diff --git a/src/service/rooms/state/mod.rs b/src/service/rooms/state/mod.rs index e083ed341..a7f79e948 100644 --- a/src/service/rooms/state/mod.rs +++ b/src/service/rooms/state/mod.rs @@ -16,7 +16,9 @@ use conduwuit::{ warn, PduEvent, Result, }; use database::{Deserialized, Ignore, Interfix, Map}; -use futures::{future::join_all, pin_mut, FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use futures::{ + future::join_all, pin_mut, FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt, +}; use ruma::{ events::{ room::{create::RoomCreateEventContent, member::RoomMemberEventContent}, @@ -70,8 +72,10 @@ impl crate::Service for Service { short: args.depend::("rooms::short"), spaces: args.depend::("rooms::spaces"), state_cache: args.depend::("rooms::state_cache"), - state_accessor: args.depend::("rooms::state_accessor"), - state_compressor: args.depend::("rooms::state_compressor"), + state_accessor: args + .depend::("rooms::state_accessor"), + state_compressor: args + .depend::("rooms::state_compressor"), timeline: args.depend::("rooms::timeline"), }, db: Data { @@ -100,7 +104,8 @@ impl Service { shortstatehash: u64, statediffnew: Arc>, _statediffremoved: Arc>, - state_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + state_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room state + * mutex */ ) -> Result { let event_ids = statediffnew .iter() @@ -120,8 +125,9 @@ impl Service { }; match pdu.kind { - TimelineEventType::RoomMember => { - let Some(user_id) = pdu.state_key.as_ref().map(UserId::parse).flat_ok() else { + | TimelineEventType::RoomMember => { + let Some(user_id) = pdu.state_key.as_ref().map(UserId::parse).flat_ok() + else { continue; }; @@ -131,10 +137,18 @@ impl Service { self.services .state_cache - .update_membership(room_id, &user_id, membership_event, &pdu.sender, None, None, false) + .update_membership( + room_id, + &user_id, + membership_event, + &pdu.sender, + None, + None, + false, + ) .await?; }, - TimelineEventType::SpaceChild => { + | TimelineEventType::SpaceChild => { self.services .spaces .roomid_spacehierarchy_cache @@ -142,7 +156,7 @@ impl Service { .await .remove(&pdu.room_id); }, - _ => continue, + | _ => continue, } } @@ -159,7 +173,10 @@ impl Service { /// to `stateid_pduid` and adds the incoming event to `eventid_statehash`. #[tracing::instrument(skip(self, state_ids_compressed), level = "debug")] pub async fn set_event_state( - &self, event_id: &EventId, room_id: &RoomId, state_ids_compressed: Arc>, + &self, + event_id: &EventId, + room_id: &RoomId, + state_ids_compressed: Arc>, ) -> Result { const KEY_LEN: usize = size_of::(); const VAL_LEN: usize = size_of::(); @@ -190,22 +207,23 @@ impl Service { Vec::new() }; - let (statediffnew, statediffremoved) = if let Some(parent_stateinfo) = states_parents.last() { - let statediffnew: HashSet<_> = state_ids_compressed - .difference(&parent_stateinfo.full_state) - .copied() - .collect(); - - let statediffremoved: HashSet<_> = parent_stateinfo - .full_state - .difference(&state_ids_compressed) - .copied() - .collect(); - - (Arc::new(statediffnew), Arc::new(statediffremoved)) - } else { - (state_ids_compressed, Arc::new(HashSet::new())) - }; + let (statediffnew, statediffremoved) = + if let Some(parent_stateinfo) = states_parents.last() { + let statediffnew: HashSet<_> = state_ids_compressed + .difference(&parent_stateinfo.full_state) + .copied() + .collect(); + + let statediffremoved: HashSet<_> = parent_stateinfo + .full_state + .difference(&state_ids_compressed) + .copied() + .collect(); + + (Arc::new(statediffnew), Arc::new(statediffremoved)) + } else { + (state_ids_compressed, Arc::new(HashSet::new())) + }; self.services.state_compressor.save_state_from_diff( shortstatehash, statediffnew, @@ -338,7 +356,8 @@ impl Service { &self, room_id: &RoomId, shortstatehash: u64, - _mutex_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + _mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room + * state mutex */ ) { const BUFSIZE: usize = size_of::(); @@ -366,7 +385,10 @@ impl Service { .deserialized() } - pub fn get_forward_extremities<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + '_ { + pub fn get_forward_extremities<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + '_ { let prefix = (room_id, Interfix); self.db @@ -380,7 +402,8 @@ impl Service { &self, room_id: &RoomId, event_ids: Vec, - _state_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + _state_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room + * state mutex */ ) { let prefix = (room_id, Interfix); self.db @@ -399,26 +422,33 @@ impl Service { /// This fetches auth events from the current state. #[tracing::instrument(skip(self, content), level = "debug")] pub async fn get_auth_events( - &self, room_id: &RoomId, kind: &TimelineEventType, sender: &UserId, state_key: Option<&str>, + &self, + room_id: &RoomId, + kind: &TimelineEventType, + sender: &UserId, + state_key: Option<&str>, content: &serde_json::value::RawValue, ) -> Result>> { let Ok(shortstatehash) = self.get_room_shortstatehash(room_id).await else { return Ok(HashMap::new()); }; - let mut sauthevents: HashMap<_, _> = state_res::auth_types_for_event(kind, sender, state_key, content)? - .iter() - .stream() - .broad_filter_map(|(event_type, state_key)| { - self.services - .short - .get_shortstatekey(event_type, state_key) - .map_ok(move |ssk| (ssk, (event_type, state_key))) - .map(Result::ok) - }) - .map(|(ssk, (event_type, state_key))| (ssk, (event_type.to_owned(), state_key.to_owned()))) - .collect() - .await; + let mut sauthevents: HashMap<_, _> = + state_res::auth_types_for_event(kind, sender, state_key, content)? + .iter() + .stream() + .broad_filter_map(|(event_type, state_key)| { + self.services + .short + .get_shortstatekey(event_type, state_key) + .map_ok(move |ssk| (ssk, (event_type, state_key))) + .map(Result::ok) + }) + .map(|(ssk, (event_type, state_key))| { + (ssk, (event_type.to_owned(), state_key.to_owned())) + }) + .collect() + .await; let (state_keys, event_ids): (Vec<_>, Vec<_>) = self .services diff --git a/src/service/rooms/state_accessor/data.rs b/src/service/rooms/state_accessor/data.rs index 9947b036b..d60e505ea 100644 --- a/src/service/rooms/state_accessor/data.rs +++ b/src/service/rooms/state_accessor/data.rs @@ -39,14 +39,16 @@ impl Data { services: Services { short: args.depend::("rooms::short"), state: args.depend::("rooms::state"), - state_compressor: args.depend::("rooms::state_compressor"), + state_compressor: args + .depend::("rooms::state_compressor"), timeline: args.depend::("rooms::timeline"), }, } } pub(super) async fn state_full( - &self, shortstatehash: ShortStateHash, + &self, + shortstatehash: ShortStateHash, ) -> Result> { let state = self .state_full_pdus(shortstatehash) @@ -58,7 +60,10 @@ impl Data { Ok(state) } - pub(super) async fn state_full_pdus(&self, shortstatehash: ShortStateHash) -> Result> { + pub(super) async fn state_full_pdus( + &self, + shortstatehash: ShortStateHash, + ) -> Result> { let short_ids = self.state_full_shortids(shortstatehash).await?; let full_pdus = self @@ -66,16 +71,19 @@ impl Data { .short .multi_get_eventid_from_short(short_ids.iter().map(ref_at!(1))) .ready_filter_map(Result::ok) - .broad_filter_map( - |event_id: OwnedEventId| async move { self.services.timeline.get_pdu(&event_id).await.ok() }, - ) + .broad_filter_map(|event_id: OwnedEventId| async move { + self.services.timeline.get_pdu(&event_id).await.ok() + }) .collect() .await; Ok(full_pdus) } - pub(super) async fn state_full_ids(&self, shortstatehash: ShortStateHash) -> Result> + pub(super) async fn state_full_ids( + &self, + shortstatehash: ShortStateHash, + ) -> Result> where Id: for<'de> Deserialize<'de> + Send + Sized + ToOwned, ::Owned: Borrow, @@ -96,7 +104,8 @@ impl Data { } pub(super) async fn state_full_shortids( - &self, shortstatehash: ShortStateHash, + &self, + shortstatehash: ShortStateHash, ) -> Result> { let shortids = self .services @@ -118,7 +127,10 @@ impl Data { /// Returns a single EventId from `room_id` with key /// (`event_type`,`state_key`). pub(super) async fn state_get_id( - &self, shortstatehash: ShortStateHash, event_type: &StateEventType, state_key: &str, + &self, + shortstatehash: ShortStateHash, + event_type: &StateEventType, + state_key: &str, ) -> Result where Id: for<'de> Deserialize<'de> + Sized + ToOwned, @@ -155,10 +167,15 @@ impl Data { /// Returns a single PDU from `room_id` with key (`event_type`,`state_key`). pub(super) async fn state_get( - &self, shortstatehash: ShortStateHash, event_type: &StateEventType, state_key: &str, + &self, + shortstatehash: ShortStateHash, + event_type: &StateEventType, + state_key: &str, ) -> Result { self.state_get_id(shortstatehash, event_type, state_key) - .and_then(|event_id: OwnedEventId| async move { self.services.timeline.get_pdu(&event_id).await }) + .and_then(|event_id: OwnedEventId| async move { + self.services.timeline.get_pdu(&event_id).await + }) .await } @@ -179,7 +196,8 @@ impl Data { /// Returns the full room state. pub(super) async fn room_state_full( - &self, room_id: &RoomId, + &self, + room_id: &RoomId, ) -> Result> { self.services .state @@ -203,7 +221,10 @@ impl Data { /// Returns a single EventId from `room_id` with key /// (`event_type`,`state_key`). pub(super) async fn room_state_get_id( - &self, room_id: &RoomId, event_type: &StateEventType, state_key: &str, + &self, + room_id: &RoomId, + event_type: &StateEventType, + state_key: &str, ) -> Result where Id: for<'de> Deserialize<'de> + Sized + ToOwned, @@ -218,7 +239,10 @@ impl Data { /// Returns a single PDU from `room_id` with key (`event_type`,`state_key`). pub(super) async fn room_state_get( - &self, room_id: &RoomId, event_type: &StateEventType, state_key: &str, + &self, + room_id: &RoomId, + event_type: &StateEventType, + state_key: &str, ) -> Result { self.services .state diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index 798bcbed7..d8093dd7f 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -34,8 +34,8 @@ use ruma::{ }, room::RoomType, space::SpaceRoomJoinRule, - EventEncryptionAlgorithm, EventId, JsOption, OwnedRoomAliasId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, - ServerName, UserId, + EventEncryptionAlgorithm, EventId, JsOption, OwnedRoomAliasId, OwnedRoomId, OwnedServerName, + OwnedUserId, RoomId, ServerName, UserId, }; use serde::Deserialize; @@ -75,8 +75,12 @@ impl crate::Service for Service { timeline: args.depend::("rooms::timeline"), }, db: Data::new(&args), - server_visibility_cache: StdMutex::new(LruCache::new(usize_from_f64(server_visibility_cache_capacity)?)), - user_visibility_cache: StdMutex::new(LruCache::new(usize_from_f64(user_visibility_cache_capacity)?)), + server_visibility_cache: StdMutex::new(LruCache::new(usize_from_f64( + server_visibility_cache_capacity, + )?)), + user_visibility_cache: StdMutex::new(LruCache::new(usize_from_f64( + user_visibility_cache_capacity, + )?)), })) } @@ -102,7 +106,10 @@ impl Service { /// Builds a StateMap by iterating over all keys that start /// with state_hash, this gives the full state for the given state_hash. #[tracing::instrument(skip(self), level = "debug")] - pub async fn state_full_ids(&self, shortstatehash: ShortStateHash) -> Result> + pub async fn state_full_ids( + &self, + shortstatehash: ShortStateHash, + ) -> Result> where Id: for<'de> Deserialize<'de> + Send + Sized + ToOwned, ::Owned: Borrow, @@ -112,13 +119,15 @@ impl Service { #[inline] pub async fn state_full_shortids( - &self, shortstatehash: ShortStateHash, + &self, + shortstatehash: ShortStateHash, ) -> Result> { self.db.state_full_shortids(shortstatehash).await } pub async fn state_full( - &self, shortstatehash: ShortStateHash, + &self, + shortstatehash: ShortStateHash, ) -> Result> { self.db.state_full(shortstatehash).await } @@ -127,7 +136,10 @@ impl Service { /// `state_key`). #[tracing::instrument(skip(self), level = "debug")] pub async fn state_get_id( - &self, shortstatehash: ShortStateHash, event_type: &StateEventType, state_key: &str, + &self, + shortstatehash: ShortStateHash, + event_type: &StateEventType, + state_key: &str, ) -> Result where Id: for<'de> Deserialize<'de> + Sized + ToOwned, @@ -142,7 +154,10 @@ impl Service { /// `state_key`). #[inline] pub async fn state_get( - &self, shortstatehash: ShortStateHash, event_type: &StateEventType, state_key: &str, + &self, + shortstatehash: ShortStateHash, + event_type: &StateEventType, + state_key: &str, ) -> Result { self.db .state_get(shortstatehash, event_type, state_key) @@ -151,7 +166,10 @@ impl Service { /// Returns a single PDU from `room_id` with key (`event_type`,`state_key`). pub async fn state_get_content( - &self, shortstatehash: ShortStateHash, event_type: &StateEventType, state_key: &str, + &self, + shortstatehash: ShortStateHash, + event_type: &StateEventType, + state_key: &str, ) -> Result where T: for<'de> Deserialize<'de>, @@ -162,7 +180,11 @@ impl Service { } /// Get membership for given user in state - async fn user_membership(&self, shortstatehash: ShortStateHash, user_id: &UserId) -> MembershipState { + async fn user_membership( + &self, + shortstatehash: ShortStateHash, + user_id: &UserId, + ) -> MembershipState { self.state_get_content(shortstatehash, &StateEventType::RoomMember, user_id.as_str()) .await .map_or(MembershipState::Leave, |c: RoomMemberEventContent| c.membership) @@ -185,7 +207,12 @@ impl Service { /// Whether a server is allowed to see an event through federation, based on /// the room's history_visibility at that event's state. #[tracing::instrument(skip_all, level = "trace")] - pub async fn server_can_see_event(&self, origin: &ServerName, room_id: &RoomId, event_id: &EventId) -> bool { + pub async fn server_can_see_event( + &self, + origin: &ServerName, + room_id: &RoomId, + event_id: &EventId, + ) -> bool { let Ok(shortstatehash) = self.pdu_shortstatehash(event_id).await else { return true; }; @@ -213,20 +240,20 @@ impl Service { .ready_filter(|member| member.server_name() == origin); let visibility = match history_visibility { - HistoryVisibility::WorldReadable | HistoryVisibility::Shared => true, - HistoryVisibility::Invited => { + | HistoryVisibility::WorldReadable | HistoryVisibility::Shared => true, + | HistoryVisibility::Invited => { // Allow if any member on requesting server was AT LEAST invited, else deny current_server_members .any(|member| self.user_was_invited(shortstatehash, member)) .await }, - HistoryVisibility::Joined => { + | HistoryVisibility::Joined => { // Allow if any member on requested server was joined, else deny current_server_members .any(|member| self.user_was_joined(shortstatehash, member)) .await }, - _ => { + | _ => { error!("Unknown history visibility {history_visibility}"); false }, @@ -243,7 +270,12 @@ impl Service { /// Whether a user is allowed to see an event, based on /// the room's history_visibility at that event's state. #[tracing::instrument(skip_all, level = "trace")] - pub async fn user_can_see_event(&self, user_id: &UserId, room_id: &RoomId, event_id: &EventId) -> bool { + pub async fn user_can_see_event( + &self, + user_id: &UserId, + room_id: &RoomId, + event_id: &EventId, + ) -> bool { let Ok(shortstatehash) = self.pdu_shortstatehash(event_id).await else { return true; }; @@ -267,17 +299,17 @@ impl Service { }); let visibility = match history_visibility { - HistoryVisibility::WorldReadable => true, - HistoryVisibility::Shared => currently_member, - HistoryVisibility::Invited => { + | HistoryVisibility::WorldReadable => true, + | HistoryVisibility::Shared => currently_member, + | HistoryVisibility::Invited => { // Allow if any member on requesting server was AT LEAST invited, else deny self.user_was_invited(shortstatehash, user_id).await }, - HistoryVisibility::Joined => { + | HistoryVisibility::Joined => { // Allow if any member on requested server was joined, else deny self.user_was_joined(shortstatehash, user_id).await }, - _ => { + | _ => { error!("Unknown history visibility {history_visibility}"); false }, @@ -307,9 +339,10 @@ impl Service { }); match history_visibility { - HistoryVisibility::Invited => self.services.state_cache.is_invited(user_id, room_id).await, - HistoryVisibility::WorldReadable => true, - _ => false, + | HistoryVisibility::Invited => + self.services.state_cache.is_invited(user_id, room_id).await, + | HistoryVisibility::WorldReadable => true, + | _ => false, } } @@ -320,7 +353,10 @@ impl Service { /// Returns the full room state. #[tracing::instrument(skip(self), level = "debug")] - pub async fn room_state_full(&self, room_id: &RoomId) -> Result> { + pub async fn room_state_full( + &self, + room_id: &RoomId, + ) -> Result> { self.db.room_state_full(room_id).await } @@ -334,7 +370,10 @@ impl Service { /// `state_key`). #[tracing::instrument(skip(self), level = "debug")] pub async fn room_state_get_id( - &self, room_id: &RoomId, event_type: &StateEventType, state_key: &str, + &self, + room_id: &RoomId, + event_type: &StateEventType, + state_key: &str, ) -> Result where Id: for<'de> Deserialize<'de> + Sized + ToOwned, @@ -349,14 +388,20 @@ impl Service { /// `state_key`). #[tracing::instrument(skip(self), level = "debug")] pub async fn room_state_get( - &self, room_id: &RoomId, event_type: &StateEventType, state_key: &str, + &self, + room_id: &RoomId, + event_type: &StateEventType, + state_key: &str, ) -> Result { self.db.room_state_get(room_id, event_type, state_key).await } /// Returns a single PDU from `room_id` with key (`event_type`,`state_key`). pub async fn room_state_get_content( - &self, room_id: &RoomId, event_type: &StateEventType, state_key: &str, + &self, + room_id: &RoomId, + event_type: &StateEventType, + state_key: &str, ) -> Result where T: for<'de> Deserialize<'de>, @@ -381,18 +426,29 @@ impl Service { JsOption::from_option(content) } - pub async fn get_member(&self, room_id: &RoomId, user_id: &UserId) -> Result { + pub async fn get_member( + &self, + room_id: &RoomId, + user_id: &UserId, + ) -> Result { self.room_state_get_content(room_id, &StateEventType::RoomMember, user_id.as_str()) .await } pub async fn user_can_invite( - &self, room_id: &RoomId, sender: &UserId, target_user: &UserId, state_lock: &RoomMutexGuard, + &self, + room_id: &RoomId, + sender: &UserId, + target_user: &UserId, + state_lock: &RoomMutexGuard, ) -> bool { self.services .timeline .create_hash_and_sign_event( - PduBuilder::state(target_user.into(), &RoomMemberEventContent::new(MembershipState::Invite)), + PduBuilder::state( + target_user.into(), + &RoomMemberEventContent::new(MembershipState::Invite), + ), sender, room_id, state_lock, @@ -405,7 +461,9 @@ impl Service { pub async fn is_world_readable(&self, room_id: &RoomId) -> bool { self.room_state_get_content(room_id, &StateEventType::RoomHistoryVisibility, "") .await - .map(|c: RoomHistoryVisibilityEventContent| c.history_visibility == HistoryVisibility::WorldReadable) + .map(|c: RoomHistoryVisibilityEventContent| { + c.history_visibility == HistoryVisibility::WorldReadable + }) .unwrap_or(false) } @@ -439,7 +497,11 @@ impl Service { /// If federation is true, it allows redaction events from any user of the /// same server as the original event sender pub async fn user_can_redact( - &self, redacts: &EventId, sender: &UserId, room_id: &RoomId, federation: bool, + &self, + redacts: &EventId, + sender: &UserId, + room_id: &RoomId, + federation: bool, ) -> Result { let redacting_event = self.services.timeline.get_pdu(redacts).await; @@ -451,7 +513,11 @@ impl Service { } if let Ok(pl_event_content) = self - .room_state_get_content::(room_id, &StateEventType::RoomPowerLevels, "") + .room_state_get_content::( + room_id, + &StateEventType::RoomPowerLevels, + "", + ) .await { let pl_event: RoomPowerLevels = pl_event_content.into(); @@ -485,10 +551,15 @@ impl Service { } /// Returns the join rule (`SpaceRoomJoinRule`) for a given room - pub async fn get_join_rule(&self, room_id: &RoomId) -> Result<(SpaceRoomJoinRule, Vec)> { + pub async fn get_join_rule( + &self, + room_id: &RoomId, + ) -> Result<(SpaceRoomJoinRule, Vec)> { self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "") .await - .map(|c: RoomJoinRulesEventContent| (c.join_rule.clone().into(), self.allowed_room_ids(c.join_rule))) + .map(|c: RoomJoinRulesEventContent| { + (c.join_rule.clone().into(), self.allowed_room_ids(c.join_rule)) + }) .or_else(|_| Ok((SpaceRoomJoinRule::Invite, vec![]))) } @@ -497,10 +568,7 @@ impl Service { let mut room_ids = Vec::with_capacity(1); if let JoinRule::Restricted(r) | JoinRule::KnockRestricted(r) = join_rule { for rule in r.allow { - if let AllowRule::RoomMembership(RoomMembership { - room_id: membership, - }) = rule - { + if let AllowRule::RoomMembership(RoomMembership { room_id: membership }) = rule { room_ids.push(membership.clone()); } } @@ -520,7 +588,10 @@ impl Service { /// Gets the room's encryption algorithm if `m.room.encryption` state event /// is found - pub async fn get_room_encryption(&self, room_id: &RoomId) -> Result { + pub async fn get_room_encryption( + &self, + room_id: &RoomId, + ) -> Result { self.room_state_get_content(room_id, &StateEventType::RoomEncryption, "") .await .map(|content: RoomEncryptionEventContent| content.algorithm) diff --git a/src/service/rooms/state_cache/mod.rs b/src/service/rooms/state_cache/mod.rs index 6b7d35d22..c2de8b624 100644 --- a/src/service/rooms/state_cache/mod.rs +++ b/src/service/rooms/state_cache/mod.rs @@ -20,7 +20,8 @@ use ruma::{ member::{MembershipState, RoomMemberEventContent}, power_levels::RoomPowerLevelsEventContent, }, - AnyStrippedStateEvent, AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType, + AnyStrippedStateEvent, AnySyncStateEvent, GlobalAccountDataEventType, + RoomAccountDataEventType, StateEventType, }, int, serde::Raw, @@ -68,7 +69,8 @@ impl crate::Service for Service { services: Services { account_data: args.depend::("account_data"), globals: args.depend::("globals"), - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), users: args.depend::("users"), }, db: Data { @@ -96,8 +98,13 @@ impl Service { #[tracing::instrument(skip(self, last_state))] #[allow(clippy::too_many_arguments)] pub async fn update_membership( - &self, room_id: &RoomId, user_id: &UserId, membership_event: RoomMemberEventContent, sender: &UserId, - last_state: Option>>, invite_via: Option>, + &self, + room_id: &RoomId, + user_id: &UserId, + membership_event: RoomMemberEventContent, + sender: &UserId, + last_state: Option>>, + invite_via: Option>, update_joined_count: bool, ) -> Result<()> { let membership = membership_event.membership; @@ -138,7 +145,7 @@ impl Service { } match &membership { - MembershipState::Join => { + | MembershipState::Join => { // Check if the user never joined this room if !self.once_joined(user_id, room_id).await { // Add the user ID to the join list then @@ -181,12 +188,21 @@ impl Service { if let Ok(tag_event) = self .services .account_data - .get_room(&predecessor.room_id, user_id, RoomAccountDataEventType::Tag) + .get_room( + &predecessor.room_id, + user_id, + RoomAccountDataEventType::Tag, + ) .await { self.services .account_data - .update(Some(room_id), user_id, RoomAccountDataEventType::Tag, &tag_event) + .update( + Some(room_id), + user_id, + RoomAccountDataEventType::Tag, + &tag_event, + ) .await .ok(); }; @@ -195,7 +211,10 @@ impl Service { if let Ok(mut direct_event) = self .services .account_data - .get_global::(user_id, GlobalAccountDataEventType::Direct) + .get_global::( + user_id, + GlobalAccountDataEventType::Direct, + ) .await { let mut room_ids_updated = false; @@ -213,7 +232,8 @@ impl Service { None, user_id, GlobalAccountDataEventType::Direct.to_string().into(), - &serde_json::to_value(&direct_event).expect("to json always works"), + &serde_json::to_value(&direct_event) + .expect("to json always works"), ) .await?; } @@ -223,7 +243,7 @@ impl Service { self.mark_as_joined(user_id, room_id); }, - MembershipState::Invite => { + | MembershipState::Invite => { // We want to know if the sender is ignored by the receiver if self.services.users.user_is_ignored(sender, user_id).await { return Ok(()); @@ -232,10 +252,10 @@ impl Service { self.mark_as_invited(user_id, room_id, last_state, invite_via) .await; }, - MembershipState::Leave | MembershipState::Ban => { + | MembershipState::Leave | MembershipState::Ban => { self.mark_as_left(user_id, room_id); }, - _ => {}, + | _ => {}, } if update_joined_count { @@ -246,7 +266,11 @@ impl Service { } #[tracing::instrument(skip(self, room_id, appservice), level = "debug")] - pub async fn appservice_in_room(&self, room_id: &RoomId, appservice: &RegistrationInfo) -> bool { + pub async fn appservice_in_room( + &self, + room_id: &RoomId, + appservice: &RegistrationInfo, + ) -> bool { if let Some(cached) = self .appservice_in_room_cache .read() @@ -347,7 +371,10 @@ impl Service { /// Returns an iterator of all servers participating in this room. #[tracing::instrument(skip(self), level = "debug")] - pub fn room_servers<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn room_servers<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { let prefix = (room_id, Interfix); self.db .roomserverids @@ -357,7 +384,11 @@ impl Service { } #[tracing::instrument(skip(self), level = "debug")] - pub async fn server_in_room<'a>(&'a self, server: &'a ServerName, room_id: &'a RoomId) -> bool { + pub async fn server_in_room<'a>( + &'a self, + server: &'a ServerName, + room_id: &'a RoomId, + ) -> bool { let key = (server, room_id); self.db.serverroomids.qry(&key).await.is_ok() } @@ -365,7 +396,10 @@ impl Service { /// Returns an iterator of all rooms a server participates in (as far as we /// know). #[tracing::instrument(skip(self), level = "debug")] - pub fn server_rooms<'a>(&'a self, server: &'a ServerName) -> impl Stream + Send + 'a { + pub fn server_rooms<'a>( + &'a self, + server: &'a ServerName, + ) -> impl Stream + Send + 'a { let prefix = (server, Interfix); self.db .serverroomids @@ -393,7 +427,9 @@ impl Service { /// List the rooms common between two users pub fn get_shared_rooms<'a>( - &'a self, user_a: &'a UserId, user_b: &'a UserId, + &'a self, + user_a: &'a UserId, + user_b: &'a UserId, ) -> impl Stream + Send + 'a { use conduwuit::utils::set; @@ -404,7 +440,10 @@ impl Service { /// Returns an iterator of all joined members of a room. #[tracing::instrument(skip(self), level = "debug")] - pub fn room_members<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn room_members<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { let prefix = (room_id, Interfix); self.db .roomuserid_joined @@ -422,7 +461,10 @@ impl Service { #[tracing::instrument(skip(self), level = "debug")] /// Returns an iterator of all our local users in the room, even if they're /// deactivated/guests - pub fn local_users_in_room<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn local_users_in_room<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { self.room_members(room_id) .ready_filter(|user| self.services.globals.user_is_local(user)) } @@ -430,7 +472,10 @@ impl Service { #[tracing::instrument(skip(self), level = "debug")] /// Returns an iterator of all our local joined users in a room who are /// active (not deactivated, not guest) - pub fn active_local_users_in_room<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn active_local_users_in_room<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { self.local_users_in_room(room_id) .filter(|user| self.services.users.is_active(user)) } @@ -447,7 +492,10 @@ impl Service { /// Returns an iterator over all User IDs who ever joined a room. #[tracing::instrument(skip(self), level = "debug")] - pub fn room_useroncejoined<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn room_useroncejoined<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { let prefix = (room_id, Interfix); self.db .roomuseroncejoinedids @@ -458,7 +506,10 @@ impl Service { /// Returns an iterator over all invited members of a room. #[tracing::instrument(skip(self), level = "debug")] - pub fn room_members_invited<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn room_members_invited<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { let prefix = (room_id, Interfix); self.db .roomuserid_invitecount @@ -485,7 +536,10 @@ impl Service { /// Returns an iterator over all rooms this user joined. #[tracing::instrument(skip(self), level = "debug")] - pub fn rooms_joined<'a>(&'a self, user_id: &'a UserId) -> impl Stream + Send + 'a { + pub fn rooms_joined<'a>( + &'a self, + user_id: &'a UserId, + ) -> impl Stream + Send + 'a { self.db .userroomid_joined .keys_raw_prefix(user_id) @@ -495,7 +549,10 @@ impl Service { /// Returns an iterator over all rooms a user was invited to. #[tracing::instrument(skip(self), level = "debug")] - pub fn rooms_invited<'a>(&'a self, user_id: &'a UserId) -> impl Stream + Send + 'a { + pub fn rooms_invited<'a>( + &'a self, + user_id: &'a UserId, + ) -> impl Stream + Send + 'a { type KeyVal<'a> = (Key<'a>, Raw>); type Key<'a> = (&'a UserId, &'a RoomId); @@ -510,30 +567,45 @@ impl Service { } #[tracing::instrument(skip(self), level = "debug")] - pub async fn invite_state(&self, user_id: &UserId, room_id: &RoomId) -> Result>> { + pub async fn invite_state( + &self, + user_id: &UserId, + room_id: &RoomId, + ) -> Result>> { let key = (user_id, room_id); self.db .userroomid_invitestate .qry(&key) .await .deserialized() - .and_then(|val: Raw>| val.deserialize_as().map_err(Into::into)) + .and_then(|val: Raw>| { + val.deserialize_as().map_err(Into::into) + }) } #[tracing::instrument(skip(self), level = "debug")] - pub async fn left_state(&self, user_id: &UserId, room_id: &RoomId) -> Result>> { + pub async fn left_state( + &self, + user_id: &UserId, + room_id: &RoomId, + ) -> Result>> { let key = (user_id, room_id); self.db .userroomid_leftstate .qry(&key) .await .deserialized() - .and_then(|val: Raw>| val.deserialize_as().map_err(Into::into)) + .and_then(|val: Raw>| { + val.deserialize_as().map_err(Into::into) + }) } /// Returns an iterator over all rooms a user left. #[tracing::instrument(skip(self), level = "debug")] - pub fn rooms_left<'a>(&'a self, user_id: &'a UserId) -> impl Stream + Send + 'a { + pub fn rooms_left<'a>( + &'a self, + user_id: &'a UserId, + ) -> impl Stream + Send + 'a { type KeyVal<'a> = (Key<'a>, Raw>>); type Key<'a> = (&'a UserId, &'a RoomId); @@ -571,7 +643,11 @@ impl Service { self.db.userroomid_leftstate.qry(&key).await.is_ok() } - pub async fn user_membership(&self, user_id: &UserId, room_id: &RoomId) -> Option { + pub async fn user_membership( + &self, + user_id: &UserId, + room_id: &RoomId, + ) -> Option { let states = join4( self.is_joined(user_id, room_id), self.is_left(user_id, room_id), @@ -581,16 +657,19 @@ impl Service { .await; match states { - (true, ..) => Some(MembershipState::Join), - (_, true, ..) => Some(MembershipState::Leave), - (_, _, true, ..) => Some(MembershipState::Invite), - (false, false, false, true) => Some(MembershipState::Ban), - _ => None, + | (true, ..) => Some(MembershipState::Join), + | (_, true, ..) => Some(MembershipState::Leave), + | (_, _, true, ..) => Some(MembershipState::Invite), + | (false, false, false, true) => Some(MembershipState::Ban), + | _ => None, } } #[tracing::instrument(skip(self), level = "debug")] - pub fn servers_invite_via<'a>(&'a self, room_id: &'a RoomId) -> impl Stream + Send + 'a { + pub fn servers_invite_via<'a>( + &'a self, + room_id: &'a RoomId, + ) -> impl Stream + Send + 'a { type KeyVal<'a> = (Ignore, Vec<&'a ServerName>); self.db @@ -711,7 +790,10 @@ impl Service { } pub async fn mark_as_invited( - &self, user_id: &UserId, room_id: &RoomId, last_state: Option>>, + &self, + user_id: &UserId, + room_id: &RoomId, + last_state: Option>>, invite_via: Option>, ) { let roomuser_id = (room_id, user_id); diff --git a/src/service/rooms/state_compressor/mod.rs b/src/service/rooms/state_compressor/mod.rs index 36bc92c03..dbe0a386f 100644 --- a/src/service/rooms/state_compressor/mod.rs +++ b/src/service/rooms/state_compressor/mod.rs @@ -69,7 +69,8 @@ pub(crate) type CompressedStateEvent = [u8; 2 * size_of::()]; impl crate::Service for Service { fn build(args: crate::Args<'_>) -> Result> { let config = &args.server.config; - let cache_capacity = f64::from(config.stateinfo_cache_capacity) * config.cache_capacity_modifier; + let cache_capacity = + f64::from(config.stateinfo_cache_capacity) * config.cache_capacity_modifier; Ok(Arc::new(Self { stateinfo_cache: LruCache::new(usize_from_f64(cache_capacity)?).into(), db: Data { @@ -85,17 +86,16 @@ impl crate::Service for Service { fn memory_usage(&self, out: &mut dyn Write) -> Result { let (cache_len, ents) = { let cache = self.stateinfo_cache.lock().expect("locked"); - let ents = cache - .iter() - .map(at!(1)) - .flat_map(|vec| vec.iter()) - .fold(HashMap::new(), |mut ents, ssi| { + let ents = cache.iter().map(at!(1)).flat_map(|vec| vec.iter()).fold( + HashMap::new(), + |mut ents, ssi| { for cs in &[&ssi.added, &ssi.removed, &ssi.full_state] { ents.insert(Arc::as_ptr(cs), compressed_state_size(cs)); } ents - }); + }, + ); (cache.len(), ents) }; @@ -117,7 +117,10 @@ impl crate::Service for Service { impl Service { /// Returns a stack with info on shortstatehash, full state, added diff and /// removed diff for the selected shortstatehash and each parent layer. - pub async fn load_shortstatehash_info(&self, shortstatehash: ShortStateHash) -> Result { + pub async fn load_shortstatehash_info( + &self, + shortstatehash: ShortStateHash, + ) -> Result { if let Some(r) = self .stateinfo_cache .lock() @@ -143,12 +146,11 @@ impl Service { Ok(stack) } - async fn new_shortstatehash_info(&self, shortstatehash: ShortStateHash) -> Result { - let StateDiff { - parent, - added, - removed, - } = self.get_statediff(shortstatehash).await?; + async fn new_shortstatehash_info( + &self, + shortstatehash: ShortStateHash, + ) -> Result { + let StateDiff { parent, added, removed } = self.get_statediff(shortstatehash).await?; let Some(parent) = parent else { return Ok(vec![ShortStateInfo { @@ -180,9 +182,17 @@ impl Service { Ok(stack) } - pub fn compress_state_events<'a, I>(&'a self, state: I) -> impl Stream + Send + 'a + pub fn compress_state_events<'a, I>( + &'a self, + state: I, + ) -> impl Stream + Send + 'a where - I: Iterator + Clone + Debug + ExactSizeIterator + Send + 'a, + I: Iterator + + Clone + + Debug + + ExactSizeIterator + + Send + + 'a, { let event_ids = state.clone().map(at!(1)); @@ -195,10 +205,16 @@ impl Service { .stream() .map(at!(0)) .zip(short_event_ids) - .map(|(shortstatekey, shorteventid)| compress_state_event(*shortstatekey, shorteventid)) + .map(|(shortstatekey, shorteventid)| { + compress_state_event(*shortstatekey, shorteventid) + }) } - pub async fn compress_state_event(&self, shortstatekey: ShortStateKey, event_id: &EventId) -> CompressedStateEvent { + pub async fn compress_state_event( + &self, + shortstatekey: ShortStateKey, + event_id: &EventId, + ) -> CompressedStateEvent { let shorteventid = self .services .short @@ -227,8 +243,11 @@ impl Service { /// * `parent_states` - A stack with info on shortstatehash, full state, /// added diff and removed diff for each parent layer pub fn save_state_from_diff( - &self, shortstatehash: ShortStateHash, statediffnew: Arc>, - statediffremoved: Arc>, diff_to_sibling: usize, + &self, + shortstatehash: ShortStateHash, + statediffnew: Arc>, + statediffremoved: Arc>, + diff_to_sibling: usize, mut parent_states: ParentStatesVec, ) -> Result { let statediffnew_len = statediffnew.len(); @@ -274,14 +293,11 @@ impl Service { if parent_states.is_empty() { // There is no parent layer, create a new state - self.save_statediff( - shortstatehash, - &StateDiff { - parent: None, - added: statediffnew, - removed: statediffremoved, - }, - ); + self.save_statediff(shortstatehash, &StateDiff { + parent: None, + added: statediffnew, + removed: statediffremoved, + }); return Ok(()); }; @@ -327,14 +343,11 @@ impl Service { )?; } else { // Diff small enough, we add diff as layer on top of parent - self.save_statediff( - shortstatehash, - &StateDiff { - parent: Some(parent.shortstatehash), - added: statediffnew, - removed: statediffremoved, - }, - ); + self.save_statediff(shortstatehash, &StateDiff { + parent: Some(parent.shortstatehash), + added: statediffnew, + removed: statediffremoved, + }); } Ok(()) @@ -344,7 +357,9 @@ impl Service { /// room state #[tracing::instrument(skip(self, new_state_ids_compressed), level = "debug")] pub async fn save_state( - &self, room_id: &RoomId, new_state_ids_compressed: Arc>, + &self, + room_id: &RoomId, + new_state_ids_compressed: Arc>, ) -> Result { let previous_shortstatehash = self .services @@ -353,7 +368,8 @@ impl Service { .await .ok(); - let state_hash = utils::calculate_hash(new_state_ids_compressed.iter().map(|bytes| &bytes[..])); + let state_hash = + utils::calculate_hash(new_state_ids_compressed.iter().map(|bytes| &bytes[..])); let (new_shortstatehash, already_existed) = self .services @@ -374,22 +390,23 @@ impl Service { ShortStateInfoVec::new() }; - let (statediffnew, statediffremoved) = if let Some(parent_stateinfo) = states_parents.last() { - let statediffnew: HashSet<_> = new_state_ids_compressed - .difference(&parent_stateinfo.full_state) - .copied() - .collect(); + let (statediffnew, statediffremoved) = + if let Some(parent_stateinfo) = states_parents.last() { + let statediffnew: HashSet<_> = new_state_ids_compressed + .difference(&parent_stateinfo.full_state) + .copied() + .collect(); - let statediffremoved: HashSet<_> = parent_stateinfo - .full_state - .difference(&new_state_ids_compressed) - .copied() - .collect(); + let statediffremoved: HashSet<_> = parent_stateinfo + .full_state + .difference(&new_state_ids_compressed) + .copied() + .collect(); - (Arc::new(statediffnew), Arc::new(statediffremoved)) - } else { - (new_state_ids_compressed, Arc::new(HashSet::new())) - }; + (Arc::new(statediffnew), Arc::new(statediffremoved)) + } else { + (new_state_ids_compressed, Arc::new(HashSet::new())) + }; if !already_existed { self.save_state_from_diff( @@ -418,7 +435,9 @@ impl Service { .shortstatehash_statediff .aqry::(&shortstatehash) .await - .map_err(|e| err!(Database("Failed to find StateDiff from short {shortstatehash:?}: {e}")))?; + .map_err(|e| { + err!(Database("Failed to find StateDiff from short {shortstatehash:?}: {e}")) + })?; let parent = utils::u64_from_bytes(&value[0..size_of::()]) .ok() @@ -484,7 +503,10 @@ impl Service { #[inline] #[must_use] -fn compress_state_event(shortstatekey: ShortStateKey, shorteventid: ShortEventId) -> CompressedStateEvent { +fn compress_state_event( + shortstatekey: ShortStateKey, + shorteventid: ShortEventId, +) -> CompressedStateEvent { const SIZE: usize = size_of::(); let mut v = ArrayVec::::new(); @@ -497,7 +519,9 @@ fn compress_state_event(shortstatekey: ShortStateKey, shorteventid: ShortEventId #[inline] #[must_use] -pub fn parse_compressed_state_event(compressed_event: CompressedStateEvent) -> (ShortStateKey, ShortEventId) { +pub fn parse_compressed_state_event( + compressed_event: CompressedStateEvent, +) -> (ShortStateKey, ShortEventId) { use utils::u64_from_u8; let shortstatekey = u64_from_u8(&compressed_event[0..size_of::()]); diff --git a/src/service/rooms/threads/mod.rs b/src/service/rooms/threads/mod.rs index f65be902d..bc995e271 100644 --- a/src/service/rooms/threads/mod.rs +++ b/src/service/rooms/threads/mod.rs @@ -11,8 +11,8 @@ use conduwuit::{ use database::{Deserialized, Map}; use futures::{Stream, StreamExt}; use ruma::{ - api::client::threads::get_threads::v1::IncludeThreads, events::relation::BundledThread, uint, CanonicalJsonValue, - EventId, OwnedUserId, RoomId, UserId, + api::client::threads::get_threads::v1::IncludeThreads, events::relation::BundledThread, uint, + CanonicalJsonValue, EventId, OwnedUserId, RoomId, UserId, }; use serde_json::json; @@ -55,7 +55,9 @@ impl Service { .timeline .get_pdu_id(root_event_id) .await - .map_err(|e| err!(Request(InvalidParam("Invalid event_id in thread message: {e:?}"))))?; + .map_err(|e| { + err!(Request(InvalidParam("Invalid event_id in thread message: {e:?}"))) + })?; let root_pdu = self .services @@ -79,8 +81,9 @@ impl Service { .get("m.relations") .and_then(|r| r.as_object()) .and_then(|r| r.get("m.thread")) - .and_then(|relations| serde_json::from_value::(relations.clone().into()).ok()) - { + .and_then(|relations| { + serde_json::from_value::(relations.clone().into()).ok() + }) { // Thread already existed relations.count = relations.count.saturating_add(uint!(1)); relations.latest_event = pdu.to_message_like_event(); @@ -129,7 +132,11 @@ impl Service { } pub async fn threads_until<'a>( - &'a self, user_id: &'a UserId, room_id: &'a RoomId, shorteventid: PduCount, _inc: &'a IncludeThreads, + &'a self, + user_id: &'a UserId, + room_id: &'a RoomId, + shorteventid: PduCount, + _inc: &'a IncludeThreads, ) -> Result + Send + 'a> { let shortroomid: ShortRoomId = self.services.short.get_shortroomid(room_id).await?; @@ -160,7 +167,11 @@ impl Service { Ok(stream) } - pub(super) fn update_participants(&self, root_id: &RawPduId, participants: &[OwnedUserId]) -> Result { + pub(super) fn update_participants( + &self, + root_id: &RawPduId, + participants: &[OwnedUserId], + ) -> Result { let users = participants .iter() .map(|user| user.as_bytes()) diff --git a/src/service/rooms/timeline/data.rs b/src/service/rooms/timeline/data.rs index a32ff54f4..0be8aa526 100644 --- a/src/service/rooms/timeline/data.rs +++ b/src/service/rooms/timeline/data.rs @@ -13,7 +13,9 @@ use conduwuit::{ }; use database::{Database, Deserialized, Json, KeyVal, Map}; use futures::{future::select_ok, FutureExt, Stream, StreamExt}; -use ruma::{api::Direction, CanonicalJsonObject, EventId, OwnedRoomId, OwnedUserId, RoomId, UserId}; +use ruma::{ + api::Direction, CanonicalJsonObject, EventId, OwnedRoomId, OwnedUserId, RoomId, UserId, +}; use tokio::sync::Mutex; use super::{PduId, RawPduId}; @@ -54,15 +56,19 @@ impl Data { } } - pub(super) async fn last_timeline_count(&self, sender_user: Option<&UserId>, room_id: &RoomId) -> Result { + pub(super) async fn last_timeline_count( + &self, + sender_user: Option<&UserId>, + room_id: &RoomId, + ) -> Result { match self .lasttimelinecount_cache .lock() .await .entry(room_id.into()) { - hash_map::Entry::Occupied(o) => Ok(*o.get()), - hash_map::Entry::Vacant(v) => Ok(self + | hash_map::Entry::Occupied(o) => Ok(*o.get()), + | hash_map::Entry::Vacant(v) => Ok(self .pdus_rev(sender_user, room_id, PduCount::max()) .await? .next() @@ -93,7 +99,10 @@ impl Data { } /// Returns the json of a pdu. - pub(super) async fn get_non_outlier_pdu_json(&self, event_id: &EventId) -> Result { + pub(super) async fn get_non_outlier_pdu_json( + &self, + event_id: &EventId, + ) -> Result { let pduid = self.get_pdu_id(event_id).await?; self.pduid_pdu.get(&pduid).await.deserialized() @@ -160,12 +169,19 @@ impl Data { } /// Returns the pdu as a `BTreeMap`. - pub(super) async fn get_pdu_json_from_id(&self, pdu_id: &RawPduId) -> Result { + pub(super) async fn get_pdu_json_from_id( + &self, + pdu_id: &RawPduId, + ) -> Result { self.pduid_pdu.get(pdu_id).await.deserialized() } pub(super) async fn append_pdu( - &self, pdu_id: &RawPduId, pdu: &PduEvent, json: &CanonicalJsonObject, count: PduCount, + &self, + pdu_id: &RawPduId, + pdu: &PduEvent, + json: &CanonicalJsonObject, + count: PduCount, ) { debug_assert!(matches!(count, PduCount::Normal(_)), "PduCount not Normal"); @@ -179,7 +195,12 @@ impl Data { self.eventid_outlierpdu.remove(pdu.event_id.as_bytes()); } - pub(super) fn prepend_backfill_pdu(&self, pdu_id: &RawPduId, event_id: &EventId, json: &CanonicalJsonObject) { + pub(super) fn prepend_backfill_pdu( + &self, + pdu_id: &RawPduId, + event_id: &EventId, + json: &CanonicalJsonObject, + ) { self.pduid_pdu.raw_put(pdu_id, Json(json)); self.eventid_pduid.insert(event_id, pdu_id); self.eventid_outlierpdu.remove(event_id); @@ -187,7 +208,10 @@ impl Data { /// Removes a pdu and creates a new one with the same id. pub(super) async fn replace_pdu( - &self, pdu_id: &RawPduId, pdu_json: &CanonicalJsonObject, _pdu: &PduEvent, + &self, + pdu_id: &RawPduId, + pdu_json: &CanonicalJsonObject, + _pdu: &PduEvent, ) -> Result { if self.pduid_pdu.get(pdu_id).await.is_not_found() { return Err!(Request(NotFound("PDU does not exist."))); @@ -202,7 +226,10 @@ impl Data { /// happened before the event with id `until` in reverse-chronological /// order. pub(super) async fn pdus_rev<'a>( - &'a self, user_id: Option<&'a UserId>, room_id: &'a RoomId, until: PduCount, + &'a self, + user_id: Option<&'a UserId>, + room_id: &'a RoomId, + until: PduCount, ) -> Result + Send + 'a> { let current = self .count_to_id(room_id, until, Direction::Backward) @@ -219,7 +246,10 @@ impl Data { } pub(super) async fn pdus<'a>( - &'a self, user_id: Option<&'a UserId>, room_id: &'a RoomId, from: PduCount, + &'a self, + user_id: Option<&'a UserId>, + room_id: &'a RoomId, + from: PduCount, ) -> Result + Send + Unpin + 'a> { let current = self.count_to_id(room_id, from, Direction::Forward).await?; let prefix = current.shortroomid(); @@ -236,8 +266,8 @@ impl Data { fn each_pdu((pdu_id, pdu): KeyVal<'_>, user_id: Option<&UserId>) -> PdusIterItem { let pdu_id: RawPduId = pdu_id.into(); - let mut pdu = - serde_json::from_slice::(pdu).expect("PduEvent in pduid_pdu database column is invalid JSON"); + let mut pdu = serde_json::from_slice::(pdu) + .expect("PduEvent in pduid_pdu database column is invalid JSON"); if Some(pdu.sender.borrow()) != user_id { pdu.remove_transaction_id().log_err().ok(); @@ -249,7 +279,10 @@ impl Data { } pub(super) fn increment_notification_counts( - &self, room_id: &RoomId, notifies: Vec, highlights: Vec, + &self, + room_id: &RoomId, + notifies: Vec, + highlights: Vec, ) { let _cork = self.db.cork(); @@ -268,7 +301,12 @@ impl Data { } } - async fn count_to_id(&self, room_id: &RoomId, shorteventid: PduCount, dir: Direction) -> Result { + async fn count_to_id( + &self, + room_id: &RoomId, + shorteventid: PduCount, + dir: Direction, + ) -> Result { let shortroomid: ShortRoomId = self .services .short diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 2bc5cf734..2ae66546f 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -15,7 +15,9 @@ use conduwuit::{ validated, warn, Err, Error, Result, Server, }; pub use conduwuit::{PduId, RawPduId}; -use futures::{future, future::ready, Future, FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use futures::{ + future, future::ready, Future, FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt, +}; use ruma::{ api::federation, canonical_json::to_canonical_value, @@ -32,8 +34,8 @@ use ruma::{ }, push::{Action, Ruleset, Tweak}, state_res::{self, Event, RoomVersion}, - uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName, - RoomId, RoomVersionId, ServerName, UserId, + uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, + OwnedServerName, RoomId, RoomVersionId, ServerName, UserId, }; use serde::Deserialize; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; @@ -116,7 +118,8 @@ impl crate::Service for Service { short: args.depend::("rooms::short"), state: args.depend::("rooms::state"), state_cache: args.depend::("rooms::state_cache"), - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), pdu_metadata: args.depend::("rooms::pdu_metadata"), read_receipt: args.depend::("rooms::read_receipt"), sending: args.depend::("sending"), @@ -127,7 +130,8 @@ impl crate::Service for Service { threads: args.depend::("rooms::threads"), search: args.depend::("rooms::search"), spaces: args.depend::("rooms::spaces"), - event_handler: args.depend::("rooms::event_handler"), + event_handler: args + .depend::("rooms::event_handler"), }, db: Data::new(&args), mutex_insert: RoomMutexMap::new(), @@ -185,12 +189,18 @@ impl Service { } #[tracing::instrument(skip(self), level = "debug")] - pub async fn last_timeline_count(&self, sender_user: Option<&UserId>, room_id: &RoomId) -> Result { + pub async fn last_timeline_count( + &self, + sender_user: Option<&UserId>, + room_id: &RoomId, + ) -> Result { self.db.last_timeline_count(sender_user, room_id).await } /// Returns the `count` of this pdu's id. - pub async fn get_pdu_count(&self, event_id: &EventId) -> Result { self.db.get_pdu_count(event_id).await } + pub async fn get_pdu_count(&self, event_id: &EventId) -> Result { + self.db.get_pdu_count(event_id).await + } // TODO Is this the same as the function above? /* @@ -222,13 +232,18 @@ impl Service { /// Returns the json of a pdu. #[inline] - pub async fn get_non_outlier_pdu_json(&self, event_id: &EventId) -> Result { + pub async fn get_non_outlier_pdu_json( + &self, + event_id: &EventId, + ) -> Result { self.db.get_non_outlier_pdu_json(event_id).await } /// Returns the pdu's id. #[inline] - pub async fn get_pdu_id(&self, event_id: &EventId) -> Result { self.db.get_pdu_id(event_id).await } + pub async fn get_pdu_id(&self, event_id: &EventId) -> Result { + self.db.get_pdu_id(event_id).await + } /// Returns the pdu. /// @@ -241,19 +256,26 @@ impl Service { /// Returns the pdu. /// /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. - pub async fn get_pdu(&self, event_id: &EventId) -> Result { self.db.get_pdu(event_id).await } + pub async fn get_pdu(&self, event_id: &EventId) -> Result { + self.db.get_pdu(event_id).await + } /// Checks if pdu exists /// /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. - pub fn pdu_exists<'a>(&'a self, event_id: &'a EventId) -> impl Future + Send + 'a { + pub fn pdu_exists<'a>( + &'a self, + event_id: &'a EventId, + ) -> impl Future + Send + 'a { self.db.pdu_exists(event_id) } /// Returns the pdu. /// /// This does __NOT__ check the outliers `Tree`. - pub async fn get_pdu_from_id(&self, pdu_id: &RawPduId) -> Result { self.db.get_pdu_from_id(pdu_id).await } + pub async fn get_pdu_from_id(&self, pdu_id: &RawPduId) -> Result { + self.db.get_pdu_from_id(pdu_id).await + } /// Returns the pdu as a `BTreeMap`. pub async fn get_pdu_json_from_id(&self, pdu_id: &RawPduId) -> Result { @@ -262,7 +284,12 @@ impl Service { /// Removes a pdu and creates a new one with the same id. #[tracing::instrument(skip(self), level = "debug")] - pub async fn replace_pdu(&self, pdu_id: &RawPduId, pdu_json: &CanonicalJsonObject, pdu: &PduEvent) -> Result<()> { + pub async fn replace_pdu( + &self, + pdu_id: &RawPduId, + pdu_json: &CanonicalJsonObject, + pdu: &PduEvent, + ) -> Result<()> { self.db.replace_pdu(pdu_id, pdu_json, pdu).await } @@ -278,7 +305,8 @@ impl Service { pdu: &PduEvent, mut pdu_json: CanonicalJsonObject, leaves: Vec, - state_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + state_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room state + * mutex */ ) -> Result { // Coalesce database writes for the remainder of this scope. let _cork = self.db.db.cork_and_flush(); @@ -313,10 +341,16 @@ impl Service { unsigned.insert( "prev_content".to_owned(), CanonicalJsonValue::Object( - utils::to_canonical_object(prev_state.content.clone()).map_err(|e| { - error!("Failed to convert prev_state to canonical JSON: {e}"); - Error::bad_database("Failed to convert prev_state to canonical JSON.") - })?, + utils::to_canonical_object(prev_state.content.clone()).map_err( + |e| { + error!( + "Failed to convert prev_state to canonical JSON: {e}" + ); + Error::bad_database( + "Failed to convert prev_state to canonical JSON.", + ) + }, + )?, ), ); unsigned.insert( @@ -357,11 +391,7 @@ impl Service { .reset_notification_counts(&pdu.sender, &pdu.room_id); let count2 = PduCount::Normal(self.services.globals.next_count().unwrap()); - let pdu_id: RawPduId = PduId { - shortroomid, - shorteventid: count2, - } - .into(); + let pdu_id: RawPduId = PduId { shortroomid, shorteventid: count2 }.into(); // Insert pdu self.db.append_pdu(&pdu_id, pdu, &pdu_json, count2).await; @@ -408,7 +438,10 @@ impl Service { .account_data .get_global(user, GlobalAccountDataEventType::PushRules) .await - .map_or_else(|_| Ruleset::server_default(user), |ev: PushRulesEvent| ev.content.global); + .map_or_else( + |_| Ruleset::server_default(user), + |ev: PushRulesEvent| ev.content.global, + ); let mut highlight = false; let mut notify = false; @@ -420,11 +453,11 @@ impl Service { .await { match action { - Action::Notify => notify = true, - Action::SetTweak(Tweak::Highlight(true)) => { + | Action::Notify => notify = true, + | Action::SetTweak(Tweak::Highlight(true)) => { highlight = true; }, - _ => {}, + | _ => {}, }; // Break early if both conditions are true @@ -457,12 +490,12 @@ impl Service { .increment_notification_counts(&pdu.room_id, notifies, highlights); match pdu.kind { - TimelineEventType::RoomRedaction => { + | TimelineEventType::RoomRedaction => { use RoomVersionId::*; let room_version_id = self.services.state.get_room_version(&pdu.room_id).await?; match room_version_id { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { if let Some(redact_id) = &pdu.redacts { if self .services @@ -474,7 +507,7 @@ impl Service { } } }, - _ => { + | _ => { let content: RoomRedactionEventContent = pdu.get_content()?; if let Some(redact_id) = &content.redacts { if self @@ -489,7 +522,7 @@ impl Service { }, }; }, - TimelineEventType::SpaceChild => { + | TimelineEventType::SpaceChild => if let Some(_state_key) = &pdu.state_key { self.services .spaces @@ -497,18 +530,18 @@ impl Service { .lock() .await .remove(&pdu.room_id); - } - }, - TimelineEventType::RoomMember => { + }, + | TimelineEventType::RoomMember => { if let Some(state_key) = &pdu.state_key { // if the state_key fails - let target_user_id = - UserId::parse(state_key.clone()).expect("This state_key was previously validated"); + let target_user_id = UserId::parse(state_key.clone()) + .expect("This state_key was previously validated"); let content: RoomMemberEventContent = pdu.get_content()?; let invite_state = match content.membership { - MembershipState::Invite => self.services.state.summary_stripped(pdu).await.into(), - _ => None, + | MembershipState::Invite => + self.services.state.summary_stripped(pdu).await.into(), + | _ => None, }; // Update our membership info, we do this here incase a user is invited @@ -527,7 +560,7 @@ impl Service { .await?; } }, - TimelineEventType::RoomMessage => { + | TimelineEventType::RoomMessage => { let content: ExtractBody = pdu.get_content()?; if let Some(body) = content.body { self.services.search.index_pdu(shortroomid, &pdu_id, &body); @@ -539,7 +572,7 @@ impl Service { } } }, - _ => {}, + | _ => {}, } if let Ok(content) = pdu.get_content::() { @@ -552,24 +585,23 @@ impl Service { if let Ok(content) = pdu.get_content::() { match content.relates_to { - Relation::Reply { - in_reply_to, - } => { + | Relation::Reply { in_reply_to } => { // We need to do it again here, because replies don't have // event_id as a top level field - if let Ok(related_pducount) = self.get_pdu_count(&in_reply_to.event_id).await { + if let Ok(related_pducount) = self.get_pdu_count(&in_reply_to.event_id).await + { self.services .pdu_metadata .add_relation(count2, related_pducount); } }, - Relation::Thread(thread) => { + | Relation::Thread(thread) => { self.services .threads .add_to_thread(&thread.event_id, pdu) .await?; }, - _ => {}, // TODO: Aggregate other types + | _ => {}, // TODO: Aggregate other types } } @@ -637,7 +669,8 @@ impl Service { pdu_builder: PduBuilder, sender: &UserId, room_id: &RoomId, - _mutex_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + _mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room + * state mutex */ ) -> Result<(PduEvent, CanonicalJsonObject)> { let PduBuilder { event_type, @@ -707,7 +740,8 @@ impl Service { unsigned.insert("prev_content".to_owned(), prev_pdu.get_content_as_value()); unsigned.insert( "prev_sender".to_owned(), - serde_json::to_value(&prev_pdu.sender).expect("UserId::to_value always works"), + serde_json::to_value(&prev_pdu.sender) + .expect("UserId::to_value always works"), ); unsigned.insert( "replaces_state".to_owned(), @@ -744,9 +778,7 @@ impl Service { } else { Some(to_raw_value(&unsigned).expect("to_raw_value always works")) }, - hashes: EventHash { - sha256: "aaa".to_owned(), - }, + hashes: EventHash { sha256: "aaa".to_owned() }, signatures: None, }; @@ -769,13 +801,14 @@ impl Service { } // Hash and sign - let mut pdu_json = utils::to_canonical_object(&pdu) - .map_err(|e| err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}")))))?; + let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| { + err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}")))) + })?; // room v3 and above removed the "event_id" field from remote PDU format match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - _ => { + | RoomVersionId::V1 | RoomVersionId::V2 => {}, + | _ => { pdu_json.remove("event_id"); }, }; @@ -783,7 +816,8 @@ impl Service { // Add origin because synapse likes that (and it's required in the spec) pdu_json.insert( "origin".to_owned(), - to_canonical_value(self.services.globals.server_name()).expect("server name is a valid CanonicalJsonValue"), + to_canonical_value(self.services.globals.server_name()) + .expect("server name is a valid CanonicalJsonValue"), ); if let Err(e) = self @@ -792,17 +826,18 @@ impl Service { .hash_and_sign_event(&mut pdu_json, &room_version_id) { return match e { - Error::Signatures(ruma::signatures::Error::PduSize) => { + | Error::Signatures(ruma::signatures::Error::PduSize) => { Err!(Request(TooLarge("Message/PDU is too long (exceeds 65535 bytes)"))) }, - _ => Err!(Request(Unknown(warn!("Signing event failed: {e}")))), + | _ => Err!(Request(Unknown(warn!("Signing event failed: {e}")))), }; } // Generate event id pdu.event_id = EventId::parse_arc(format!( "${}", - ruma::signatures::reference_hash(&pdu_json, &room_version_id).expect("ruma can calculate reference hashes") + ruma::signatures::reference_hash(&pdu_json, &room_version_id) + .expect("ruma can calculate reference hashes") )) .expect("ruma's reference hashes are valid event ids"); @@ -830,7 +865,8 @@ impl Service { pdu_builder: PduBuilder, sender: &UserId, room_id: &RoomId, - state_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + state_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room state + * mutex */ ) -> Result> { let (pdu, pdu_json) = self .create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock) @@ -844,7 +880,7 @@ impl Service { if pdu.kind == TimelineEventType::RoomRedaction { use RoomVersionId::*; match self.services.state.get_room_version(&pdu.room_id).await? { - V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { if let Some(redact_id) = &pdu.redacts { if !self .services @@ -856,7 +892,7 @@ impl Service { } }; }, - _ => { + | _ => { let content: RoomRedactionEventContent = pdu.get_content()?; if let Some(redact_id) = &content.redacts { if !self @@ -937,7 +973,8 @@ impl Service { new_room_leaves: Vec, state_ids_compressed: Arc>, soft_fail: bool, - state_lock: &RoomMutexGuard, // Take mutex guard to make sure users get the room state mutex + state_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room state + * mutex */ ) -> Result> { // We append to state before appending the pdu, so we don't have a moment in // time with the pdu without it's state. This is okay because append_pdu can't @@ -971,7 +1008,9 @@ impl Service { /// items. #[inline] pub fn all_pdus<'a>( - &'a self, user_id: &'a UserId, room_id: &'a RoomId, + &'a self, + user_id: &'a UserId, + room_id: &'a RoomId, ) -> impl Stream + Send + Unpin + 'a { self.pdus(Some(user_id), room_id, None) .map_ok(|stream| stream.map(Ok)) @@ -983,7 +1022,10 @@ impl Service { /// Reverse iteration starting at from. #[tracing::instrument(skip(self), level = "debug")] pub async fn pdus_rev<'a>( - &'a self, user_id: Option<&'a UserId>, room_id: &'a RoomId, until: Option, + &'a self, + user_id: Option<&'a UserId>, + room_id: &'a RoomId, + until: Option, ) -> Result + Send + 'a> { self.db .pdus_rev(user_id, room_id, until.unwrap_or_else(PduCount::max)) @@ -993,7 +1035,10 @@ impl Service { /// Forward iteration starting at from. #[tracing::instrument(skip(self), level = "debug")] pub async fn pdus<'a>( - &'a self, user_id: Option<&'a UserId>, room_id: &'a RoomId, from: Option, + &'a self, + user_id: Option<&'a UserId>, + room_id: &'a RoomId, + from: Option, ) -> Result + Send + 'a> { self.db .pdus(user_id, room_id, from.unwrap_or_else(PduCount::min)) @@ -1002,17 +1047,21 @@ impl Service { /// Replace a PDU with the redacted form. #[tracing::instrument(skip(self, reason))] - pub async fn redact_pdu(&self, event_id: &EventId, reason: &PduEvent, shortroomid: ShortRoomId) -> Result { + pub async fn redact_pdu( + &self, + event_id: &EventId, + reason: &PduEvent, + shortroomid: ShortRoomId, + ) -> Result { // TODO: Don't reserialize, keep original json let Ok(pdu_id) = self.get_pdu_id(event_id).await else { // If event does not exist, just noop return Ok(()); }; - let mut pdu = self - .get_pdu_from_id(&pdu_id) - .await - .map_err(|e| err!(Database(error!(?pdu_id, ?event_id, ?e, "PDU ID points to invalid PDU."))))?; + let mut pdu = self.get_pdu_from_id(&pdu_id).await.map_err(|e| { + err!(Database(error!(?pdu_id, ?event_id, ?e, "PDU ID points to invalid PDU."))) + })?; if let Ok(content) = pdu.get_content::() { if let Some(body) = content.body { @@ -1026,8 +1075,9 @@ impl Service { pdu.redact(&room_version_id, reason)?; - let obj = utils::to_canonical_object(&pdu) - .map_err(|e| err!(Database(error!(?event_id, ?e, "Failed to convert PDU to canonical JSON"))))?; + let obj = utils::to_canonical_object(&pdu).map_err(|e| { + err!(Database(error!(?event_id, ?e, "Failed to convert PDU to canonical JSON"))) + })?; self.replace_pdu(&pdu_id, &obj, &pdu).await } @@ -1069,7 +1119,9 @@ impl Service { .unwrap_or_default(); let room_mods = power_levels.users.iter().filter_map(|(user_id, level)| { - if level > &power_levels.users_default && !self.services.globals.user_is_local(user_id) { + if level > &power_levels.users_default + && !self.services.globals.user_is_local(user_id) + { Some(user_id.server_name()) } else { None @@ -1124,7 +1176,7 @@ impl Service { ) .await; match response { - Ok(response) => { + | Ok(response) => { for pdu in response.pdus { if let Err(e) = self.backfill_pdu(backfill_server, pdu).boxed().await { debug_warn!("Failed to add backfilled pdu in room {room_id}: {e}"); @@ -1132,7 +1184,7 @@ impl Service { } return Ok(()); }, - Err(e) => { + | Err(e) => { warn!("{backfill_server} failed to provide backfill for room {room_id}: {e}"); }, } @@ -1144,7 +1196,8 @@ impl Service { #[tracing::instrument(skip(self, pdu))] pub async fn backfill_pdu(&self, origin: &ServerName, pdu: Box) -> Result<()> { - let (event_id, value, room_id) = self.services.event_handler.parse_incoming_pdu(&pdu).await?; + let (event_id, value, room_id) = + self.services.event_handler.parse_incoming_pdu(&pdu).await?; // Lock so we cannot backfill the same pdu twice at the same time let mutex_lock = self @@ -1210,10 +1263,10 @@ impl Service { #[tracing::instrument(skip_all, level = "debug")] async fn check_pdu_for_admin_room(&self, pdu: &PduEvent, sender: &UserId) -> Result<()> { match pdu.event_type() { - TimelineEventType::RoomEncryption => { + | TimelineEventType::RoomEncryption => { return Err!(Request(Forbidden(error!("Encryption not supported in admins room.")))); }, - TimelineEventType::RoomMember => { + | TimelineEventType::RoomMember => { let target = pdu .state_key() .filter(|v| v.starts_with('@')) @@ -1223,9 +1276,11 @@ async fn check_pdu_for_admin_room(&self, pdu: &PduEvent, sender: &UserId) -> Res let content: RoomMemberEventContent = pdu.get_content()?; match content.membership { - MembershipState::Leave => { + | MembershipState::Leave => { if target == server_user { - return Err!(Request(Forbidden(error!("Server user cannot leave the admins room.")))); + return Err!(Request(Forbidden(error!( + "Server user cannot leave the admins room." + )))); } let count = self @@ -1239,13 +1294,17 @@ async fn check_pdu_for_admin_room(&self, pdu: &PduEvent, sender: &UserId) -> Res .await; if count < 2 { - return Err!(Request(Forbidden(error!("Last admin cannot leave the admins room.")))); + return Err!(Request(Forbidden(error!( + "Last admin cannot leave the admins room." + )))); } }, - MembershipState::Ban if pdu.state_key().is_some() => { + | MembershipState::Ban if pdu.state_key().is_some() => { if target == server_user { - return Err!(Request(Forbidden(error!("Server cannot be banned from admins room.")))); + return Err!(Request(Forbidden(error!( + "Server cannot be banned from admins room." + )))); } let count = self @@ -1259,13 +1318,15 @@ async fn check_pdu_for_admin_room(&self, pdu: &PduEvent, sender: &UserId) -> Res .await; if count < 2 { - return Err!(Request(Forbidden(error!("Last admin cannot be banned from admins room.")))); + return Err!(Request(Forbidden(error!( + "Last admin cannot be banned from admins room." + )))); } }, - _ => {}, + | _ => {}, }; }, - _ => {}, + | _ => {}, }; Ok(()) diff --git a/src/service/rooms/typing/mod.rs b/src/service/rooms/typing/mod.rs index 59862a852..a61233220 100644 --- a/src/service/rooms/typing/mod.rs +++ b/src/service/rooms/typing/mod.rs @@ -52,7 +52,12 @@ impl crate::Service for Service { impl Service { /// Sets a user as typing until the timeout timestamp is reached or /// roomtyping_remove is called. - pub async fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> { + pub async fn typing_add( + &self, + user_id: &UserId, + room_id: &RoomId, + timeout: u64, + ) -> Result<()> { debug_info!("typing started {user_id:?} in {room_id:?} timeout:{timeout:?}"); // update clients self.typing @@ -177,15 +182,15 @@ impl Service { /// Returns a new typing EDU. pub async fn typings_all( - &self, room_id: &RoomId, sender_user: &UserId, + &self, + room_id: &RoomId, + sender_user: &UserId, ) -> Result> { let room_typing_indicators = self.typing.read().await.get(room_id).cloned(); let Some(typing_indicators) = room_typing_indicators else { return Ok(SyncEphemeralRoomEvent { - content: ruma::events::typing::TypingEventContent { - user_ids: Vec::new(), - }, + content: ruma::events::typing::TypingEventContent { user_ids: Vec::new() }, }); }; @@ -204,13 +209,16 @@ impl Service { .await; Ok(SyncEphemeralRoomEvent { - content: ruma::events::typing::TypingEventContent { - user_ids, - }, + content: ruma::events::typing::TypingEventContent { user_ids }, }) } - async fn federation_send(&self, room_id: &RoomId, user_id: &UserId, typing: bool) -> Result<()> { + async fn federation_send( + &self, + room_id: &RoomId, + user_id: &UserId, + typing: bool, + ) -> Result<()> { debug_assert!( self.services.globals.user_is_local(user_id), "tried to broadcast typing status of remote user", diff --git a/src/service/rooms/user/mod.rs b/src/service/rooms/user/mod.rs index 80d33de4a..6a0c6aa1f 100644 --- a/src/service/rooms/user/mod.rs +++ b/src/service/rooms/user/mod.rs @@ -92,7 +92,12 @@ pub async fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) - } #[implement(Service)] -pub async fn associate_token_shortstatehash(&self, room_id: &RoomId, token: u64, shortstatehash: ShortStateHash) { +pub async fn associate_token_shortstatehash( + &self, + room_id: &RoomId, + token: u64, + shortstatehash: ShortStateHash, +) { let shortroomid = self .services .short @@ -108,7 +113,11 @@ pub async fn associate_token_shortstatehash(&self, room_id: &RoomId, token: u64, } #[implement(Service)] -pub async fn get_token_shortstatehash(&self, room_id: &RoomId, token: u64) -> Result { +pub async fn get_token_shortstatehash( + &self, + room_id: &RoomId, + token: u64, +) -> Result { let shortroomid = self.services.short.get_shortroomid(room_id).await?; let key: &[u64] = &[shortroomid, token]; diff --git a/src/service/sending/appservice.rs b/src/service/sending/appservice.rs index 9008a21fd..6b58d9644 100644 --- a/src/service/sending/appservice.rs +++ b/src/service/sending/appservice.rs @@ -3,14 +3,18 @@ use std::{fmt::Debug, mem}; use bytes::BytesMut; use conduwuit::{debug_error, err, trace, utils, warn, Err, Result}; use reqwest::Client; -use ruma::api::{appservice::Registration, IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken}; +use ruma::api::{ + appservice::Registration, IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken, +}; /// Sends a request to an appservice /// /// Only returns Ok(None) if there is no url specified in the appservice /// registration file pub(crate) async fn send_request( - client: &Client, registration: Registration, request: T, + client: &Client, + registration: Registration, + request: T, ) -> Result> where T: OutgoingRequest + Debug + Send, @@ -25,17 +29,17 @@ where let hs_token = registration.hs_token.as_str(); let mut http_request = request - .try_into_http_request::(&dest, SendAccessToken::IfRequired(hs_token), &VERSIONS) + .try_into_http_request::( + &dest, + SendAccessToken::IfRequired(hs_token), + &VERSIONS, + ) .map_err(|e| err!(BadServerResponse(warn!("Failed to find destination {dest}: {e}"))))? .map(BytesMut::freeze); let mut parts = http_request.uri().clone().into_parts(); let old_path_and_query = parts.path_and_query.unwrap().as_str().to_owned(); - let symbol = if old_path_and_query.contains('?') { - "&" - } else { - "?" - }; + let symbol = if old_path_and_query.contains('?') { "&" } else { "?" }; parts.path_and_query = Some( (old_path_and_query + symbol + "access_token=" + hs_token) diff --git a/src/service/sending/data.rs b/src/service/sending/data.rs index 372d8e14f..ac06424f7 100644 --- a/src/service/sending/data.rs +++ b/src/service/sending/data.rs @@ -43,7 +43,9 @@ impl Data { } } - pub(super) fn delete_active_request(&self, key: &[u8]) { self.servercurrentevent_data.remove(key); } + pub(super) fn delete_active_request(&self, key: &[u8]) { + self.servercurrentevent_data.remove(key); + } pub(super) async fn delete_all_active_requests_for(&self, destination: &Destination) { let prefix = destination.get_prefix(); @@ -76,11 +78,7 @@ impl Data { events .filter(|(key, _)| !key.is_empty()) .for_each(|(key, val)| { - let val = if let SendingEvent::Edu(val) = &val { - &**val - } else { - &[] - }; + let val = if let SendingEvent::Edu(val) = &val { &**val } else { &[] }; self.servercurrentevent_data.insert(key, val); self.servernameevent_data.remove(key); @@ -93,21 +91,26 @@ impl Data { .raw_stream() .ignore_err() .map(|(key, val)| { - let (dest, event) = parse_servercurrentevent(key, val).expect("invalid servercurrentevent"); + let (dest, event) = + parse_servercurrentevent(key, val).expect("invalid servercurrentevent"); (key.to_vec(), event, dest) }) } #[inline] - pub fn active_requests_for(&self, destination: &Destination) -> impl Stream + Send + '_ { + pub fn active_requests_for( + &self, + destination: &Destination, + ) -> impl Stream + Send + '_ { let prefix = destination.get_prefix(); self.servercurrentevent_data .raw_stream_from(&prefix) .ignore_err() .ready_take_while(move |(key, _)| key.starts_with(&prefix)) .map(|(key, val)| { - let (_, event) = parse_servercurrentevent(key, val).expect("invalid servercurrentevent"); + let (_, event) = + parse_servercurrentevent(key, val).expect("invalid servercurrentevent"); (key.to_vec(), event) }) @@ -150,14 +153,18 @@ impl Data { keys } - pub fn queued_requests(&self, destination: &Destination) -> impl Stream + Send + '_ { + pub fn queued_requests( + &self, + destination: &Destination, + ) -> impl Stream + Send + '_ { let prefix = destination.get_prefix(); self.servernameevent_data .raw_stream_from(&prefix) .ignore_err() .ready_take_while(move |(key, _)| key.starts_with(&prefix)) .map(|(key, val)| { - let (_, event) = parse_servercurrentevent(key, val).expect("invalid servercurrentevent"); + let (_, event) = + parse_servercurrentevent(key, val).expect("invalid servercurrentevent"); (key.to_vec(), event) }) @@ -186,8 +193,9 @@ fn parse_servercurrentevent(key: &[u8], value: &[u8]) -> Result<(Destination, Se .next() .ok_or_else(|| Error::bad_database("Invalid bytes in servercurrentpdus."))?; - let server = utils::string_from_bytes(server) - .map_err(|_| Error::bad_database("Invalid server bytes in server_currenttransaction"))?; + let server = utils::string_from_bytes(server).map_err(|_| { + Error::bad_database("Invalid server bytes in server_currenttransaction") + })?; ( Destination::Appservice(server), @@ -203,8 +211,8 @@ fn parse_servercurrentevent(key: &[u8], value: &[u8]) -> Result<(Destination, Se let user = parts.next().expect("splitn always returns one element"); let user_string = utils::string_from_bytes(user) .map_err(|_| Error::bad_database("Invalid user string in servercurrentevent"))?; - let user_id = - UserId::parse(user_string).map_err(|_| Error::bad_database("Invalid user id in servercurrentevent"))?; + let user_id = UserId::parse(user_string) + .map_err(|_| Error::bad_database("Invalid user id in servercurrentevent"))?; let pushkey = parts .next() @@ -233,14 +241,14 @@ fn parse_servercurrentevent(key: &[u8], value: &[u8]) -> Result<(Destination, Se .next() .ok_or_else(|| Error::bad_database("Invalid bytes in servercurrentpdus."))?; - let server = utils::string_from_bytes(server) - .map_err(|_| Error::bad_database("Invalid server bytes in server_currenttransaction"))?; + let server = utils::string_from_bytes(server).map_err(|_| { + Error::bad_database("Invalid server bytes in server_currenttransaction") + })?; ( - Destination::Normal( - ServerName::parse(server) - .map_err(|_| Error::bad_database("Invalid server string in server_currenttransaction"))?, - ), + Destination::Normal(ServerName::parse(server).map_err(|_| { + Error::bad_database("Invalid server string in server_currenttransaction") + })?), if value.is_empty() { SendingEvent::Pdu(event.into()) } else { diff --git a/src/service/sending/dest.rs b/src/service/sending/dest.rs index 0a5893b72..2c6063cc9 100644 --- a/src/service/sending/dest.rs +++ b/src/service/sending/dest.rs @@ -14,7 +14,7 @@ pub enum Destination { #[must_use] pub(super) fn get_prefix(&self) -> Vec { match self { - Self::Normal(server) => { + | Self::Normal(server) => { let len = server.as_bytes().len().saturating_add(1); let mut p = Vec::with_capacity(len); @@ -22,7 +22,7 @@ pub(super) fn get_prefix(&self) -> Vec { p.push(0xFF); p }, - Self::Appservice(server) => { + | Self::Appservice(server) => { let sigil = b"+"; let len = sigil.len().saturating_add(server.len()).saturating_add(1); @@ -32,7 +32,7 @@ pub(super) fn get_prefix(&self) -> Vec { p.push(0xFF); p }, - Self::Push(user, pushkey) => { + | Self::Push(user, pushkey) => { let sigil = b"$"; let len = sigil .len() diff --git a/src/service/sending/mod.rs b/src/service/sending/mod.rs index f98281782..2038f4eb5 100644 --- a/src/service/sending/mod.rs +++ b/src/service/sending/mod.rs @@ -25,8 +25,8 @@ pub use self::{ sender::{EDU_LIMIT, PDU_LIMIT}, }; use crate::{ - account_data, client, globals, presence, pusher, resolver, rooms, rooms::timeline::RawPduId, server_keys, users, - Dep, + account_data, client, globals, presence, pusher, resolver, rooms, rooms::timeline::RawPduId, + server_keys, users, Dep, }; pub struct Service { @@ -156,18 +156,16 @@ impl Service { { let _cork = self.db.db.cork(); let requests = servers - .map(|server| (Destination::Normal(server.into()), SendingEvent::Pdu(pdu_id.to_owned()))) + .map(|server| { + (Destination::Normal(server.into()), SendingEvent::Pdu(pdu_id.to_owned())) + }) .collect::>() .await; let keys = self.db.queue_requests(requests.iter().map(|(o, e)| (e, o))); for ((dest, event), queue_id) in requests.into_iter().zip(keys) { - self.dispatch(Msg { - dest, - event, - queue_id, - })?; + self.dispatch(Msg { dest, event, queue_id })?; } Ok(()) @@ -204,18 +202,16 @@ impl Service { { let _cork = self.db.db.cork(); let requests = servers - .map(|server| (Destination::Normal(server.to_owned()), SendingEvent::Edu(serialized.clone()))) + .map(|server| { + (Destination::Normal(server.to_owned()), SendingEvent::Edu(serialized.clone())) + }) .collect::>() .await; let keys = self.db.queue_requests(requests.iter().map(|(o, e)| (e, o))); for ((dest, event), queue_id) in requests.into_iter().zip(keys) { - self.dispatch(Msg { - dest, - event, - queue_id, - })?; + self.dispatch(Msg { dest, event, queue_id })?; } Ok(()) @@ -253,7 +249,11 @@ impl Service { /// Sends a request to a federation server #[tracing::instrument(skip_all, name = "request")] - pub async fn send_federation_request(&self, dest: &ServerName, request: T) -> Result + pub async fn send_federation_request( + &self, + dest: &ServerName, + request: T, + ) -> Result where T: OutgoingRequest + Debug + Send, { @@ -263,7 +263,11 @@ impl Service { /// Like send_federation_request() but with a very large timeout #[tracing::instrument(skip_all, name = "synapse")] - pub async fn send_synapse_request(&self, dest: &ServerName, request: T) -> Result + pub async fn send_synapse_request( + &self, + dest: &ServerName, + request: T, + ) -> Result where T: OutgoingRequest + Debug + Send, { @@ -276,7 +280,9 @@ impl Service { /// Only returns None if there is no url specified in the appservice /// registration file pub async fn send_appservice_request( - &self, registration: Registration, request: T, + &self, + registration: Registration, + request: T, ) -> Result> where T: OutgoingRequest + Debug + Send, @@ -291,24 +297,30 @@ impl Service { /// key #[tracing::instrument(skip(self), level = "debug")] pub async fn cleanup_events( - &self, appservice_id: Option<&str>, user_id: Option<&UserId>, push_key: Option<&str>, + &self, + appservice_id: Option<&str>, + user_id: Option<&UserId>, + push_key: Option<&str>, ) -> Result { match (appservice_id, user_id, push_key) { - (None, Some(user_id), Some(push_key)) => { + | (None, Some(user_id), Some(push_key)) => { self.db - .delete_all_requests_for(&Destination::Push(user_id.to_owned(), push_key.to_owned())) + .delete_all_requests_for(&Destination::Push( + user_id.to_owned(), + push_key.to_owned(), + )) .await; Ok(()) }, - (Some(appservice_id), None, None) => { + | (Some(appservice_id), None, None) => { self.db .delete_all_requests_for(&Destination::Appservice(appservice_id.to_owned())) .await; Ok(()) }, - _ => { + | _ => { debug_warn!("cleanup_events called with too many or too few arguments"); Ok(()) }, diff --git a/src/service/sending/send.rs b/src/service/sending/send.rs index 862d2a426..81467c161 100644 --- a/src/service/sending/send.rs +++ b/src/service/sending/send.rs @@ -2,16 +2,16 @@ use std::mem; use bytes::Bytes; use conduwuit::{ - debug, debug_error, debug_warn, err, error::inspect_debug_log, implement, trace, utils::string::EMPTY, Err, Error, - Result, + debug, debug_error, debug_warn, err, error::inspect_debug_log, implement, trace, + utils::string::EMPTY, Err, Error, Result, }; use http::{header::AUTHORIZATION, HeaderValue}; use ipaddress::IPAddress; use reqwest::{Client, Method, Request, Response, Url}; use ruma::{ api::{ - client::error::Error as RumaError, EndpointError, IncomingResponse, MatrixVersion, OutgoingRequest, - SendAccessToken, + client::error::Error as RumaError, EndpointError, IncomingResponse, MatrixVersion, + OutgoingRequest, SendAccessToken, }, serde::Base64, server_util::authorization::XMatrix, @@ -25,7 +25,12 @@ use crate::{ impl super::Service { #[tracing::instrument(skip_all, level = "debug")] - pub async fn send(&self, client: &Client, dest: &ServerName, request: T) -> Result + pub async fn send( + &self, + client: &Client, + dest: &ServerName, + request: T, + ) -> Result where T: OutgoingRequest + Send, { @@ -39,7 +44,9 @@ impl super::Service { .forbidden_remote_server_names .contains(dest) { - return Err!(Request(Forbidden(debug_warn!("Federation with {dest} is not allowed.")))); + return Err!(Request(Forbidden(debug_warn!( + "Federation with {dest} is not allowed." + )))); } let actual = self.services.resolver.get_actual_dest(dest).await?; @@ -49,7 +56,11 @@ impl super::Service { } async fn execute( - &self, dest: &ServerName, actual: &ActualDest, request: Request, client: &Client, + &self, + dest: &ServerName, + actual: &ActualDest, + request: Request, + client: &Client, ) -> Result where T: OutgoingRequest + Send, @@ -59,8 +70,18 @@ impl super::Service { debug!(?method, ?url, "Sending request"); match client.execute(request).await { - Ok(response) => handle_response::(&self.services.resolver, dest, actual, &method, &url, response).await, - Err(error) => Err(handle_error(actual, &method, &url, error).expect_err("always returns error")), + | Ok(response) => + handle_response::( + &self.services.resolver, + dest, + actual, + &method, + &url, + response, + ) + .await, + | Err(error) => + Err(handle_error(actual, &method, &url, error).expect_err("always returns error")), } } @@ -86,7 +107,11 @@ impl super::Service { } async fn handle_response( - resolver: &resolver::Service, dest: &ServerName, actual: &ActualDest, method: &Method, url: &Url, + resolver: &resolver::Service, + dest: &ServerName, + actual: &ActualDest, + method: &Method, + url: &Url, response: Response, ) -> Result where @@ -96,21 +121,22 @@ where let result = T::IncomingResponse::try_from_http_response(response); if result.is_ok() && !actual.cached { - resolver.set_cached_destination( - dest.to_owned(), - CachedDest { - dest: actual.dest.clone(), - host: actual.host.clone(), - expire: CachedDest::default_expire(), - }, - ); + resolver.set_cached_destination(dest.to_owned(), CachedDest { + dest: actual.dest.clone(), + host: actual.host.clone(), + expire: CachedDest::default_expire(), + }); } result.map_err(|e| err!(BadServerResponse("Server returned bad 200 response: {e:?}"))) } async fn into_http_response( - dest: &ServerName, actual: &ActualDest, method: &Method, url: &Url, mut response: Response, + dest: &ServerName, + actual: &ActualDest, + method: &Method, + url: &Url, + mut response: Response, ) -> Result> { let status = response.status(); trace!( @@ -146,13 +172,21 @@ async fn into_http_response( debug!("Got {status:?} for {method} {url}"); if !status.is_success() { - return Err(Error::Federation(dest.to_owned(), RumaError::from_http_response(http_response))); + return Err(Error::Federation( + dest.to_owned(), + RumaError::from_http_response(http_response), + )); } Ok(http_response) } -fn handle_error(actual: &ActualDest, method: &Method, url: &Url, mut e: reqwest::Error) -> Result { +fn handle_error( + actual: &ActualDest, + method: &Method, + url: &Url, + mut e: reqwest::Error, +) -> Result { if e.is_timeout() || e.is_connect() { e = e.without_url(); debug_warn!("{e:?}"); @@ -186,7 +220,8 @@ fn sign_request(&self, http_request: &mut http::Request>, dest: &ServerN .expect("http::Request missing path_and_query"); let mut req: Object = if !body.is_empty() { - let content: CanonicalJsonValue = serde_json::from_slice(body).expect("failed to serialize body"); + let content: CanonicalJsonValue = + serde_json::from_slice(body).expect("failed to serialize body"); let authorization: [Member; 5] = [ ("content".into(), content), diff --git a/src/service/sending/sender.rs b/src/service/sending/sender.rs index 77fd7d5ce..1f462f396 100644 --- a/src/service/sending/sender.rs +++ b/src/service/sending/sender.rs @@ -24,15 +24,19 @@ use ruma::{ appservice::event::push_events::v1::Edu as RumaEdu, federation::transactions::{ edu::{ - DeviceListUpdateContent, Edu, PresenceContent, PresenceUpdate, ReceiptContent, ReceiptData, ReceiptMap, + DeviceListUpdateContent, Edu, PresenceContent, PresenceUpdate, ReceiptContent, + ReceiptData, ReceiptMap, }, send_transaction_message, }, }, device_id, - events::{push_rules::PushRulesEvent, receipt::ReceiptType, AnySyncEphemeralRoomEvent, GlobalAccountDataEventType}, - push, uint, CanonicalJsonObject, MilliSecondsSinceUnixEpoch, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, - RoomVersionId, ServerName, UInt, + events::{ + push_rules::PushRulesEvent, receipt::ReceiptType, AnySyncEphemeralRoomEvent, + GlobalAccountDataEventType, + }, + push, uint, CanonicalJsonObject, MilliSecondsSinceUnixEpoch, OwnedRoomId, OwnedServerName, + OwnedUserId, RoomId, RoomVersionId, ServerName, UInt, }; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; @@ -86,11 +90,14 @@ impl Service { } async fn handle_response<'a>( - &'a self, response: SendingResult, futures: &mut SendingFutures<'a>, statuses: &mut CurTransactionStatus, + &'a self, + response: SendingResult, + futures: &mut SendingFutures<'a>, + statuses: &mut CurTransactionStatus, ) { match response { - Ok(dest) => self.handle_response_ok(&dest, futures, statuses).await, - Err((dest, e)) => Self::handle_response_err(dest, statuses, &e), + | Ok(dest) => self.handle_response_ok(&dest, futures, statuses).await, + | Err((dest, e)) => Self::handle_response_err(dest, statuses, &e), }; } @@ -98,16 +105,22 @@ impl Service { debug!(dest = ?dest, "{e:?}"); statuses.entry(dest).and_modify(|e| { *e = match e { - TransactionStatus::Running => TransactionStatus::Failed(1, Instant::now()), - TransactionStatus::Retrying(ref n) => TransactionStatus::Failed(n.saturating_add(1), Instant::now()), - TransactionStatus::Failed(..) => panic!("Request that was not even running failed?!"), + | TransactionStatus::Running => TransactionStatus::Failed(1, Instant::now()), + | TransactionStatus::Retrying(ref n) => + TransactionStatus::Failed(n.saturating_add(1), Instant::now()), + | TransactionStatus::Failed(..) => { + panic!("Request that was not even running failed?!") + }, } }); } #[allow(clippy::needless_pass_by_ref_mut)] async fn handle_response_ok<'a>( - &'a self, dest: &Destination, futures: &mut SendingFutures<'a>, statuses: &mut CurTransactionStatus, + &'a self, + dest: &Destination, + futures: &mut SendingFutures<'a>, + statuses: &mut CurTransactionStatus, ) { let _cork = self.db.db.cork(); self.db.delete_all_active_requests_for(dest).await; @@ -133,7 +146,10 @@ impl Service { #[allow(clippy::needless_pass_by_ref_mut)] async fn handle_request<'a>( - &'a self, msg: Msg, futures: &mut SendingFutures<'a>, statuses: &mut CurTransactionStatus, + &'a self, + msg: Msg, + futures: &mut SendingFutures<'a>, + statuses: &mut CurTransactionStatus, ) { let iv = vec![(msg.queue_id, msg.event)]; if let Ok(Some(events)) = self.select_events(&msg.dest, iv, statuses).await { @@ -168,8 +184,13 @@ impl Service { } #[allow(clippy::needless_pass_by_ref_mut)] - async fn initial_requests<'a>(&'a self, futures: &mut SendingFutures<'a>, statuses: &mut CurTransactionStatus) { - let keep = usize::try_from(self.server.config.startup_netburst_keep).unwrap_or(usize::MAX); + async fn initial_requests<'a>( + &'a self, + futures: &mut SendingFutures<'a>, + statuses: &mut CurTransactionStatus, + ) { + let keep = + usize::try_from(self.server.config.startup_netburst_keep).unwrap_or(usize::MAX); let mut txns = HashMap::>::new(); let mut active = self.db.active_requests().boxed(); @@ -240,7 +261,11 @@ impl Service { } #[tracing::instrument(skip_all, level = "debug")] - fn select_events_current(&self, dest: Destination, statuses: &mut CurTransactionStatus) -> Result<(bool, bool)> { + fn select_events_current( + &self, + dest: Destination, + statuses: &mut CurTransactionStatus, + ) -> Result<(bool, bool)> { let (mut allow, mut retry) = (true, false); statuses .entry(dest.clone()) // TODO: can we avoid cloning? @@ -278,7 +303,8 @@ impl Service { let events_len = AtomicUsize::default(); let max_edu_count = AtomicU64::new(since); - let device_changes = self.select_edus_device_changes(server_name, batch, &max_edu_count, &events_len); + let device_changes = + self.select_edus_device_changes(server_name, batch, &max_edu_count, &events_len); let receipts: OptionFuture<_> = self .server @@ -305,7 +331,11 @@ impl Service { /// Look for presence async fn select_edus_device_changes( - &self, server_name: &ServerName, since: (u64, u64), max_edu_count: &AtomicU64, events_len: &AtomicUsize, + &self, + server_name: &ServerName, + since: (u64, u64), + max_edu_count: &AtomicU64, + events_len: &AtomicUsize, ) -> Vec> { let mut events = Vec::new(); let server_rooms = self.services.state_cache.server_rooms(server_name); @@ -342,7 +372,8 @@ impl Service { keys: None, }); - let edu = serde_json::to_vec(&edu).expect("failed to serialize device list update to JSON"); + let edu = serde_json::to_vec(&edu) + .expect("failed to serialize device list update to JSON"); events.push(edu); if events_len.fetch_add(1, Ordering::Relaxed) >= SELECT_EDU_LIMIT - 1 { @@ -356,7 +387,10 @@ impl Service { /// Look for read receipts in this room async fn select_edus_receipts( - &self, server_name: &ServerName, since: (u64, u64), max_edu_count: &AtomicU64, + &self, + server_name: &ServerName, + since: (u64, u64), + max_edu_count: &AtomicU64, ) -> Option> { let server_rooms = self.services.state_cache.server_rooms(server_name); @@ -377,19 +411,21 @@ impl Service { return None; } - let receipt_content = Edu::Receipt(ReceiptContent { - receipts, - }); + let receipt_content = Edu::Receipt(ReceiptContent { receipts }); - let receipt_content = - serde_json::to_vec(&receipt_content).expect("Failed to serialize Receipt EDU to JSON vec"); + let receipt_content = serde_json::to_vec(&receipt_content) + .expect("Failed to serialize Receipt EDU to JSON vec"); Some(receipt_content) } /// Look for read receipts in this room async fn select_edus_receipts_room( - &self, room_id: &RoomId, since: (u64, u64), max_edu_count: &AtomicU64, num: &mut usize, + &self, + room_id: &RoomId, + since: (u64, u64), + max_edu_count: &AtomicU64, + num: &mut usize, ) -> ReceiptMap { let receipts = self .services @@ -444,14 +480,15 @@ impl Service { } } - ReceiptMap { - read, - } + ReceiptMap { read } } /// Look for presence async fn select_edus_presence( - &self, server_name: &ServerName, since: (u64, u64), max_edu_count: &AtomicU64, + &self, + server_name: &ServerName, + since: (u64, u64), + max_edu_count: &AtomicU64, ) -> Option> { let presence_since = self.services.presence.presence_since(since.0); @@ -511,7 +548,8 @@ impl Service { push: presence_updates.into_values().collect(), }); - let presence_content = serde_json::to_vec(&presence_content).expect("failed to serialize Presence EDU to JSON"); + let presence_content = serde_json::to_vec(&presence_content) + .expect("failed to serialize Presence EDU to JSON"); Some(presence_content) } @@ -519,21 +557,28 @@ impl Service { async fn send_events(&self, dest: Destination, events: Vec) -> SendingResult { //debug_assert!(!events.is_empty(), "sending empty transaction"); match dest { - Destination::Normal(ref server) => self.send_events_dest_normal(&dest, server, events).await, - Destination::Appservice(ref id) => self.send_events_dest_appservice(&dest, id, events).await, - Destination::Push(ref userid, ref pushkey) => { + | Destination::Normal(ref server) => + self.send_events_dest_normal(&dest, server, events).await, + | Destination::Appservice(ref id) => + self.send_events_dest_appservice(&dest, id, events).await, + | Destination::Push(ref userid, ref pushkey) => self.send_events_dest_push(&dest, userid, pushkey, events) - .await - }, + .await, } } #[tracing::instrument(skip(self, dest, events), name = "appservice")] async fn send_events_dest_appservice( - &self, dest: &Destination, id: &str, events: Vec, + &self, + dest: &Destination, + id: &str, + events: Vec, ) -> SendingResult { let Some(appservice) = self.services.appservice.get_registration(id).await else { - return Err((dest.clone(), err!(Database(warn!(?id, "Missing appservice registration"))))); + return Err(( + dest.clone(), + err!(Database(warn!(?id, "Missing appservice registration"))), + )); }; let mut pdu_jsons = Vec::with_capacity( @@ -550,12 +595,12 @@ impl Service { ); for event in &events { match event { - SendingEvent::Pdu(pdu_id) => { + | SendingEvent::Pdu(pdu_id) => { if let Ok(pdu) = self.services.timeline.get_pdu_from_id(pdu_id).await { pdu_jsons.push(pdu.to_room_event()); } }, - SendingEvent::Edu(edu) => { + | SendingEvent::Edu(edu) => { if appservice .receive_ephemeral .is_some_and(|receive_edus| receive_edus) @@ -565,14 +610,14 @@ impl Service { } } }, - SendingEvent::Flush => {}, // flush only; no new content + | SendingEvent::Flush => {}, // flush only; no new content } } let txn_hash = calculate_hash(events.iter().filter_map(|e| match e { - SendingEvent::Edu(b) => Some(&**b), - SendingEvent::Pdu(b) => Some(b.as_ref()), - SendingEvent::Flush => None, + | SendingEvent::Edu(b) => Some(&**b), + | SendingEvent::Pdu(b) => Some(b.as_ref()), + | SendingEvent::Flush => None, })); let txn_id = &*general_purpose::URL_SAFE_NO_PAD.encode(txn_hash); @@ -592,28 +637,35 @@ impl Service { ) .await { - Ok(_) => Ok(dest.clone()), - Err(e) => Err((dest.clone(), e)), + | Ok(_) => Ok(dest.clone()), + | Err(e) => Err((dest.clone(), e)), } } #[tracing::instrument(skip(self, dest, events), name = "push")] async fn send_events_dest_push( - &self, dest: &Destination, userid: &OwnedUserId, pushkey: &str, events: Vec, + &self, + dest: &Destination, + userid: &OwnedUserId, + pushkey: &str, + events: Vec, ) -> SendingResult { let Ok(pusher) = self.services.pusher.get_pusher(userid, pushkey).await else { - return Err((dest.clone(), err!(Database(error!(?userid, ?pushkey, "Missing pusher"))))); + return Err(( + dest.clone(), + err!(Database(error!(?userid, ?pushkey, "Missing pusher"))), + )); }; let mut pdus = Vec::new(); for event in &events { match event { - SendingEvent::Pdu(pdu_id) => { + | SendingEvent::Pdu(pdu_id) => { if let Ok(pdu) = self.services.timeline.get_pdu_from_id(pdu_id).await { pdus.push(pdu); } }, - SendingEvent::Edu(_) | SendingEvent::Flush => { + | SendingEvent::Edu(_) | SendingEvent::Flush => { // Push gateways don't need EDUs (?) and flush only; // no new content }, @@ -657,7 +709,10 @@ impl Service { #[tracing::instrument(skip(self, dest, events), name = "", level = "debug")] async fn send_events_dest_normal( - &self, dest: &Destination, server: &OwnedServerName, events: Vec, + &self, + dest: &Destination, + server: &OwnedServerName, + events: Vec, ) -> SendingResult { let mut pdu_jsons = Vec::with_capacity( events @@ -675,17 +730,16 @@ impl Service { for event in &events { match event { // TODO: check room version and remove event_id if needed - SendingEvent::Pdu(pdu_id) => { + | SendingEvent::Pdu(pdu_id) => { if let Ok(pdu) = self.services.timeline.get_pdu_json_from_id(pdu_id).await { pdu_jsons.push(self.convert_to_outgoing_federation_event(pdu).await); } }, - SendingEvent::Edu(edu) => { + | SendingEvent::Edu(edu) => if let Ok(raw) = serde_json::from_slice(edu) { edu_jsons.push(raw); - } - }, - SendingEvent::Flush => {}, // flush only; no new content + }, + | SendingEvent::Flush => {}, // flush only; no new content } } @@ -693,9 +747,9 @@ impl Service { // transaction"); let txn_hash = calculate_hash(events.iter().filter_map(|e| match e { - SendingEvent::Edu(b) => Some(&**b), - SendingEvent::Pdu(b) => Some(b.as_ref()), - SendingEvent::Flush => None, + | SendingEvent::Edu(b) => Some(&**b), + | SendingEvent::Pdu(b) => Some(b.as_ref()), + | SendingEvent::Flush => None, })); let txn_id = &*general_purpose::URL_SAFE_NO_PAD.encode(txn_hash); @@ -725,7 +779,10 @@ impl Service { } /// This does not return a full `Pdu` it is only to satisfy ruma's types. - pub async fn convert_to_outgoing_federation_event(&self, mut pdu_json: CanonicalJsonObject) -> Box { + pub async fn convert_to_outgoing_federation_event( + &self, + mut pdu_json: CanonicalJsonObject, + ) -> Box { if let Some(unsigned) = pdu_json .get_mut("unsigned") .and_then(|val| val.as_object_mut()) @@ -739,11 +796,11 @@ impl Service { .and_then(|val| RoomId::parse(val.as_str()?).ok()) { match self.services.state.get_room_version(&room_id).await { - Ok(room_version_id) => match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - _ => _ = pdu_json.remove("event_id"), + | Ok(room_version_id) => match room_version_id { + | RoomVersionId::V1 | RoomVersionId::V2 => {}, + | _ => _ = pdu_json.remove("event_id"), }, - Err(_) => _ = pdu_json.remove("event_id"), + | Err(_) => _ = pdu_json.remove("event_id"), } } else { pdu_json.remove("event_id"); diff --git a/src/service/server_keys/acquire.rs b/src/service/server_keys/acquire.rs index 886c4750f..305cbfef3 100644 --- a/src/service/server_keys/acquire.rs +++ b/src/service/server_keys/acquire.rs @@ -4,11 +4,13 @@ use std::{ time::Duration, }; -use conduwuit::{debug, debug_error, debug_warn, error, implement, info, result::FlatOk, trace, warn}; +use conduwuit::{ + debug, debug_error, debug_warn, error, implement, info, result::FlatOk, trace, warn, +}; use futures::{stream::FuturesUnordered, StreamExt}; use ruma::{ - api::federation::discovery::ServerSigningKeys, serde::Raw, CanonicalJsonObject, OwnedServerName, - OwnedServerSigningKeyId, ServerName, ServerSigningKeyId, + api::federation::discovery::ServerSigningKeys, serde::Raw, CanonicalJsonObject, + OwnedServerName, OwnedServerSigningKeyId, ServerName, ServerSigningKeyId, }; use serde_json::value::RawValue as RawJsonValue; use tokio::time::{timeout_at, Instant}; @@ -79,7 +81,9 @@ where return; } - warn!("missing {missing_keys} keys for {missing_servers} servers from all notaries first"); + warn!( + "missing {missing_keys} keys for {missing_servers} servers from all notaries first" + ); } if !notary_only { @@ -101,13 +105,15 @@ where return; } - debug_warn!("still missing {missing_keys} keys for {missing_servers} servers from all notaries."); + debug_warn!( + "still missing {missing_keys} keys for {missing_servers} servers from all notaries." + ); } if missing_keys > 0 { warn!( - "did not obtain {missing_keys} keys for {missing_servers} servers out of {requested_keys} total keys for \ - {requested_servers} total servers." + "did not obtain {missing_keys} keys for {missing_servers} servers out of \ + {requested_keys} total keys for {requested_servers} total servers." ); } @@ -162,12 +168,15 @@ where #[implement(super::Service)] async fn acquire_origin( - &self, origin: OwnedServerName, mut key_ids: Vec, timeout: Instant, + &self, + origin: OwnedServerName, + mut key_ids: Vec, + timeout: Instant, ) -> (OwnedServerName, Vec) { match timeout_at(timeout, self.server_request(&origin)).await { - Err(e) => debug_warn!(?origin, "timed out: {e}"), - Ok(Err(e)) => debug_error!(?origin, "{e}"), - Ok(Ok(server_keys)) => { + | Err(e) => debug_warn!(?origin, "timed out: {e}"), + | Ok(Err(e)) => debug_error!(?origin, "{e}"), + | Ok(Ok(server_keys)) => { trace!( %origin, ?key_ids, @@ -192,19 +201,21 @@ where for notary in self.services.globals.trusted_servers() { let missing_keys = keys_count(&missing); let missing_servers = missing.len(); - debug!("Asking notary {notary} for {missing_keys} missing keys from {missing_servers} servers"); + debug!( + "Asking notary {notary} for {missing_keys} missing keys from {missing_servers} \ + servers" + ); let batch = missing .iter() .map(|(server, keys)| (server.borrow(), keys.iter().map(Borrow::borrow))); match self.batch_notary_request(notary, batch).await { - Err(e) => error!("Failed to contact notary {notary:?}: {e}"), - Ok(results) => { + | Err(e) => error!("Failed to contact notary {notary:?}: {e}"), + | Ok(results) => for server_keys in results { self.acquire_notary_result(&mut missing, server_keys).await; - } - }, + }, } } @@ -224,4 +235,6 @@ async fn acquire_notary_result(&self, missing: &mut Batch, server_keys: ServerSi } } -fn keys_count(batch: &Batch) -> usize { batch.iter().flat_map(|(_, key_ids)| key_ids.iter()).count() } +fn keys_count(batch: &Batch) -> usize { + batch.iter().flat_map(|(_, key_ids)| key_ids.iter()).count() +} diff --git a/src/service/server_keys/get.rs b/src/service/server_keys/get.rs index 94d2575a5..5a027d644 100644 --- a/src/service/server_keys/get.rs +++ b/src/service/server_keys/get.rs @@ -1,17 +1,25 @@ use std::borrow::Borrow; use conduwuit::{implement, Err, Result}; -use ruma::{api::federation::discovery::VerifyKey, CanonicalJsonObject, RoomVersionId, ServerName, ServerSigningKeyId}; +use ruma::{ + api::federation::discovery::VerifyKey, CanonicalJsonObject, RoomVersionId, ServerName, + ServerSigningKeyId, +}; use super::{extract_key, PubKeyMap, PubKeys}; #[implement(super::Service)] -pub async fn get_event_keys(&self, object: &CanonicalJsonObject, version: &RoomVersionId) -> Result { +pub async fn get_event_keys( + &self, + object: &CanonicalJsonObject, + version: &RoomVersionId, +) -> Result { use ruma::signatures::required_keys; let required = match required_keys(object, version) { - Ok(required) => required, - Err(e) => return Err!(BadServerResponse("Failed to determine keys required to verify: {e}")), + | Ok(required) => required, + | Err(e) => + return Err!(BadServerResponse("Failed to determine keys required to verify: {e}")), }; let batch = required @@ -52,7 +60,11 @@ where } #[implement(super::Service)] -pub async fn get_verify_key(&self, origin: &ServerName, key_id: &ServerSigningKeyId) -> Result { +pub async fn get_verify_key( + &self, + origin: &ServerName, + key_id: &ServerSigningKeyId, +) -> Result { let notary_first = self.services.server.config.query_trusted_key_servers_first; let notary_only = self.services.server.config.only_query_trusted_key_servers; @@ -86,7 +98,11 @@ pub async fn get_verify_key(&self, origin: &ServerName, key_id: &ServerSigningKe } #[implement(super::Service)] -async fn get_verify_key_from_notaries(&self, origin: &ServerName, key_id: &ServerSigningKeyId) -> Result { +async fn get_verify_key_from_notaries( + &self, + origin: &ServerName, + key_id: &ServerSigningKeyId, +) -> Result { for notary in self.services.globals.trusted_servers() { if let Ok(server_keys) = self.notary_request(notary, origin).await { for server_key in server_keys.clone() { @@ -105,7 +121,11 @@ async fn get_verify_key_from_notaries(&self, origin: &ServerName, key_id: &Serve } #[implement(super::Service)] -async fn get_verify_key_from_origin(&self, origin: &ServerName, key_id: &ServerSigningKeyId) -> Result { +async fn get_verify_key_from_origin( + &self, + origin: &ServerName, + key_id: &ServerSigningKeyId, +) -> Result { if let Ok(server_key) = self.server_request(origin).await { self.add_signing_keys(server_key.clone()).await; if let Some(result) = extract_key(server_key, key_id) { diff --git a/src/service/server_keys/keypair.rs b/src/service/server_keys/keypair.rs index 927171f3f..6f983c266 100644 --- a/src/service/server_keys/keypair.rs +++ b/src/service/server_keys/keypair.rs @@ -39,14 +39,15 @@ fn load(db: &Arc) -> Result> { create(db) })?; - let key = - Ed25519KeyPair::from_der(&key, version).map_err(|e| err!("Failed to load ed25519 keypair from der: {e:?}"))?; + let key = Ed25519KeyPair::from_der(&key, version) + .map_err(|e| err!("Failed to load ed25519 keypair from der: {e:?}"))?; Ok(Box::new(key)) } fn create(db: &Arc) -> Result<(String, Vec)> { - let keypair = Ed25519KeyPair::generate().map_err(|e| err!("Failed to generate new ed25519 keypair: {e:?}"))?; + let keypair = Ed25519KeyPair::generate() + .map_err(|e| err!("Failed to generate new ed25519 keypair: {e:?}"))?; let id = utils::rand::string(8); debug_info!("Generated new Ed25519 keypair: {id:?}"); diff --git a/src/service/server_keys/mod.rs b/src/service/server_keys/mod.rs index 45c01c0b4..3f6a30396 100644 --- a/src/service/server_keys/mod.rs +++ b/src/service/server_keys/mod.rs @@ -18,8 +18,8 @@ use ruma::{ api::federation::discovery::{ServerSigningKeys, VerifyKey}, serde::Raw, signatures::{Ed25519KeyPair, PublicKeyMap, PublicKeySet}, - CanonicalJsonObject, MilliSecondsSinceUnixEpoch, OwnedServerSigningKeyId, RoomVersionId, ServerName, - ServerSigningKeyId, + CanonicalJsonObject, MilliSecondsSinceUnixEpoch, OwnedServerSigningKeyId, RoomVersionId, + ServerName, ServerSigningKeyId, }; use serde_json::value::RawValue as RawJsonValue; @@ -113,7 +113,11 @@ async fn add_signing_keys(&self, new_keys: ServerSigningKeys) { } #[implement(Service)] -pub async fn required_keys_exist(&self, object: &CanonicalJsonObject, version: &RoomVersionId) -> bool { +pub async fn required_keys_exist( + &self, + object: &CanonicalJsonObject, + version: &RoomVersionId, +) -> bool { use ruma::signatures::required_keys; let Ok(required_keys) = required_keys(object, version) else { @@ -179,7 +183,8 @@ pub async fn signing_keys_for(&self, origin: &ServerName) -> Result MilliSecondsSinceUnixEpoch { - let timepoint = timepoint_from_now(self.minimum_valid).expect("SystemTime should not overflow"); + let timepoint = + timepoint_from_now(self.minimum_valid).expect("SystemTime should not overflow"); MilliSecondsSinceUnixEpoch::from_system_time(timepoint).expect("UInt should not overflow") } diff --git a/src/service/server_keys/request.rs b/src/service/server_keys/request.rs index da7fa08a4..afe8958b4 100644 --- a/src/service/server_keys/request.rs +++ b/src/service/server_keys/request.rs @@ -12,7 +12,9 @@ use ruma::{ #[implement(super::Service)] pub(super) async fn batch_notary_request<'a, S, K>( - &self, notary: &ServerName, batch: S, + &self, + notary: &ServerName, + batch: S, ) -> Result> where S: Iterator + Send, @@ -74,7 +76,9 @@ where #[implement(super::Service)] pub async fn notary_request( - &self, notary: &ServerName, target: &ServerName, + &self, + notary: &ServerName, + target: &ServerName, ) -> Result + Clone + Debug + Send> { use get_remote_server_keys::v2::Request; diff --git a/src/service/server_keys/sign.rs b/src/service/server_keys/sign.rs index 715653808..8d6f108c9 100644 --- a/src/service/server_keys/sign.rs +++ b/src/service/server_keys/sign.rs @@ -10,7 +10,11 @@ pub fn sign_json(&self, object: &mut CanonicalJsonObject) -> Result { } #[implement(super::Service)] -pub fn hash_and_sign_event(&self, object: &mut CanonicalJsonObject, room_version: &RoomVersionId) -> Result { +pub fn hash_and_sign_event( + &self, + object: &mut CanonicalJsonObject, + room_version: &RoomVersionId, +) -> Result { use ruma::signatures::hash_and_sign_event; let server_name = self.services.globals.server_name().as_str(); diff --git a/src/service/server_keys/verify.rs b/src/service/server_keys/verify.rs index d06b55ab7..0f03e59ea 100644 --- a/src/service/server_keys/verify.rs +++ b/src/service/server_keys/verify.rs @@ -1,14 +1,20 @@ use conduwuit::{implement, pdu::gen_event_id_canonical_json, Err, Result}; -use ruma::{signatures::Verified, CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId}; +use ruma::{ + signatures::Verified, CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId, +}; use serde_json::value::RawValue as RawJsonValue; #[implement(super::Service)] pub async fn validate_and_add_event_id( - &self, pdu: &RawJsonValue, room_version: &RoomVersionId, + &self, + pdu: &RawJsonValue, + room_version: &RoomVersionId, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version)?; if let Err(e) = self.verify_event(&value, Some(room_version)).await { - return Err!(BadServerResponse(debug_error!("Event {event_id} failed verification: {e:?}"))); + return Err!(BadServerResponse(debug_error!( + "Event {event_id} failed verification: {e:?}" + ))); } value.insert("event_id".into(), CanonicalJsonValue::String(event_id.as_str().into())); @@ -18,7 +24,9 @@ pub async fn validate_and_add_event_id( #[implement(super::Service)] pub async fn validate_and_add_event_id_no_fetch( - &self, pdu: &RawJsonValue, room_version: &RoomVersionId, + &self, + pdu: &RawJsonValue, + room_version: &RoomVersionId, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version)?; if !self.required_keys_exist(&value, room_version).await { @@ -28,7 +36,9 @@ pub async fn validate_and_add_event_id_no_fetch( } if let Err(e) = self.verify_event(&value, Some(room_version)).await { - return Err!(BadServerResponse(debug_error!("Event {event_id} failed verification: {e:?}"))); + return Err!(BadServerResponse(debug_error!( + "Event {event_id} failed verification: {e:?}" + ))); } value.insert("event_id".into(), CanonicalJsonValue::String(event_id.as_str().into())); @@ -38,7 +48,9 @@ pub async fn validate_and_add_event_id_no_fetch( #[implement(super::Service)] pub async fn verify_event( - &self, event: &CanonicalJsonObject, room_version: Option<&RoomVersionId>, + &self, + event: &CanonicalJsonObject, + room_version: Option<&RoomVersionId>, ) -> Result { let room_version = room_version.unwrap_or(&RoomVersionId::V11); let keys = self.get_event_keys(event, room_version).await?; @@ -46,7 +58,11 @@ pub async fn verify_event( } #[implement(super::Service)] -pub async fn verify_json(&self, event: &CanonicalJsonObject, room_version: Option<&RoomVersionId>) -> Result { +pub async fn verify_json( + &self, + event: &CanonicalJsonObject, + room_version: Option<&RoomVersionId>, +) -> Result { let room_version = room_version.unwrap_or(&RoomVersionId::V11); let keys = self.get_event_keys(event, room_version).await?; ruma::signatures::verify_json(&keys, event.clone()).map_err(Into::into) diff --git a/src/service/service.rs b/src/service/service.rs index 4b1774cc6..7adb189ea 100644 --- a/src/service/service.rs +++ b/src/service/service.rs @@ -114,7 +114,9 @@ impl<'a> Args<'a> { /// Create a reference immediately to a service when constructing another /// Service. The other service must be constructed. #[inline] - pub(crate) fn require(&'a self, name: &str) -> Arc { require::(self.service, name) } + pub(crate) fn require(&'a self, name: &str) -> Arc { + require::(self.service, name) + } } /// Reference a Service by name. Panics if the Service does not exist or was diff --git a/src/service/sync/mod.rs b/src/service/sync/mod.rs index a45232465..97f4ce9c3 100644 --- a/src/service/sync/mod.rs +++ b/src/service/sync/mod.rs @@ -47,7 +47,8 @@ struct Services { struct SlidingSyncCache { lists: BTreeMap, subscriptions: BTreeMap, - known_rooms: BTreeMap>, // For every room, the roomsince number + known_rooms: BTreeMap>, /* For every room, the + * roomsince number */ extensions: ExtensionsConfig, } @@ -85,14 +86,24 @@ impl crate::Service for Service { } impl Service { - pub fn remembered(&self, user_id: OwnedUserId, device_id: OwnedDeviceId, conn_id: String) -> bool { + pub fn remembered( + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, + conn_id: String, + ) -> bool { self.connections .lock() .unwrap() .contains_key(&(user_id, device_id, conn_id)) } - pub fn forget_sync_request_connection(&self, user_id: OwnedUserId, device_id: OwnedDeviceId, conn_id: String) { + pub fn forget_sync_request_connection( + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, + conn_id: String, + ) { self.connections .lock() .expect("locked") @@ -100,25 +111,26 @@ impl Service { } pub fn update_sync_request_with_cache( - &self, user_id: OwnedUserId, device_id: OwnedDeviceId, request: &mut sync_events::v4::Request, + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, + request: &mut sync_events::v4::Request, ) -> BTreeMap> { let Some(conn_id) = request.conn_id.clone() else { return BTreeMap::new(); }; let mut cache = self.connections.lock().expect("locked"); - let cached = Arc::clone( - cache - .entry((user_id, device_id, conn_id)) - .or_insert_with(|| { - Arc::new(Mutex::new(SlidingSyncCache { - lists: BTreeMap::new(), - subscriptions: BTreeMap::new(), - known_rooms: BTreeMap::new(), - extensions: ExtensionsConfig::default(), - })) - }), - ); + let cached = Arc::clone(cache.entry((user_id, device_id, conn_id)).or_insert_with( + || { + Arc::new(Mutex::new(SlidingSyncCache { + lists: BTreeMap::new(), + subscriptions: BTreeMap::new(), + known_rooms: BTreeMap::new(), + extensions: ExtensionsConfig::default(), + })) + }, + )); let cached = &mut cached.lock().expect("locked"); drop(cache); @@ -141,13 +153,15 @@ impl Service { .clone() .or_else(|| cached_list.include_old_rooms.clone()); match (&mut list.filters, cached_list.filters.clone()) { - (Some(list_filters), Some(cached_filters)) => { + | (Some(list_filters), Some(cached_filters)) => { list_filters.is_dm = list_filters.is_dm.or(cached_filters.is_dm); if list_filters.spaces.is_empty() { list_filters.spaces = cached_filters.spaces; } - list_filters.is_encrypted = list_filters.is_encrypted.or(cached_filters.is_encrypted); - list_filters.is_invite = list_filters.is_invite.or(cached_filters.is_invite); + list_filters.is_encrypted = + list_filters.is_encrypted.or(cached_filters.is_encrypted); + list_filters.is_invite = + list_filters.is_invite.or(cached_filters.is_invite); if list_filters.room_types.is_empty() { list_filters.room_types = cached_filters.room_types; } @@ -165,9 +179,9 @@ impl Service { list_filters.not_tags = cached_filters.not_tags; } }, - (_, Some(cached_filters)) => list.filters = Some(cached_filters), - (Some(list_filters), _) => list.filters = Some(list_filters.clone()), - (..) => {}, + | (_, Some(cached_filters)) => list.filters = Some(cached_filters), + | (Some(list_filters), _) => list.filters = Some(list_filters.clone()), + | (..) => {}, } if list.bump_event_types.is_empty() { list.bump_event_types @@ -220,22 +234,23 @@ impl Service { } pub fn update_sync_subscriptions( - &self, user_id: OwnedUserId, device_id: OwnedDeviceId, conn_id: String, + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, + conn_id: String, subscriptions: BTreeMap, ) { let mut cache = self.connections.lock().expect("locked"); - let cached = Arc::clone( - cache - .entry((user_id, device_id, conn_id)) - .or_insert_with(|| { - Arc::new(Mutex::new(SlidingSyncCache { - lists: BTreeMap::new(), - subscriptions: BTreeMap::new(), - known_rooms: BTreeMap::new(), - extensions: ExtensionsConfig::default(), - })) - }), - ); + let cached = Arc::clone(cache.entry((user_id, device_id, conn_id)).or_insert_with( + || { + Arc::new(Mutex::new(SlidingSyncCache { + lists: BTreeMap::new(), + subscriptions: BTreeMap::new(), + known_rooms: BTreeMap::new(), + extensions: ExtensionsConfig::default(), + })) + }, + )); let cached = &mut cached.lock().expect("locked"); drop(cache); @@ -243,22 +258,25 @@ impl Service { } pub fn update_sync_known_rooms( - &self, user_id: OwnedUserId, device_id: OwnedDeviceId, conn_id: String, list_id: String, - new_cached_rooms: BTreeSet, globalsince: u64, + &self, + user_id: OwnedUserId, + device_id: OwnedDeviceId, + conn_id: String, + list_id: String, + new_cached_rooms: BTreeSet, + globalsince: u64, ) { let mut cache = self.connections.lock().expect("locked"); - let cached = Arc::clone( - cache - .entry((user_id, device_id, conn_id)) - .or_insert_with(|| { - Arc::new(Mutex::new(SlidingSyncCache { - lists: BTreeMap::new(), - subscriptions: BTreeMap::new(), - known_rooms: BTreeMap::new(), - extensions: ExtensionsConfig::default(), - })) - }), - ); + let cached = Arc::clone(cache.entry((user_id, device_id, conn_id)).or_insert_with( + || { + Arc::new(Mutex::new(SlidingSyncCache { + lists: BTreeMap::new(), + subscriptions: BTreeMap::new(), + known_rooms: BTreeMap::new(), + extensions: ExtensionsConfig::default(), + })) + }, + )); let cached = &mut cached.lock().expect("locked"); drop(cache); diff --git a/src/service/transaction_ids/mod.rs b/src/service/transaction_ids/mod.rs index 2b979f996..912c0b49c 100644 --- a/src/service/transaction_ids/mod.rs +++ b/src/service/transaction_ids/mod.rs @@ -25,7 +25,13 @@ impl crate::Service for Service { } #[implement(Service)] -pub fn add_txnid(&self, user_id: &UserId, device_id: Option<&DeviceId>, txn_id: &TransactionId, data: &[u8]) { +pub fn add_txnid( + &self, + user_id: &UserId, + device_id: Option<&DeviceId>, + txn_id: &TransactionId, + data: &[u8], +) { let mut key = user_id.as_bytes().to_vec(); key.push(0xFF); key.extend_from_slice(device_id.map(DeviceId::as_bytes).unwrap_or_default()); @@ -38,7 +44,10 @@ pub fn add_txnid(&self, user_id: &UserId, device_id: Option<&DeviceId>, txn_id: // If there's no entry, this is a new transaction #[implement(Service)] pub async fn existing_txnid( - &self, user_id: &UserId, device_id: Option<&DeviceId>, txn_id: &TransactionId, + &self, + user_id: &UserId, + device_id: Option<&DeviceId>, + txn_id: &TransactionId, ) -> Result> { let key = (user_id, device_id, txn_id); self.db.userdevicetxnid_response.qry(&key).await diff --git a/src/service/uiaa/mod.rs b/src/service/uiaa/mod.rs index 4d30a612c..f7e552517 100644 --- a/src/service/uiaa/mod.rs +++ b/src/service/uiaa/mod.rs @@ -58,7 +58,13 @@ impl crate::Service for Service { /// Creates a new Uiaa session. Make sure the session token is unique. #[implement(Service)] -pub fn create(&self, user_id: &UserId, device_id: &DeviceId, uiaainfo: &UiaaInfo, json_body: &CanonicalJsonValue) { +pub fn create( + &self, + user_id: &UserId, + device_id: &DeviceId, + uiaainfo: &UiaaInfo, + json_body: &CanonicalJsonValue, +) { // TODO: better session error handling (why is uiaainfo.session optional in // ruma?) self.set_uiaa_request( @@ -78,7 +84,11 @@ pub fn create(&self, user_id: &UserId, device_id: &DeviceId, uiaainfo: &UiaaInfo #[implement(Service)] pub async fn try_auth( - &self, user_id: &UserId, device_id: &DeviceId, auth: &AuthData, uiaainfo: &UiaaInfo, + &self, + user_id: &UserId, + device_id: &DeviceId, + auth: &AuthData, + uiaainfo: &UiaaInfo, ) -> Result<(bool, UiaaInfo)> { let mut uiaainfo = if let Some(session) = auth.session() { self.get_uiaa_session(user_id, device_id, session).await? @@ -92,7 +102,7 @@ pub async fn try_auth( match auth { // Find out what the user completed - AuthData::Password(Password { + | AuthData::Password(Password { identifier, password, #[cfg(feature = "element_hacks")] @@ -105,17 +115,26 @@ pub async fn try_auth( } else if let Some(username) = user { username } else { - return Err(Error::BadRequest(ErrorKind::Unrecognized, "Identifier type not recognized.")); + return Err(Error::BadRequest( + ErrorKind::Unrecognized, + "Identifier type not recognized.", + )); }; #[cfg(not(feature = "element_hacks"))] let Some(UserIdentifier::UserIdOrLocalpart(username)) = identifier else { - return Err(Error::BadRequest(ErrorKind::Unrecognized, "Identifier type not recognized.")); + return Err(Error::BadRequest( + ErrorKind::Unrecognized, + "Identifier type not recognized.", + )); }; - let user_id = UserId::parse_with_server_name(username.clone(), self.services.globals.server_name()) - .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "User ID is invalid."))?; + let user_id = UserId::parse_with_server_name( + username.clone(), + self.services.globals.server_name(), + ) + .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "User ID is invalid."))?; // Check if password is correct if let Ok(hash) = self.services.users.password_hash(&user_id).await { @@ -132,7 +151,7 @@ pub async fn try_auth( // Password was correct! Let's add it to `completed` uiaainfo.completed.push(AuthType::Password); }, - AuthData::RegistrationToken(t) => { + | AuthData::RegistrationToken(t) => { if self .services .globals @@ -149,10 +168,10 @@ pub async fn try_auth( return Ok((false, uiaainfo)); } }, - AuthData::Dummy(_) => { + | AuthData::Dummy(_) => { uiaainfo.completed.push(AuthType::Dummy); }, - k => error!("type not supported: {:?}", k), + | k => error!("type not supported: {:?}", k), } // Check if a flow now succeeds @@ -190,7 +209,13 @@ pub async fn try_auth( } #[implement(Service)] -fn set_uiaa_request(&self, user_id: &UserId, device_id: &DeviceId, session: &str, request: &CanonicalJsonValue) { +fn set_uiaa_request( + &self, + user_id: &UserId, + device_id: &DeviceId, + session: &str, + request: &CanonicalJsonValue, +) { let key = (user_id.to_owned(), device_id.to_owned(), session.to_owned()); self.userdevicesessionid_uiaarequest .write() @@ -200,7 +225,10 @@ fn set_uiaa_request(&self, user_id: &UserId, device_id: &DeviceId, session: &str #[implement(Service)] pub fn get_uiaa_request( - &self, user_id: &UserId, device_id: Option<&DeviceId>, session: &str, + &self, + user_id: &UserId, + device_id: Option<&DeviceId>, + session: &str, ) -> Option { let key = ( user_id.to_owned(), @@ -216,7 +244,13 @@ pub fn get_uiaa_request( } #[implement(Service)] -fn update_uiaa_session(&self, user_id: &UserId, device_id: &DeviceId, session: &str, uiaainfo: Option<&UiaaInfo>) { +fn update_uiaa_session( + &self, + user_id: &UserId, + device_id: &DeviceId, + session: &str, + uiaainfo: Option<&UiaaInfo>, +) { let key = (user_id, device_id, session); if let Some(uiaainfo) = uiaainfo { @@ -229,7 +263,12 @@ fn update_uiaa_session(&self, user_id: &UserId, device_id: &DeviceId, session: & } #[implement(Service)] -async fn get_uiaa_session(&self, user_id: &UserId, device_id: &DeviceId, session: &str) -> Result { +async fn get_uiaa_session( + &self, + user_id: &UserId, + device_id: &DeviceId, + session: &str, +) -> Result { let key = (user_id, device_id, session); self.db .userdevicesessionid_uiaainfo diff --git a/src/service/updates/mod.rs b/src/service/updates/mod.rs index 1d13337d6..1f499692f 100644 --- a/src/service/updates/mod.rs +++ b/src/service/updates/mod.rs @@ -119,7 +119,8 @@ impl Service { self.services .admin .send_message(RoomMessageEventContent::text_markdown(format!( - "### the following is a message from the conduwuit puppy\n\nit was sent on `{}`:\n\n@room: {}", + "### the following is a message from the conduwuit puppy\n\nit was sent on \ + `{}`:\n\n@room: {}", update.date, update.message ))) .await @@ -127,7 +128,9 @@ impl Service { } #[inline] - pub fn update_check_for_updates_id(&self, id: u64) { self.db.raw_put(LAST_CHECK_FOR_UPDATES_COUNT, id); } + pub fn update_check_for_updates_id(&self, id: u64) { + self.db.raw_put(LAST_CHECK_FOR_UPDATES_COUNT, id); + } pub async fn last_check_for_updates_id(&self) -> u64 { self.db diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index 8ceec2a01..1d7f42486 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -10,10 +10,12 @@ use futures::{FutureExt, Stream, StreamExt, TryFutureExt}; use ruma::{ api::client::{device::Device, error::ErrorKind, filter::FilterDefinition}, encryption::{CrossSigningKey, DeviceKeys, OneTimeKey}, - events::{ignored_user_list::IgnoredUserListEvent, AnyToDeviceEvent, GlobalAccountDataEventType}, + events::{ + ignored_user_list::IgnoredUserListEvent, AnyToDeviceEvent, GlobalAccountDataEventType, + }, serde::Raw, - DeviceId, KeyId, MilliSecondsSinceUnixEpoch, OneTimeKeyAlgorithm, OneTimeKeyId, OneTimeKeyName, OwnedDeviceId, - OwnedKeyId, OwnedMxcUri, OwnedUserId, RoomId, UInt, UserId, + DeviceId, KeyId, MilliSecondsSinceUnixEpoch, OneTimeKeyAlgorithm, OneTimeKeyId, + OneTimeKeyName, OwnedDeviceId, OwnedKeyId, OwnedMxcUri, OwnedUserId, RoomId, UInt, UserId, }; use serde_json::json; @@ -65,7 +67,8 @@ impl crate::Service for Service { account_data: args.depend::("account_data"), admin: args.depend::("admin"), globals: args.depend::("globals"), - state_accessor: args.depend::("rooms::state_accessor"), + state_accessor: args + .depend::("rooms::state_accessor"), state_cache: args.depend::("rooms::state_cache"), }, db: Data { @@ -114,7 +117,9 @@ impl Service { /// Check if a user is an admin #[inline] - pub async fn is_admin(&self, user_id: &UserId) -> bool { self.services.admin.user_is_admin(user_id).await } + pub async fn is_admin(&self, user_id: &UserId) -> bool { + self.services.admin.user_is_admin(user_id).await + } /// Create a new user account on this homeserver. #[inline] @@ -141,7 +146,9 @@ impl Service { /// Check if a user has an account on this homeserver. #[inline] - pub async fn exists(&self, user_id: &UserId) -> bool { self.db.userid_password.get(user_id).await.is_ok() } + pub async fn exists(&self, user_id: &UserId) -> bool { + self.db.userid_password.get(user_id).await.is_ok() + } /// Check if account is deactivated pub async fn is_deactivated(&self, user_id: &UserId) -> Result { @@ -154,7 +161,9 @@ impl Service { } /// Check if account is active, infallible - pub async fn is_active(&self, user_id: &UserId) -> bool { !self.is_deactivated(user_id).await.unwrap_or(true) } + pub async fn is_active(&self, user_id: &UserId) -> bool { + !self.is_deactivated(user_id).await.unwrap_or(true) + } /// Check if account is active, infallible pub async fn is_active_local(&self, user_id: &UserId) -> bool { @@ -173,10 +182,14 @@ impl Service { /// Returns an iterator over all users on this homeserver (offered for /// compatibility) #[allow(clippy::iter_without_into_iter, clippy::iter_not_returning_iterator)] - pub fn iter(&self) -> impl Stream + Send + '_ { self.stream().map(ToOwned::to_owned) } + pub fn iter(&self) -> impl Stream + Send + '_ { + self.stream().map(ToOwned::to_owned) + } /// Returns an iterator over all users on this homeserver. - pub fn stream(&self) -> impl Stream + Send { self.db.userid_password.keys().ignore_err() } + pub fn stream(&self) -> impl Stream + Send { + self.db.userid_password.keys().ignore_err() + } /// Returns a list of local users as list of usernames. /// @@ -200,7 +213,9 @@ impl Service { password .map(utils::hash::password) .transpose() - .map_err(|e| err!(Request(InvalidParam("Password does not meet the requirements: {e}"))))? + .map_err(|e| { + err!(Request(InvalidParam("Password does not meet the requirements: {e}"))) + })? .map_or_else( || self.db.userid_password.insert(user_id, b""), |hash| self.db.userid_password.insert(user_id, hash), @@ -254,13 +269,19 @@ impl Service { /// Adds a new device to a user. pub async fn create_device( - &self, user_id: &UserId, device_id: &DeviceId, token: &str, initial_device_display_name: Option, + &self, + user_id: &UserId, + device_id: &DeviceId, + token: &str, + initial_device_display_name: Option, client_ip: Option, ) -> Result<()> { // This method should never be called for nonexistent users. We shouldn't assert // though... if !self.exists(user_id).await { - return Err!(Request(InvalidParam(error!("Called create_device for non-existent {user_id}")))); + return Err!(Request(InvalidParam(error!( + "Called create_device for non-existent {user_id}" + )))); } let key = (user_id, device_id); @@ -304,7 +325,10 @@ impl Service { } /// Returns an iterator over all device ids of this user. - pub fn all_device_ids<'a>(&'a self, user_id: &'a UserId) -> impl Stream + Send + 'a { + pub fn all_device_ids<'a>( + &'a self, + user_id: &'a UserId, + ) -> impl Stream + Send + 'a { let prefix = (user_id, Interfix); self.db .userdeviceid_metadata @@ -319,7 +343,12 @@ impl Service { } /// Replaces the access token of one device. - pub async fn set_token(&self, user_id: &UserId, device_id: &DeviceId, token: &str) -> Result<()> { + pub async fn set_token( + &self, + user_id: &UserId, + device_id: &DeviceId, + token: &str, + ) -> Result<()> { let key = (user_id, device_id); // should not be None, but we shouldn't assert either lol... if self.db.userdeviceid_metadata.qry(&key).await.is_err() { @@ -344,7 +373,10 @@ impl Service { } pub async fn add_one_time_key( - &self, user_id: &UserId, device_id: &DeviceId, one_time_key_key: &KeyId, + &self, + user_id: &UserId, + device_id: &DeviceId, + one_time_key_key: &KeyId, one_time_key_value: &Raw, ) -> Result { // All devices have metadata @@ -391,7 +423,10 @@ impl Service { } pub async fn take_one_time_key( - &self, user_id: &UserId, device_id: &DeviceId, key_algorithm: &OneTimeKeyAlgorithm, + &self, + user_id: &UserId, + device_id: &DeviceId, + key_algorithm: &OneTimeKeyAlgorithm, ) -> Result<(OwnedKeyId, Raw)> { let count = self.services.globals.next_count()?.to_be_bytes(); self.db.userid_lastonetimekeyupdate.insert(user_id, count); @@ -435,7 +470,9 @@ impl Service { } pub async fn count_one_time_keys( - &self, user_id: &UserId, device_id: &DeviceId, + &self, + user_id: &UserId, + device_id: &DeviceId, ) -> BTreeMap { type KeyVal<'a> = ((Ignore, Ignore, &'a Unquoted), Ignore); @@ -462,7 +499,12 @@ impl Service { algorithm_counts } - pub async fn add_device_keys(&self, user_id: &UserId, device_id: &DeviceId, device_keys: &Raw) { + pub async fn add_device_keys( + &self, + user_id: &UserId, + device_id: &DeviceId, + device_keys: &Raw, + ) { let key = (user_id, device_id); self.db.keyid_key.put(key, Json(device_keys)); @@ -470,8 +512,12 @@ impl Service { } pub async fn add_cross_signing_keys( - &self, user_id: &UserId, master_key: &Raw, self_signing_key: &Option>, - user_signing_key: &Option>, notify: bool, + &self, + user_id: &UserId, + master_key: &Raw, + self_signing_key: &Option>, + user_signing_key: &Option>, + notify: bool, ) -> Result<()> { // TODO: Check signatures let mut prefix = user_id.as_bytes().to_vec(); @@ -495,9 +541,10 @@ impl Service { .keys .into_values(); - let self_signing_key_id = self_signing_key_ids - .next() - .ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Self signing key contained no key."))?; + let self_signing_key_id = self_signing_key_ids.next().ok_or(Error::BadRequest( + ErrorKind::InvalidParam, + "Self signing key contained no key.", + ))?; if self_signing_key_ids.next().is_some() { return Err(Error::BadRequest( @@ -531,7 +578,9 @@ impl Service { .ok_or(err!(Request(InvalidParam("User signing key contained no key."))))?; if user_signing_key_ids.next().is_some() { - return Err!(Request(InvalidParam("User signing key contained more than one key."))); + return Err!(Request(InvalidParam( + "User signing key contained more than one key." + ))); } let mut user_signing_key_key = prefix; @@ -554,7 +603,11 @@ impl Service { } pub async fn sign_key( - &self, target_id: &UserId, key_id: &str, signature: (String, String), sender_id: &UserId, + &self, + target_id: &UserId, + key_id: &str, + signature: (String, String), + sender_id: &UserId, ) -> Result<()> { let key = (target_id, key_id); @@ -590,7 +643,10 @@ impl Service { #[inline] pub fn keys_changed<'a>( - &'a self, user_id: &'a UserId, from: u64, to: Option, + &'a self, + user_id: &'a UserId, + from: u64, + to: Option, ) -> impl Stream + Send + 'a { self.keys_changed_user_or_room(user_id.as_str(), from, to) .map(|(user_id, ..)| user_id) @@ -598,13 +654,19 @@ impl Service { #[inline] pub fn room_keys_changed<'a>( - &'a self, room_id: &'a RoomId, from: u64, to: Option, + &'a self, + room_id: &'a RoomId, + from: u64, + to: Option, ) -> impl Stream + Send + 'a { self.keys_changed_user_or_room(room_id.as_str(), from, to) } fn keys_changed_user_or_room<'a>( - &'a self, user_or_room_id: &'a str, from: u64, to: Option, + &'a self, + user_or_room_id: &'a str, + from: u64, + to: Option, ) -> impl Stream + Send + 'a { type KeyVal<'a> = ((&'a str, u64), &'a UserId); @@ -614,7 +676,9 @@ impl Service { .keychangeid_userid .stream_from(&start) .ignore_err() - .ready_take_while(move |((prefix, count), _): &KeyVal<'_>| *prefix == user_or_room_id && *count <= to) + .ready_take_while(move |((prefix, count), _): &KeyVal<'_>| { + *prefix == user_or_room_id && *count <= to + }) .map(|((_, count), user_id): KeyVal<'_>| (user_id, count)) } @@ -636,13 +700,21 @@ impl Service { self.db.keychangeid_userid.put_raw(key, user_id); } - pub async fn get_device_keys<'a>(&'a self, user_id: &'a UserId, device_id: &DeviceId) -> Result> { + pub async fn get_device_keys<'a>( + &'a self, + user_id: &'a UserId, + device_id: &DeviceId, + ) -> Result> { let key_id = (user_id, device_id); self.db.keyid_key.qry(&key_id).await.deserialized() } pub async fn get_key( - &self, key_id: &[u8], sender_user: Option<&UserId>, user_id: &UserId, allowed_signatures: &F, + &self, + key_id: &[u8], + sender_user: Option<&UserId>, + user_id: &UserId, + allowed_signatures: &F, ) -> Result> where F: Fn(&UserId) -> bool + Send + Sync, @@ -655,7 +727,10 @@ impl Service { } pub async fn get_master_key( - &self, sender_user: Option<&UserId>, user_id: &UserId, allowed_signatures: &F, + &self, + sender_user: Option<&UserId>, + user_id: &UserId, + allowed_signatures: &F, ) -> Result> where F: Fn(&UserId) -> bool + Send + Sync, @@ -667,7 +742,10 @@ impl Service { } pub async fn get_self_signing_key( - &self, sender_user: Option<&UserId>, user_id: &UserId, allowed_signatures: &F, + &self, + sender_user: Option<&UserId>, + user_id: &UserId, + allowed_signatures: &F, ) -> Result> where F: Fn(&UserId) -> bool + Send + Sync, @@ -688,7 +766,11 @@ impl Service { } pub async fn add_to_device_event( - &self, sender: &UserId, target_user_id: &UserId, target_device_id: &DeviceId, event_type: &str, + &self, + sender: &UserId, + target_user_id: &UserId, + target_device_id: &DeviceId, + event_type: &str, content: serde_json::Value, ) { let count = self.services.globals.next_count().unwrap(); @@ -705,7 +787,9 @@ impl Service { } pub fn get_to_device_events<'a>( - &'a self, user_id: &'a UserId, device_id: &'a DeviceId, + &'a self, + user_id: &'a UserId, + device_id: &'a DeviceId, ) -> impl Stream> + Send + 'a { let prefix = (user_id, device_id, Interfix); self.db @@ -715,7 +799,12 @@ impl Service { .map(|(_, val): (Ignore, Raw)| val) } - pub async fn remove_to_device_events(&self, user_id: &UserId, device_id: &DeviceId, until: u64) { + pub async fn remove_to_device_events( + &self, + user_id: &UserId, + device_id: &DeviceId, + until: u64, + ) { let mut prefix = user_id.as_bytes().to_vec(); prefix.push(0xFF); prefix.extend_from_slice(device_id.as_bytes()); @@ -742,7 +831,12 @@ impl Service { .await; } - pub async fn update_device_metadata(&self, user_id: &UserId, device_id: &DeviceId, device: &Device) -> Result<()> { + pub async fn update_device_metadata( + &self, + user_id: &UserId, + device_id: &DeviceId, + device: &Device, + ) -> Result<()> { increment(&self.db.userid_devicelistversion, user_id.as_bytes()); let key = (user_id, device_id); @@ -752,7 +846,11 @@ impl Service { } /// Get device metadata. - pub async fn get_device_metadata(&self, user_id: &UserId, device_id: &DeviceId) -> Result { + pub async fn get_device_metadata( + &self, + user_id: &UserId, + device_id: &DeviceId, + ) -> Result { self.db .userdeviceid_metadata .qry(&(user_id, device_id)) @@ -768,7 +866,10 @@ impl Service { .deserialized() } - pub fn all_devices_metadata<'a>(&'a self, user_id: &'a UserId) -> impl Stream + Send + 'a { + pub fn all_devices_metadata<'a>( + &'a self, + user_id: &'a UserId, + ) -> impl Stream + Send + 'a { let key = (user_id, Interfix); self.db .userdeviceid_metadata @@ -787,7 +888,11 @@ impl Service { filter_id } - pub async fn get_filter(&self, user_id: &UserId, filter_id: &str) -> Result { + pub async fn get_filter( + &self, + user_id: &UserId, + filter_id: &str, + ) -> Result { let key = (user_id, filter_id); self.db.userfilterid_filter.qry(&key).await.deserialized() } @@ -817,11 +922,10 @@ impl Service { }; let (expires_at_bytes, user_bytes) = value.split_at(0_u64.to_be_bytes().len()); - let expires_at = u64::from_be_bytes( - expires_at_bytes - .try_into() - .map_err(|e| err!(Database("expires_at in openid_userid is invalid u64. {e}")))?, - ); + let expires_at = + u64::from_be_bytes(expires_at_bytes.try_into().map_err(|e| { + err!(Database("expires_at in openid_userid is invalid u64. {e}")) + })?); if expires_at < utils::millis_since_unix_epoch() { debug_warn!("OpenID token is expired, removing"); @@ -833,11 +937,16 @@ impl Service { let user_string = utils::string_from_bytes(user_bytes) .map_err(|e| err!(Database("User ID in openid_userid is invalid unicode. {e}")))?; - UserId::parse(user_string).map_err(|e| err!(Database("User ID in openid_userid is invalid. {e}"))) + UserId::parse(user_string) + .map_err(|e| err!(Database("User ID in openid_userid is invalid. {e}"))) } /// Gets a specific user profile key - pub async fn profile_key(&self, user_id: &UserId, profile_key: &str) -> Result { + pub async fn profile_key( + &self, + user_id: &UserId, + profile_key: &str, + ) -> Result { let key = (user_id, profile_key); self.db .useridprofilekey_value @@ -848,7 +957,8 @@ impl Service { /// Gets all the user's profile keys and values in an iterator pub fn all_profile_keys<'a>( - &'a self, user_id: &'a UserId, + &'a self, + user_id: &'a UserId, ) -> impl Stream + 'a + Send { type KeyVal = ((Ignore, String), serde_json::Value); @@ -861,7 +971,12 @@ impl Service { } /// Sets a new profile key value, removes the key if value is None - pub fn set_profile_key(&self, user_id: &UserId, profile_key: &str, profile_key_value: Option) { + pub fn set_profile_key( + &self, + user_id: &UserId, + profile_key: &str, + profile_key_value: Option, + ) { // TODO: insert to the stable MSC4175 key when it's stable let key = (user_id, profile_key); @@ -901,7 +1016,10 @@ impl Service { } } -pub fn parse_master_key(user_id: &UserId, master_key: &Raw) -> Result<(Vec, CrossSigningKey)> { +pub fn parse_master_key( + user_id: &UserId, + master_key: &Raw, +) -> Result<(Vec, CrossSigningKey)> { let mut prefix = user_id.as_bytes().to_vec(); prefix.push(0xFF); @@ -925,7 +1043,10 @@ pub fn parse_master_key(user_id: &UserId, master_key: &Raw) -> /// Ensure that a user only sees signatures from themselves and the target user fn clean_signatures( - mut cross_signing_key: serde_json::Value, sender_user: Option<&UserId>, user_id: &UserId, allowed_signatures: &F, + mut cross_signing_key: serde_json::Value, + sender_user: Option<&UserId>, + user_id: &UserId, + allowed_signatures: &F, ) -> Result where F: Fn(&UserId) -> bool + Send + Sync, @@ -937,9 +1058,11 @@ where // Don't allocate for the full size of the current signatures, but require // at most one resize if nothing is dropped let new_capacity = signatures.len() / 2; - for (user, signature) in mem::replace(signatures, serde_json::Map::with_capacity(new_capacity)) { - let sid = - <&UserId>::try_from(user.as_str()).map_err(|_| Error::bad_database("Invalid user ID in database."))?; + for (user, signature) in + mem::replace(signatures, serde_json::Map::with_capacity(new_capacity)) + { + let sid = <&UserId>::try_from(user.as_str()) + .map_err(|_| Error::bad_database("Invalid user ID in database."))?; if sender_user == Some(user_id) || sid == user_id || allowed_signatures(sid) { signatures.insert(user, signature); }