diff --git a/clippy.toml b/clippy.toml index 1743ee5c..c942b93c 100644 --- a/clippy.toml +++ b/clippy.toml @@ -2,6 +2,6 @@ array-size-threshold = 4096 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 = 173577 # reduce me ALARA +stack-size-threshold = 144000 # reduce me ALARA too-many-lines-threshold = 700 # TODO reduce me to <= 100 type-complexity-threshold = 250 # reduce me to ~200 diff --git a/src/admin/room/room_moderation_commands.rs b/src/admin/room/room_moderation_commands.rs index f5176147..6b759c9b 100644 --- a/src/admin/room/room_moderation_commands.rs +++ b/src/admin/room/room_moderation_commands.rs @@ -18,91 +18,103 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> force, room, disable_federation, - } => { - debug!("Got room alias or ID: {}", room); + } => ban_room(body, force, room, disable_federation).await, + RoomModerationCommand::BanListOfRooms { + force, + disable_federation, + } => ban_list_of_rooms(body, force, disable_federation).await, + RoomModerationCommand::UnbanRoom { + room, + enable_federation, + } => unban_room(body, room, enable_federation).await, + RoomModerationCommand::ListBannedRooms => list_banned_rooms(body).await, + } +} - let admin_room_alias: Box = format!("#admins:{}", services().globals.server_name()) - .try_into() - .expect("#admins:server_name is a valid alias name"); +async fn ban_room( + _body: Vec<&str>, force: bool, room: Box, disable_federation: bool, +) -> Result { + debug!("Got room alias or ID: {}", room); - if let Some(admin_room_id) = Service::get_admin_room().await? { - if room.to_string().eq(&admin_room_id) || room.to_string().eq(&admin_room_alias) { - return Ok(RoomMessageEventContent::text_plain("Not allowed to ban the admin room.")); - } + let admin_room_alias: Box = format!("#admins:{}", services().globals.server_name()) + .try_into() + .expect("#admins:server_name is a valid alias name"); + + if let Some(admin_room_id) = Service::get_admin_room().await? { + if room.to_string().eq(&admin_room_id) || room.to_string().eq(&admin_room_alias) { + return Ok(RoomMessageEventContent::text_plain("Not allowed to ban the admin room.")); + } + } + + let room_id = if room.is_room_id() { + let room_id = match RoomId::parse(&room) { + 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}" + ))) + }, + }; + + debug!("Room specified is a room ID, banning room ID"); + + services().rooms.metadata.ban_room(&room_id, true)?; + + room_id + } else if room.is_room_alias_id() { + let room_alias = match RoomAliasId::parse(&room) { + 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}" + ))) + }, + }; + + 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" + ); + + let room_id = if let Some(room_id) = services().rooms.alias.resolve_local_alias(&room_alias)? { + room_id + } else { + debug!("We don't have this room alias to a room ID locally, attempting to fetch room ID over federation"); + + match get_alias_helper(room_alias, None).await { + Ok(response) => { + debug!("Got federation response fetching room ID for room {room}: {:?}", response); + response.room_id + }, + Err(e) => { + return Ok(RoomMessageEventContent::text_plain(format!( + "Failed to resolve room alias {room} to a room ID: {e}" + ))); + }, } + }; - let room_id = if room.is_room_id() { - let room_id = match RoomId::parse(&room) { - 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}" - ))) - }, - }; + services().rooms.metadata.ban_room(&room_id, true)?; - debug!("Room specified is a room ID, banning room ID"); + 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`)", + )); + }; - services().rooms.metadata.ban_room(&room_id, true)?; - - room_id - } else if room.is_room_alias_id() { - let room_alias = match RoomAliasId::parse(&room) { - 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}" - ))) - }, - }; - - 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" - ); - - let room_id = if let Some(room_id) = services().rooms.alias.resolve_local_alias(&room_alias)? { - room_id - } else { - debug!( - "We don't have this room alias to a room ID locally, attempting to fetch room ID over \ - federation" - ); - - match get_alias_helper(room_alias, None).await { - Ok(response) => { - debug!("Got federation response fetching room ID for room {room}: {:?}", response); - response.room_id - }, - Err(e) => { - return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to resolve room alias {room} to a room ID: {e}" - ))); - }, - } - }; - - services().rooms.metadata.ban_room(&room_id, true)?; - - 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`)", - )); - }; - - debug!("Making all users leave the room {}", &room); - if force { - for local_user in services() - .rooms - .state_cache - .room_members(&room_id) - .filter_map(|user| { - user.ok().filter(|local_user| { - user_is_local(local_user) + debug!("Making all users leave the room {}", &room); + if force { + for local_user in services() + .rooms + .state_cache + .room_members(&room_id) + .filter_map(|user| { + user.ok().filter(|local_user| { + user_is_local(local_user) // additional wrapped check here is to avoid adding remote users // who are in the admin room to the list of local users (would fail auth check) && (user_is_local(local_user) @@ -110,18 +122,221 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> .users .is_admin(local_user) .unwrap_or(true)) // since this is a force - // operation, assume user - // is an admin if somehow - // this fails + // operation, assume user + // is an admin if somehow + // this fails + }) + }) + .collect::>() + { + debug!( + "Attempting leave for user {} in room {} (forced, ignoring all errors, evicting admins too)", + &local_user, &room_id + ); + + if let Err(e) = leave_room(&local_user, &room_id, None).await { + warn!(%e, "Failed to leave room"); + } + } + } else { + for local_user in services() + .rooms + .state_cache + .room_members(&room_id) + .filter_map(|user| { + user.ok().filter(|local_user| { + local_user.server_name() == services().globals.server_name() + // additional wrapped check here is to avoid adding remote users + // who are in the admin room to the list of local users (would fail auth check) + && (local_user.server_name() + == services().globals.server_name() + && !services() + .users + .is_admin(local_user) + .unwrap_or(false)) + }) + }) + .collect::>() + { + debug!("Attempting leave for user {} in room {}", &local_user, &room_id); + if let Err(e) = leave_room(&local_user, &room_id, None).await { + error!( + "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", + &local_user, &room_id, e + ))); + } + } + } + + if disable_federation { + 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.", + )); + } + + 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.", + )) +} + +async fn ban_list_of_rooms(body: Vec<&str>, force: bool, disable_federation: bool) -> Result { + if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" { + let rooms_s = body.clone().drain(1..body.len() - 1).collect::>(); + + let admin_room_alias: Box = format!("#admins:{}", services().globals.server_name()) + .try_into() + .expect("#admins:server_name is a valid alias name"); + + let mut room_ban_count: usize = 0; + let mut room_ids: Vec = Vec::new(); + + for &room in &rooms_s { + match <&RoomOrAliasId>::try_from(room) { + Ok(room_alias_or_id) => { + if let Some(admin_room_id) = Service::get_admin_room().await? { + 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; + } + } + + 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) => { + 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}" + ); + 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_ids.push(room_id); + } + + if room_alias_or_id.is_room_alias_id() { + match RoomAliasId::parse(room_alias_or_id) { + Ok(room_alias) => { + let room_id = + if let Some(room_id) = services().rooms.alias.resolve_local_alias(&room_alias)? { + room_id + } else { + debug!( + "We don't have this room alias to a room ID locally, attempting to fetch \ + room ID over federation" + ); + + match get_alias_helper(room_alias, None).await { + Ok(response) => { + debug!( + "Got federation response fetching room ID for room {room}: {:?}", + response + ); + response.room_id + }, + Err(e) => { + // don't fail if force blocking + if force { + 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}" + ))); + }, + } + }; + + room_ids.push(room_id); + }, + 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}" + ); + 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}" + ))); + }, + } + } + }, + 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}" + ); + 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}" + ))); + }, + } + } + + for room_id in room_ids { + if services().rooms.metadata.ban_room(&room_id, true).is_ok() { + debug!("Banned {room_id} successfully"); + room_ban_count = room_ban_count.saturating_add(1); + } + + debug!("Making all users leave the room {}", &room_id); + if force { + for local_user in services() + .rooms + .state_cache + .room_members(&room_id) + .filter_map(|user| { + user.ok().filter(|local_user| { + local_user.server_name() == services().globals.server_name() + // additional wrapped check here is to avoid adding remote users + // who are in the admin room to the list of local users (would fail auth check) + && (local_user.server_name() + == services().globals.server_name() + && services() + .users + .is_admin(local_user) + .unwrap_or(true)) // since this is a + // force operation, + // assume user is + // an admin if + // somehow this + // fails }) }) .collect::>() { debug!( "Attempting leave for user {} in room {} (forced, ignoring all errors, evicting admins too)", - &local_user, &room_id + &local_user, room_id ); - if let Err(e) = leave_room(&local_user, &room_id, None).await { warn!(%e, "Failed to leave room"); } @@ -134,215 +349,6 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> .filter_map(|user| { user.ok().filter(|local_user| { local_user.server_name() == services().globals.server_name() - // additional wrapped check here is to avoid adding remote users - // who are in the admin room to the list of local users (would fail auth check) - && (local_user.server_name() - == services().globals.server_name() - && !services() - .users - .is_admin(local_user) - .unwrap_or(false)) - }) - }) - .collect::>() - { - debug!("Attempting leave for user {} in room {}", &local_user, &room_id); - if let Err(e) = leave_room(&local_user, &room_id, None).await { - error!( - "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", - &local_user, &room_id, e - ))); - } - } - } - - if disable_federation { - 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.", - )); - } - - 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.", - )) - }, - RoomModerationCommand::BanListOfRooms { - force, - disable_federation, - } => { - if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" { - let rooms_s = body.clone().drain(1..body.len() - 1).collect::>(); - - let admin_room_alias: Box = format!("#admins:{}", services().globals.server_name()) - .try_into() - .expect("#admins:server_name is a valid alias name"); - - let mut room_ban_count: usize = 0; - let mut room_ids: Vec = Vec::new(); - - for &room in &rooms_s { - match <&RoomOrAliasId>::try_from(room) { - Ok(room_alias_or_id) => { - if let Some(admin_room_id) = Service::get_admin_room().await? { - 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; - } - } - - 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) => { - 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}" - ); - 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_ids.push(room_id); - } - - if room_alias_or_id.is_room_alias_id() { - match RoomAliasId::parse(room_alias_or_id) { - Ok(room_alias) => { - let room_id = if let Some(room_id) = - services().rooms.alias.resolve_local_alias(&room_alias)? - { - room_id - } else { - debug!( - "We don't have this room alias to a room ID locally, attempting to \ - fetch room ID over federation" - ); - - match get_alias_helper(room_alias, None).await { - Ok(response) => { - debug!( - "Got federation response fetching room ID for room {room}: \ - {:?}", - response - ); - response.room_id - }, - Err(e) => { - // don't fail if force blocking - if force { - 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}" - ))); - }, - } - }; - - room_ids.push(room_id); - }, - 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}" - ); - 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}" - ))); - }, - } - } - }, - 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}" - ); - 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}" - ))); - }, - } - } - - for room_id in room_ids { - if services().rooms.metadata.ban_room(&room_id, true).is_ok() { - debug!("Banned {room_id} successfully"); - room_ban_count = room_ban_count.saturating_add(1); - } - - debug!("Making all users leave the room {}", &room_id); - if force { - for local_user in services() - .rooms - .state_cache - .room_members(&room_id) - .filter_map(|user| { - user.ok().filter(|local_user| { - local_user.server_name() == services().globals.server_name() - // additional wrapped check here is to avoid adding remote users - // who are in the admin room to the list of local users (would fail auth check) - && (local_user.server_name() - == services().globals.server_name() - && services() - .users - .is_admin(local_user) - .unwrap_or(true)) // since this is a - // force operation, - // assume user is - // an admin if - // somehow this - // fails - }) - }) - .collect::>() - { - debug!( - "Attempting leave for user {} in room {} (forced, ignoring all errors, evicting \ - admins too)", - &local_user, room_id - ); - if let Err(e) = leave_room(&local_user, &room_id, None).await { - warn!(%e, "Failed to leave room"); - } - } - } else { - for local_user in services() - .rooms - .state_cache - .room_members(&room_id) - .filter_map(|user| { - user.ok().filter(|local_user| { - local_user.server_name() == services().globals.server_name() // additional wrapped check here is to avoid adding remote users // who are in the admin room to the list of local users (would fail auth check) && (local_user.server_name() @@ -351,154 +357,150 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> .users .is_admin(local_user) .unwrap_or(false)) - }) - }) - .collect::>() - { - debug!("Attempting leave for user {} in room {}", &local_user, &room_id); - if let Err(e) = leave_room(&local_user, &room_id, None).await { - error!( - "Error attempting to make local user {} leave room {} during bulk 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 and not banning any more rooms): \ - {}\nIf you would like to ignore errors, use --force", - &local_user, &room_id, e - ))); - } - } - } - - if disable_federation { - services().rooms.metadata.disable_room(&room_id, true)?; + }) + }) + .collect::>() + { + debug!("Attempting leave for user {} in room {}", &local_user, &room_id); + if let Err(e) = leave_room(&local_user, &room_id, None).await { + error!( + "Error attempting to make local user {} leave room {} during bulk 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 and not banning any more rooms): {}\nIf you would \ + like to ignore errors, use --force", + &local_user, &room_id, e + ))); } } + } - if disable_federation { - return 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." - ))); - } + if disable_federation { + services().rooms.metadata.disable_room(&room_id, true)?; + } + } + + if disable_federation { + return 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." + ))); + } + return Ok(RoomMessageEventContent::text_plain(format!( + "Finished bulk room ban, banned {room_ban_count} total rooms and evicted all users." + ))); + } + + Ok(RoomMessageEventContent::text_plain( + "Expected code block in command body. Add --help for details.", + )) +} + +async fn unban_room( + _body: Vec<&str>, room: Box, enable_federation: bool, +) -> Result { + let room_id = if room.is_room_id() { + let room_id = match RoomId::parse(&room) { + Ok(room_id) => room_id, + Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( - "Finished bulk room ban, banned {room_ban_count} total rooms and evicted all users." - ))); - } + "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}" + ))) + }, + }; - Ok(RoomMessageEventContent::text_plain( - "Expected code block in command body. Add --help for details.", - )) - }, - RoomModerationCommand::UnbanRoom { - room, - enable_federation, - } => { - let room_id = if room.is_room_id() { - let room_id = match RoomId::parse(&room) { - 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}" - ))) - }, - }; + debug!("Room specified is a room ID, unbanning room ID"); - debug!("Room specified is a room ID, unbanning room ID"); + services().rooms.metadata.ban_room(&room_id, false)?; - services().rooms.metadata.ban_room(&room_id, false)?; + room_id + } else if room.is_room_alias_id() { + let room_alias = match RoomAliasId::parse(&room) { + 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}" + ))) + }, + }; - room_id - } else if room.is_room_alias_id() { - let room_alias = match RoomAliasId::parse(&room) { - 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}" - ))) - }, - }; + 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" + ); - 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" - ); + let room_id = if let Some(room_id) = services().rooms.alias.resolve_local_alias(&room_alias)? { + room_id + } else { + debug!("We don't have this room alias to a room ID locally, attempting to fetch room ID over federation"); - let room_id = if let Some(room_id) = services().rooms.alias.resolve_local_alias(&room_alias)? { - room_id - } else { - debug!( - "We don't have this room alias to a room ID locally, attempting to fetch room ID over \ - federation" - ); - - match get_alias_helper(room_alias, None).await { - Ok(response) => { - debug!("Got federation response fetching room ID for room {room}: {:?}", response); - response.room_id - }, - Err(e) => { - return Ok(RoomMessageEventContent::text_plain(format!( - "Failed to resolve room alias {room} to a room ID: {e}" - ))); - }, - } - }; - - services().rooms.metadata.ban_room(&room_id, false)?; - - 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`)", - )); - }; - - if enable_federation { - services().rooms.metadata.disable_room(&room_id, false)?; - return Ok(RoomMessageEventContent::text_plain("Room unbanned.")); - } - - 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.", - )) - }, - RoomModerationCommand::ListBannedRooms => { - let rooms = services() - .rooms - .metadata - .list_banned_rooms() - .collect::, _>>(); - - match rooms { - Ok(room_ids) => { - // TODO: add room name from our state cache if available, default to the room ID - // as the room name if we dont have it TODO: do same if we have a room alias for - // this - let plain_list = room_ids.iter().fold(String::new(), |mut output, room_id| { - writeln!(output, "- `{room_id}`").unwrap(); - output - }); - - let html_list = room_ids.iter().fold(String::new(), |mut output, room_id| { - writeln!(output, "
  • {}
  • ", escape_html(room_id.as_ref())).unwrap(); - output - }); - - let plain = format!("Rooms:\n{plain_list}"); - let html = format!("Rooms:\n
      {html_list}
    "); - Ok(RoomMessageEventContent::text_html(plain, html)) + match get_alias_helper(room_alias, None).await { + Ok(response) => { + debug!("Got federation response fetching room ID for room {room}: {:?}", response); + response.room_id }, Err(e) => { - error!("Failed to list banned rooms: {}", e); - Ok(RoomMessageEventContent::text_plain(format!("Unable to list room aliases: {e}"))) + return Ok(RoomMessageEventContent::text_plain(format!( + "Failed to resolve room alias {room} to a room ID: {e}" + ))); }, } + }; + + services().rooms.metadata.ban_room(&room_id, false)?; + + 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`)", + )); + }; + + if enable_federation { + services().rooms.metadata.disable_room(&room_id, false)?; + return Ok(RoomMessageEventContent::text_plain("Room unbanned.")); + } + + 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.", + )) +} + +async fn list_banned_rooms(_body: Vec<&str>) -> Result { + let rooms = services() + .rooms + .metadata + .list_banned_rooms() + .collect::, _>>(); + + match rooms { + Ok(room_ids) => { + // TODO: add room name from our state cache if available, default to the room ID + // as the room name if we dont have it TODO: do same if we have a room alias for + // this + let plain_list = room_ids.iter().fold(String::new(), |mut output, room_id| { + writeln!(output, "- `{room_id}`").unwrap(); + output + }); + + let html_list = room_ids.iter().fold(String::new(), |mut output, room_id| { + writeln!(output, "
  • {}
  • ", escape_html(room_id.as_ref())).unwrap(); + output + }); + + let plain = format!("Rooms:\n{plain_list}"); + let html = format!("Rooms:\n
      {html_list}
    "); + Ok(RoomMessageEventContent::text_html(plain, html)) + }, + Err(e) => { + error!("Failed to list banned rooms: {}", e); + Ok(RoomMessageEventContent::text_plain(format!("Unable to list room aliases: {e}"))) }, } }