Refactor Event.redacts_id to look at room version rules, use it

This commit is contained in:
dasha_uwu
2026-03-06 23:52:37 +05:00
committed by Jason Volk
parent 9246636b87
commit fbbea7ae1d
5 changed files with 42 additions and 65 deletions

View File

@@ -11,8 +11,8 @@ mod unsigned;
use std::fmt::Debug; use std::fmt::Debug;
use ruma::{ use ruma::{
CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId,
RoomVersionId, UserId, events::TimelineEventType, events::TimelineEventType, room_version_rules::RoomVersionRules,
}; };
use serde::Deserialize; use serde::Deserialize;
use serde_json::{Value as JsonValue, value::RawValue as RawJsonValue}; use serde_json::{Value as JsonValue, value::RawValue as RawJsonValue};
@@ -107,11 +107,11 @@ pub trait Event: Clone + Debug + Send + Sync {
} }
#[inline] #[inline]
fn redacts_id(&self, room_version: &RoomVersionId) -> Option<OwnedEventId> fn redacts_id(&self, room_rules: &RoomVersionRules) -> Option<OwnedEventId>
where where
Self: Sized, Self: Sized,
{ {
redact::redacts_id(self, room_version) redact::redacts_id(self, room_rules)
} }
#[inline] #[inline]

View File

@@ -1,6 +1,7 @@
use ruma::{ use ruma::{
OwnedEventId, RoomVersionId, OwnedEventId,
events::{TimelineEventType, room::redaction::RoomRedactionEventContent}, events::{TimelineEventType, room::redaction::RoomRedactionEventContent},
room_version_rules::RoomVersionRules,
}; };
use serde::Deserialize; use serde::Deserialize;
use serde_json::value::{RawValue as RawJsonValue, to_raw_value}; use serde_json::value::{RawValue as RawJsonValue, to_raw_value};
@@ -61,22 +62,19 @@ pub(super) fn is_redacted<E: Event>(event: &E) -> bool {
#[must_use] #[must_use]
pub(super) fn redacts_id<E: Event>( pub(super) fn redacts_id<E: Event>(
event: &E, event: &E,
room_version: &RoomVersionId, room_rules: &RoomVersionRules,
) -> Option<OwnedEventId> { ) -> Option<OwnedEventId> {
use RoomVersionId::*;
if *event.kind() != TimelineEventType::RoomRedaction { if *event.kind() != TimelineEventType::RoomRedaction {
return None; return None;
} }
match *room_version { if room_rules.redaction.content_field_redacts {
| V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => event
event.redacts().map(ToOwned::to_owned), .get_content::<RoomRedactionEventContent>()
| _ => .ok()?
event .redacts
.get_content::<RoomRedactionEventContent>() } else {
.ok()? event.redacts().map(ToOwned::to_owned)
.redacts,
} }
} }

View File

@@ -139,7 +139,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
// Soft fail check before doing state res // Soft fail check before doing state res
trace!("Performing soft-fail check"); 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, | None => false,
| Some(redact_id) => | Some(redact_id) =>
!self !self

View File

@@ -1,13 +1,12 @@
use std::{collections::BTreeMap, sync::Arc}; use std::{collections::BTreeMap, sync::Arc};
use ruma::{ use ruma::{
CanonicalJsonObject, CanonicalJsonValue, EventId, RoomVersionId, UserId, CanonicalJsonObject, CanonicalJsonValue, EventId, UserId,
events::{ events::{
TimelineEventType, TimelineEventType,
room::{ room::{
encrypted::Relation, encrypted::Relation,
member::{MembershipState, RoomMemberEventContent}, member::{MembershipState, RoomMemberEventContent},
redaction::RoomRedactionEventContent,
}, },
}, },
}; };
@@ -16,6 +15,7 @@ use tuwunel_core::{
matrix::{ matrix::{
event::Event, event::Event,
pdu::{PduCount, PduEvent, PduId, RawPduId}, pdu::{PduCount, PduEvent, PduId, RawPduId},
room_version,
}, },
utils::{self, result::LogErr}, utils::{self, result::LogErr},
}; };
@@ -211,30 +211,24 @@ async fn append_pdu_effects(
) -> Result { ) -> Result {
match *pdu.kind() { match *pdu.kind() {
| TimelineEventType::RoomRedaction => { | TimelineEventType::RoomRedaction => {
use RoomVersionId::*; let room_version = self
let room_version_id = self
.services .services
.state .state
.get_room_version(pdu.room_id()) .get_room_version(pdu.room_id())
.await?; .await?;
let content: RoomRedactionEventContent; let room_rules = room_version::rules(&room_version)?;
let event_id = match room_version_id {
| V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => pdu.redacts(), let redacts_id = pdu.redacts_id(&room_rules);
| _ => {
content = pdu.get_content()?; if let Some(redacts_id) = &redacts_id
content.redacts.as_deref()
},
};
if let Some(redact_id) = event_id
&& self && self
.services .services
.state_accessor .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? .await?
{ {
self.redact_pdu(redact_id, pdu, shortroomid, state_lock) self.redact_pdu(redacts_id, pdu, shortroomid, state_lock)
.await?; .await?;
} }
}, },

View File

@@ -2,18 +2,15 @@ use std::{collections::HashSet, iter::once};
use futures::{FutureExt, StreamExt}; use futures::{FutureExt, StreamExt};
use ruma::{ use ruma::{
OwnedEventId, OwnedServerName, RoomId, RoomVersionId, UserId, OwnedEventId, OwnedServerName, RoomId, UserId,
events::{ events::{
TimelineEventType, TimelineEventType,
room::{ room::member::{MembershipState, RoomMemberEventContent},
member::{MembershipState, RoomMemberEventContent},
redaction::RoomRedactionEventContent,
},
}, },
}; };
use tuwunel_core::{ use tuwunel_core::{
Err, Result, implement, Err, Result, implement,
matrix::{event::Event, pdu::PduBuilder}, matrix::{event::Event, pdu::PduBuilder, room_version},
utils::{IterStream, ReadyExt}, 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 redaction event is not authorized, do not append it to the timeline
if *pdu.kind() == TimelineEventType::RoomRedaction { if *pdu.kind() == TimelineEventType::RoomRedaction {
use RoomVersionId::*; let room_version = self
match self
.services .services
.state .state
.get_room_version(pdu.room_id()) .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 => { return Err!(Request(Forbidden("User cannot redact this event.")));
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.")));
}
},
} }
} }