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::{FutureExt, 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 .boxed()
74 .await
75 {
76 warn!("Failed to leave room: {e}");
77 }
78
79 drop(state_lock);
80
81 services.state_cache.forget(room_id, user_id);
82 }
83
84 services
86 .alias
87 .local_aliases_for_room(room_id)
88 .map(ToOwned::to_owned)
89 .for_each(async |local_alias| {
90 if let Err(e) = services.alias.remove_alias(&local_alias).await {
91 warn!("Error removing alias {local_alias} for {room_id}: {e}");
92 }
93 })
94 .await;
95
96 services.directory.set_not_public(room_id);
98
99 services.metadata.disable_room(room_id);
100}