Files
tuwunel/src/service/membership/kick.rs
dasha_uwu 8e9c6661b2 Membership refactor
Introduce deactivate, membership services

Move membership and user deactivation functions from api crate into those services
2025-08-28 23:28:20 +05:00

64 lines
1.3 KiB
Rust

use ruma::{
RoomId, UserId,
events::room::member::{MembershipState, RoomMemberEventContent},
};
use tuwunel_core::{Err, Result, implement, pdu::PduBuilder};
use super::Service;
use crate::rooms::timeline::RoomMutexGuard;
#[implement(Service)]
#[tracing::instrument(
level = "debug",
skip_all,
fields(%sender_user, %room_id, %user_id)
)]
pub async fn kick(
&self,
room_id: &RoomId,
user_id: &UserId,
reason: Option<&String>,
sender_user: &UserId,
state_lock: &RoomMutexGuard,
) -> Result {
// kicking doesn't make sense if there is no membership
let Ok(event) = self
.services
.state_accessor
.get_member(room_id, user_id)
.await
else {
return Ok(());
};
// this is required to prevent ban -> leave transitions
if !matches!(
event.membership,
MembershipState::Invite | MembershipState::Knock | MembershipState::Join,
) {
return Err!(Request(Forbidden(
"Cannot kick a user who is not apart of the room (current membership: {})",
event.membership
)));
}
self.services
.timeline
.build_and_append_pdu(
PduBuilder::state(user_id.to_string(), &RoomMemberEventContent {
membership: MembershipState::Leave,
reason: reason.cloned(),
is_direct: None,
join_authorized_via_users_server: None,
third_party_invite: None,
..event
}),
sender_user,
room_id,
state_lock,
)
.await?;
Ok(())
}