diff --git a/src/core/matrix/event.rs b/src/core/matrix/event.rs index a9b958bf..ff7b927b 100644 --- a/src/core/matrix/event.rs +++ b/src/core/matrix/event.rs @@ -11,8 +11,8 @@ mod unsigned; use std::fmt::Debug; use ruma::{ - CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, - RoomVersionId, UserId, events::TimelineEventType, + CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId, + events::TimelineEventType, room_version_rules::RoomVersionRules, }; use serde::Deserialize; use serde_json::{Value as JsonValue, value::RawValue as RawJsonValue}; @@ -107,11 +107,11 @@ pub trait Event: Clone + Debug + Send + Sync { } #[inline] - fn redacts_id(&self, room_version: &RoomVersionId) -> Option + fn redacts_id(&self, room_rules: &RoomVersionRules) -> Option where Self: Sized, { - redact::redacts_id(self, room_version) + redact::redacts_id(self, room_rules) } #[inline] diff --git a/src/core/matrix/event/redact.rs b/src/core/matrix/event/redact.rs index 5deac874..458b2da7 100644 --- a/src/core/matrix/event/redact.rs +++ b/src/core/matrix/event/redact.rs @@ -1,6 +1,7 @@ use ruma::{ - OwnedEventId, RoomVersionId, + OwnedEventId, events::{TimelineEventType, room::redaction::RoomRedactionEventContent}, + room_version_rules::RoomVersionRules, }; use serde::Deserialize; use serde_json::value::{RawValue as RawJsonValue, to_raw_value}; @@ -61,22 +62,19 @@ pub(super) fn is_redacted(event: &E) -> bool { #[must_use] pub(super) fn redacts_id( event: &E, - room_version: &RoomVersionId, + room_rules: &RoomVersionRules, ) -> Option { - use RoomVersionId::*; - if *event.kind() != TimelineEventType::RoomRedaction { return None; } - match *room_version { - | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => - event.redacts().map(ToOwned::to_owned), - | _ => - event - .get_content::() - .ok()? - .redacts, + if room_rules.redaction.content_field_redacts { + event + .get_content::() + .ok()? + .redacts + } else { + event.redacts().map(ToOwned::to_owned) } } diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 996f39cf..2279989e 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -139,7 +139,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( // Soft fail check before doing state res trace!("Performing soft-fail check"); - let soft_fail = match incoming_pdu.redacts_id(room_version) { + let soft_fail = match incoming_pdu.redacts_id(&room_rules) { | None => false, | Some(redact_id) => !self diff --git a/src/service/rooms/timeline/append.rs b/src/service/rooms/timeline/append.rs index 74e0bc4d..07dce70e 100644 --- a/src/service/rooms/timeline/append.rs +++ b/src/service/rooms/timeline/append.rs @@ -1,13 +1,12 @@ use std::{collections::BTreeMap, sync::Arc}; use ruma::{ - CanonicalJsonObject, CanonicalJsonValue, EventId, RoomVersionId, UserId, + CanonicalJsonObject, CanonicalJsonValue, EventId, UserId, events::{ TimelineEventType, room::{ encrypted::Relation, member::{MembershipState, RoomMemberEventContent}, - redaction::RoomRedactionEventContent, }, }, }; @@ -16,6 +15,7 @@ use tuwunel_core::{ matrix::{ event::Event, pdu::{PduCount, PduEvent, PduId, RawPduId}, + room_version, }, utils::{self, result::LogErr}, }; @@ -211,30 +211,24 @@ async fn append_pdu_effects( ) -> Result { match *pdu.kind() { | TimelineEventType::RoomRedaction => { - use RoomVersionId::*; - - let room_version_id = self + let room_version = self .services .state .get_room_version(pdu.room_id()) .await?; - let content: RoomRedactionEventContent; - let event_id = match room_version_id { - | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => pdu.redacts(), - | _ => { - content = pdu.get_content()?; - content.redacts.as_deref() - }, - }; - if let Some(redact_id) = event_id + let room_rules = room_version::rules(&room_version)?; + + let redacts_id = pdu.redacts_id(&room_rules); + + if let Some(redacts_id) = &redacts_id && self .services .state_accessor - .user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false) + .user_can_redact(redacts_id, pdu.sender(), pdu.room_id(), false) .await? { - self.redact_pdu(redact_id, pdu, shortroomid, state_lock) + self.redact_pdu(redacts_id, pdu, shortroomid, state_lock) .await?; } }, diff --git a/src/service/rooms/timeline/build.rs b/src/service/rooms/timeline/build.rs index ab53499c..48612592 100644 --- a/src/service/rooms/timeline/build.rs +++ b/src/service/rooms/timeline/build.rs @@ -2,18 +2,15 @@ use std::{collections::HashSet, iter::once}; use futures::{FutureExt, StreamExt}; use ruma::{ - OwnedEventId, OwnedServerName, RoomId, RoomVersionId, UserId, + OwnedEventId, OwnedServerName, RoomId, UserId, events::{ TimelineEventType, - room::{ - member::{MembershipState, RoomMemberEventContent}, - redaction::RoomRedactionEventContent, - }, + room::member::{MembershipState, RoomMemberEventContent}, }, }; use tuwunel_core::{ Err, Result, implement, - matrix::{event::Event, pdu::PduBuilder}, + matrix::{event::Event, pdu::PduBuilder, room_version}, utils::{IterStream, ReadyExt}, }; @@ -62,36 +59,24 @@ pub async fn build_and_append_pdu( // If redaction event is not authorized, do not append it to the timeline if *pdu.kind() == TimelineEventType::RoomRedaction { - use RoomVersionId::*; - match self + let room_version = self .services .state .get_room_version(pdu.room_id()) - .await? + .await?; + + let room_rules = room_version::rules(&room_version)?; + + let redacts_id = pdu.redacts_id(&room_rules); + + if let Some(redacts_id) = &redacts_id + && !self + .services + .state_accessor + .user_can_redact(redacts_id, pdu.sender(), pdu.room_id(), false) + .await? { - | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { - if let Some(redact_id) = pdu.redacts() - && !self - .services - .state_accessor - .user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false) - .await? - { - return Err!(Request(Forbidden("User cannot redact this event."))); - } - }, - | _ => { - let content: RoomRedactionEventContent = pdu.get_content()?; - if let Some(redact_id) = &content.redacts - && !self - .services - .state_accessor - .user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false) - .await? - { - return Err!(Request(Forbidden("User cannot redact this event."))); - } - }, + return Err!(Request(Forbidden("User cannot redact this event."))); } }