From 1018d8d6083a9c0813e17852398f0377ae7950ed Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 17 Aug 2025 13:20:30 +0200 Subject: [PATCH] fix: set previous creators to max power level if "upgraded" room doesn't support creator power level --- src/api/client_server/room.rs | 64 +++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/src/api/client_server/room.rs b/src/api/client_server/room.rs index 2efe2e7e..64060a38 100644 --- a/src/api/client_server/room.rs +++ b/src/api/client_server/room.rs @@ -23,13 +23,15 @@ use ruma::{ }, int, serde::JsonObject, - CanonicalJsonObject, CanonicalJsonValue, OwnedRoomAliasId, OwnedUserId, RoomAliasId, + CanonicalJsonObject, CanonicalJsonValue, Int, OwnedRoomAliasId, OwnedUserId, RoomAliasId, + RoomVersionId, }; use serde::Deserialize; use serde_json::{json, value::to_raw_value}; use std::{ cmp::max, collections::{BTreeMap, HashSet}, + str::FromStr, sync::Arc, }; use tracing::{error, info, warn}; @@ -600,16 +602,29 @@ pub async fn upgrade_room_route( .authorization; // Get the old room creation event - let mut create_event_content = serde_json::from_str::( - services() - .rooms - .state_accessor - .room_state_get(&body.room_id, &StateEventType::RoomCreate, "")? - .ok_or_else(|| Error::bad_database("Found room without m.room.create event."))? - .content - .get(), - ) - .map_err(|_| Error::bad_database("Invalid room event in database."))?; + let create_event = services() + .rooms + .state_accessor + .room_state_get(&body.room_id, &StateEventType::RoomCreate, "")? + .ok_or_else(|| Error::bad_database("Found room without m.room.create event."))?; + + let mut create_event_content = + serde_json::from_str::(create_event.content.get()) + .map_err(|_| Error::bad_database("Invalid room event in database."))?; + + let old_rules = if let Some(CanonicalJsonValue::String(old_version)) = + create_event_content.get("room_version") + { + RoomVersionId::from_str(old_version) + .map_err(|_| Error::BadDatabase("Create event must be a valid room version ID"))? + .rules() + .expect("Supported room version must have rules") + .authorization + } else { + return Err(Error::BadDatabase( + "Room create event does not have content", + )); + }; // Use the m.room.tombstone event as the predecessor let predecessor = Some(ruma::events::room::create::PreviousRoom::new( @@ -772,8 +787,7 @@ pub async fn upgrade_room_route( None => continue, // Skipping missing events. }; - if event_type == StateEventType::RoomPowerLevels && rules.explicitly_privilege_room_creators - { + if event_type == StateEventType::RoomPowerLevels { let mut pl_event_content: CanonicalJsonObject = serde_json::from_str(event_content.get()).map_err(|e| { error!( @@ -784,11 +798,27 @@ pub async fn upgrade_room_route( })?; if let Some(CanonicalJsonValue::Object(users)) = pl_event_content.get_mut("users") { - users.remove(sender_user.as_str()); + if rules.explicitly_privilege_room_creators { + users.remove(sender_user.as_str()); - if rules.additional_room_creators { - for user in &body.additional_creators { - users.remove(user.as_str()); + if rules.additional_room_creators { + for user in &body.additional_creators { + users.remove(user.as_str()); + } + } + } else if old_rules.explicitly_privilege_room_creators { + users.insert(create_event.sender.to_string(), Int::MAX.into()); + + if old_rules.additional_room_creators { + if let Some(CanonicalJsonValue::Array(creators)) = + create_event_content.get("additional_creators") + { + for creator in creators { + if let CanonicalJsonValue::String(creator) = creator { + users.insert(creator.to_owned(), Int::MAX.into()); + } + } + } } } }