leave room locally if room is banned, rescind knocks on deactivation too
Signed-off-by: June Clementine Strawberry <june@3.dog>
This commit is contained in:
parent
24be579477
commit
f14756fb76
5 changed files with 87 additions and 28 deletions
|
@ -475,9 +475,9 @@ pub(crate) async fn leave_room_route(
|
|||
State(services): State<crate::State>,
|
||||
body: Ruma<leave_room::v3::Request>,
|
||||
) -> Result<leave_room::v3::Response> {
|
||||
leave_room(&services, body.sender_user(), &body.room_id, body.reason.clone()).await?;
|
||||
|
||||
Ok(leave_room::v3::Response::new())
|
||||
leave_room(&services, body.sender_user(), &body.room_id, body.reason.clone())
|
||||
.await
|
||||
.map(|()| leave_room::v3::Response::new())
|
||||
}
|
||||
|
||||
/// # `POST /_matrix/client/r0/rooms/{roomId}/invite`
|
||||
|
@ -1763,8 +1763,8 @@ pub(crate) async fn invite_helper(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Make a user leave all their joined rooms, forgets all rooms, and ignores
|
||||
// errors
|
||||
// Make a user leave all their joined rooms, rescinds knocks, forgets all rooms,
|
||||
// and ignores errors
|
||||
pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
|
||||
let rooms_joined = services
|
||||
.rooms
|
||||
|
@ -1778,7 +1778,17 @@ pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
|
|||
.rooms_invited(user_id)
|
||||
.map(|(r, _)| r);
|
||||
|
||||
let all_rooms: Vec<_> = rooms_joined.chain(rooms_invited).collect().await;
|
||||
let rooms_knocked = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.rooms_knocked(user_id)
|
||||
.map(|(r, _)| r);
|
||||
|
||||
let all_rooms: Vec<_> = rooms_joined
|
||||
.chain(rooms_invited)
|
||||
.chain(rooms_knocked)
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
for room_id in all_rooms {
|
||||
// ignore errors
|
||||
|
@ -1795,7 +1805,40 @@ pub async fn leave_room(
|
|||
user_id: &UserId,
|
||||
room_id: &RoomId,
|
||||
reason: Option<String>,
|
||||
) -> Result<()> {
|
||||
) -> Result {
|
||||
let default_member_content = RoomMemberEventContent {
|
||||
membership: MembershipState::Leave,
|
||||
reason: reason.clone(),
|
||||
join_authorized_via_users_server: None,
|
||||
is_direct: None,
|
||||
avatar_url: None,
|
||||
displayname: None,
|
||||
third_party_invite: None,
|
||||
blurhash: None,
|
||||
};
|
||||
|
||||
if services.rooms.metadata.is_banned(room_id).await
|
||||
|| services.rooms.metadata.is_disabled(room_id).await
|
||||
{
|
||||
// the room is banned/disabled, the room must be rejected locally since we
|
||||
// cant/dont want to federate with this server
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.update_membership(
|
||||
room_id,
|
||||
user_id,
|
||||
default_member_content,
|
||||
user_id,
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Ask a remote server if we don't have this room and are not knocking on it
|
||||
if !services
|
||||
.rooms
|
||||
|
@ -1828,7 +1871,7 @@ pub async fn leave_room(
|
|||
.update_membership(
|
||||
room_id,
|
||||
user_id,
|
||||
RoomMemberEventContent::new(MembershipState::Leave),
|
||||
default_member_content,
|
||||
user_id,
|
||||
last_state,
|
||||
None,
|
||||
|
@ -1848,26 +1891,23 @@ pub async fn leave_room(
|
|||
)
|
||||
.await
|
||||
else {
|
||||
// Fix for broken rooms
|
||||
warn!(
|
||||
debug_warn!(
|
||||
"Trying to leave a room you are not a member of, marking room as left locally."
|
||||
);
|
||||
|
||||
services
|
||||
return services
|
||||
.rooms
|
||||
.state_cache
|
||||
.update_membership(
|
||||
room_id,
|
||||
user_id,
|
||||
RoomMemberEventContent::new(MembershipState::Leave),
|
||||
default_member_content,
|
||||
user_id,
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
.await;
|
||||
};
|
||||
|
||||
services
|
||||
|
@ -1897,7 +1937,7 @@ async fn remote_leave_room(
|
|||
room_id: &RoomId,
|
||||
) -> Result<()> {
|
||||
let mut make_leave_response_and_server =
|
||||
Err!(BadServerResponse("No server available to assist in leaving."));
|
||||
Err!(BadServerResponse("No remote server available to assist in leaving {room_id}."));
|
||||
|
||||
let mut servers: HashSet<OwnedServerName> = services
|
||||
.rooms
|
||||
|
@ -1977,20 +2017,25 @@ async fn remote_leave_room(
|
|||
let (make_leave_response, remote_server) = make_leave_response_and_server?;
|
||||
|
||||
let Some(room_version_id) = make_leave_response.room_version else {
|
||||
return Err!(BadServerResponse("Remote room version is not supported by conduwuit"));
|
||||
return Err!(BadServerResponse(warn!(
|
||||
"No room version was returned by {remote_server} for {room_id}, room version is \
|
||||
likely not supported by conduwuit"
|
||||
)));
|
||||
};
|
||||
|
||||
if !services.server.supported_room_version(&room_version_id) {
|
||||
return Err!(BadServerResponse(
|
||||
"Remote room version {room_version_id} is not supported by conduwuit"
|
||||
));
|
||||
return Err!(BadServerResponse(warn!(
|
||||
"Remote room version {room_version_id} for {room_id} is not supported by conduwuit",
|
||||
)));
|
||||
}
|
||||
|
||||
let mut leave_event_stub = serde_json::from_str::<CanonicalJsonObject>(
|
||||
make_leave_response.event.get(),
|
||||
)
|
||||
.map_err(|e| {
|
||||
err!(BadServerResponse("Invalid make_leave event json received from server: {e:?}"))
|
||||
err!(BadServerResponse(warn!(
|
||||
"Invalid make_leave event json received from {remote_server} for {room_id}: {e:?}"
|
||||
)))
|
||||
})?;
|
||||
|
||||
// TODO: Is origin needed?
|
||||
|
|
|
@ -15,6 +15,7 @@ use conduwuit::{
|
|||
math::ruma_from_u64,
|
||||
stream::{BroadbandExt, Tools, TryExpect, WidebandExt},
|
||||
},
|
||||
warn,
|
||||
};
|
||||
use conduwuit_service::{
|
||||
Services,
|
||||
|
@ -428,9 +429,12 @@ async fn handle_left_room(
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
if !services.rooms.metadata.exists(room_id).await {
|
||||
if !services.rooms.metadata.exists(room_id).await
|
||||
|| services.rooms.metadata.is_disabled(room_id).await
|
||||
|| services.rooms.metadata.is_banned(room_id).await
|
||||
{
|
||||
// This is just a rejected invite, not a room we know
|
||||
// Insert a leave event anyways
|
||||
// Insert a leave event anyways for the client
|
||||
let event = PduEvent {
|
||||
event_id: EventId::new(services.globals.server_name()),
|
||||
sender: sender_user.to_owned(),
|
||||
|
@ -489,7 +493,7 @@ async fn handle_left_room(
|
|||
.room_state_get_id(room_id, &StateEventType::RoomMember, sender_user.as_str())
|
||||
.await
|
||||
else {
|
||||
error!("Left room but no left state event");
|
||||
warn!("Left {room_id} but no left state event");
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
|
@ -499,7 +503,7 @@ async fn handle_left_room(
|
|||
.pdu_shortstatehash(&left_event_id)
|
||||
.await
|
||||
else {
|
||||
error!(event_id = %left_event_id, "Leave event has no state");
|
||||
warn!(event_id = %left_event_id, "Leave event has no state in {room_id}");
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
|
|
|
@ -438,7 +438,10 @@ pub(crate) async fn sync_events_v4_route(
|
|||
|
||||
let mut known_subscription_rooms = BTreeSet::new();
|
||||
for (room_id, room) in &body.room_subscriptions {
|
||||
if !services.rooms.metadata.exists(room_id).await {
|
||||
if !services.rooms.metadata.exists(room_id).await
|
||||
|| services.rooms.metadata.is_disabled(room_id).await
|
||||
|| services.rooms.metadata.is_banned(room_id).await
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let todo_room =
|
||||
|
|
|
@ -214,7 +214,10 @@ async fn fetch_subscriptions(
|
|||
) {
|
||||
let mut known_subscription_rooms = BTreeSet::new();
|
||||
for (room_id, room) in &body.room_subscriptions {
|
||||
if !services.rooms.metadata.exists(room_id).await {
|
||||
if !services.rooms.metadata.exists(room_id).await
|
||||
|| services.rooms.metadata.is_disabled(room_id).await
|
||||
|| services.rooms.metadata.is_banned(room_id).await
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let todo_room =
|
||||
|
|
|
@ -40,6 +40,7 @@ struct Services {
|
|||
account_data: Dep<account_data::Service>,
|
||||
config: Dep<config::Service>,
|
||||
globals: Dep<globals::Service>,
|
||||
metadata: Dep<rooms::metadata::Service>,
|
||||
state_accessor: Dep<rooms::state_accessor::Service>,
|
||||
users: Dep<users::Service>,
|
||||
}
|
||||
|
@ -73,6 +74,7 @@ impl crate::Service for Service {
|
|||
account_data: args.depend::<account_data::Service>("account_data"),
|
||||
config: args.depend::<config::Service>("config"),
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
metadata: args.depend::<rooms::metadata::Service>("rooms::metadata"),
|
||||
state_accessor: args
|
||||
.depend::<rooms::state_accessor::Service>("rooms::state_accessor"),
|
||||
users: args.depend::<users::Service>("users"),
|
||||
|
@ -271,7 +273,9 @@ impl Service {
|
|||
self.mark_as_left(user_id, room_id);
|
||||
|
||||
if self.services.globals.user_is_local(user_id)
|
||||
&& self.services.config.forget_forced_upon_leave
|
||||
&& (self.services.config.forget_forced_upon_leave
|
||||
|| self.services.metadata.is_banned(room_id).await
|
||||
|| self.services.metadata.is_disabled(room_id).await)
|
||||
{
|
||||
self.forget(room_id, user_id);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue