Fix filtering of rooms when supplying the destination query parameter to /_synapse/admin/v1/federation/destinations/<destination>/rooms (#17077)

This commit is contained in:
Andrew Morgan 2024-04-26 10:52:24 +01:00 committed by GitHub
parent 9c91873922
commit 89fc579329
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 66 additions and 3 deletions

1
changelog.d/17077.bugfix Normal file
View file

@ -0,0 +1 @@
Fixes a bug introduced in v1.52.0 where the `destination` query parameter for the [Destination Rooms Admin API](https://element-hq.github.io/synapse/v1.105/usage/administration/admin_api/federation.html#destination-rooms) failed to actually filter returned rooms.

View file

@ -660,6 +660,7 @@ class TransactionWorkerStore(CacheInvalidationWorkerStore):
limit=limit,
retcols=("room_id", "stream_ordering"),
order_direction=order,
keyvalues={"destination": destination},
),
)
return rooms, count

View file

@ -778,20 +778,81 @@ class DestinationMembershipTestCase(unittest.HomeserverTestCase):
self.assertEqual(number_rooms, len(channel.json_body["rooms"]))
self._check_fields(channel.json_body["rooms"])
def _create_destination_rooms(self, number_rooms: int) -> None:
"""Create a number rooms for destination
def test_room_filtering(self) -> None:
"""Tests that rooms are correctly filtered"""
# Create two rooms on the homeserver. Each has a different remote homeserver
# participating in it.
other_destination = "other.destination.org"
room_ids_self_dest = self._create_destination_rooms(2, destination=self.dest)
room_ids_other_dest = self._create_destination_rooms(
1, destination=other_destination
)
# Ask for the rooms that `self.dest` is participating in.
channel = self.make_request("GET", self.url, access_token=self.admin_user_tok)
self.assertEqual(200, channel.code, msg=channel.json_body)
# Verify that we received only the rooms that `self.dest` is participating in.
# This assertion method name is a bit misleading. It does check that both lists
# contain the same items, and the same counts.
self.assertCountEqual(
[r["room_id"] for r in channel.json_body["rooms"]], room_ids_self_dest
)
self.assertEqual(channel.json_body["total"], len(room_ids_self_dest))
# Ask for the rooms that `other_destination` is participating in.
channel = self.make_request(
"GET",
self.url.replace(self.dest, other_destination),
access_token=self.admin_user_tok,
)
self.assertEqual(200, channel.code, msg=channel.json_body)
# Verify that we received only the rooms that `other_destination` is
# participating in.
self.assertCountEqual(
[r["room_id"] for r in channel.json_body["rooms"]], room_ids_other_dest
)
self.assertEqual(channel.json_body["total"], len(room_ids_other_dest))
def _create_destination_rooms(
self,
number_rooms: int,
destination: Optional[str] = None,
) -> List[str]:
"""
Create the given number of rooms. The given `destination` homeserver will
be recorded as a participant.
Args:
number_rooms: Number of rooms to be created
destination: The domain of the homeserver that will be considered
as a participant in the rooms.
Returns:
The IDs of the rooms that have been created.
"""
room_ids = []
# If no destination was provided, default to `self.dest`.
if destination is None:
destination = self.dest
for _ in range(number_rooms):
room_id = self.helper.create_room_as(
self.admin_user, tok=self.admin_user_tok
)
room_ids.append(room_id)
self.get_success(
self.store.store_destination_rooms_entries((self.dest,), room_id, 1234)
self.store.store_destination_rooms_entries(
(destination,), room_id, 1234
)
)
return room_ids
def _check_fields(self, content: List[JsonDict]) -> None:
"""Checks that the expected room attributes are present in content