admin command to get rooms a remote user is in, remove unnecessary dedupe+sort
imagine this SQL query but in conduwuit: select * from users_in_public_rooms where user_id like '%user_id%'; Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
450f15df4f
commit
61f813c187
3 changed files with 76 additions and 7 deletions
|
@ -1,8 +1,13 @@
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
use ruma::{events::room::message::RoomMessageEventContent, RoomId, ServerName};
|
use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, RoomId, ServerName, UserId};
|
||||||
|
|
||||||
use crate::{services, utils::HtmlEscape, Result};
|
use crate::{
|
||||||
|
service::admin::{escape_html, get_room_info},
|
||||||
|
services,
|
||||||
|
utils::HtmlEscape,
|
||||||
|
Result,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) async fn disable_room(_body: Vec<&str>, room_id: Box<RoomId>) -> Result<RoomMessageEventContent> {
|
pub(crate) async fn disable_room(_body: Vec<&str>, room_id: Box<RoomId>) -> Result<RoomMessageEventContent> {
|
||||||
services().rooms.metadata.disable_room(&room_id, true)?;
|
services().rooms.metadata.disable_room(&room_id, true)?;
|
||||||
|
@ -70,3 +75,60 @@ pub(crate) async fn fetch_support_well_known(
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn remote_user_in_rooms(_body: Vec<&str>, user_id: Box<UserId>) -> Result<RoomMessageEventContent> {
|
||||||
|
if user_id.server_name() == services().globals.config.server_name {
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(
|
||||||
|
"User belongs to our server, please use `list-joined-rooms` user admin command instead.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !services().users.exists(&user_id)? {
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(
|
||||||
|
"Remote user does not exist in our database.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rooms: Vec<(OwnedRoomId, u64, String)> = services()
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.rooms_joined(&user_id)
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.map(|room_id| get_room_info(&room_id))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
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} shares with us:\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} shares with \
|
||||||
|
us</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
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(RoomMessageEventContent::text_html(output_plain, output_html))
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
use ruma::{events::room::message::RoomMessageEventContent, RoomId, ServerName};
|
use ruma::{events::room::message::RoomMessageEventContent, RoomId, ServerName, UserId};
|
||||||
|
|
||||||
use self::federation_commands::{disable_room, enable_room, fetch_support_well_known, incoming_federeation};
|
use self::federation_commands::{
|
||||||
|
disable_room, enable_room, fetch_support_well_known, incoming_federeation, remote_user_in_rooms,
|
||||||
|
};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
pub(crate) mod federation_commands;
|
pub(crate) mod federation_commands;
|
||||||
|
@ -34,6 +36,11 @@ pub(crate) enum FederationCommand {
|
||||||
FetchSupportWellKnown {
|
FetchSupportWellKnown {
|
||||||
server_name: Box<ServerName>,
|
server_name: Box<ServerName>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// - Lists all the rooms we share/track with the specified *remote* user
|
||||||
|
RemoteUserInRooms {
|
||||||
|
user_id: Box<UserId>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn process(command: FederationCommand, body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
pub(crate) async fn process(command: FederationCommand, body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
||||||
|
@ -48,5 +55,8 @@ pub(crate) async fn process(command: FederationCommand, body: Vec<&str>) -> Resu
|
||||||
FederationCommand::FetchSupportWellKnown {
|
FederationCommand::FetchSupportWellKnown {
|
||||||
server_name,
|
server_name,
|
||||||
} => fetch_support_well_known(body, server_name).await?,
|
} => fetch_support_well_known(body, server_name).await?,
|
||||||
|
FederationCommand::RemoteUserInRooms {
|
||||||
|
user_id,
|
||||||
|
} => remote_user_in_rooms(body, user_id).await?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::{fmt::Write as _, sync::Arc};
|
use std::{fmt::Write as _, sync::Arc};
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, UserId};
|
use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, UserId};
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
|
@ -318,8 +317,6 @@ pub(crate) async fn list_joined_rooms(_body: Vec<&str>, user_id: String) -> Resu
|
||||||
.rooms_joined(&user_id)
|
.rooms_joined(&user_id)
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.map(|room_id| get_room_info(&room_id))
|
.map(|room_id| get_room_info(&room_id))
|
||||||
.sorted_unstable()
|
|
||||||
.dedup()
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if rooms.is_empty() {
|
if rooms.is_empty() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue