mirror of
https://github.com/matrix-org/synapse.git
synced 2025-02-06 15:25:46 +00:00
Fix error when sending message into deleted room. (#15235)
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
This commit is contained in:
parent
a5fb382a29
commit
827f198177
1
changelog.d/15235.bugfix
Normal file
1
changelog.d/15235.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix long-standing error when sending message into deleted room.
|
@ -987,10 +987,11 @@ class EventCreationHandler:
|
|||||||
# a situation where event persistence can't keep up, causing
|
# a situation where event persistence can't keep up, causing
|
||||||
# extremities to pile up, which in turn leads to state resolution
|
# extremities to pile up, which in turn leads to state resolution
|
||||||
# taking longer.
|
# 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:
|
if txn_id:
|
||||||
event = await self.get_event_from_transaction(
|
event = await self.get_event_from_transaction(
|
||||||
requester, txn_id, event_dict["room_id"]
|
requester, txn_id, room_id
|
||||||
)
|
)
|
||||||
if event:
|
if event:
|
||||||
# we know it was persisted, so must have a stream ordering
|
# we know it was persisted, so must have a stream ordering
|
||||||
@ -1000,6 +1001,18 @@ class EventCreationHandler:
|
|||||||
event.internal_metadata.stream_ordering,
|
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
|
# Try several times, it could fail with PartialStateConflictError
|
||||||
# in handle_new_client_event, cf comment in except block.
|
# in handle_new_client_event, cf comment in except block.
|
||||||
max_retries = 5
|
max_retries = 5
|
||||||
|
@ -402,6 +402,21 @@ class DeleteRoomTestCase(unittest.HomeserverTestCase):
|
|||||||
# Assert we can no longer peek into the room
|
# Assert we can no longer peek into the room
|
||||||
self._assert_peek(self.room_id, expect_code=403)
|
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:
|
def _is_blocked(self, room_id: str, expect: bool = True) -> None:
|
||||||
"""Assert that the room is blocked or not"""
|
"""Assert that the room is blocked or not"""
|
||||||
d = self.store.is_room_blocked(room_id)
|
d = self.store.is_room_blocked(room_id)
|
||||||
|
Loading…
Reference in New Issue
Block a user