Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

events: Add support for redacts key into content of RoomRedactionEvent #1615

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/ruma-common/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Breaking changes:
(MSC2746 / Matrix 1.7)
- The `Replacement` relation for `RoomMessageEventContent` now takes a
`RoomMessageEventContentWithoutRelation` instead of a `MessageType`
- Make `RoomRedactionEvent` and associated types enums to handle the format where the `redacts` key
is moved inside the `content`, as introduced in room version 11, according to MSC2174 / MSC3820

Improvements:

Expand Down
18 changes: 16 additions & 2 deletions crates/ruma-common/src/events/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::fmt;
use serde::{de::DeserializeOwned, Serialize};
use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};

use crate::serde::{CanBeEmpty, Raw};
use crate::{
serde::{CanBeEmpty, Raw},
TransactionId,
};

use super::{
EphemeralRoomEventType, GlobalAccountDataEventType, MessageLikeEventType,
Expand Down Expand Up @@ -70,7 +73,12 @@ pub trait StaticStateEventContent: StateEventContent {
type PossiblyRedacted: PossiblyRedactedStateEventContent;

/// The type of the event's `unsigned` field.
type Unsigned: Clone + fmt::Debug + Default + CanBeEmpty + DeserializeOwned;
type Unsigned: Clone
+ fmt::Debug
+ Default
+ CanBeEmpty
+ DeserializeOwned
+ OriginalStateUnsigned;
}

/// Content of a redacted state event.
Expand Down Expand Up @@ -103,3 +111,9 @@ where
from_json_str(content.get())
}
}

/// Unsigned data of an unredacted event.
pub trait OriginalStateUnsigned {
/// The transaction ID if this event was sent from this session.
fn transaction_id(&self) -> Option<&TransactionId>;
}
82 changes: 75 additions & 7 deletions crates/ruma-common/src/events/kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
use serde_json::value::RawValue as RawJsonValue;

use super::{
AnyInitialStateEvent, EmptyStateKey, EphemeralRoomEventContent, EventContent,
EventContentFromType, GlobalAccountDataEventContent, MessageLikeEventContent,
MessageLikeEventType, MessageLikeUnsigned, PossiblyRedactedStateEventContent, RedactContent,
RedactedMessageLikeEventContent, RedactedStateEventContent, RedactedUnsigned,
RedactionDeHelper, RoomAccountDataEventContent, StateEventType, StaticStateEventContent,
ToDeviceEventContent,
AnyInitialStateEvent, BundledMessageLikeRelations, EmptyStateKey, EphemeralRoomEventContent,
EventContent, EventContentFromType, GlobalAccountDataEventContent, MessageLikeEventContent,
MessageLikeEventType, MessageLikeUnsigned, OriginalStateUnsigned,
PossiblyRedactedStateEventContent, RedactContent, RedactedMessageLikeEventContent,
RedactedStateEventContent, RedactedUnsigned, RedactionDeHelper, RoomAccountDataEventContent,
StateEventType, StaticStateEventContent, ToDeviceEventContent,
};
use crate::{
serde::{from_raw_json_value, Raw},
EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId,
RoomVersionId, UserId,
RoomVersionId, TransactionId, UserId,
};

/// A global account data event.
Expand Down Expand Up @@ -668,6 +668,27 @@ impl_possibly_redacted_event!(
_ => None,
}
}

/// Get the inner content if this is an unredacted event.
pub fn original_content(&self) -> Option<&C> {
self.as_original().map(|ev| &ev.content)
}

/// Get the `TransactionId` from the unsigned data of this event.
pub fn transaction_id(&self) -> Option<&TransactionId> {
match self {
Self::Original(ev) => ev.unsigned.transaction_id.as_deref(),
_ => None,
}
}

/// Get the `BundledMessageLikeRelations` from the unsigned data of this event.
pub fn relations(&self) -> Option<&BundledMessageLikeRelations<OriginalSyncMessageLikeEvent<C>>> {
match self {
Self::Original(ev) => Some(&ev.unsigned.relations),
_ => None,
}
}
}
);

Expand All @@ -683,6 +704,27 @@ impl_possibly_redacted_event!(
}
}

/// Get the inner content if this is an unredacted event.
pub fn original_content(&self) -> Option<&C> {
self.as_original().map(|ev| &ev.content)
}

/// Get the `TransactionId` from the unsigned data of this event.
pub fn transaction_id(&self) -> Option<&TransactionId> {
match self {
Self::Original(ev) => ev.unsigned.transaction_id.as_deref(),
_ => None,
}
}

/// Get the `BundledMessageLikeRelations` from the unsigned data of this event.
pub fn relations(&self) -> Option<&BundledMessageLikeRelations<OriginalSyncMessageLikeEvent<C>>> {
match self {
Self::Original(ev) => Some(&ev.unsigned.relations),
_ => None,
}
}

/// Convert this sync event into a full event (one with a `room_id` field).
pub fn into_full_event(self, room_id: OwnedRoomId) -> MessageLikeEvent<C> {
match self {
Expand Down Expand Up @@ -721,6 +763,19 @@ impl_possibly_redacted_event!(
_ => None,
}
}

/// Get the inner content if this is an unredacted event.
pub fn original_content(&self) -> Option<&C> {
self.as_original().map(|ev| &ev.content)
}

/// Get the `TransactionId` from the unsigned data of this event.
pub fn transaction_id(&self) -> Option<&TransactionId> {
match self {
Self::Original(ev) => ev.unsigned.transaction_id(),
_ => None,
}
}
}
);

Expand All @@ -745,6 +800,19 @@ impl_possibly_redacted_event!(
}
}

/// Get the inner content if this is an unredacted event.
pub fn original_content(&self) -> Option<&C> {
self.as_original().map(|ev| &ev.content)
}

/// Get the `TransactionId` from the unsigned data of this event.
pub fn transaction_id(&self) -> Option<&TransactionId> {
match self {
Self::Original(ev) => ev.unsigned.transaction_id(),
_ => None,
}
}

/// Convert this sync event into a full event (one with a `room_id` field).
pub fn into_full_event(self, room_id: OwnedRoomId) -> StateEvent<C> {
match self {
Expand Down
8 changes: 7 additions & 1 deletion crates/ruma-common/src/events/room/member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};

use crate::{
events::{
AnyStrippedStateEvent, BundledStateRelations, EventContent,
AnyStrippedStateEvent, BundledStateRelations, EventContent, OriginalStateUnsigned,
PossiblyRedactedStateEventContent, RedactContent, RedactedStateEventContent,
StateEventType,
},
Expand Down Expand Up @@ -533,6 +533,12 @@ impl CanBeEmpty for RoomMemberUnsigned {
}
}

impl OriginalStateUnsigned for RoomMemberUnsigned {
fn transaction_id(&self) -> Option<&crate::TransactionId> {
self.transaction_id.as_deref()
}
}

#[cfg(test)]
mod tests {
use assert_matches2::assert_matches;
Expand Down
Loading