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

Commit

Permalink
Fix error when sending message into deleted room. (#15235)
Browse files Browse the repository at this point in the history
When a room is deleted in Synapse we remove the event forward
extremities in the room, so if (say a bot) tries to send a message into
the room we error out due to not being able to calculate prev events for
the new event *before* we check if the sender is in the room.

Fixes #8094
  • Loading branch information
erikjohnston authored Mar 21, 2023
1 parent a5fb382 commit 827f198
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog.d/15235.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix long-standing error when sending message into deleted room.
17 changes: 15 additions & 2 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,10 +987,11 @@ async def create_and_send_nonmember_event(
# a situation where event persistence can't keep up, causing
# extremities to pile up, which in turn leads to state resolution
# taking longer.
async with self.limiter.queue(event_dict["room_id"]):
room_id = event_dict["room_id"]
async with self.limiter.queue(room_id):
if txn_id:
event = await self.get_event_from_transaction(
requester, txn_id, event_dict["room_id"]
requester, txn_id, room_id
)
if event:
# we know it was persisted, so must have a stream ordering
Expand All @@ -1000,6 +1001,18 @@ async def create_and_send_nonmember_event(
event.internal_metadata.stream_ordering,
)

# If we don't have any prev event IDs specified then we need to
# check that the host is in the room (as otherwise populating the
# prev events will fail), at which point we may as well check the
# local user is in the room.
if not prev_event_ids:
user_id = requester.user.to_string()
is_user_in_room = await self.store.check_local_user_in_room(
user_id, room_id
)
if not is_user_in_room:
raise AuthError(403, f"User {user_id} not in room {room_id}")

# Try several times, it could fail with PartialStateConflictError
# in handle_new_client_event, cf comment in except block.
max_retries = 5
Expand Down
15 changes: 15 additions & 0 deletions tests/rest/admin/test_room.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,21 @@ def test_shutdown_room_block_peek(self) -> None:
# Assert we can no longer peek into the room
self._assert_peek(self.room_id, expect_code=403)

def test_room_delete_send(self) -> None:
"""Test that sending into a deleted room returns a 403"""
channel = self.make_request(
"DELETE",
self.url,
content={},
access_token=self.admin_user_tok,
)

self.assertEqual(200, channel.code, msg=channel.json_body)

self.helper.send(
self.room_id, "test message", expect_code=403, tok=self.other_user_tok
)

def _is_blocked(self, room_id: str, expect: bool = True) -> None:
"""Assert that the room is blocked or not"""
d = self.store.is_room_blocked(room_id)
Expand Down

0 comments on commit 827f198

Please sign in to comment.