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

Do not consider events by ignored users for relations #12285

Merged
merged 2 commits into from
Mar 24, 2022
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/12227.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where events from ignored users were still considered for relations.
1 change: 0 additions & 1 deletion changelog.d/12227.misc

This file was deleted.

1 change: 1 addition & 0 deletions changelog.d/12232.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where events from ignored users were still considered for relations.
1 change: 0 additions & 1 deletion changelog.d/12232.misc

This file was deleted.

1 change: 1 addition & 0 deletions changelog.d/12285.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where events from ignored users were still considered for relations.
9 changes: 8 additions & 1 deletion synapse/handlers/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from synapse.api.errors import SynapseError
from synapse.events import EventBase
from synapse.types import JsonDict, Requester, StreamToken
from synapse.visibility import filter_events_for_client

if TYPE_CHECKING:
from synapse.server import HomeServer
Expand Down Expand Up @@ -62,6 +63,7 @@ def __bool__(self) -> bool:
class RelationsHandler:
def __init__(self, hs: "HomeServer"):
self._main_store = hs.get_datastores().main
self._storage = hs.get_storage()
self._auth = hs.get_auth()
self._clock = hs.get_clock()
self._event_handler = hs.get_event_handler()
Expand Down Expand Up @@ -103,7 +105,8 @@ async def get_relations(

user_id = requester.user.to_string()

await self._auth.check_user_in_room_or_world_readable(
# TODO Properly handle a user leaving a room.
(_, member_event_id) = await self._auth.check_user_in_room_or_world_readable(
room_id, user_id, allow_departed_users=True
)

Expand All @@ -130,6 +133,10 @@ async def get_relations(
[c["event_id"] for c in pagination_chunk.chunk]
)

events = await filter_events_for_client(
self._storage, user_id, events, is_peeking=(member_event_id is None)
)

now = self._clock.time_msec()
# Do not bundle aggregations when retrieving the original event because
# we want the content before relations are applied to it.
Expand Down
80 changes: 79 additions & 1 deletion tests/rest/client/test_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from twisted.test.proto_helpers import MemoryReactor

from synapse.api.constants import EventTypes, RelationTypes
from synapse.api.constants import AccountDataTypes, EventTypes, RelationTypes
from synapse.rest import admin
from synapse.rest.client import login, register, relations, room, sync
from synapse.server import HomeServer
Expand Down Expand Up @@ -1324,6 +1324,84 @@ def test_bundled_aggregations_with_filter(self) -> None:
self.assertIn("m.relations", parent_event["unsigned"])


class RelationIgnoredUserTestCase(BaseRelationsTestCase):
"""Relations sent from an ignored user should be ignored."""

def _test_ignored_user(
self, allowed_event_ids: List[str], ignored_event_ids: List[str]
) -> None:
"""
Fetch the relations and ensure they're all there, then ignore user2, and
repeat.
"""
# Get the relations.
event_ids = self._get_related_events()
self.assertCountEqual(event_ids, allowed_event_ids + ignored_event_ids)

# Ignore user2 and re-do the requests.
self.get_success(
self.store.add_account_data_for_user(
self.user_id,
AccountDataTypes.IGNORED_USER_LIST,
{"ignored_users": {self.user2_id: {}}},
)
)

# Get the relations.
event_ids = self._get_related_events()
self.assertCountEqual(event_ids, allowed_event_ids)

def test_annotation(self) -> None:
"""Annotations should ignore"""
# Send 2 from us, 2 from the to be ignored user.
allowed_event_ids = []
ignored_event_ids = []
channel = self._send_relation(RelationTypes.ANNOTATION, "m.reaction", key="a")
allowed_event_ids.append(channel.json_body["event_id"])
channel = self._send_relation(RelationTypes.ANNOTATION, "m.reaction", key="b")
allowed_event_ids.append(channel.json_body["event_id"])
channel = self._send_relation(
RelationTypes.ANNOTATION,
"m.reaction",
key="a",
access_token=self.user2_token,
)
ignored_event_ids.append(channel.json_body["event_id"])
channel = self._send_relation(
RelationTypes.ANNOTATION,
"m.reaction",
key="c",
access_token=self.user2_token,
)
ignored_event_ids.append(channel.json_body["event_id"])

self._test_ignored_user(allowed_event_ids, ignored_event_ids)

def test_reference(self) -> None:
"""Annotations should ignore"""
channel = self._send_relation(RelationTypes.REFERENCE, "m.room.test")
allowed_event_ids = [channel.json_body["event_id"]]

channel = self._send_relation(
RelationTypes.REFERENCE, "m.room.test", access_token=self.user2_token
)
ignored_event_ids = [channel.json_body["event_id"]]

self._test_ignored_user(allowed_event_ids, ignored_event_ids)

def test_thread(self) -> None:
"""Annotations should ignore"""
channel = self._send_relation(RelationTypes.THREAD, "m.room.test")
allowed_event_ids = [channel.json_body["event_id"]]

channel = self._send_relation(
RelationTypes.THREAD, "m.room.test", access_token=self.user2_token
)
ignored_event_ids = [channel.json_body["event_id"]]

self._test_ignored_user(allowed_event_ids, ignored_event_ids)


class RelationRedactionTestCase(BaseRelationsTestCase):
"""
Test the behaviour of relations when the parent or child event is redacted.
Expand Down