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

Add a catch-all * to the supported relation types when redacting #15705

Merged
merged 3 commits into from
Jun 2, 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/15705.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a catch-all * to the supported relation types when redacting an event and its related events. This is an update to [MSC3912](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) implementation.
16 changes: 11 additions & 5 deletions synapse/handlers/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,22 @@ async def redact_events_related_to(
event_id: The event IDs to look and redact relations of.
initial_redaction_event: The redaction for the event referred to by
event_id.
relation_types: The types of relations to look for.
relation_types: The types of relations to look for. If "*" is in the list,
all related events will be redacted regardless of the type.

Raises:
ShadowBanError if the requester is shadow-banned
"""
related_event_ids = (
await self._main_store.get_all_relations_for_event_with_types(
event_id, relation_types
if "*" in relation_types:
related_event_ids = await self._main_store.get_all_relations_for_event(
event_id
)
else:
related_event_ids = (
await self._main_store.get_all_relations_for_event_with_types(
event_id, relation_types
)
)
)

for related_event_id in related_event_ids:
try:
Expand Down
30 changes: 30 additions & 0 deletions synapse/storage/databases/main/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,36 @@ def get_all_relation_ids_for_event_with_types_txn(
func=get_all_relation_ids_for_event_with_types_txn,
)

async def get_all_relations_for_event(
self,
event_id: str,
) -> List[str]:
"""Get the event IDs of all events that have a relation to the given event.

Args:
event_id: The event for which to look for related events.

Returns:
A list of the IDs of the events that relate to the given event.
"""

def get_all_relation_ids_for_event_txn(
txn: LoggingTransaction,
) -> List[str]:
rows = self.db_pool.simple_select_list_txn(
txn=txn,
table="event_relations",
keyvalues={"relates_to_id": event_id},
retcols=["event_id"],
)

return [row["event_id"] for row in rows]

return await self.db_pool.runInteraction(
desc="get_all_relation_ids_for_event",
func=get_all_relation_ids_for_event_txn,
)

async def event_includes_relation(self, event_id: str) -> bool:
"""Check if the given event relates to another event.

Expand Down
104 changes: 101 additions & 3 deletions tests/rest/client/test_redactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ def test_redact_event_as_moderator_ratelimit(self) -> None:
self._redact_event(self.mod_access_token, self.room_id, msg_id)

@override_config({"experimental_features": {"msc3912_enabled": True}})
def test_redact_relations(self) -> None:
"""Tests that we can redact the relations of an event at the same time as the
event itself.
def test_redact_relations_with_types(self) -> None:
"""Tests that we can redact the relations of an event of specific types
at the same time as the event itself.
"""
# Send a root event.
res = self.helper.send_event(
Expand Down Expand Up @@ -317,6 +317,104 @@ def test_redact_relations(self) -> None:
)
self.assertNotIn("redacted_because", event_dict, event_dict)

@override_config({"experimental_features": {"msc3912_enabled": True}})
def test_redact_all_relations(self) -> None:
"""Tests that we can redact all the relations of an event at the same time as the
event itself.
"""
# Send a root event.
res = self.helper.send_event(
room_id=self.room_id,
type=EventTypes.Message,
content={"msgtype": "m.text", "body": "hello"},
tok=self.mod_access_token,
)
root_event_id = res["event_id"]

# Send an edit to this root event.
res = self.helper.send_event(
room_id=self.room_id,
type=EventTypes.Message,
content={
"body": " * hello world",
"m.new_content": {
"body": "hello world",
"msgtype": "m.text",
},
"m.relates_to": {
"event_id": root_event_id,
"rel_type": RelationTypes.REPLACE,
},
"msgtype": "m.text",
},
tok=self.mod_access_token,
)
edit_event_id = res["event_id"]

# Also send a threaded message whose root is the same as the edit's.
res = self.helper.send_event(
room_id=self.room_id,
type=EventTypes.Message,
content={
"msgtype": "m.text",
"body": "message 1",
"m.relates_to": {
"event_id": root_event_id,
"rel_type": RelationTypes.THREAD,
},
},
tok=self.mod_access_token,
)
threaded_event_id = res["event_id"]

# Also send a reaction, again with the same root.
res = self.helper.send_event(
room_id=self.room_id,
type=EventTypes.Reaction,
content={
"m.relates_to": {
"rel_type": RelationTypes.ANNOTATION,
"event_id": root_event_id,
"key": "👍",
}
},
tok=self.mod_access_token,
)
reaction_event_id = res["event_id"]

# Redact the root event, specifying that we also want to delete all events that
# relate to it.
self._redact_event(
self.mod_access_token,
self.room_id,
root_event_id,
with_relations=["*"],
)

# Check that the root event got redacted.
event_dict = self.helper.get_event(
self.room_id, root_event_id, self.mod_access_token
)
self.assertIn("redacted_because", event_dict, event_dict)

# Check that the edit got redacted.
event_dict = self.helper.get_event(
self.room_id, edit_event_id, self.mod_access_token
)
self.assertIn("redacted_because", event_dict, event_dict)

# Check that the threaded message got redacted.
event_dict = self.helper.get_event(
self.room_id, threaded_event_id, self.mod_access_token
)
self.assertIn("redacted_because", event_dict, event_dict)

# Check that the reaction got redacted.
event_dict = self.helper.get_event(
self.room_id, reaction_event_id, self.mod_access_token
)
self.assertIn("redacted_because", event_dict, event_dict)

@override_config({"experimental_features": {"msc3912_enabled": True}})
def test_redact_relations_no_perms(self) -> None:
"""Tests that, when redacting a message along with its relations, if not all
Expand Down