admin debug command to fetch a server's true destination

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-04-26 23:36:23 -04:00 committed by June
parent 1cbf2bdc6b
commit 450f15df4f
11 changed files with 329 additions and 42 deletions

View file

@ -8,7 +8,10 @@ use tokio::sync::RwLock;
use tracing::{debug, info, warn};
use tracing_subscriber::EnvFilter;
use crate::{api::server_server::parse_incoming_pdu, services, utils::HtmlEscape, Error, PduEvent, Result};
use crate::{
api::server_server::parse_incoming_pdu, service::sending::send::resolve_actual_dest, services, utils::HtmlEscape,
Error, PduEvent, Result,
};
pub(crate) async fn get_auth_chain(_body: Vec<&str>, event_id: Box<EventId>) -> Result<RoomMessageEventContent> {
let event_id = Arc::<EventId>::from(event_id);
@ -428,3 +431,25 @@ pub(crate) async fn verify_json(body: Vec<&str>) -> Result<RoomMessageEventConte
))
}
}
pub(crate) async fn resolve_true_destination(
_body: Vec<&str>, server_name: Box<ServerName>, no_cache: bool,
) -> Result<RoomMessageEventContent> {
if !services().globals.config.allow_federation {
return Ok(RoomMessageEventContent::text_plain(
"Federation is disabled on this homeserver.",
));
}
if server_name == services().globals.config.server_name {
return Ok(RoomMessageEventContent::text_plain(
"Not allowed to send federation requests to ourselves. Please use `get-pdu` for fetching local PDUs.",
));
}
let (actual_dest, hostname_uri) = resolve_actual_dest(&server_name, no_cache, true).await?;
Ok(RoomMessageEventContent::text_plain(format!(
"Actual destination: {actual_dest:?} | Hostname URI: {hostname_uri}"
)))
}

View file

@ -3,7 +3,7 @@ use ruma::{events::room::message::RoomMessageEventContent, EventId, RoomId, Serv
use self::debug_commands::{
change_log_level, force_device_list_updates, get_auth_chain, get_pdu, get_remote_pdu, get_remote_pdu_list,
get_room_state, parse_pdu, ping, sign_json, verify_json,
get_room_state, parse_pdu, ping, resolve_true_destination, sign_json, verify_json,
};
use crate::Result;
@ -106,6 +106,17 @@ pub(crate) enum DebugCommand {
/// This command needs a JSON blob provided in a Markdown code block below
/// the command.
VerifyJson,
/// - Runs a server name through conduwuit's true destination resolution
/// process
///
/// Useful for debugging well-known issues
ResolveTrueDestination {
server_name: Box<ServerName>,
#[arg(short, long)]
no_cache: bool,
},
}
pub(crate) async fn process(command: DebugCommand, body: Vec<&str>) -> Result<RoomMessageEventContent> {
@ -138,5 +149,9 @@ pub(crate) async fn process(command: DebugCommand, body: Vec<&str>) -> Result<Ro
server,
force,
} => get_remote_pdu_list(body, server, force).await?,
DebugCommand::ResolveTrueDestination {
server_name,
no_cache,
} => resolve_true_destination(body, server_name, no_cache).await?,
})
}

View file

@ -127,7 +127,7 @@ impl Service {
let conduit_user = UserId::parse(format!("@conduit:{}", services().globals.server_name()))
.expect("@conduit:server_name is valid");
if let Ok(Some(conduit_room)) = Self::get_admin_room() {
if let Ok(Some(conduit_room)) = Self::get_admin_room().await {
loop {
tokio::select! {
event = receiver.recv_async() => {
@ -201,15 +201,17 @@ impl Service {
Ok(())
}
pub(crate) fn process_message(&self, room_message: String, event_id: Arc<EventId>) {
pub(crate) async fn process_message(&self, room_message: String, event_id: Arc<EventId>) {
self.sender
.send(AdminRoomEvent::ProcessMessage(room_message, event_id))
.send_async(AdminRoomEvent::ProcessMessage(room_message, event_id))
.await
.unwrap();
}
pub(crate) fn send_message(&self, message_content: RoomMessageEventContent) {
pub(crate) async fn send_message(&self, message_content: RoomMessageEventContent) {
self.sender
.send(AdminRoomEvent::SendMessage(message_content))
.send_async(AdminRoomEvent::SendMessage(message_content))
.await
.unwrap();
}
@ -621,7 +623,7 @@ impl Service {
///
/// Errors are propagated from the database, and will have None if there is
/// no admin room
pub(crate) fn get_admin_room() -> Result<Option<OwnedRoomId>> {
pub(crate) async fn get_admin_room() -> Result<Option<OwnedRoomId>> {
let admin_room_alias: Box<RoomAliasId> = format!("#admins:{}", services().globals.server_name())
.try_into()
.expect("#admins:server_name is a valid alias name");
@ -636,7 +638,7 @@ impl Service {
///
/// In conduit, this is equivalent to granting admin privileges.
pub(crate) async fn make_user_admin(&self, user_id: &UserId, displayname: String) -> Result<()> {
if let Some(room_id) = Self::get_admin_room()? {
if let Some(room_id) = Self::get_admin_room().await? {
let mutex_state = Arc::clone(
services()
.globals

View file

@ -25,7 +25,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
.try_into()
.expect("#admins:server_name is a valid alias name");
if let Some(admin_room_id) = Service::get_admin_room()? {
if let Some(admin_room_id) = Service::get_admin_room().await? {
if room.to_string().eq(&admin_room_id) || room.to_string().eq(&admin_room_alias) {
return Ok(RoomMessageEventContent::text_plain("Not allowed to ban the admin room."));
}
@ -190,7 +190,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
for &room in &rooms_s {
match <&RoomOrAliasId>::try_from(room) {
Ok(room_alias_or_id) => {
if let Some(admin_room_id) = Service::get_admin_room()? {
if let Some(admin_room_id) = Service::get_admin_room().await? {
if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(&admin_room_alias) {
info!("User specified admin room in bulk ban list, ignoring");
continue;