Ensure we filter out federated users in lazy loading sync when collecting profile updates from timeline events

This commit is contained in:
Jason Robinson
2026-07-02 23:13:05 +03:00
parent 182e4c2d10
commit 2c7b418105
2 changed files with 121 additions and 5 deletions
+11 -5
View File
@@ -2255,22 +2255,28 @@ class SyncHandler:
lazy_load_members = sync_config.filter_collection.lazy_load_members()
include_users = None
if lazy_load_members:
# Collect members from the existing `sync_result_builder` data
# Collect members from the existing `sync_result_builder` data.
# Ensure we filter out any remove users until we support profile
# updates for federated users.
include_users = set()
# invited
for invited in sync_result_builder.invited:
include_users.add(invited.invite.sender)
if self._is_mine_id(invited.invite.sender):
include_users.add(invited.invite.sender)
# joined
for joined in sync_result_builder.joined:
for timeline_event in joined.timeline.events:
include_users.add(timeline_event.event.sender)
if self._is_mine_id(timeline_event.event.sender):
include_users.add(timeline_event.event.sender)
# knocked
for knocked in sync_result_builder.knocked:
include_users.add(knocked.knock.sender)
if self._is_mine_id(knocked.knock.sender):
include_users.add(knocked.knock.sender)
# archived
for archived in sync_result_builder.archived:
for timeline_event in archived.timeline.events:
include_users.add(timeline_event.event.sender)
if self._is_mine_id(timeline_event.event.sender):
include_users.add(timeline_event.event.sender)
if since_token is None:
await self._generate_initial_sync_entry_for_profile_updates(
+110
View File
@@ -55,6 +55,7 @@ from synapse.util.duration import Duration
import tests.unittest
import tests.utils
from tests.test_utils.event_builders import make_test_pdu_event
from tests.test_utils.event_injection import inject_member_event
from tests.unittest import override_config
_request_key = 0
@@ -1523,6 +1524,15 @@ class SyncProfileUpdatesTestCase(tests.unittest.HomeserverTestCase):
self.helper.send_messages(
room_id=self.joined_room, num_events=10, tok=third_tok
)
# Join a federated user to the room
self.get_success(
inject_member_event(
self.hs,
self.joined_room,
"@federateduser:federatedhs",
"join",
)
)
incremental_result = self.get_success(
self.sync_handler.wait_for_sync_for_user(
requester,
@@ -1546,6 +1556,12 @@ class SyncProfileUpdatesTestCase(tests.unittest.HomeserverTestCase):
request_key=generate_request_key(),
)
)
# Ensure our federated user is filtered out, even though they have an
# event in the joined room timeline
self.assertFalse(
"@federateduser:federatedhs" in incremental_result.profile_updates.keys()
)
# Lazy loading only filters initial sync profile updates. Incremental syncs
# should include all tracked profile updates for the syncing user.
self.assertCountEqual(
@@ -1577,6 +1593,100 @@ class SyncProfileUpdatesTestCase(tests.unittest.HomeserverTestCase):
"third_user",
)
@parameterized.expand(
[
True,
False,
]
)
@override_config({"include_profile_updates_in_sync": True})
def test_lazy_loading_sync_filters_out_profile_updates_from_federated_users(
self,
is_initial: bool,
) -> None:
"""Test that with MSC4429 enabled lazy loading sync response
doesn't contain federated users even if there are timeline events from them.
"""
# Join a federated user to the room, causing a membership event into
# the joined rooms sync response
self.get_success(
inject_member_event(
self.hs,
self.joined_room,
"@federateduser1:federatedhs",
"join",
)
)
requester = create_requester(self.user)
initial_result = self.get_success(
self.sync_handler.wait_for_sync_for_user(
requester,
sync_config=generate_sync_config(
user_id=self.user,
filter_collection=FilterCollection(
hs=self.hs,
filter_json={
"org.matrix.msc4429.profile_fields": {
"ids": ["m.status", "displayname", "avatar_url"]
},
"room": {
"state": {
"lazy_load_members": True,
},
},
},
),
),
request_key=generate_request_key(),
)
)
# Ensure our federated user is filtered out, even though they have an
# event in the joined room timeline
self.assertFalse(
"@federateduser1:federatedhs" in initial_result.profile_updates.keys()
)
if not is_initial:
# Join another federated user to the room, causing a membership event into
# the joined rooms sync response
self.get_success(
inject_member_event(
self.hs,
self.joined_room,
"@federateduser2:federatedhs",
"join",
)
)
incremental_result = self.get_success(
self.sync_handler.wait_for_sync_for_user(
requester,
since_token=initial_result.next_batch,
sync_config=generate_sync_config(
user_id=self.user,
filter_collection=FilterCollection(
hs=self.hs,
filter_json={
"org.matrix.msc4429.profile_fields": {
"ids": ["m.status", "displayname", "avatar_url"]
},
"room": {
"state": {
"lazy_load_members": True,
},
},
},
),
),
request_key=generate_request_key(),
)
)
# Ensure our federated user is filtered out, even though they have an
# event in the joined room timeline
self.assertFalse(
"@federateduser2:federatedhs"
in incremental_result.profile_updates.keys()
)
@override_config({"include_profile_updates_in_sync": True})
def test_incremental_sync_lazy_loading_cache_filters_recently_sent_profiles(
self,