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

Commit

Permalink
Merge pull request #6553 from matrix-org/babolivier/fix-context-filter
Browse files Browse the repository at this point in the history
* commit '631653036':
  Incorporate review
  Update changelog.d/6553.bugfix
  Lint
  Add test case
  Changelog
  Update the documentation of the filtering function
  Use the filtered version of an event when responding to /context requests for that event
  • Loading branch information
anoadragon453 committed Mar 19, 2020
2 parents 1964f11 + 6316530 commit 194287c
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog.d/6553.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug causing responses to the `/context` client endpoint to not use the pruned version of the event.
7 changes: 5 additions & 2 deletions synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,10 @@ def filter_evts(events):

results["events_before"] = yield filter_evts(results["events_before"])
results["events_after"] = yield filter_evts(results["events_after"])
results["event"] = event
# filter_evts can return a pruned event in case the user is allowed to see that
# there's something there but not see the content, so use the event that's in
# `filtered` rather than the event we retrieved from the datastore.
results["event"] = filtered[0]

if results["events_after"]:
last_event_id = results["events_after"][-1].event_id
Expand Down Expand Up @@ -965,7 +968,7 @@ def filter_evts(events):
if event_filter:
state_events = event_filter.filter(state_events)

results["state"] = state_events
results["state"] = yield filter_evts(state_events)

# We use a dummy token here as we only care about the room portion of
# the token, which we replace.
Expand Down
3 changes: 2 additions & 1 deletion synapse/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ def filter_events_for_client(
apply_retention_policies=True,
):
"""
Check which events a user is allowed to see
Check which events a user is allowed to see. If the user can see the event but its
sender asked for their data to be erased, prune the content of the event.
Args:
storage
Expand Down
127 changes: 127 additions & 0 deletions tests/rest/client/v1/test_rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from synapse.api.constants import EventContentFields, EventTypes, Membership
from synapse.handlers.pagination import PurgeStatus
from synapse.rest.client.v1 import login, profile, room
from synapse.rest.client.v2_alpha import account
from synapse.util.stringutils import random_string

from tests import unittest
Expand Down Expand Up @@ -1597,3 +1598,129 @@ def _send_labelled_messages_in_room(self):
)

return event_id


class ContextTestCase(unittest.HomeserverTestCase):

servlets = [
synapse.rest.admin.register_servlets_for_client_rest_resource,
room.register_servlets,
login.register_servlets,
account.register_servlets,
]

def prepare(self, reactor, clock, homeserver):
self.user_id = self.register_user("user", "password")
self.tok = self.login("user", "password")
self.room_id = self.helper.create_room_as(self.user_id, tok=self.tok)

self.other_user_id = self.register_user("user2", "password")
self.other_tok = self.login("user2", "password")

self.helper.invite(self.room_id, self.user_id, self.other_user_id, tok=self.tok)
self.helper.join(self.room_id, self.other_user_id, tok=self.other_tok)

def test_erased_sender(self):
"""Test that an erasure request results in the requester's events being hidden
from any new member of the room.
"""

# Send a bunch of events in the room.

self.helper.send(self.room_id, "message 1", tok=self.tok)
self.helper.send(self.room_id, "message 2", tok=self.tok)
event_id = self.helper.send(self.room_id, "message 3", tok=self.tok)["event_id"]
self.helper.send(self.room_id, "message 4", tok=self.tok)
self.helper.send(self.room_id, "message 5", tok=self.tok)

# Check that we can still see the messages before the erasure request.

request, channel = self.make_request(
"GET",
'/rooms/%s/context/%s?filter={"types":["m.room.message"]}'
% (self.room_id, event_id),
access_token=self.tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

events_before = channel.json_body["events_before"]

self.assertEqual(len(events_before), 2, events_before)
self.assertEqual(
events_before[0].get("content", {}).get("body"),
"message 2",
events_before[0],
)
self.assertEqual(
events_before[1].get("content", {}).get("body"),
"message 1",
events_before[1],
)

self.assertEqual(
channel.json_body["event"].get("content", {}).get("body"),
"message 3",
channel.json_body["event"],
)

events_after = channel.json_body["events_after"]

self.assertEqual(len(events_after), 2, events_after)
self.assertEqual(
events_after[0].get("content", {}).get("body"),
"message 4",
events_after[0],
)
self.assertEqual(
events_after[1].get("content", {}).get("body"),
"message 5",
events_after[1],
)

# Deactivate the first account and erase the user's data.

deactivate_account_handler = self.hs.get_deactivate_account_handler()
self.get_success(
deactivate_account_handler.deactivate_account(self.user_id, erase_data=True)
)

# Invite another user in the room. This is needed because messages will be
# pruned only if the user wasn't a member of the room when the messages were
# sent.

invited_user_id = self.register_user("user3", "password")
invited_tok = self.login("user3", "password")

self.helper.invite(
self.room_id, self.other_user_id, invited_user_id, tok=self.other_tok
)
self.helper.join(self.room_id, invited_user_id, tok=invited_tok)

# Check that a user that joined the room after the erasure request can't see
# the messages anymore.

request, channel = self.make_request(
"GET",
'/rooms/%s/context/%s?filter={"types":["m.room.message"]}'
% (self.room_id, event_id),
access_token=invited_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

events_before = channel.json_body["events_before"]

self.assertEqual(len(events_before), 2, events_before)
self.assertDictEqual(events_before[0].get("content"), {}, events_before[0])
self.assertDictEqual(events_before[1].get("content"), {}, events_before[1])

self.assertDictEqual(
channel.json_body["event"].get("content"), {}, channel.json_body["event"]
)

events_after = channel.json_body["events_after"]

self.assertEqual(len(events_after), 2, events_after)
self.assertDictEqual(events_after[0].get("content"), {}, events_after[0])
self.assertEqual(events_after[1].get("content"), {}, events_after[1])

0 comments on commit 194287c

Please sign in to comment.