mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-28 13:44:24 +00:00
Handle room join/leave for profiles extension
This commit is contained in:
@@ -1179,6 +1179,19 @@ class SlidingSyncExtensionHandler:
|
||||
field_names_empty_means_all_fields=False if fields else True,
|
||||
)
|
||||
profile_user_ids = set()
|
||||
left_room_user_ids = {
|
||||
update.user_id
|
||||
for update in updates
|
||||
if update.action == ProfileUpdateAction.LEFT_ROOM.value
|
||||
}
|
||||
joined_room_user_ids = {
|
||||
update.user_id
|
||||
for update in updates
|
||||
if update.action == ProfileUpdateAction.JOINED_ROOM.value
|
||||
}
|
||||
# Add any newly joined users
|
||||
profile_user_ids.update(joined_room_user_ids)
|
||||
|
||||
updated_users = {
|
||||
update.user_id
|
||||
for update in updates
|
||||
@@ -1201,54 +1214,57 @@ class SlidingSyncExtensionHandler:
|
||||
continue
|
||||
updated_user_fields.setdefault(update.user_id, set()).add(update.field_name)
|
||||
|
||||
profile_data_by_user = await self.store.get_profile_data_for_users(
|
||||
profile_user_ids
|
||||
)
|
||||
profile_data_by_user = await self.store.get_profile_data_for_users(
|
||||
profile_user_ids
|
||||
)
|
||||
|
||||
# TODO lazy loading
|
||||
is_lazy = False
|
||||
# TODO lazy loading
|
||||
is_lazy = False
|
||||
|
||||
# Serialise the profile updates into the sync response format.
|
||||
for profile_user_id in profile_user_ids:
|
||||
profile_data = profile_data_by_user.get(profile_user_id)
|
||||
if profile_data is None:
|
||||
# No profile data for this user, just return a blank dictionary
|
||||
# in incremental sync, telling the clients to remove all profile
|
||||
# information for this user.
|
||||
response[profile_user_id] = None
|
||||
continue
|
||||
# Serialise the profile updates into the sync response format.
|
||||
for profile_user_id in profile_user_ids:
|
||||
profile_data = profile_data_by_user.get(profile_user_id)
|
||||
if profile_data is None:
|
||||
# No profile data for this user, just return a blank dictionary
|
||||
# in incremental sync, telling the clients to remove all profile
|
||||
# information for this user.
|
||||
response[profile_user_id] = None
|
||||
continue
|
||||
|
||||
per_user_updates: dict[str, JsonValue | dict[str, JsonValue]] = {}
|
||||
if is_lazy:
|
||||
# TODO lazy cache
|
||||
per_user_updates: dict[str, JsonValue | dict[str, JsonValue]] = {}
|
||||
# Include the fields the client asked for, or all, if not specified
|
||||
if fields:
|
||||
user_fields = set(profile_data.keys()).intersection(fields)
|
||||
else:
|
||||
user_fields = set(profile_data.keys())
|
||||
if is_lazy:
|
||||
# TODO lazy cache
|
||||
for field_name in user_fields:
|
||||
per_user_updates[field_name] = profile_data.get(field_name)
|
||||
else:
|
||||
# Include only the diff, unless the user recently joined,
|
||||
# then send all the fields the client asked for.
|
||||
# We don't use a cache here as for non-lazy sync we always
|
||||
# send changes and/or fields the client asked for, if relevant
|
||||
# as above joined condition.
|
||||
user_fields = (
|
||||
user_fields
|
||||
if profile_user_id in joined_room_user_ids
|
||||
else set(updated_user_fields.get(profile_user_id, []))
|
||||
)
|
||||
for field_name in user_fields:
|
||||
per_user_updates[field_name] = profile_data[field_name]
|
||||
|
||||
# Include the fields the client asked for, or all, if not specified
|
||||
if fields:
|
||||
user_fields = set(profile_data.keys()).intersection(fields)
|
||||
else:
|
||||
user_fields = set(profile_data.keys())
|
||||
for field_name in user_fields:
|
||||
per_user_updates[field_name] = profile_data.get(field_name)
|
||||
else:
|
||||
# Include only the diff, unless the user recently joined,
|
||||
# then send all the fields the client asked for.
|
||||
# We don't use a cache here as for non-lazy sync we always
|
||||
# send changes and/or fields the client asked for, if relevant
|
||||
# as above joined condition.
|
||||
user_fields = (
|
||||
fields
|
||||
# TODO joined_room_user_ids
|
||||
if profile_user_id in []
|
||||
else set(updated_user_fields.get(profile_user_id, []))
|
||||
)
|
||||
user_fields = set(profile_data.keys()).intersection(user_fields)
|
||||
for field_name in user_fields:
|
||||
per_user_updates[field_name] = profile_data[field_name]
|
||||
if per_user_updates:
|
||||
response[profile_user_id] = {
|
||||
"updated": per_user_updates,
|
||||
}
|
||||
|
||||
if per_user_updates:
|
||||
response[profile_user_id] = {
|
||||
"updated": per_user_updates,
|
||||
}
|
||||
# Process left rooms
|
||||
if left_room_user_ids:
|
||||
for other_user_id in left_room_user_ids:
|
||||
# Return a null response to the client
|
||||
response[other_user_id] = None
|
||||
|
||||
return SlidingSyncResult.Extensions.ProfilesExtension(
|
||||
users=response,
|
||||
|
||||
@@ -434,3 +434,99 @@ class SlidingSyncProfilesTestCase(SlidingSyncBase):
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@parameterized.expand(
|
||||
[
|
||||
[True, False],
|
||||
[True, True],
|
||||
[False, False],
|
||||
[False, True],
|
||||
]
|
||||
)
|
||||
@override_config({"include_profile_updates_in_sync": True})
|
||||
def test_null_profile_returned_if_user_left_all_rooms(
|
||||
self, request_fields: bool, is_lazy: bool
|
||||
) -> None:
|
||||
"""
|
||||
Test that profile extension response returns a null for the user in
|
||||
incremental sync.
|
||||
"""
|
||||
# TODO handle is_lazy
|
||||
# Make an initial Sliding Sync request with the profiles extension enabled
|
||||
profiles_config: dict = {
|
||||
"enabled": True,
|
||||
}
|
||||
if request_fields:
|
||||
profiles_config["fields"] = ["field"]
|
||||
sync_body = {
|
||||
"lists": {},
|
||||
"extensions": {
|
||||
"org.matrix.msc4262.profiles": profiles_config,
|
||||
},
|
||||
}
|
||||
response_body, from_token = self.do_sync(sync_body, tok=self.tok)
|
||||
|
||||
self.helper.leave(self.joined_room, self.other_user, tok=self.other_tok)
|
||||
|
||||
# Make an incremental Sliding Sync request
|
||||
response_body, _ = self.do_sync(sync_body, since=from_token, tok=self.tok)
|
||||
# We should see a null profile
|
||||
self.assertIsNone(
|
||||
response_body["extensions"]["org.matrix.msc4262.profiles"]["users"][
|
||||
"@other_user:test"
|
||||
],
|
||||
)
|
||||
|
||||
@parameterized.expand(
|
||||
[
|
||||
True,
|
||||
False,
|
||||
]
|
||||
)
|
||||
@override_config({"include_profile_updates_in_sync": True})
|
||||
def test_all_fields_returned_in_incremental_non_lazy_sync_if_someone_joined(
|
||||
self, request_fields: bool
|
||||
) -> None:
|
||||
"""
|
||||
Test that profile extension response returns all profile fields in
|
||||
incremental non-lazy sync, if someone joined the room..
|
||||
"""
|
||||
# Make an initial Sliding Sync request with the profiles extension enabled
|
||||
profiles_config: dict = {
|
||||
"enabled": True,
|
||||
}
|
||||
if request_fields:
|
||||
profiles_config["fields"] = ["displayname"]
|
||||
sync_body = {
|
||||
"lists": {},
|
||||
"extensions": {
|
||||
"org.matrix.msc4262.profiles": profiles_config,
|
||||
},
|
||||
}
|
||||
response_body, from_token = self.do_sync(sync_body, tok=self.tok)
|
||||
|
||||
third_user = self.register_user("third_user", "third_user")
|
||||
third_tok = self.login(third_user, "third_user")
|
||||
self.helper.join(self.joined_room, third_user, tok=third_tok)
|
||||
|
||||
# Make an incremental Sliding Sync request
|
||||
response_body, _ = self.do_sync(sync_body, since=from_token, tok=self.tok)
|
||||
|
||||
expectation = {
|
||||
"updated": {
|
||||
"avatar_url": None,
|
||||
"displayname": "third_user",
|
||||
}
|
||||
}
|
||||
if request_fields:
|
||||
expectation = {
|
||||
"updated": {
|
||||
"displayname": "third_user",
|
||||
},
|
||||
}
|
||||
self.assertEqual(
|
||||
response_body["extensions"]["org.matrix.msc4262.profiles"]["users"][
|
||||
"@third_user:test"
|
||||
],
|
||||
expectation,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user