mirror of
https://github.com/element-hq/synapse.git
synced 2026-11-04 09:07:22 +00:00
Read a joining local user's profile in one query
A join without profile data read the user's display name and then their avatar URL, two transactions. For a local user with neither in the content, `get_profileinfo` now reads both at once. A remote user, or content that has one of the two, takes the same path as before. If the user has no profile row, the first read used to fail with a 404, logged, and leave both out. Now both are left out without the log line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PVLsNh6akt4ifEizY4D1ta
This commit is contained in:
1 parent
7eac9c44b6
commit
43d2a88e30
2 files changed
+38
-8
No files matched your search
@@ -823,14 +823,26 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
profile = self.profile_handler
|
||||
|
||||
try:
|
||||
if "displayname" not in content:
|
||||
displayname = await profile.get_displayname(target)
|
||||
if displayname is not None:
|
||||
content["displayname"] = displayname
|
||||
if "avatar_url" not in content:
|
||||
avatar_url = await profile.get_avatar_url(target)
|
||||
if avatar_url is not None:
|
||||
content["avatar_url"] = avatar_url
|
||||
if (
|
||||
"displayname" not in content
|
||||
and "avatar_url" not in content
|
||||
and self.hs.is_mine(target)
|
||||
):
|
||||
# Both in one query.
|
||||
info = await self.store.get_profileinfo(target)
|
||||
if info.display_name is not None:
|
||||
content["displayname"] = info.display_name
|
||||
if info.avatar_url is not None:
|
||||
content["avatar_url"] = info.avatar_url
|
||||
else:
|
||||
if "displayname" not in content:
|
||||
displayname = await profile.get_displayname(target)
|
||||
if displayname is not None:
|
||||
content["displayname"] = displayname
|
||||
if "avatar_url" not in content:
|
||||
avatar_url = await profile.get_avatar_url(target)
|
||||
if avatar_url is not None:
|
||||
content["avatar_url"] = avatar_url
|
||||
except Exception as e:
|
||||
logger.info("Failed to get profile information for %r: %s", target, e)
|
||||
|
||||
|
||||
@@ -3446,6 +3446,24 @@ class PerRoomProfilesForbiddenTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
self.room_id = self.helper.create_room_as(self.user_id, tok=self.tok)
|
||||
|
||||
def test_join_has_the_global_profile(self) -> None:
|
||||
"""A join without profile data gets the user's display name and
|
||||
avatar."""
|
||||
channel = self.make_request(
|
||||
"PUT",
|
||||
"/_matrix/client/r0/profile/%s/avatar_url" % (self.user_id,),
|
||||
{"avatar_url": "mxc://test/avatar"},
|
||||
access_token=self.tok,
|
||||
)
|
||||
self.assertEqual(channel.code, HTTPStatus.OK, channel.result)
|
||||
|
||||
room_id = self.helper.create_room_as(self.user_id, tok=self.tok)
|
||||
member = self.helper.get_state(
|
||||
room_id, "m.room.member", self.tok, state_key=self.user_id
|
||||
)
|
||||
self.assertEqual(member["displayname"], self.displayname)
|
||||
self.assertEqual(member["avatar_url"], "mxc://test/avatar")
|
||||
|
||||
def test_per_room_profile_forbidden(self) -> None:
|
||||
request_data = {"membership": "join", "displayname": "other test user"}
|
||||
channel = self.make_request(
|
||||
|
||||
Reference in new issue
Block a user