diff --git a/src/admin/space/roles.rs b/src/admin/space/roles.rs index eb0a5d5a..0782fc8f 100644 --- a/src/admin/space/roles.rs +++ b/src/admin/space/roles.rs @@ -13,6 +13,22 @@ use serde_json::value::to_raw_value; use crate::{admin_command, admin_command_dispatch}; +fn roles_event_type() -> StateEventType { + StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()) +} + +fn member_event_type() -> StateEventType { + StateEventType::from(SPACE_ROLE_MEMBER_EVENT_TYPE.to_owned()) +} + +fn room_event_type() -> StateEventType { + StateEventType::from(SPACE_ROLE_ROOM_EVENT_TYPE.to_owned()) +} + +fn cascading_event_type() -> StateEventType { + StateEventType::from(SPACE_CASCADING_EVENT_TYPE.to_owned()) +} + macro_rules! resolve_room_as_space { ($self:expr, $space:expr) => {{ let space_id = $self.services.rooms.alias.resolve(&$space).await?; @@ -159,7 +175,7 @@ pub enum SpaceRolesCommand { #[admin_command] async fn list(&self, space: OwnedRoomOrAliasId) -> Result { let space_id = resolve_space!(self, space); - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); let content: SpaceRolesEventContent = self .services @@ -195,7 +211,7 @@ async fn add( power_level: Option, ) -> Result { let space_id = resolve_space!(self, space); - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); let mut content: SpaceRolesEventContent = self .services @@ -223,7 +239,7 @@ async fn add( #[admin_command] async fn remove(&self, space: OwnedRoomOrAliasId, role_name: String) -> Result { let space_id = resolve_space!(self, space); - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); let mut content: SpaceRolesEventContent = self .services @@ -239,7 +255,7 @@ async fn remove(&self, space: OwnedRoomOrAliasId, role_name: String) -> Result { send_space_state!(self, space_id, SPACE_ROLES_EVENT_TYPE, "", &content); - let member_event_type = StateEventType::from(SPACE_ROLE_MEMBER_EVENT_TYPE.to_owned()); + let member_event_type = member_event_type(); let server_user = &self.services.globals.server_user; if let Ok(shortstatehash) = self .services @@ -282,7 +298,7 @@ async fn remove(&self, space: OwnedRoomOrAliasId, role_name: String) -> Result { } // Cascade: remove the role from all rooms' role requirement events - let room_event_type = StateEventType::from(SPACE_ROLE_ROOM_EVENT_TYPE.to_owned()); + let room_event_type = room_event_type(); let room_entries: Vec<(_, ruma::OwnedEventId)> = self .services @@ -330,7 +346,7 @@ async fn assign( ) -> Result { let space_id = resolve_space!(self, space); - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); let role_defs: SpaceRolesEventContent = self .services .rooms @@ -343,7 +359,7 @@ async fn assign( return Err!("Role '{role_name}' does not exist in this space."); } - let member_event_type = StateEventType::from(SPACE_ROLE_MEMBER_EVENT_TYPE.to_owned()); + let member_event_type = member_event_type(); let mut content: SpaceRoleMemberEventContent = self .services @@ -373,7 +389,7 @@ async fn revoke( role_name: String, ) -> Result { let space_id = resolve_space!(self, space); - let member_event_type = StateEventType::from(SPACE_ROLE_MEMBER_EVENT_TYPE.to_owned()); + let member_event_type = member_event_type(); let mut content: SpaceRoleMemberEventContent = self .services @@ -405,7 +421,7 @@ async fn require( ) -> Result { let space_id = resolve_space!(self, space); - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); let role_defs: SpaceRolesEventContent = self .services .rooms @@ -418,7 +434,7 @@ async fn require( return Err!("Role '{role_name}' does not exist in this space."); } - let room_event_type = StateEventType::from(SPACE_ROLE_ROOM_EVENT_TYPE.to_owned()); + let room_event_type = room_event_type(); let mut content: SpaceRoleRoomEventContent = self .services @@ -450,7 +466,7 @@ async fn unrequire( role_name: String, ) -> Result { let space_id = resolve_space!(self, space); - let room_event_type = StateEventType::from(SPACE_ROLE_ROOM_EVENT_TYPE.to_owned()); + let room_event_type = room_event_type(); let mut content: SpaceRoleRoomEventContent = self .services @@ -566,7 +582,7 @@ async fn status(&self, space: OwnedRoomOrAliasId) -> Result { let space_id = resolve_room_as_space!(self, space); let global_default = self.services.rooms.roles.is_enabled(); - let cascading_event_type = StateEventType::from(SPACE_CASCADING_EVENT_TYPE.to_owned()); + let cascading_event_type = cascading_event_type(); let per_space_override: Option = self .services .rooms diff --git a/src/service/rooms/roles/mod.rs b/src/service/rooms/roles/mod.rs index 676d5160..0fcfc021 100644 --- a/src/service/rooms/roles/mod.rs +++ b/src/service/rooms/roles/mod.rs @@ -40,6 +40,22 @@ use tokio::sync::RwLock; use crate::{Dep, globals, rooms}; +fn roles_event_type() -> StateEventType { + StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()) +} + +fn member_event_type() -> StateEventType { + StateEventType::from(SPACE_ROLE_MEMBER_EVENT_TYPE.to_owned()) +} + +fn room_event_type() -> StateEventType { + StateEventType::from(SPACE_ROLE_ROOM_EVENT_TYPE.to_owned()) +} + +fn cascading_event_type() -> StateEventType { + StateEventType::from(SPACE_CASCADING_EVENT_TYPE.to_owned()) +} + pub struct Service { services: Services, server: Arc, @@ -164,7 +180,7 @@ pub fn is_enabled(&self) -> bool { self.server.config.space_permission_cascading #[implement(Service)] pub async fn is_enabled_for_space(&self, space_id: &RoomId) -> bool { - let cascading_event_type = StateEventType::from(SPACE_CASCADING_EVENT_TYPE.to_owned()); + let cascading_event_type = cascading_event_type(); if let Ok(content) = self .services .state_accessor @@ -183,7 +199,7 @@ pub async fn ensure_default_roles(&self, space_id: &RoomId) -> Result { return Ok(()); } - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); if self .services .state_accessor @@ -246,7 +262,7 @@ pub async fn populate_space(&self, space_id: &RoomId) { debug_warn!("Space roles cache exceeded capacity, cleared"); } - let roles_event_type = StateEventType::from(SPACE_ROLES_EVENT_TYPE.to_owned()); + let roles_event_type = roles_event_type(); if let Ok(content) = self .services .state_accessor @@ -259,7 +275,7 @@ pub async fn populate_space(&self, space_id: &RoomId) { .insert(space_id.to_owned(), content.roles); } - let member_event_type = StateEventType::from(SPACE_ROLE_MEMBER_EVENT_TYPE.to_owned()); + let member_event_type = member_event_type(); let shortstatehash = match self.services.state.get_room_shortstatehash(space_id).await { | Ok(hash) => hash, | Err(e) => { @@ -298,7 +314,7 @@ pub async fn populate_space(&self, space_id: &RoomId) { .await .insert(space_id.to_owned(), user_roles_map); - let room_event_type = StateEventType::from(SPACE_ROLE_ROOM_EVENT_TYPE.to_owned()); + let room_event_type = room_event_type(); let mut room_reqs_map: HashMap> = HashMap::new(); self.services @@ -653,6 +669,16 @@ async fn invite_and_join_user( Ok(()) } +#[implement(Service)] +async fn sync_power_levels_for_children(&self, space_id: &RoomId) { + let child_rooms = self.get_child_rooms(space_id).await; + for child_room_id in &child_rooms { + if let Err(e) = self.sync_power_levels(space_id, child_room_id).await { + debug_warn!(room_id = %child_room_id, error = ?e, "Failed to sync power levels"); + } + } +} + impl Service { pub fn handle_state_event_change( self: &Arc, @@ -683,12 +709,7 @@ impl Service { match event_type.as_str() { | SPACE_ROLES_EVENT_TYPE => { - let child_rooms = this.get_child_rooms(&space_id).await; - for child_room_id in &child_rooms { - if let Err(e) = this.sync_power_levels(&space_id, child_room_id).await { - debug_warn!(room_id = %child_room_id, error = ?e, "Failed to sync power levels"); - } - } + this.sync_power_levels_for_children(&space_id).await; let space_members: Vec = this .services .state_cache @@ -715,13 +736,7 @@ impl Service { { debug_warn!(user_id = %user_id, error = ?e, "Space role auto-kick failed"); } - let child_rooms = this.get_child_rooms(&space_id).await; - for child_room_id in &child_rooms { - if let Err(e) = this.sync_power_levels(&space_id, child_room_id).await - { - debug_warn!(room_id = %child_room_id, error = ?e, "Failed to sync power levels"); - } - } + this.sync_power_levels_for_children(&space_id).await; } }, | SPACE_ROLE_ROOM_EVENT_TYPE => { @@ -869,12 +884,7 @@ impl Service { if let Err(e) = this.auto_join_qualifying_rooms(&space_id, &user_id).await { debug_warn!(user_id = %user_id, error = ?e, "Auto-join on Space join failed"); } - let child_rooms = this.get_child_rooms(&space_id).await; - for child_room_id in &child_rooms { - if let Err(e) = this.sync_power_levels(&space_id, child_room_id).await { - debug_warn!(room_id = %child_room_id, error = ?e, "Failed to sync power levels on join"); - } - } + this.sync_power_levels_for_children(&space_id).await; }); } }