From ee4f0a0ae5d0dc1cae112cf6f106cf62e7f8ec3a Mon Sep 17 00:00:00 2001
From: strawberry <strawberry@puppygock.gay>
Date: Wed, 28 Feb 2024 12:34:04 -0500
Subject: [PATCH] admin cmd to list all rooms a user is in

Signed-off-by: strawberry <strawberry@puppygock.gay>
---
 src/service/admin/mod.rs | 43 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs
index 1439cc288..7c48fa083 100644
--- a/src/service/admin/mod.rs
+++ b/src/service/admin/mod.rs
@@ -179,6 +179,9 @@ enum UserCommand {
 
     /// - List local users in the database
     List,
+
+    /// - Lists all the rooms (local and remote) that the specified user is joined in
+    ListJoinedRooms { user_id: Box<UserId> },
 }
 
 #[cfg_attr(test, derive(Debug))]
@@ -1005,6 +1008,46 @@ async fn process_admin_command(
                         )
                     }
                 }
+                UserCommand::ListJoinedRooms { user_id } => {
+                    let mut rooms: Vec<(OwnedRoomId, u64, String)> = vec![]; // room ID, members joined, room name
+
+                    for room_id in services().rooms.state_cache.rooms_joined(&user_id) {
+                        let room_id = room_id?;
+                        rooms.push(Self::get_room_info(room_id));
+                    }
+
+                    if rooms.is_empty() {
+                        return Ok(RoomMessageEventContent::text_plain(
+                            "User is not in any rooms.",
+                        ));
+                    }
+
+                    rooms.sort_by_key(|r| r.1);
+                    rooms.reverse();
+
+                    let output_plain = format!(
+                        "Rooms {user_id} Joined:\n{}",
+                        rooms
+                            .iter()
+                            .map(|(id, members, name)| format!(
+                                "{id}\tMembers: {members}\tName: {name}"
+                            ))
+                            .collect::<Vec<_>>()
+                            .join("\n")
+                    );
+                    let output_html = format!(
+                        "<table><caption>Rooms {user_id} Joined</caption>\n<tr><th>id</th>\t<th>members</th>\t<th>name</th></tr>\n{}</table>",
+                        rooms
+                            .iter()
+                            .fold(String::new(), |mut output, (id, members, name)| {
+                                writeln!(output, "<tr><td>{}</td>\t<td>{}</td>\t<td>{}</td></tr>", escape_html(id.as_ref()),
+                                members,
+                                escape_html(name)).unwrap();
+                                output
+                            })
+                    );
+                    RoomMessageEventContent::text_html(output_plain, output_html)
+                }
             },
             AdminCommand::Rooms(command) => match command {
                 RoomCommand::Moderation(command) => match command {
-- 
GitLab