diff --git a/src/admin/space/roles.rs b/src/admin/space/roles.rs index 1a583d34..150cb2cc 100644 --- a/src/admin/space/roles.rs +++ b/src/admin/space/roles.rs @@ -568,15 +568,15 @@ async fn room(&self, space: OwnedRoomOrAliasId, room_id: OwnedRoomId) -> Result async fn enable(&self, space: OwnedRoomOrAliasId) -> Result { let space_id = resolve_room_as_space!(self, space); - let content = SpaceCascadingEventContent { enabled: true }; - send_space_state!(self, space_id, SPACE_CASCADING_EVENT_TYPE, "", &content); - self.services .rooms .roles .ensure_default_roles(&space_id) .await?; + let content = SpaceCascadingEventContent { enabled: true }; + send_space_state!(self, space_id, SPACE_CASCADING_EVENT_TYPE, "", &content); + self.write_str(&format!("Space permission cascading enabled for {space_id}.")) .await } diff --git a/src/service/rooms/roles/mod.rs b/src/service/rooms/roles/mod.rs index 1e3238c6..e8501ea0 100644 --- a/src/service/rooms/roles/mod.rs +++ b/src/service/rooms/roles/mod.rs @@ -733,12 +733,21 @@ pub fn on_pdu_appended(self: &Arc, room_id: &RoomId, pdu: &PduEvent) { } if *pdu.kind() == ruma::events::TimelineEventType::RoomMember { if let Ok(content) = pdu.get_content::() { - if content.membership == MembershipState::Join { - if let Ok(user_id) = UserId::parse(&*state_key) { - self.handle_space_member_join( - room_id.to_owned(), - user_id.to_owned(), - ); + if let Ok(user_id) = UserId::parse(&*state_key) { + match content.membership { + | MembershipState::Join => { + self.handle_space_member_join( + room_id.to_owned(), + user_id.to_owned(), + ); + }, + | MembershipState::Leave | MembershipState::Ban => { + self.handle_space_member_leave( + room_id.to_owned(), + user_id.to_owned(), + ); + }, + | _ => {}, } } } @@ -1089,6 +1098,35 @@ impl Service { this.sync_power_levels_for_children(&space_id).await; }); } + + pub fn handle_space_member_leave( + self: &Arc, + space_id: OwnedRoomId, + user_id: OwnedUserId, + ) { + if user_id == self.services.globals.server_user { + return; + } + + let this = Arc::clone(self); + self.server.runtime().spawn(async move { + if !this.server.running() { + return; + } + if !this.is_enabled_for_space(&space_id).await { + return; + } + + let Ok(_permit) = this.enforcement_semaphore.acquire().await else { + return; + }; + + if let Err(e) = Box::pin(this.kick_unqualified_from_rooms(&space_id, &user_id)).await + { + debug_warn!(user_id = %user_id, error = ?e, "Kick on Space leave failed"); + } + }); + } } #[implement(Service)]