diff --git a/src/database/key_value/rooms/alias.rs b/src/database/key_value/rooms/alias.rs index 073e7c41..0114d322 100644 --- a/src/database/key_value/rooms/alias.rs +++ b/src/database/key_value/rooms/alias.rs @@ -75,18 +75,28 @@ impl service::rooms::alias::Data for KeyValueDatabase { }) .transpose() } - - fn all_local_aliases<'a>(&'a self) -> Box> + 'a> { - Box::new(self.alias_roomid.iter().map(|(room_alias_bytes, room_id_bytes)| { - let room_alias_localpart = utils::string_from_bytes(&room_alias_bytes) - .map_err(|_| Error::bad_database("Invalid alias bytes in aliasid_alias."))?; - let room_id = utils::string_from_bytes(&room_id_bytes) - .map_err(|_| Error::bad_database("Invalid room_id bytes in aliasid_alias."))? - .try_into() - .map_err(|_| Error::bad_database("Invalid room_id in aliasid_alias."))?; + fn all_local_aliases<'a>( + &'a self, + ) -> Box> + 'a> { + Box::new( + self.alias_roomid + .iter() + .map(|(room_alias_bytes, room_id_bytes)| { + let room_alias_localpart = utils::string_from_bytes(&room_alias_bytes) + .map_err(|_| { + Error::bad_database("Invalid alias bytes in aliasid_alias.") + })?; - Ok((room_id, room_alias_localpart)) - })) + let room_id = utils::string_from_bytes(&room_id_bytes) + .map_err(|_| { + Error::bad_database("Invalid room_id bytes in aliasid_alias.") + })? + .try_into() + .map_err(|_| Error::bad_database("Invalid room_id in aliasid_alias."))?; + + Ok((room_id, room_alias_localpart)) + }), + ) } } diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index c18b89e9..4031a70b 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -3,7 +3,9 @@ use std::{collections::BTreeMap, convert::TryFrom, sync::Arc, time::Instant}; use clap::{Parser, Subcommand}; use regex::Regex; use ruma::{ - api::appservice::Registration, events::{ + api::appservice::Registration, + events::{ + relation::InReplyTo, room::{ canonical_alias::RoomCanonicalAliasEventContent, create::RoomCreateEventContent, @@ -11,15 +13,15 @@ use ruma::{ history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent}, join_rules::{JoinRule, RoomJoinRulesEventContent}, member::{MembershipState, RoomMemberEventContent}, - message::{RoomMessageEventContent, Relation::Reply}, + message::{Relation::Reply, RoomMessageEventContent}, name::RoomNameEventContent, power_levels::RoomPowerLevelsEventContent, topic::RoomTopicEventContent, }, - TimelineEventType, relation::InReplyTo, + TimelineEventType, }, - MilliSecondsSinceUnixEpoch, EventId, OwnedRoomAliasId, RoomAliasId, - RoomId, OwnedRoomId, RoomVersionId, ServerName, UserId, OwnedUserId, + EventId, MilliSecondsSinceUnixEpoch, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, + RoomId, RoomVersionId, ServerName, UserId, }; use serde_json::value::to_raw_value; use tokio::sync::{mpsc, Mutex, RwLock}; @@ -43,23 +45,23 @@ enum AdminCommand { #[command(subcommand)] /// Commands for managing appservices Appservice(AppserviceCommand), - + #[command(subcommand)] /// Commands for managing local users User(UserCommand), - + #[command(subcommand)] /// Commands for managing rooms Room(RoomCommand), - + #[command(subcommand)] /// Commands for managing federation Federation(FederationCommand), - + #[command(subcommand)] /// Commands for managing the server Server(ServerCommand), - + #[command(subcommand)] // TODO: should i split out debug commands to a separate thing? the // debug commands seem like they could fit in the other categories fine @@ -129,7 +131,7 @@ enum UserCommand { /// /// User will not be removed from all rooms by default. /// Use --leave-rooms to force the user to leave all rooms - Deactivate{ + Deactivate { #[arg(short, long)] leave_rooms: bool, user_id: Box, @@ -157,7 +159,7 @@ enum UserCommand { /// Also deactivate admin accounts force: bool, }, - + /// List local users in the database List, } @@ -166,9 +168,7 @@ enum UserCommand { #[derive(Subcommand)] enum RoomCommand { /// List all rooms the server knows about - List { - page: Option, - }, + List { page: Option }, #[command(subcommand)] /// Manage rooms' aliases @@ -187,20 +187,20 @@ enum RoomAliasCommand { #[arg(short, long)] /// Set the alias even if a room is already using it force: bool, - + /// The room id to set the alias on room_id: Box, - + /// The alias localpart to use (`alias`, not `#alias:servername.tld`) room_alias_localpart: Box, }, - + /// Remove an alias Remove { /// The alias localpart to remove (`alias`, not `#alias:servername.tld`) room_alias_localpart: Box, }, - + /// Show which room is using an alias Which { /// The alias localpart to look up (`alias`, not `#alias:servername.tld`) @@ -222,7 +222,7 @@ enum RoomDirectoryCommand { /// The room id of the room to publish room_id: Box, }, - + /// Unpublish a room to the room directory Unpublish { /// The room id of the room to unpublish @@ -231,9 +231,7 @@ enum RoomDirectoryCommand { /// List rooms that are published // TODO: is this really necessary? - List { - page: Option, - }, + List { page: Option }, } #[cfg_attr(test, derive(Debug))] @@ -241,13 +239,13 @@ enum RoomDirectoryCommand { enum FederationCommand { /// List all rooms we are currently handling an incoming pdu from IncomingFederation, - + /// Disables incoming federation handling for a room. DisableRoom { room_id: Box }, - + /// Enables incoming federation handling for a room again. EnableRoom { room_id: Box }, - + #[command(verbatim_doc_comment)] /// Verify json signatures /// [commandbody] @@ -298,7 +296,7 @@ enum DebugCommand { enum ServerCommand { /// Show configuration values ShowConfig, - + /// Print database memory usage statistics MemoryUsage, @@ -366,7 +364,7 @@ impl Service { if let Some(reply) = reply { message_content.relates_to = Some(Reply { in_reply_to: InReplyTo { event_id: reply.into() } }) } - + services() .rooms .timeline @@ -394,9 +392,18 @@ impl Service { } } - pub fn process_message(&self, room_message: String, event_id: Arc, sender: OwnedUserId) { + pub fn process_message( + &self, + room_message: String, + event_id: Arc, + sender: OwnedUserId, + ) { self.sender - .send(AdminRoomEvent::ProcessMessage(room_message, event_id, sender)) + .send(AdminRoomEvent::ProcessMessage( + room_message, + event_id, + sender, + )) .unwrap(); } @@ -407,7 +414,11 @@ impl Service { } // Parse and process a message from the admin room - async fn process_admin_message(&self, room_message: String, sender: &UserId) -> RoomMessageEventContent { + async fn process_admin_message( + &self, + room_message: String, + sender: &UserId, + ) -> RoomMessageEventContent { let mut lines = room_message.lines().filter(|l| !l.trim().is_empty()); let command_line = lines.next().expect("each string has at least one line"); let body: Vec<_> = lines.collect(); @@ -423,7 +434,10 @@ impl Service { } }; - match self.process_admin_command(admin_command, body, sender).await { + match self + .process_admin_command(admin_command, body, sender) + .await + { Ok(reply_message) => reply_message, Err(error) => { let markdown_message = format!( @@ -471,13 +485,16 @@ impl Service { let reply_message_content = match command { AdminCommand::Appservice(command) => match command { AppserviceCommand::Register => { - if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" + if body.len() > 2 + && body[0].trim().starts_with("```") + && body.last().unwrap().trim() == "```" { let appservice_config = body[1..body.len() - 1].join("\n"); let parsed_config = serde_yaml::from_str::(&appservice_config); match parsed_config { - Ok(yaml) => match services().appservice.register_appservice(yaml).await { + Ok(yaml) => match services().appservice.register_appservice(yaml).await + { Ok(id) => RoomMessageEventContent::text_plain(format!( "Appservice registered with ID: {id}." )), @@ -507,18 +524,20 @@ impl Service { "Failed to unregister appservice: {e}" )), }, - AppserviceCommand::Show { appservice_identifier } => { + AppserviceCommand::Show { + appservice_identifier, + } => { match services() .appservice .get_registration(&appservice_identifier) - .await { + .await + { Some(registration) => { let config_str = serde_yaml::to_string(®istration) .expect("config should've been validated on register"); let output = format!( "Config for {}:\n\n```yaml\n{}\n```", - appservice_identifier, - config_str, + appservice_identifier, config_str, ); let output_html = format!( "Config for {}:\n\n
{}
", @@ -526,28 +545,22 @@ impl Service { escape_html(&config_str), ); RoomMessageEventContent::text_html(output, output_html) - }, + } None => RoomMessageEventContent::text_plain("Appservice does not exist."), } } AppserviceCommand::List => { - let appservices = services() - .appservice - .iter_ids() - .await; + let appservices = services().appservice.iter_ids().await; let count = appservices.len(); - let output = format!( - "Appservices ({}): {}", - count, - appservices.join(", ") - ); + let output = format!("Appservices ({}): {}", count, appservices.join(", ")); RoomMessageEventContent::text_plain(output) } - } + }, AdminCommand::User(command) => match command { UserCommand::List => match services().users.list_local_users() { Ok(users) => { - let mut msg: String = format!("Found {} local user account(s):\n", users.len()); + let mut msg: String = + format!("Found {} local user account(s):\n", users.len()); msg += &users.join("\n"); RoomMessageEventContent::text_plain(&msg) } @@ -615,7 +628,10 @@ impl Service { "Created user with user_id: {user_id} and password: {password}" )) } - UserCommand::Deactivate { leave_rooms, user_id } => { + UserCommand::Deactivate { + leave_rooms, + user_id, + } => { let user_id = Arc::::from(user_id); if services().users.exists(&user_id)? { RoomMessageEventContent::text_plain(format!( @@ -677,9 +693,11 @@ impl Service { "Couldn't reset the password for user {user_id}: {e}" )), } - }, + } UserCommand::DeactivateAll { leave_rooms, force } => { - if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" + if body.len() > 2 + && body[0].trim().starts_with("```") + && body.last().unwrap().trim() == "```" { let usernames = body.clone().drain(1..body.len() - 1).collect::>(); @@ -736,37 +754,57 @@ impl Service { "Expected code block in command body. Add --help for details.", ) } - }, - } + } + }, AdminCommand::Room(command) => match command { RoomCommand::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 = services().rooms.metadata.iter_ids() + let mut rooms = services() + .rooms + .metadata + .iter_ids() .filter_map(|r| r.ok()) - .map(|id| ( - id.clone(), - services().rooms.state_cache.room_joined_count(&id).ok().flatten().unwrap_or(0), - services().rooms.state_accessor.get_name(&id).ok().flatten().unwrap_or(id.to_string()), - )) + .map(|id| { + ( + id.clone(), + services() + .rooms + .state_cache + .room_joined_count(&id) + .ok() + .flatten() + .unwrap_or(0), + services() + .rooms + .state_accessor + .get_name(&id) + .ok() + .flatten() + .unwrap_or(id.to_string()), + ) + }) .collect::>(); rooms.sort_by_key(|r| r.1); rooms.reverse(); - let rooms: Vec<_> = rooms.into_iter() + let rooms: Vec<_> = rooms + .into_iter() .skip(page.saturating_sub(1) * PAGE_SIZE) .take(PAGE_SIZE) .collect(); - + if rooms.is_empty() { return Ok(RoomMessageEventContent::text_plain("No more rooms.")); }; - + let output_plain = format!( "Rooms:\n{}", rooms .iter() - .map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}")) + .map(|(id, members, name)| format!( + "{id}\tMembers: {members}\tName: {name}" + )) .collect::>() .join("\n") ); @@ -785,18 +823,35 @@ impl Service { RoomMessageEventContent::text_html(output_plain, output_html) } // TODO: clean up and deduplicate code - RoomCommand::Alias(command) => { - 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()); - 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))), - }; + RoomCommand::Alias(command) => 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() + ); + 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 + ))) + } + }; - match command { - RoomAliasCommand::Set { force, room_id, .. } => { - match (force, services().rooms.alias.resolve_local_alias(&room_alias)) { + match command { + RoomAliasCommand::Set { force, room_id, .. } => { + match (force, services().rooms.alias.resolve_local_alias(&room_alias)) { (true, Ok(Some(id))) => match services().rooms.alias.set_alias(&room_alias, &room_id, sender) { Ok(()) => RoomMessageEventContent::text_plain(format!("Successfully overwrote alias (formerly {})", id)), Err(err) => RoomMessageEventContent::text_plain(format!("Failed to remove alias: {}", err)), @@ -809,107 +864,189 @@ impl Service { Err(err) => RoomMessageEventContent::text_plain(format!("Failed to remove alias: {}", err)), } (_, Err(err)) => RoomMessageEventContent::text_plain(format!("Unable to lookup alias: {}", err)), - } - }, - RoomAliasCommand::Remove { .. } => { - match services().rooms.alias.resolve_local_alias(&room_alias) { - Ok(Some(id)) => match services().rooms.alias.remove_alias(&room_alias, sender) { - Ok(()) => RoomMessageEventContent::text_plain(format!("Removed alias from {}", id)), - Err(err) => RoomMessageEventContent::text_plain(format!("Failed to remove alias: {}", err)), - } - Ok(None) => RoomMessageEventContent::text_plain("Alias isn't in use."), - Err(err) => RoomMessageEventContent::text_plain(format!("Unable to lookup alias: {}", err)), } - }, - RoomAliasCommand::Which { .. } => { - match services().rooms.alias.resolve_local_alias(&room_alias) { - Ok(Some(id)) => RoomMessageEventContent::text_plain(format!("Alias resolves to {}", id)), - Ok(None) => RoomMessageEventContent::text_plain("Alias isn't in use."), - Err(err) => RoomMessageEventContent::text_plain(&format!("Unable to lookup alias: {}", err)), - } - }, - RoomAliasCommand::List { .. } => unreachable!(), } - } - RoomAliasCommand::List { room_id } => match room_id { - Some(room_id) => { - let aliases: Result, _> = services().rooms.alias.local_aliases_for_room(&room_id).collect(); - match aliases { - Ok(aliases) => { - let plain_list: String = aliases.iter() - .map(|alias| format!("- {}\n", alias)) - .collect(); - - let html_list: String = aliases.iter() - .map(|alias| format!("
  • {}
  • \n", escape_html(&alias.to_string()))) - .collect(); - - let plain = format!("Aliases for {}:\n{}", room_id, plain_list); - let html = format!("Aliases for {}:\n
      {}
    ", room_id, html_list); - RoomMessageEventContent::text_html(plain, html) + RoomAliasCommand::Remove { .. } => { + match services().rooms.alias.resolve_local_alias(&room_alias) { + Ok(Some(id)) => match services() + .rooms + .alias + .remove_alias(&room_alias, sender) + { + Ok(()) => RoomMessageEventContent::text_plain(format!( + "Removed alias from {}", + id + )), + Err(err) => RoomMessageEventContent::text_plain(format!( + "Failed to remove alias: {}", + err + )), }, - Err(err) => RoomMessageEventContent::text_plain(&format!("Unable to list aliases: {}", err)), + Ok(None) => { + RoomMessageEventContent::text_plain("Alias isn't in use.") + } + Err(err) => RoomMessageEventContent::text_plain(format!( + "Unable to lookup alias: {}", + err + )), } } - None => { - let aliases: Result, _> = services().rooms.alias.all_local_aliases().collect(); - match aliases { - Ok(aliases) => { - let server_name = services().globals.server_name(); - let plain_list: String = aliases.iter() - .map(|(id, alias)| format!("- #{}:{} -> {}\n", alias, server_name, id)) - .collect(); - - let html_list: String = aliases.iter() - .map(|(id, alias)| format!("
  • #{}:{} -> {}
  • \n", escape_html(&alias.to_string()), server_name, escape_html(&id.to_string()))) - .collect(); - - let plain = format!("Aliases:\n{}", plain_list); - let html = format!("Aliases:\n
      {}
    ", html_list); - RoomMessageEventContent::text_html(plain, html) - }, - Err(err) => RoomMessageEventContent::text_plain(&format!("Unable to list aliases: {}", err)), + RoomAliasCommand::Which { .. } => { + match services().rooms.alias.resolve_local_alias(&room_alias) { + Ok(Some(id)) => RoomMessageEventContent::text_plain(format!( + "Alias resolves to {}", + id + )), + Ok(None) => { + RoomMessageEventContent::text_plain("Alias isn't in use.") + } + Err(err) => RoomMessageEventContent::text_plain(&format!( + "Unable to lookup alias: {}", + err + )), } } + RoomAliasCommand::List { .. } => unreachable!(), } } - } + RoomAliasCommand::List { room_id } => match room_id { + Some(room_id) => { + let aliases: Result, _> = services() + .rooms + .alias + .local_aliases_for_room(&room_id) + .collect(); + match aliases { + Ok(aliases) => { + let plain_list: String = aliases + .iter() + .map(|alias| format!("- {}\n", alias)) + .collect(); + + let html_list: String = aliases + .iter() + .map(|alias| { + format!( + "
  • {}
  • \n", + escape_html(&alias.to_string()) + ) + }) + .collect(); + + let plain = format!("Aliases for {}:\n{}", room_id, plain_list); + let html = + format!("Aliases for {}:\n
      {}
    ", room_id, html_list); + RoomMessageEventContent::text_html(plain, html) + } + Err(err) => RoomMessageEventContent::text_plain(&format!( + "Unable to list aliases: {}", + err + )), + } + } + None => { + let aliases: Result, _> = + services().rooms.alias.all_local_aliases().collect(); + match aliases { + Ok(aliases) => { + let server_name = services().globals.server_name(); + let plain_list: String = aliases + .iter() + .map(|(id, alias)| { + format!("- #{}:{} -> {}\n", alias, server_name, id) + }) + .collect(); + + let html_list: String = aliases + .iter() + .map(|(id, alias)| { + format!( + "
  • #{}:{} -> {}
  • \n", + escape_html(&alias.to_string()), + server_name, + escape_html(&id.to_string()) + ) + }) + .collect(); + + let plain = format!("Aliases:\n{}", plain_list); + let html = format!("Aliases:\n
      {}
    ", html_list); + RoomMessageEventContent::text_html(plain, html) + } + Err(err) => RoomMessageEventContent::text_plain(&format!( + "Unable to list aliases: {}", + err + )), + } + } + }, + }, RoomCommand::Directory(command) => match command { - RoomDirectoryCommand::Publish { room_id } => match services().rooms.directory.set_public(&room_id) { - Ok(()) => RoomMessageEventContent::text_plain("Room published"), - Err(err) => RoomMessageEventContent::text_plain(&format!("Unable to update room: {}", err)), + RoomDirectoryCommand::Publish { room_id } => { + match services().rooms.directory.set_public(&room_id) { + Ok(()) => RoomMessageEventContent::text_plain("Room published"), + Err(err) => RoomMessageEventContent::text_plain(&format!( + "Unable to update room: {}", + err + )), + } } - RoomDirectoryCommand::Unpublish { room_id } => match services().rooms.directory.set_not_public(&room_id) { - Ok(()) => RoomMessageEventContent::text_plain("Room unpublished"), - Err(err) => RoomMessageEventContent::text_plain(&format!("Unable to update room: {}", err)), + RoomDirectoryCommand::Unpublish { room_id } => { + match services().rooms.directory.set_not_public(&room_id) { + Ok(()) => RoomMessageEventContent::text_plain("Room unpublished"), + Err(err) => RoomMessageEventContent::text_plain(&format!( + "Unable to update room: {}", + err + )), + } } RoomDirectoryCommand::List { page } => { let page = page.unwrap_or(1); - let mut rooms = services().rooms.directory.public_rooms() + let mut rooms = services() + .rooms + .directory + .public_rooms() .filter_map(|r| r.ok()) - .map(|id| ( - id.clone(), - services().rooms.state_cache.room_joined_count(&id).ok().flatten().unwrap_or(0), - services().rooms.state_accessor.get_name(&id).ok().flatten().unwrap_or(id.to_string()), - )) + .map(|id| { + ( + id.clone(), + services() + .rooms + .state_cache + .room_joined_count(&id) + .ok() + .flatten() + .unwrap_or(0), + services() + .rooms + .state_accessor + .get_name(&id) + .ok() + .flatten() + .unwrap_or(id.to_string()), + ) + }) .collect::>(); rooms.sort_by_key(|r| r.1); rooms.reverse(); - let rooms: Vec<_> = rooms.into_iter() + let rooms: Vec<_> = rooms + .into_iter() .skip(page.saturating_sub(1) * PAGE_SIZE) .take(PAGE_SIZE) .collect(); - + if rooms.is_empty() { return Ok(RoomMessageEventContent::text_plain("No more rooms.")); }; - + let output_plain = format!( "Rooms:\n{}", rooms .iter() - .map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}")) + .map(|(id, members, name)| format!( + "{id}\tMembers: {members}\tName: {name}" + )) .collect::>() .join("\n") ); @@ -927,8 +1064,8 @@ impl Service { ); RoomMessageEventContent::text_html(output_plain, output_html) } - } - } + }, + }, AdminCommand::Federation(command) => match command { FederationCommand::DisableRoom { room_id } => { services().rooms.metadata.disable_room(&room_id, true)?; @@ -939,11 +1076,7 @@ impl Service { RoomMessageEventContent::text_plain("Room enabled.") } FederationCommand::IncomingFederation => { - let map = services() - .globals - .roomid_federationhandletime - .read() - .await; + let map = services().globals.roomid_federationhandletime.read().await; let mut msg: String = format!("Handling {} incoming pdus:\n", map.len()); for (r, (e, i)) in map.iter() { @@ -957,9 +1090,11 @@ impl Service { ); } RoomMessageEventContent::text_plain(&msg) - }, + } FederationCommand::SignJson => { - if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" + if body.len() > 2 + && body[0].trim().starts_with("```") + && body.last().unwrap().trim() == "```" { let string = body[1..body.len() - 1].join("\n"); match serde_json::from_str(&string) { @@ -974,16 +1109,20 @@ impl Service { .expect("canonical json is valid json"); RoomMessageEventContent::text_plain(json_text) } - Err(e) => RoomMessageEventContent::text_plain(format!("Invalid json: {e}")), + Err(e) => { + RoomMessageEventContent::text_plain(format!("Invalid json: {e}")) + } } } else { RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", ) } - }, + } FederationCommand::VerifyJson => { - if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" + if body.len() > 2 + && body[0].trim().starts_with("```") + && body.last().unwrap().trim() == "```" { let string = body[1..body.len() - 1].join("\n"); match serde_json::from_str(&string) { @@ -1018,8 +1157,7 @@ impl Service { ); } } - - + if ruma::signatures::verify_json(&valid_key_map, &value).is_ok() { RoomMessageEventContent::text_plain("Signature correct") } else if let Err(e) = @@ -1034,20 +1172,22 @@ impl Service { ) } } - Err(e) => RoomMessageEventContent::text_plain(format!("Invalid json: {e}")), + Err(e) => { + RoomMessageEventContent::text_plain(format!("Invalid json: {e}")) + } } } else { RoomMessageEventContent::text_plain( "Expected code block in command body. Add --help for details.", ) } - }, - } + } + }, AdminCommand::Server(command) => match command { ServerCommand::ShowConfig => { // Construct and send the response RoomMessageEventContent::text_plain(format!("{}", services().globals.config)) - }, + } ServerCommand::MemoryUsage => { let response1 = services().memory_usage().await; let response2 = services().globals.db.memory_usage(); @@ -1055,18 +1195,18 @@ impl Service { RoomMessageEventContent::text_plain(format!( "Services:\n{response1}\n\nDatabase:\n{response2}" )) - }, + } ServerCommand::ClearDatabaseCaches { amount } => { services().globals.db.clear_caches(amount); RoomMessageEventContent::text_plain("Done.") - }, + } ServerCommand::ClearServiceCaches { amount } => { services().clear_caches(amount).await; RoomMessageEventContent::text_plain("Done.") - }, - } + } + }, AdminCommand::Debug(command) => match command { DebugCommand::GetAuthChain { event_id } => { let event_id = Arc::::from(event_id); @@ -1093,9 +1233,11 @@ impl Service { } else { RoomMessageEventContent::text_plain("Event not found.") } - }, + } DebugCommand::ParsePdu => { - if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" + if body.len() > 2 + && body[0].trim().starts_with("```") + && body.last().unwrap().trim() == "```" { let string = body[1..body.len() - 1].join("\n"); match serde_json::from_str(&string) { @@ -1107,9 +1249,9 @@ impl Service { match serde_json::from_value::( serde_json::to_value(value).expect("value is json"), ) { - Ok(pdu) => RoomMessageEventContent::text_plain(format!( - "EventId: {event_id:?}\n{pdu:#?}" - )), + Ok(pdu) => RoomMessageEventContent::text_plain( + format!("EventId: {event_id:?}\n{pdu:#?}"), + ), Err(e) => RoomMessageEventContent::text_plain(format!( "EventId: {event_id:?}\nCould not parse event: {e}" )), @@ -1127,7 +1269,7 @@ impl Service { } else { RoomMessageEventContent::text_plain("Expected code block in command body.") } - }, + } DebugCommand::GetPdu { event_id } => { let mut outlier = false; let mut pdu_json = services() @@ -1165,8 +1307,8 @@ impl Service { } None => RoomMessageEventContent::text_plain("PDU not found."), } - }, - } + } + }, }; Ok(reply_message_content) @@ -1659,7 +1801,9 @@ impl Service { } fn escape_html(s: &str) -> String { - s.replace('&', "&").replace('<', "<").replace('>', ">") + s.replace('&', "&") + .replace('<', "<") + .replace('>', ">") } #[cfg(test)] diff --git a/src/service/rooms/alias/data.rs b/src/service/rooms/alias/data.rs index 288cfb93..61164147 100644 --- a/src/service/rooms/alias/data.rs +++ b/src/service/rooms/alias/data.rs @@ -19,7 +19,7 @@ pub trait Data: Send + Sync { &'a self, room_id: &RoomId, ) -> Box> + 'a>; - + /// Returns all local aliases on the server fn all_local_aliases<'a>( &'a self, diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 695cd05d..4e019ff8 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -506,7 +506,11 @@ impl Service { .state_cache .is_joined(server_user, &admin_room)? { - services().admin.process_message(body, pdu.event_id.clone(), pdu.sender.clone()); + services().admin.process_message( + body, + pdu.event_id.clone(), + pdu.sender.clone(), + ); } } }