mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-16 15:21:24 +01:00
don't strip unknown keys when copying redacts property to/from content
Servers are required to preserve unknown properties in event content, since they may be added by a future version of the spec. Round-tripping through RoomRedactionEventContent results in dropping all unknown properties.
This commit is contained in:
parent
9a142c7557
commit
55a01e7113
2 changed files with 36 additions and 19 deletions
|
|
@ -245,6 +245,9 @@ This will be the first release of Grapevine since it was forked from Conduit
|
||||||
29. Fix bug where ban reasons would be ignored when the banned user already had
|
29. Fix bug where ban reasons would be ignored when the banned user already had
|
||||||
a member event in the room.
|
a member event in the room.
|
||||||
([!185](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/185))
|
([!185](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/185))
|
||||||
|
30. Stop stripping unknown properties from redaction events before sending them
|
||||||
|
to clients.
|
||||||
|
([!191](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/191))
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
use std::{cmp::Ordering, collections::BTreeMap, sync::Arc};
|
use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap, sync::Arc};
|
||||||
|
|
||||||
use ruma::{
|
use ruma::{
|
||||||
canonical_json::redact_content_in_place,
|
canonical_json::redact_content_in_place,
|
||||||
events::{
|
events::{
|
||||||
room::{
|
room::member::RoomMemberEventContent,
|
||||||
member::RoomMemberEventContent,
|
space::child::HierarchySpaceChildEvent, AnyEphemeralRoomEvent,
|
||||||
redaction::RoomRedactionEventContent,
|
AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent,
|
||||||
},
|
AnySyncStateEvent, AnySyncTimelineEvent, AnyTimelineEvent, StateEvent,
|
||||||
space::child::HierarchySpaceChildEvent,
|
TimelineEventType,
|
||||||
AnyEphemeralRoomEvent, AnyMessageLikeEvent, AnyStateEvent,
|
|
||||||
AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent,
|
|
||||||
AnyTimelineEvent, StateEvent, TimelineEventType,
|
|
||||||
},
|
},
|
||||||
serde::Raw,
|
serde::Raw,
|
||||||
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId,
|
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId,
|
||||||
|
|
@ -161,24 +158,41 @@ impl PduEvent {
|
||||||
pub(crate) fn copy_redacts(
|
pub(crate) fn copy_redacts(
|
||||||
&self,
|
&self,
|
||||||
) -> (Option<Arc<EventId>>, Box<RawJsonValue>) {
|
) -> (Option<Arc<EventId>>, Box<RawJsonValue>) {
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct ExtractRedacts<'a> {
|
||||||
|
#[serde(borrow)]
|
||||||
|
redacts: Option<Cow<'a, EventId>>,
|
||||||
|
}
|
||||||
|
|
||||||
if self.kind != TimelineEventType::RoomRedaction {
|
if self.kind != TimelineEventType::RoomRedaction {
|
||||||
return (self.redacts.clone(), self.content.clone());
|
return (self.redacts.clone(), self.content.clone());
|
||||||
}
|
}
|
||||||
let Ok(mut content) = serde_json::from_str::<RoomRedactionEventContent>(
|
let Ok(extract) =
|
||||||
self.content.get(),
|
serde_json::from_str::<ExtractRedacts<'_>>(self.content.get())
|
||||||
) else {
|
else {
|
||||||
return (self.redacts.clone(), self.content.clone());
|
return (self.redacts.clone(), self.content.clone());
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(redacts) = content.redacts {
|
if let Some(redacts) = extract.redacts {
|
||||||
(Some(redacts.into()), self.content.clone())
|
(Some(redacts.into()), self.content.clone())
|
||||||
} else if let Some(redacts) = self.redacts.clone() {
|
} else if let Some(redacts) = self.redacts.clone() {
|
||||||
content.redacts = Some(redacts.into());
|
let content = serde_json::from_str::<BTreeMap<&str, &RawJsonValue>>(
|
||||||
(
|
self.content.get(),
|
||||||
self.redacts.clone(),
|
);
|
||||||
to_raw_value(&content)
|
let mut content = match content {
|
||||||
.expect("Must be valid, we only added redacts field"),
|
Ok(content) => content,
|
||||||
)
|
Err(error) => {
|
||||||
|
warn!(%error, "PDU is not a valid json object");
|
||||||
|
return (self.redacts.clone(), self.content.clone());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let redacts_json = to_raw_value(&redacts)
|
||||||
|
.expect("all strings should be representable as json");
|
||||||
|
content.insert("redacts", &redacts_json);
|
||||||
|
let content_json = to_raw_value(&content)
|
||||||
|
.expect("Must be valid, we only added redacts field");
|
||||||
|
(self.redacts.clone(), content_json)
|
||||||
} else {
|
} else {
|
||||||
(self.redacts.clone(), self.content.clone())
|
(self.redacts.clone(), self.content.clone())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue