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 {
38 room: OwnedRoomOrAliasId,
41 },
42
43 ListBannedRooms {
45 #[arg(long)]
46 no_details: bool,
49 },
50}
51
52async fn do_ban_room(services: &Services, room_id: &RoomId) {
53 services.metadata.ban_room(room_id);
54
55 debug!("Banned {room_id} successfully");
56
57 debug!("Making all users leave the room {room_id} and forgetting it");
58 let mut users = services
59 .state_cache
60 .room_members(room_id)
61 .ready_filter(|user| services.globals.user_is_local(user))
62 .map(ToOwned::to_owned)
63 .boxed();
64
65 while let Some(ref user_id) = users.next().await {
66 debug!(
67 "Attempting leave for user {user_id} in room {room_id} (ignoring all errors, \
68 evicting admins too)",
69 );
70
71 let state_lock = services.state.mutex.lock(room_id).await;
72
73 if let Err(e) = services
74 .membership
75 .leave(user_id, room_id, None, false, &state_lock)
76 .await
77 {
78 warn!("Failed to leave room: {e}");
79 }
80
81 drop(state_lock);
82
83 services.state_cache.forget(room_id, user_id);
84 }
85
86 services
88 .alias
89 .local_aliases_for_room(room_id)
90 .map(ToOwned::to_owned)
91 .for_each(async |local_alias| {
92 if let Err(e) = services.alias.remove_alias(&local_alias).await {
93 warn!("Error removing alias {local_alias} for {room_id}: {e}");
94 }
95 })
96 .await;
97
98 services.directory.set_not_public(room_id);
100
101 services.metadata.disable_room(room_id);
102}