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

Commit

Permalink
Add a catch-all * to the supported relation types when redacting (#15705
Browse files Browse the repository at this point in the history
)


This is an update to MSC3912 implementation
  • Loading branch information
Mathieu Velten authored Jun 2, 2023
1 parent 30a5076 commit e0f2429
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 8 deletions.
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

0 comments on commit e0f2429

Please sign in to comment.