Limit initial sync response to rooms within the scope of the sliding sync request

This commit is contained in:
Jason Robinson
2026-07-21 23:21:33 +03:00
parent 88f1990a39
commit e393b282df
3 changed files with 94 additions and 3 deletions
+4 -1
View File
@@ -1082,6 +1082,7 @@ class SlidingSyncExtensionHandler:
self,
user_id: UserID,
fields: set[str],
rooms: set[str],
) -> dict[str, JsonDict | None]:
"""
Build an initial sync response for the profiles extension.
@@ -1089,15 +1090,16 @@ class SlidingSyncExtensionHandler:
Args:
user_id: The syncing user UserID
fields: A set of fields to include in the response.
rooms: A set of rooms to limit the user profiles for.
Returns:
A dictionary containing the profile updates in an `updated` dictionary.
"""
response: dict[str, JsonDict | None] = {}
# TODO should be filtered for the rooms for this sync
profile_user_ids = await self.store.get_local_users_who_share_room_with_user(
user_id.to_string(),
limit_to_rooms=rooms,
)
# Ensure we're in the list even if we don't belong to any rooms
profile_user_ids.add(user_id.to_string())
@@ -1164,6 +1166,7 @@ class SlidingSyncExtensionHandler:
users=await self._get_profiles_extension_initial_sync_response(
user_id=sync_config.user,
fields=fields,
rooms=all_interested_room_ids,
),
)
+16 -2
View File
@@ -1035,12 +1035,26 @@ class RoomMemberWorkerStore(EventsWorkerStore, CacheInvalidationWorkerStore):
return user_who_share_room
async def get_local_users_who_share_room_with_user(self, user_id: str) -> set[str]:
"""Returns the set of local users who share a room with `user_id`.
async def get_local_users_who_share_room_with_user(
self,
user_id: str,
limit_to_rooms: set[str] | None = None,
) -> set[str]:
"""
Returns the set of local users who share a room with `user_id`.
This also includes the `user_id` themselves.
Args:
user_id: The user ID to find the local users who share rooms.
limit_to_rooms: Optional set of rooms to limit to.
Returns:
Set of local user ID's who share a room with the given user.
"""
room_ids = await self.get_rooms_for_user(user_id)
if limit_to_rooms:
room_ids = room_ids.intersection(limit_to_rooms)
user_who_share_room: set[str] = set()
for room_id in room_ids:
@@ -292,6 +292,80 @@ class SlidingSyncProfilesTestCase(SlidingSyncBase):
response_body["extensions"].get("org.matrix.msc4262.profiles")
)
@parameterized.expand(
[
True,
False,
]
)
@override_config({"include_profile_updates_in_sync": True})
def test_updated_fields_are_not_if_not_in_requested_rooms(
self, is_initial: bool
) -> None:
"""
Test that profile extension response respects the room subscriptions, by:
* for initial sync returning updates for only those users in the given rooms
* for incremental sync returning all updates in shared rooms
"""
new_room = self.helper.create_room_as(self.user, tok=self.tok)
if is_initial:
self.get_success(
self.profile_handler.set_field(
target_user=UserID.from_string(self.other_user),
requester=create_requester(self.other_user),
field_name="field",
new_value="value",
)
)
# Make an initial Sliding Sync request with the profiles extension enabled
sync_body = {
"lists": {},
"room_subscriptions": {
new_room: {
"required_state": [],
"timeline_limit": 10,
},
},
"extensions": {
"org.matrix.msc4262.profiles": {
"enabled": True,
"fields": ["field"],
},
},
}
response_body, from_token = self.do_sync(sync_body, tok=self.tok)
if is_initial:
# Nothing returned since even though user and other_user share a room,
# we didn't ask for that room.
self.assertIsNone(
response_body["extensions"].get("org.matrix.msc4262.profiles")
)
if not is_initial:
self.get_success(
self.profile_handler.set_field(
target_user=UserID.from_string(self.other_user),
requester=create_requester(self.other_user),
field_name="field",
new_value="value",
)
)
# Make an incremental Sliding Sync request
response_body, _ = self.do_sync(sync_body, since=from_token, tok=self.tok)
# Even though we only asked for a room other_user is not in,
# since these users share a room, updates are always sent via incremental
# sync.
self.assertEqual(
response_body["extensions"]["org.matrix.msc4262.profiles"]["users"][
"@other_user:test"
],
{
"updated": {
"field": "value",
}
},
)
@parameterized.expand(
[
True,