Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Implement MSC3389 to protect relations from redaction. #15565

Merged
merged 4 commits into from
May 15, 2023
Merged
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
1 change: 1 addition & 0 deletions changelog.d/15565.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement updated redaction rules from [MSC3389](https://github.com/matrix-org/matrix-spec-proposals/pull/3389).
17 changes: 17 additions & 0 deletions synapse/api/room_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class RoomVersion:
msc2716_historical: bool
# MSC2716: Adds support for redacting "insertion", "chunk", and "marker" events
msc2716_redactions: bool
# MSC3389: Protect relation information from redaction.
msc3389_relation_redactions: bool
# MSC3787: Adds support for a `knock_restricted` join rule, mixing concepts of
# knocks and restricted join rules into the same join condition.
msc3787_knock_restricted_join_rule: bool
Expand Down Expand Up @@ -128,6 +130,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -149,6 +152,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -170,6 +174,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -191,6 +196,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -212,6 +218,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -233,6 +240,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -254,6 +262,7 @@ class RoomVersions:
msc2403_knocking=False,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -275,6 +284,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -296,6 +306,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -317,6 +328,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -338,6 +350,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=True,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -359,6 +372,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=True,
msc3667_int_only_power_levels=True,
msc3931_push_features=(),
Expand All @@ -380,6 +394,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=True,
msc2716_redactions=True,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
msc3931_push_features=(),
Expand All @@ -402,6 +417,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=True,
msc3667_int_only_power_levels=True,
msc3931_push_features=(PushRuleRoomFlag.EXTENSIBLE_EVENTS,),
Expand All @@ -423,6 +439,7 @@ class RoomVersions:
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3389_relation_redactions=False,
msc3787_knock_restricted_join_rule=True,
msc3667_int_only_power_levels=True,
msc3931_push_features=(),
Expand Down
12 changes: 12 additions & 0 deletions synapse/events/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,18 @@ def add_fields(*fields: str) -> None:
elif room_version.msc2716_redactions and event_type == EventTypes.MSC2716_MARKER:
add_fields(EventContentFields.MSC2716_INSERTION_EVENT_REFERENCE)

# Protect the rel_type and event_id fields under the m.relates_to field.
if room_version.msc3389_relation_redactions:
relates_to = event_dict["content"].get("m.relates_to")
if isinstance(relates_to, collections.abc.Mapping):
new_relates_to = {}
for field in ("rel_type", "event_id"):
if field in relates_to:
new_relates_to[field] = relates_to[field]
# Only include a non-empty relates_to field.
if new_relates_to:
new_content["m.relates_to"] = new_relates_to

allowed_fields = {k: v for k, v in event_dict.items() if k in allowed_keys}

allowed_fields["content"] = new_content
Expand Down
90 changes: 90 additions & 0 deletions tests/events/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import unittest as stdlib_unittest
from typing import Any, List, Mapping, Optional

import attr

from synapse.api.constants import EventContentFields
from synapse.api.room_versions import RoomVersions
from synapse.events import EventBase, make_event_from_dict
Expand Down Expand Up @@ -435,6 +437,94 @@ def test_member(self) -> None:
room_version=RoomVersions.V9,
)

def test_relations(self) -> None:
"""Event relations get redacted until MSC3389."""
# Normally the m._relates_to field is redacted.
self.run_test(
{
"type": "m.room.message",
"content": {
"body": "foo",
"m.relates_to": {
"rel_type": "rel_type",
"event_id": "$parent:domain",
"other": "stripped",
},
},
},
{
"type": "m.room.message",
"content": {},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.V10,
)

# Create a new room version.
msc3389_room_ver = attr.evolve(
RoomVersions.V10, msc3389_relation_redactions=True
)

self.run_test(
{
"type": "m.room.message",
"content": {
"body": "foo",
"m.relates_to": {
"rel_type": "rel_type",
"event_id": "$parent:domain",
"other": "stripped",
},
},
},
{
"type": "m.room.message",
"content": {
"m.relates_to": {
"rel_type": "rel_type",
"event_id": "$parent:domain",
},
},
"signatures": {},
"unsigned": {},
},
room_version=msc3389_room_ver,
)

# If the field is not an object, redact it.
self.run_test(
{
"type": "m.room.message",
"content": {
"body": "foo",
"m.relates_to": "stripped",
},
},
{
"type": "m.room.message",
"content": {},
"signatures": {},
"unsigned": {},
},
room_version=msc3389_room_ver,
)

# If the m.relates_to property would be empty, redact it.
self.run_test(
{
"type": "m.room.message",
"content": {"body": "foo", "m.relates_to": {"foo": "stripped"}},
},
{
"type": "m.room.message",
"content": {},
"signatures": {},
"unsigned": {},
},
room_version=msc3389_room_ver,
)


class SerializeEventTestCase(stdlib_unittest.TestCase):
def serialize(self, ev: EventBase, fields: Optional[List[str]]) -> JsonDict:
Expand Down