Compare commits

...

3 commits

Author SHA1 Message Date
nexy7574
57eae642be
feat: Only inject vias when manual ones aren't provided during join 2025-07-31 17:48:30 +01:00
nexy7574
6a85b6d5b0
fix: Make remote leave helper a public fn 2025-07-30 19:29:33 +01:00
nexy7574
f6ef95c365
feat: Force leave remote rooms admin command 2025-07-30 19:19:32 +01:00
6 changed files with 63 additions and 28 deletions

View file

@ -1,8 +1,8 @@
use std::{collections::BTreeMap, fmt::Write as _};
use api::client::{
full_user_deactivate, join_room_by_id_helper, leave_all_rooms, leave_room, update_avatar_url,
update_displayname,
full_user_deactivate, join_room_by_id_helper, leave_all_rooms, leave_room, remote_leave_room,
update_avatar_url, update_displayname,
};
use conduwuit::{
Err, Result, debug, debug_warn, error, info, is_equal_to,
@ -924,3 +924,29 @@ pub(super) async fn redact_event(&self, event_id: OwnedEventId) -> Result {
))
.await
}
#[admin_command]
pub(super) async fn force_leave_remote_room(
&self,
user_id: String,
room_id: OwnedRoomOrAliasId,
) -> Result {
let user_id = parse_local_user_id(self.services, &user_id)?;
let (room_id, _) = self
.services
.rooms
.alias
.resolve_with_servers(&room_id, None)
.await?;
assert!(
self.services.globals.user_is_local(&user_id),
"Parsed user_id must be a local user"
);
remote_leave_room(self.services, &user_id, &room_id, None)
.boxed()
.await?;
self.write_str(&format!("{user_id} has been joined to {room_id}.",))
.await
}

View file

@ -103,6 +103,12 @@ pub enum UserCommand {
room_id: OwnedRoomOrAliasId,
},
/// - Manually leave a remote room for a local user.
ForceLeaveRemoteRoom {
user_id: String,
room_id: OwnedRoomOrAliasId,
},
/// - Forces the specified user to drop their power levels to the room
/// default, if their permissions allow and the auth check permits
ForceDemote {

View file

@ -156,31 +156,34 @@ pub(crate) async fn join_room_by_id_or_alias_route(
.await?;
let mut servers = body.via.clone();
servers.extend(
services
.rooms
.state_cache
.servers_invite_via(&room_id)
.map(ToOwned::to_owned)
.collect::<Vec<_>>()
.await,
);
if servers.is_empty() {
debug!("No via servers provided for join, injecting some.");
servers.extend(
services
.rooms
.state_cache
.servers_invite_via(&room_id)
.map(ToOwned::to_owned)
.collect::<Vec<_>>()
.await,
);
servers.extend(
services
.rooms
.state_cache
.invite_state(sender_user, &room_id)
.await
.unwrap_or_default()
.iter()
.filter_map(|event| event.get_field("sender").ok().flatten())
.filter_map(|sender: &str| UserId::parse(sender).ok())
.map(|user| user.server_name().to_owned()),
);
servers.extend(
services
.rooms
.state_cache
.invite_state(sender_user, &room_id)
.await
.unwrap_or_default()
.iter()
.filter_map(|event| event.get_field("sender").ok().flatten())
.filter_map(|sender: &str| UserId::parse(sender).ok())
.map(|user| user.server_name().to_owned()),
);
if let Some(server) = room_id.server_name() {
servers.push(server.to_owned());
if let Some(server) = room_id.server_name() {
servers.push(server.to_owned());
}
}
servers.sort_unstable();

View file

@ -215,7 +215,7 @@ pub async fn leave_room(
Ok(())
}
async fn remote_leave_room(
pub async fn remote_leave_room(
services: &Services,
user_id: &UserId,
room_id: &RoomId,

View file

@ -29,7 +29,7 @@ pub(crate) use self::{
};
pub use self::{
join::join_room_by_id_helper,
leave::{leave_all_rooms, leave_room},
leave::{leave_all_rooms, leave_room, remote_leave_room},
};
use crate::{Ruma, client::full_user_deactivate};

View file

@ -54,7 +54,7 @@ pub(super) use keys::*;
pub(super) use media::*;
pub(super) use media_legacy::*;
pub(super) use membership::*;
pub use membership::{join_room_by_id_helper, leave_all_rooms, leave_room};
pub use membership::{join_room_by_id_helper, leave_all_rooms, leave_room, remote_leave_room};
pub(super) use message::*;
pub(super) use openid::*;
pub(super) use presence::*;