From 67b4f19c60b00f6637b0eed218d0fd298dd3f0d3 Mon Sep 17 00:00:00 2001 From: strawberry <strawberry@puppygock.gay> Date: Sun, 21 Apr 2024 13:02:56 -0400 Subject: [PATCH] simplify room v11 top level redacts key Signed-off-by: strawberry <strawberry@puppygock.gay> --- src/service/pdu.rs | 63 +++++++++++++++++++++++++------ src/service/rooms/timeline/mod.rs | 15 -------- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/service/pdu.rs b/src/service/pdu.rs index 6dc965ff8..d8f020e6c 100644 --- a/src/service/pdu.rs +++ b/src/service/pdu.rs @@ -3,9 +3,10 @@ use ruma::{ canonical_json::redact_content_in_place, events::{ - room::member::RoomMemberEventContent, space::child::HierarchySpaceChildEvent, AnyEphemeralRoomEvent, - AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent, - AnyTimelineEvent, StateEvent, TimelineEventType, + room::{member::RoomMemberEventContent, redaction::RoomRedactionEventContent}, + space::child::HierarchySpaceChildEvent, + AnyEphemeralRoomEvent, AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent, + AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, TimelineEventType, }, serde::Raw, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, @@ -98,10 +99,47 @@ pub fn add_age(&mut self) -> crate::Result<()> { Ok(()) } + /// Copies the `redacts` property of the event to the `content` dict and + /// vice-versa. + /// + /// This follows the specification's + /// [recommendation](https://spec.matrix.org/v1.10/rooms/v11/#moving-the-redacts-property-of-mroomredaction-events-to-a-content-property): + /// + /// > For backwards-compatibility with older clients, servers should add a + /// > redacts + /// > property to the top level of m.room.redaction events in when serving + /// > such events + /// > over the Client-Server API. + /// + /// > For improved compatibility with newer clients, servers should add a + /// > redacts property + /// > to the content of m.room.redaction events in older room versions when + /// > serving + /// > such events over the Client-Server API. + #[must_use] + pub fn copy_redacts(&self) -> (Option<Arc<EventId>>, Box<RawJsonValue>) { + if self.kind == TimelineEventType::RoomRedaction { + if let Ok(mut content) = serde_json::from_str::<RoomRedactionEventContent>(self.content.get()) { + if let Some(redacts) = content.redacts { + return (Some(redacts.into()), self.content.clone()); + } else if let Some(redacts) = self.redacts.clone() { + content.redacts = Some(redacts.into()); + return ( + self.redacts.clone(), + to_raw_value(&content).expect("Must be valid, we only added redacts field"), + ); + } + } + } + + (self.redacts.clone(), self.content.clone()) + } + #[tracing::instrument(skip(self))] pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> { + let (redacts, content) = self.copy_redacts(); let mut json = json!({ - "content": self.content, + "content": content, "type": self.kind, "event_id": self.event_id, "sender": self.sender, @@ -114,7 +152,7 @@ pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> { if let Some(state_key) = &self.state_key { json["state_key"] = json!(state_key); } - if let Some(redacts) = &self.redacts { + if let Some(redacts) = &redacts { json["redacts"] = json!(redacts); } @@ -124,8 +162,9 @@ pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> { /// This only works for events that are also AnyRoomEvents. #[tracing::instrument(skip(self))] pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> { + let (redacts, content) = self.copy_redacts(); let mut json = json!({ - "content": self.content, + "content": content, "type": self.kind, "event_id": self.event_id, "sender": self.sender, @@ -139,7 +178,7 @@ pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> { if let Some(state_key) = &self.state_key { json["state_key"] = json!(state_key); } - if let Some(redacts) = &self.redacts { + if let Some(redacts) = &redacts { json["redacts"] = json!(redacts); } @@ -148,8 +187,9 @@ pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> { #[tracing::instrument(skip(self))] pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> { + let (redacts, content) = self.copy_redacts(); let mut json = json!({ - "content": self.content, + "content": content, "type": self.kind, "event_id": self.event_id, "sender": self.sender, @@ -163,7 +203,7 @@ pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> { if let Some(state_key) = &self.state_key { json["state_key"] = json!(state_key); } - if let Some(redacts) = &self.redacts { + if let Some(redacts) = &redacts { json["redacts"] = json!(redacts); } @@ -172,8 +212,9 @@ pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> { #[tracing::instrument(skip(self))] pub fn to_message_like_event(&self) -> Raw<AnyMessageLikeEvent> { + let (redacts, content) = self.copy_redacts(); let mut json = json!({ - "content": self.content, + "content": content, "type": self.kind, "event_id": self.event_id, "sender": self.sender, @@ -187,7 +228,7 @@ pub fn to_message_like_event(&self) -> Raw<AnyMessageLikeEvent> { if let Some(state_key) = &self.state_key { json["state_key"] = json!(state_key); } - if let Some(redacts) = &self.redacts { + if let Some(redacts) = &redacts { json["redacts"] = json!(redacts); } diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 3639c56b1..94b993f8d 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -307,21 +307,6 @@ pub async fn append_pdu( let mut pdu_id = shortroomid.to_be_bytes().to_vec(); pdu_id.extend_from_slice(&count2.to_be_bytes()); - // https://spec.matrix.org/v1.9/rooms/v11/#moving-the-redacts-property-of-mroomredaction-events-to-a-content-property - // For backwards-compatibility with older clients, - // servers should add a redacts property to the top level of m.room.redaction - // events in when serving such events over the Client-Server API. - if pdu.kind == TimelineEventType::RoomRedaction - && services().rooms.state.get_room_version(&pdu.room_id)? == RoomVersionId::V11 - { - let content = serde_json::from_str::<RoomRedactionEventContent>(pdu.content.get()) - .map_err(|_| Error::bad_database("Invalid content in redaction pdu."))?; - - if let Some(redact_id) = &content.redacts { - pdu_json.insert("redacts".to_owned(), CanonicalJsonValue::String(redact_id.to_string())); - } - } - // Insert pdu self.db.append_pdu(&pdu_id, pdu, &pdu_json, count2)?; -- GitLab