2024-05-23 01:27:04 -04:00
|
|
|
use std::fmt::Write;
|
2024-04-20 19:55:14 -04:00
|
|
|
|
2024-12-14 21:58:01 -05:00
|
|
|
use conduwuit::Result;
|
2024-08-08 17:18:30 +00:00
|
|
|
use futures::StreamExt;
|
2024-12-15 00:05:47 -05:00
|
|
|
use ruma::{
|
2025-04-08 04:39:01 +00:00
|
|
|
OwnedRoomId, OwnedServerName, OwnedUserId, events::room::message::RoomMessageEventContent,
|
2024-12-15 00:05:47 -05:00
|
|
|
};
|
2024-04-20 19:55:14 -04:00
|
|
|
|
2024-10-27 13:21:16 -04:00
|
|
|
use crate::{admin_command, get_room_info};
|
2024-04-20 19:55:14 -04:00
|
|
|
|
2024-07-27 00:11:41 +00:00
|
|
|
#[admin_command]
|
2025-04-08 04:39:01 +00:00
|
|
|
pub(super) async fn disable_room(&self, room_id: OwnedRoomId) -> Result<RoomMessageEventContent> {
|
2024-08-08 17:18:30 +00:00
|
|
|
self.services.rooms.metadata.disable_room(&room_id, true);
|
2024-04-20 19:55:14 -04:00
|
|
|
Ok(RoomMessageEventContent::text_plain("Room disabled."))
|
|
|
|
}
|
|
|
|
|
2024-07-27 00:11:41 +00:00
|
|
|
#[admin_command]
|
2025-04-08 04:39:01 +00:00
|
|
|
pub(super) async fn enable_room(&self, room_id: OwnedRoomId) -> Result<RoomMessageEventContent> {
|
2024-08-08 17:18:30 +00:00
|
|
|
self.services.rooms.metadata.disable_room(&room_id, false);
|
2024-04-20 19:55:14 -04:00
|
|
|
Ok(RoomMessageEventContent::text_plain("Room enabled."))
|
|
|
|
}
|
|
|
|
|
2024-07-27 00:11:41 +00:00
|
|
|
#[admin_command]
|
|
|
|
pub(super) async fn incoming_federation(&self) -> Result<RoomMessageEventContent> {
|
|
|
|
let map = self
|
|
|
|
.services
|
2024-07-09 21:10:14 +00:00
|
|
|
.rooms
|
|
|
|
.event_handler
|
|
|
|
.federation_handletime
|
2024-07-04 03:26:19 +00:00
|
|
|
.read()
|
|
|
|
.expect("locked");
|
2024-04-20 19:55:14 -04:00
|
|
|
let mut msg = format!("Handling {} incoming pdus:\n", map.len());
|
|
|
|
|
|
|
|
for (r, (e, i)) in map.iter() {
|
|
|
|
let elapsed = i.elapsed();
|
2024-07-04 03:26:19 +00:00
|
|
|
writeln!(msg, "{} {}: {}m{}s", r, e, elapsed.as_secs() / 60, elapsed.as_secs() % 60)?;
|
2024-04-20 19:55:14 -04:00
|
|
|
}
|
2024-07-04 03:26:19 +00:00
|
|
|
|
2024-04-20 19:55:14 -04:00
|
|
|
Ok(RoomMessageEventContent::text_plain(&msg))
|
|
|
|
}
|
|
|
|
|
2024-07-27 00:11:41 +00:00
|
|
|
#[admin_command]
|
2024-12-15 00:05:47 -05:00
|
|
|
pub(super) async fn fetch_support_well_known(
|
|
|
|
&self,
|
2025-04-08 04:39:01 +00:00
|
|
|
server_name: OwnedServerName,
|
2024-12-15 00:05:47 -05:00
|
|
|
) -> Result<RoomMessageEventContent> {
|
2024-07-27 00:11:41 +00:00
|
|
|
let response = self
|
|
|
|
.services
|
2024-04-20 19:55:14 -04:00
|
|
|
.client
|
|
|
|
.default
|
|
|
|
.get(format!("https://{server_name}/.well-known/matrix/support"))
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
let text = response.text().await?;
|
|
|
|
|
|
|
|
if text.is_empty() {
|
|
|
|
return Ok(RoomMessageEventContent::text_plain("Response text/body is empty."));
|
|
|
|
}
|
|
|
|
|
|
|
|
if text.len() > 1500 {
|
|
|
|
return Ok(RoomMessageEventContent::text_plain(
|
|
|
|
"Response text/body is over 1500 characters, assuming no support well-known.",
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
let json: serde_json::Value = match serde_json::from_str(&text) {
|
2024-12-15 00:05:47 -05:00
|
|
|
| Ok(json) => json,
|
|
|
|
| Err(_) => {
|
|
|
|
return Ok(RoomMessageEventContent::text_plain(
|
|
|
|
"Response text/body is not valid JSON.",
|
|
|
|
));
|
2024-04-20 19:55:14 -04:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
let pretty_json: String = match serde_json::to_string_pretty(&json) {
|
2024-12-15 00:05:47 -05:00
|
|
|
| Ok(json) => json,
|
|
|
|
| Err(_) => {
|
|
|
|
return Ok(RoomMessageEventContent::text_plain(
|
|
|
|
"Response text/body is not valid JSON.",
|
|
|
|
));
|
2024-04-20 19:55:14 -04:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2024-06-19 01:55:21 +00:00
|
|
|
Ok(RoomMessageEventContent::notice_markdown(format!(
|
|
|
|
"Got JSON response:\n\n```json\n{pretty_json}\n```"
|
|
|
|
)))
|
2024-04-20 19:55:14 -04:00
|
|
|
}
|
2024-04-27 01:06:43 -04:00
|
|
|
|
2024-07-27 00:11:41 +00:00
|
|
|
#[admin_command]
|
2024-12-15 00:05:47 -05:00
|
|
|
pub(super) async fn remote_user_in_rooms(
|
|
|
|
&self,
|
2025-04-08 04:39:01 +00:00
|
|
|
user_id: OwnedUserId,
|
2024-12-15 00:05:47 -05:00
|
|
|
) -> Result<RoomMessageEventContent> {
|
2025-01-25 23:41:39 +00:00
|
|
|
if user_id.server_name() == self.services.server.name {
|
2024-04-27 01:06:43 -04:00
|
|
|
return Ok(RoomMessageEventContent::text_plain(
|
2024-12-15 00:05:47 -05:00
|
|
|
"User belongs to our server, please use `list-joined-rooms` user admin command \
|
|
|
|
instead.",
|
2024-04-27 01:06:43 -04:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2024-08-08 17:18:30 +00:00
|
|
|
if !self.services.users.exists(&user_id).await {
|
2024-04-27 01:06:43 -04:00
|
|
|
return Ok(RoomMessageEventContent::text_plain(
|
|
|
|
"Remote user does not exist in our database.",
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2024-07-27 00:11:41 +00:00
|
|
|
let mut rooms: Vec<(OwnedRoomId, u64, String)> = self
|
|
|
|
.services
|
2024-04-27 01:06:43 -04:00
|
|
|
.rooms
|
|
|
|
.state_cache
|
|
|
|
.rooms_joined(&user_id)
|
2024-08-08 17:18:30 +00:00
|
|
|
.then(|room_id| get_room_info(self.services, room_id))
|
|
|
|
.collect()
|
|
|
|
.await;
|
2024-04-27 01:06:43 -04:00
|
|
|
|
|
|
|
if rooms.is_empty() {
|
|
|
|
return Ok(RoomMessageEventContent::text_plain("User is not in any rooms."));
|
|
|
|
}
|
|
|
|
|
|
|
|
rooms.sort_by_key(|r| r.1);
|
|
|
|
rooms.reverse();
|
|
|
|
|
2024-10-27 13:21:16 -04:00
|
|
|
let output = format!(
|
|
|
|
"Rooms {user_id} shares with us ({}):\n```\n{}\n```",
|
2024-06-10 03:27:15 -04:00
|
|
|
rooms.len(),
|
2024-04-27 01:06:43 -04:00
|
|
|
rooms
|
|
|
|
.iter()
|
2024-10-27 13:21:16 -04:00
|
|
|
.map(|(id, members, name)| format!("{id} | Members: {members} | Name: {name}"))
|
2024-04-27 01:06:43 -04:00
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join("\n")
|
|
|
|
);
|
|
|
|
|
2024-10-27 13:21:16 -04:00
|
|
|
Ok(RoomMessageEventContent::text_markdown(output))
|
2024-04-27 01:06:43 -04:00
|
|
|
}
|