From 06a2e73e8a044efee801bf34b1e1099b77f5af46 Mon Sep 17 00:00:00 2001 From: timedout Date: Sun, 1 Nov 2026 02:47:05 +0000 Subject: [PATCH] feat: Move & rename join-all-local-users --- src/admin/room/membership.rs | 50 ++++++++++++++++++++++ src/admin/user/commands.rs | 82 ------------------------------------ src/admin/user/mod.rs | 12 ------ 3 files changed, 50 insertions(+), 94 deletions(-) diff --git a/src/admin/room/membership.rs b/src/admin/room/membership.rs index cc69a465d..addabf2ee 100644 --- a/src/admin/room/membership.rs +++ b/src/admin/room/membership.rs @@ -3,6 +3,7 @@ use std::hash::RandomState; use clap::Subcommand; use conduwuit::{Err, Result, info}; use conduwuit_macros::admin_command_dispatch; +use futures::StreamExt; use ruma::{OwnedRoomOrAliasId, OwnedServerName, OwnedUserId}; #[admin_command_dispatch] @@ -21,6 +22,13 @@ pub enum RoomMembershipCommands { #[arg(long)] via: Option, }, + + /// Makes all local users join the designated room. + JoinAllLocalUsers { + /// The room (ID or alias) to join. + room: OwnedRoomOrAliasId, + }, + /// Make a local user leave a room or reject an invite. #[clap(name = "leave", alias = "reject-invite")] LeaveRoom { @@ -63,6 +71,48 @@ impl crate::Context<'_> { .await } + pub(super) async fn join_all_local_users(&self, room: OwnedRoomOrAliasId) -> Result { + self.bail_restricted()?; + let (room_id, residents) = self + .services + .rooms + .alias + .resolve_with_servers(&room, None) + .await?; + if !self + .services + .rooms + .state_cache + .is_joined( + self.sender + .expect("This command must be executed by a user"), + &room_id, + ) + .await + { + return Err!("You must be a member of the room you want to join everyone to."); + } + let mut success = 0_usize; + let mut failed = 0_usize; + let mut local_users = self.services.users.stream_local_users(); + while let Some(user_id) = local_users.next().await { + if self + .services + .rooms + .membership + .join_room(&user_id, &room_id, None, &residents) + .await + .is_ok() + { + success = success.saturating_add(1); + } else { + failed = failed.saturating_add(1); + } + } + self.write_str(&format!("Done: {success} successful joins, {failed} failed.")) + .await + } + pub(super) async fn leave_room( &self, user_id: OwnedUserId, diff --git a/src/admin/user/commands.rs b/src/admin/user/commands.rs index a61c6d95a..b88410984 100644 --- a/src/admin/user/commands.rs +++ b/src/admin/user/commands.rs @@ -582,88 +582,6 @@ impl crate::Context<'_> { .await } - pub(super) async fn force_join_all_local_users( - &self, - room_id: OwnedRoomOrAliasId, - yes_i_want_to_do_this: bool, - ) -> Result { - if !yes_i_want_to_do_this { - return Err!( - "You must pass the --yes-i-want-to-do-this-flag to ensure you really want to \ - force bulk join all local users.", - ); - } - - let server_admins = self.services.admin.get_admins().await; - - if server_admins.is_empty() { - return Err!("There are no admins set for this server."); - } - - let (room_id, servers) = self - .services - .rooms - .alias - .resolve_with_servers(&room_id, None) - .await?; - - if !self - .services - .rooms - .state_cache - .server_in_room(self.services.globals.server_name(), &room_id) - .await - { - return Err!("We are not joined in this room."); - } - - if !self - .services - .rooms - .state_cache - .room_members(&room_id) - .ready_any(|user_id| server_admins.contains(&user_id)) - .await - { - return Err!("There is not a single server admin in the room.",); - } - - let mut failed_joins: usize = 0; - let mut successful_joins: usize = 0; - - for user_id in &self - .services - .users - .stream_local_users() - .collect::>() - .await - { - match self - .services - .rooms - .membership - .join_room(user_id, &room_id, Some(String::from(BULK_JOIN_REASON)), &servers) - .await - { - | Ok(_res) => { - successful_joins = successful_joins.saturating_add(1); - }, - | Err(e) => { - debug_warn!( - "Failed force joining {user_id} to {room_id} during bulk join: {e}" - ); - failed_joins = failed_joins.saturating_add(1); - }, - } - } - - self.write_str(&format!( - "{successful_joins} local users have been joined to {room_id}. {failed_joins} joins \ - failed.", - )) - .await - } - pub(super) async fn force_demote( &self, user_id: String, diff --git a/src/admin/user/mod.rs b/src/admin/user/mod.rs index a52910ce3..fe9c89ee8 100644 --- a/src/admin/user/mod.rs +++ b/src/admin/user/mod.rs @@ -254,18 +254,6 @@ pub enum UserCommand { yes_i_want_to_do_this: bool, }, - /// Force joins all local users to the specified room. - /// - /// At least 1 server admin must be in the room to reduce abuse. - /// - /// Requires the `--yes-i-want-to-do-this` flag. - ForceJoinAllLocalUsers { - room_id: OwnedRoomOrAliasId, - - #[arg(long)] - yes_i_want_to_do_this: bool, - }, - /// Resets the push-rules (notification settings) of the target user to the /// server defaults. ResetPushRules {