mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-13 12:16:54 +00:00
feat: Move & merge some membership-related commands into rooms membership
This commit is contained in:
5 files changed
+129
-138
No files matched your search
@@ -0,0 +1,117 @@
|
||||
use std::hash::RandomState;
|
||||
|
||||
use clap::Subcommand;
|
||||
use conduwuit::{Err, Result, info};
|
||||
use conduwuit_macros::admin_command_dispatch;
|
||||
use ruma::{OwnedRoomOrAliasId, OwnedServerName, OwnedUserId};
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomMembershipCommands {
|
||||
/// Make a local user join a room.
|
||||
#[clap(name = "join")]
|
||||
JoinRoom {
|
||||
/// The user to make join the room. Must be a local user.
|
||||
user_id: OwnedUserId,
|
||||
/// The room (ID or alias) to join.
|
||||
room: OwnedRoomOrAliasId,
|
||||
/// The server to join through, if a remote room.
|
||||
///
|
||||
/// Residents returned after resolving an alias override this option.
|
||||
#[arg(long)]
|
||||
via: Option<OwnedServerName>,
|
||||
},
|
||||
/// Make a local user leave a room or reject an invite.
|
||||
#[clap(name = "leave", alias = "reject-invite")]
|
||||
LeaveRoom {
|
||||
/// The user to make leave the room. Must be a local user.
|
||||
user_id: OwnedUserId,
|
||||
/// The room (ID or alias) to leave.
|
||||
room: OwnedRoomOrAliasId,
|
||||
/// The server to leave through, if a room we are not a member of (e.g.
|
||||
/// an invite).
|
||||
///
|
||||
/// Residents returned after resolving an alias override this option.
|
||||
#[arg(long)]
|
||||
via: Option<OwnedServerName>,
|
||||
},
|
||||
}
|
||||
|
||||
impl crate::Context<'_> {
|
||||
pub(super) async fn join_room(
|
||||
&self,
|
||||
user_id: OwnedUserId,
|
||||
room: OwnedRoomOrAliasId,
|
||||
via: Option<OwnedServerName>,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
if !self.services.globals.user_is_local(&user_id) {
|
||||
return Err!("User {user_id:?} does not belong to our server.");
|
||||
}
|
||||
let (room_id, residents) = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_with_servers(&room, via.map(|v| vec![v]))
|
||||
.await?;
|
||||
self.services
|
||||
.rooms
|
||||
.membership
|
||||
.join_room(&user_id, &room_id, None, &residents)
|
||||
.await?;
|
||||
self.write_str(&format!("Successfully joined {room_id} as {user_id}."))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn leave_room(
|
||||
&self,
|
||||
user_id: OwnedUserId,
|
||||
room: OwnedRoomOrAliasId,
|
||||
via: Option<OwnedServerName>,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
if !self.services.globals.user_is_local(&user_id) {
|
||||
return Err!("User {user_id:?} does not belong to our server.");
|
||||
}
|
||||
let no_explicit_via = via.is_none();
|
||||
let (room_id, residents) = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_with_servers(&room, via.map(|v| vec![v]))
|
||||
.await?;
|
||||
if no_explicit_via
|
||||
|| self
|
||||
.services
|
||||
.rooms
|
||||
.state_cache
|
||||
.server_in_room(self.services.globals.server_name(), &room_id)
|
||||
.await
|
||||
{
|
||||
if !self
|
||||
.services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(&user_id, &room_id)
|
||||
.await
|
||||
{
|
||||
return Err!("User {user_id:?} is not a member of room {room_id:?}.");
|
||||
}
|
||||
|
||||
info!("Leaving room locally...");
|
||||
conduwuit_api::client::leave_room(self.services, &user_id, &room_id, None).await?;
|
||||
} else {
|
||||
info!("Leaving room remotely...");
|
||||
conduwuit_api::client::remote_leave_room::<RandomState>(
|
||||
self.services,
|
||||
&user_id,
|
||||
&room_id,
|
||||
None,
|
||||
residents.into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
self.write_str(&format!("Successfully made {user_id} leave {room_id}."))
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ mod commands;
|
||||
mod directory;
|
||||
mod graph;
|
||||
mod info;
|
||||
mod membership;
|
||||
mod moderation;
|
||||
mod state;
|
||||
|
||||
@@ -12,9 +13,10 @@ use ruma::OwnedRoomId;
|
||||
|
||||
use self::{
|
||||
alias::RoomAliasCommand, directory::RoomDirectoryCommand, graph::GraphCommand,
|
||||
info::RoomInfoCommand, moderation::RoomModerationCommand,
|
||||
info::RoomInfoCommand, membership::RoomMembershipCommands, moderation::RoomModerationCommand,
|
||||
state::RoomStateCommand,
|
||||
};
|
||||
use crate::{admin_command_dispatch, room::state::RoomStateCommand};
|
||||
use crate::admin_command_dispatch;
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
@@ -58,6 +60,10 @@ pub enum RoomCommand {
|
||||
#[command(subcommand)]
|
||||
Directory(RoomDirectoryCommand),
|
||||
|
||||
/// Manage room memberships (join, leave, invite, etc.) for local users.
|
||||
#[command(subcommand)]
|
||||
Membership(RoomMembershipCommands),
|
||||
|
||||
/// Interface with room graphs directly (advanced).
|
||||
#[command(subcommand)]
|
||||
Graph(GraphCommand),
|
||||
|
||||
+3
-109
@@ -1,8 +1,6 @@
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use api::client::{
|
||||
full_user_deactivate, leave_room, recreate_push_rules_and_return, remote_leave_room,
|
||||
};
|
||||
use api::client::{full_user_deactivate, leave_room, recreate_push_rules_and_return};
|
||||
use conduwuit::{
|
||||
Err, Result, debug_warn, info,
|
||||
matrix::{Event, pdu::PartialPdu},
|
||||
@@ -12,8 +10,7 @@ use conduwuit::{
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use lettre::Address;
|
||||
use ruma::{
|
||||
OwnedEventId, OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, ServerName,
|
||||
UserId, assign,
|
||||
OwnedEventId, OwnedRoomId, OwnedRoomOrAliasId, OwnedUserId, UserId, assign,
|
||||
events::{
|
||||
RoomAccountDataEventType,
|
||||
room::{power_levels::RoomPowerLevelsEventContent, redaction::RoomRedactionEventContent},
|
||||
@@ -667,69 +664,6 @@ impl crate::Context<'_> {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn force_join_room(
|
||||
&self,
|
||||
user_id: String,
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
via: Option<String>,
|
||||
) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
let (room_id, mut servers) = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_with_servers(&room_id, None)
|
||||
.await?;
|
||||
if let Some(via) = via.map(ServerName::parse).transpose()? {
|
||||
servers.retain(|n| *n != via);
|
||||
servers.insert(0, via);
|
||||
}
|
||||
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
self.services
|
||||
.rooms
|
||||
.membership
|
||||
.join_room(&user_id, &room_id, None, &servers)
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("{user_id} has been joined to {room_id}."))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn force_leave_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(&room_id).await?;
|
||||
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
|
||||
if !self
|
||||
.services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(&user_id, &room_id)
|
||||
.await
|
||||
{
|
||||
return Err!("{user_id} is not joined in the room");
|
||||
}
|
||||
|
||||
leave_room(self.services, &user_id, &room_id, None)
|
||||
.boxed()
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("{user_id} has left {room_id}."))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn force_demote(
|
||||
&self,
|
||||
user_id: String,
|
||||
@@ -943,46 +877,6 @@ impl crate::Context<'_> {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn force_leave_remote_room(
|
||||
&self,
|
||||
user_id: String,
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
via: Option<String>,
|
||||
) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
let (room_id, vias_raw) = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_with_servers(
|
||||
&room_id,
|
||||
if let Some(v) = via.clone() {
|
||||
Some(vec![ServerName::parse(v)?])
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
let mut vias: HashSet<OwnedServerName> = HashSet::new();
|
||||
if let Some(via) = via {
|
||||
vias.insert(ServerName::parse(via)?);
|
||||
}
|
||||
for server in vias_raw {
|
||||
vias.insert(server);
|
||||
}
|
||||
remote_leave_room(self.services, &user_id, &room_id, None, vias)
|
||||
.boxed()
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("{user_id} successfully left {room_id} via remote server."))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn lock(&self, user_id: String) -> Result {
|
||||
let user_id = parse_active_local_user_id(self.services, &user_id).await?;
|
||||
|
||||
|
||||
@@ -193,32 +193,6 @@ pub enum UserCommand {
|
||||
user_id: String,
|
||||
},
|
||||
|
||||
/// Manually join a local user to a room.
|
||||
ForceJoinRoom {
|
||||
/// The user to join
|
||||
user_id: String,
|
||||
/// The room to join
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
/// The server name to join via.
|
||||
///
|
||||
/// This server will always be tried first, however if more are
|
||||
/// available, they may be tried after.
|
||||
via: Option<String>,
|
||||
},
|
||||
|
||||
/// Manually leave a local user from a room.
|
||||
ForceLeaveRoom {
|
||||
user_id: String,
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
},
|
||||
|
||||
/// Manually leave a remote room for a local user.
|
||||
ForceLeaveRemoteRoom {
|
||||
user_id: String,
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
via: Option<String>,
|
||||
},
|
||||
|
||||
/// Forces the specified user to drop their power levels to the room
|
||||
/// default, if their permissions allow and the auth check permits
|
||||
ForceDemote {
|
||||
|
||||
@@ -214,7 +214,7 @@ pub async fn leave_room(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remote_leave_room<S: ::std::hash::BuildHasher>(
|
||||
pub async fn remote_leave_room<S: std::hash::BuildHasher>(
|
||||
services: &Services,
|
||||
user_id: &UserId,
|
||||
room_id: &RoomId,
|
||||
|
||||
Reference in new issue
Block a user