diff --git a/crates/ruma-state-res/CHANGELOG.md b/crates/ruma-state-res/CHANGELOG.md index 5a36c5eb..fb28e50d 100644 --- a/crates/ruma-state-res/CHANGELOG.md +++ b/crates/ruma-state-res/CHANGELOG.md @@ -1,5 +1,9 @@ # [unreleased] +Improvements: + +- Add `RoomVersion::V11` according to MSC3820 + # 0.9.1 No changes for this version diff --git a/crates/ruma-state-res/src/event_auth.rs b/crates/ruma-state-res/src/event_auth.rs index 20a9373e..d18323e8 100644 --- a/crates/ruma-state-res/src/event_auth.rs +++ b/crates/ruma-state-res/src/event_auth.rs @@ -15,7 +15,10 @@ use ruma_common::{ serde::{Base64, Raw}, OwnedUserId, RoomVersionId, UserId, }; -use serde::{de::IgnoredAny, Deserialize}; +use serde::{ + de::{Error as _, IgnoredAny}, + Deserialize, +}; use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue}; use tracing::{debug, error, info, warn}; @@ -175,10 +178,12 @@ pub fn auth_check( return Ok(false); } - // If content has no creator field, reject - if content.creator.is_none() { - warn!("no creator field found in m.room.create content"); - return Ok(false); + if !room_version.use_room_create_sender { + // If content has no creator field, reject + if content.creator.is_none() { + warn!("no creator field found in m.room.create content"); + return Ok(false); + } } info!("m.room.create event was allowed"); @@ -343,11 +348,19 @@ pub fn auth_check( } } else { // If no power level event found the creator gets 100 everyone else gets 0 - #[allow(deprecated)] - from_json_str::(room_create_event.content().get()) - .ok() - .and_then(|create| (create.creator.unwrap() == *sender).then(|| int!(100))) - .unwrap_or_default() + let is_creator = if room_version.use_room_create_sender { + room_create_event.sender() == sender + } else { + #[allow(deprecated)] + from_json_str::(room_create_event.content().get()) + .is_ok_and(|create| create.creator.unwrap() == *sender) + }; + + if is_creator { + int!(100) + } else { + int!(0) + } }; // Allow if and only if sender's current power level is greater than @@ -531,12 +544,21 @@ fn valid_membership_change( let no_more_prev_events = prev_events.next().is_none(); if prev_event_is_create_event && no_more_prev_events { - let create_content = - from_json_str::(create_room.content().get())?; + let is_creator = if room_version.use_room_create_sender { + let creator = create_room.sender(); - #[allow(deprecated)] - let creator = create_content.creator.unwrap(); - if creator == sender && creator == target_user { + creator == sender && creator == target_user + } else { + #[allow(deprecated)] + let creator = + from_json_str::(create_room.content().get())? + .creator + .ok_or_else(|| serde_json::Error::missing_field("creator"))?; + + creator == sender && creator == target_user + }; + + if is_creator { return Ok(true); } } diff --git a/crates/ruma-state-res/src/room_version.rs b/crates/ruma-state-res/src/room_version.rs index f0e6b943..fd581ab9 100644 --- a/crates/ruma-state-res/src/room_version.rs +++ b/crates/ruma-state-res/src/room_version.rs @@ -74,6 +74,11 @@ pub struct RoomVersion { /// /// See: [MSC3667](https://github.com/matrix-org/matrix-spec-proposals/pull/3667) for more information. pub integer_power_levels: bool, + /// Determine the room creator using the `m.room.create` event's `sender`, + /// instead of the event content's `creator` field. + /// + /// See: [MSC2175](https://github.com/matrix-org/matrix-spec-proposals/pull/2175) for more information. + pub use_room_create_sender: bool, } impl RoomVersion { @@ -90,6 +95,7 @@ impl RoomVersion { restricted_join_rules: false, knock_restricted_join_rule: false, integer_power_levels: false, + use_room_create_sender: false, }; pub const V2: Self = Self { state_res: StateResolutionVersion::V2, ..Self::V1 }; @@ -117,6 +123,8 @@ impl RoomVersion { pub const V10: Self = Self { knock_restricted_join_rule: true, integer_power_levels: true, ..Self::V9 }; + pub const V11: Self = Self { use_room_create_sender: true, ..Self::V10 }; + pub fn new(version: &RoomVersionId) -> Result { Ok(match version { RoomVersionId::V1 => Self::V1, @@ -129,6 +137,7 @@ impl RoomVersion { RoomVersionId::V8 => Self::V8, RoomVersionId::V9 => Self::V9, RoomVersionId::V10 => Self::V10, + RoomVersionId::V11 => Self::V11, ver => return Err(Error::Unsupported(format!("found version `{ver}`"))), }) }