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

Commit

Permalink
Ignore EDUs for rooms we're not in (#10317)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilmari authored Jul 6, 2021
1 parent bcb0962 commit 47e28b4
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 0 deletions.
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

0 comments on commit 47e28b4

Please sign in to comment.