state-res: Add RoomVersion::V11

According to MSC3820
This commit is contained in:
Kévin Commaille 2023-08-13 10:57:17 +02:00 committed by Kévin Commaille
parent bcae4e5799
commit afd8f2f652
3 changed files with 50 additions and 15 deletions

View File

@ -1,5 +1,9 @@
# [unreleased] # [unreleased]
Improvements:
- Add `RoomVersion::V11` according to MSC3820
# 0.9.1 # 0.9.1
No changes for this version No changes for this version

View File

@ -15,7 +15,10 @@ use ruma_common::{
serde::{Base64, Raw}, serde::{Base64, Raw},
OwnedUserId, RoomVersionId, UserId, 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 serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
@ -175,11 +178,13 @@ pub fn auth_check<E: Event>(
return Ok(false); return Ok(false);
} }
if !room_version.use_room_create_sender {
// If content has no creator field, reject // If content has no creator field, reject
if content.creator.is_none() { if content.creator.is_none() {
warn!("no creator field found in m.room.create content"); warn!("no creator field found in m.room.create content");
return Ok(false); return Ok(false);
} }
}
info!("m.room.create event was allowed"); info!("m.room.create event was allowed");
return Ok(true); return Ok(true);
@ -343,11 +348,19 @@ pub fn auth_check<E: Event>(
} }
} else { } else {
// If no power level event found the creator gets 100 everyone else gets 0 // If no power level event found the creator gets 100 everyone else gets 0
let is_creator = if room_version.use_room_create_sender {
room_create_event.sender() == sender
} else {
#[allow(deprecated)] #[allow(deprecated)]
from_json_str::<RoomCreateEventContent>(room_create_event.content().get()) from_json_str::<RoomCreateEventContent>(room_create_event.content().get())
.ok() .is_ok_and(|create| create.creator.unwrap() == *sender)
.and_then(|create| (create.creator.unwrap() == *sender).then(|| int!(100))) };
.unwrap_or_default()
if is_creator {
int!(100)
} else {
int!(0)
}
}; };
// Allow if and only if sender's current power level is greater than // 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(); let no_more_prev_events = prev_events.next().is_none();
if prev_event_is_create_event && no_more_prev_events { if prev_event_is_create_event && no_more_prev_events {
let create_content = let is_creator = if room_version.use_room_create_sender {
from_json_str::<RoomCreateEventContent>(create_room.content().get())?; let creator = create_room.sender();
creator == sender && creator == target_user
} else {
#[allow(deprecated)] #[allow(deprecated)]
let creator = create_content.creator.unwrap(); let creator =
if creator == sender && creator == target_user { from_json_str::<RoomCreateEventContent>(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); return Ok(true);
} }
} }

View File

@ -74,6 +74,11 @@ pub struct RoomVersion {
/// ///
/// See: [MSC3667](https://github.com/matrix-org/matrix-spec-proposals/pull/3667) for more information. /// See: [MSC3667](https://github.com/matrix-org/matrix-spec-proposals/pull/3667) for more information.
pub integer_power_levels: bool, 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 { impl RoomVersion {
@ -90,6 +95,7 @@ impl RoomVersion {
restricted_join_rules: false, restricted_join_rules: false,
knock_restricted_join_rule: false, knock_restricted_join_rule: false,
integer_power_levels: false, integer_power_levels: false,
use_room_create_sender: false,
}; };
pub const V2: Self = Self { state_res: StateResolutionVersion::V2, ..Self::V1 }; pub const V2: Self = Self { state_res: StateResolutionVersion::V2, ..Self::V1 };
@ -117,6 +123,8 @@ impl RoomVersion {
pub const V10: Self = pub const V10: Self =
Self { knock_restricted_join_rule: true, integer_power_levels: true, ..Self::V9 }; 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<Self> { pub fn new(version: &RoomVersionId) -> Result<Self> {
Ok(match version { Ok(match version {
RoomVersionId::V1 => Self::V1, RoomVersionId::V1 => Self::V1,
@ -129,6 +137,7 @@ impl RoomVersion {
RoomVersionId::V8 => Self::V8, RoomVersionId::V8 => Self::V8,
RoomVersionId::V9 => Self::V9, RoomVersionId::V9 => Self::V9,
RoomVersionId::V10 => Self::V10, RoomVersionId::V10 => Self::V10,
RoomVersionId::V11 => Self::V11,
ver => return Err(Error::Unsupported(format!("found version `{ver}`"))), ver => return Err(Error::Unsupported(format!("found version `{ver}`"))),
}) })
} }