tuwunel_admin/room/moderation/
mod.rs1mod ban_list_of_rooms;
2mod ban_room;
3mod list_banned_rooms;
4mod unban_room;
5
6use clap::Subcommand;
7use futures::StreamExt;
8use ruma::{OwnedRoomOrAliasId, RoomId};
9use tuwunel_core::{Result, debug, utils::ReadyExt, warn};
10use tuwunel_service::Services;
11
12use crate::admin_command_dispatch;
13
14#[admin_command_dispatch]
15#[derive(Debug, Subcommand)]
16pub(crate) enum RoomModerationCommand {
17 BanRoom {
23 room: OwnedRoomOrAliasId,
26 },
27
28 BanListOfRooms,
32
33 UnbanRoom {
35 room: OwnedRoomOrAliasId,
38 },
39
40 ListBannedRooms {
42 #[arg(long)]
43 no_details: bool,
46 },
47}
48
49async fn do_ban_room(services: &Services, room_id: &RoomId) {
50 services.metadata.ban_room(room_id);
51
52 debug!("Banned {room_id} successfully");
53
54 debug!("Making all users leave the room {room_id} and forgetting it");
55 let mut users = services
56 .state_cache
57 .room_members(room_id)
58 .ready_filter(|user| services.globals.user_is_local(user))
59 .map(ToOwned::to_owned)
60 .boxed();
61
62 while let Some(ref user_id) = users.next().await {
63 debug!(
64 "Attempting leave for user {user_id} in room {room_id} (ignoring all errors, \
65 evicting admins too)",
66 );
67
68 let state_lock = services.state.mutex.lock(room_id).await;
69
70 if let Err(e) = services
71 .membership
72 .leave(user_id, room_id, None, false, &state_lock)
73 .await
74 {
75 warn!("Failed to leave room: {e}");
76 }
77
78 drop(state_lock);
79
80 services.state_cache.forget(room_id, user_id);
81 }
82
83 services
85 .alias
86 .local_aliases_for_room(room_id)
87 .map(ToOwned::to_owned)
88 .for_each(async |local_alias| {
89 if let Err(e) = services.alias.remove_alias(&local_alias).await {
90 warn!("Error removing alias {local_alias} for {room_id}: {e}");
91 }
92 })
93 .await;
94
95 services.directory.set_not_public(room_id);
97
98 services.metadata.disable_room(room_id);
99}