feat/space-permission-cascading #2

Merged
ember merged 6 commits from feat/space-permission-cascading into deployment 2026-03-20 08:03:11 +00:00
5 changed files with 23 additions and 1 deletions
Showing only changes of commit 1f91a74b27 - Show all commits

View file

@ -0,0 +1 @@
Add Space permission cascading: power levels cascade from Spaces to child rooms, role-based room access with custom roles, continuous enforcement (auto-join/kick), and admin commands for role management. Server-wide default controlled by `space_permission_cascading` config flag (off by default), with per-Space overrides via `!admin space roles enable/disable <space>`.

View file

@ -347,6 +347,12 @@ pub async fn join_room_by_id_helper(
}
}
services
.rooms
.roles
.check_join_allowed(room_id, sender_user)
.await?;
if server_in_room {
join_room_by_id_helper_local(services, sender_user, room_id, reason, servers, state_lock)
.boxed()

View file

@ -327,7 +327,7 @@ where
}
},
| TimelineEventType::SpaceChild =>
if let Some(_state_key) = pdu.state_key() {
if pdu.state_key().is_some() {
self.services
.spaces
.roomid_spacehierarchy_cache
@ -359,6 +359,8 @@ where
| _ => {},
}
self.services.roles.on_pdu_appended(room_id, &pdu);
// CONCERN: If we receive events with a relation out-of-order, we never write
// their relation / thread. We need some kind of way to trigger when we receive
// this event, and potentially a way to rebuild the table entirely.

View file

@ -97,6 +97,17 @@ pub async fn build_and_append_pdu(
)));
}
}
if *pdu.kind() == TimelineEventType::RoomPowerLevels {
if let Ok(proposed) =
pdu.get_content::<ruma::events::room::power_levels::RoomPowerLevelsEventContent>()
{
self.services
.roles
.validate_pl_change(&room_id, pdu.sender(), &proposed)
.await?;
}
}
if *pdu.kind() == TimelineEventType::RoomCreate {
trace!("Creating shortroomid for {room_id}");
self.services

View file

@ -80,6 +80,7 @@ struct Services {
threads: Dep<rooms::threads::Service>,
search: Dep<rooms::search::Service>,
spaces: Dep<rooms::spaces::Service>,
roles: Dep<rooms::roles::Service>,
event_handler: Dep<rooms::event_handler::Service>,
}
@ -112,6 +113,7 @@ impl crate::Service for Service {
threads: args.depend::<rooms::threads::Service>("rooms::threads"),
search: args.depend::<rooms::search::Service>("rooms::search"),
spaces: args.depend::<rooms::spaces::Service>("rooms::spaces"),
roles: args.depend::<rooms::roles::Service>("rooms::roles"),
event_handler: args
.depend::<rooms::event_handler::Service>("rooms::event_handler"),
},