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

Ignore EDUs for rooms we're not in #10317

Merged
merged 2 commits into from
Jul 6, 2021
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/10317.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix purging rooms that other homeservers are still sending events for. Contributed by @ilmari.
15 changes: 15 additions & 0 deletions synapse/handlers/receipts.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def __init__(self, hs: "HomeServer"):

self.server_name = hs.config.server_name
self.store = hs.get_datastore()
self.event_auth_handler = hs.get_event_auth_handler()

self.hs = hs

# We only need to poke the federation sender explicitly if its on the
Expand Down Expand Up @@ -59,6 +61,19 @@ async def _received_remote_receipt(self, origin: str, content: JsonDict) -> None
"""Called when we receive an EDU of type m.receipt from a remote HS."""
receipts = []
for room_id, room_values in content.items():
# If we're not in the room just ditch the event entirely. This is
# probably an old server that has come back and thinks we're still in
# the room (or we've been rejoined to the room by a state reset).
is_in_room = await self.event_auth_handler.check_host_in_room(
room_id, self.server_name
)
if not is_in_room:
logger.info(
"Ignoring receipt from %s as we're not in the room",
origin,
)
continue

for receipt_type, users in room_values.items():
for user_id, user_values in users.items():
if get_domain_from_id(user_id) != origin:
Expand Down
14 changes: 14 additions & 0 deletions synapse/handlers/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ def __init__(self, hs: "HomeServer"):

self.auth = hs.get_auth()
self.notifier = hs.get_notifier()
self.event_auth_handler = hs.get_event_auth_handler()

self.hs = hs

Expand Down Expand Up @@ -326,6 +327,19 @@ async def _recv_edu(self, origin: str, content: JsonDict) -> None:
room_id = content["room_id"]
user_id = content["user_id"]

# If we're not in the room just ditch the event entirely. This is
# probably an old server that has come back and thinks we're still in
# the room (or we've been rejoined to the room by a state reset).
is_in_room = await self.event_auth_handler.check_host_in_room(
room_id, self.server_name
)
if not is_in_room:
logger.info(
"Ignoring typing update from %s as we're not in the room",
origin,
)
return

member = RoomMember(user_id=user_id, room_id=room_id)

# Check that the string is a valid user id
Expand Down
37 changes: 37 additions & 0 deletions tests/handlers/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
# Test room id
ROOM_ID = "a-room"

# Room we're not in
OTHER_ROOM_ID = "another-room"


def _expect_edu_transaction(edu_type, content, origin="test"):
return {
Expand Down Expand Up @@ -115,6 +118,11 @@ async def check_user_in_room(room_id, user_id):

hs.get_auth().check_user_in_room = check_user_in_room

async def check_host_in_room(room_id, server_name):
return room_id == ROOM_ID

hs.get_event_auth_handler().check_host_in_room = check_host_in_room

def get_joined_hosts_for_room(room_id):
return {member.domain for member in self.room_members}

Expand Down Expand Up @@ -244,6 +252,35 @@ def test_started_typing_remote_recv(self):
],
)

def test_started_typing_remote_recv_not_in_room(self):
self.room_members = [U_APPLE, U_ONION]

self.assertEquals(self.event_source.get_current_key(), 0)

channel = self.make_request(
"PUT",
"/_matrix/federation/v1/send/1000000",
_make_edu_transaction_json(
"m.typing",
content={
"room_id": OTHER_ROOM_ID,
"user_id": U_ONION.to_string(),
"typing": True,
},
),
federation_auth_origin=b"farm",
)
self.assertEqual(channel.code, 200)

self.on_new_event.assert_not_called()

self.assertEquals(self.event_source.get_current_key(), 0)
events = self.get_success(
self.event_source.get_new_events(room_ids=[OTHER_ROOM_ID], from_key=0)
)
self.assertEquals(events[0], [])
self.assertEquals(events[1], 0)

@override_config({"send_federation": True})
def test_stopped_typing(self):
self.room_members = [U_APPLE, U_BANANA, U_ONION]
Expand Down