Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add a ModuleApi method to update a user's membership in a room #11147

Merged
merged 16 commits into from
Oct 28, 2021
Merged
34 changes: 23 additions & 11 deletions synapse/module_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from twisted.internet import defer
from twisted.web.resource import IResource

from synapse.api.errors import SynapseError
from synapse.events import EventBase
from synapse.events.presence_router import PresenceRouter
from synapse.http.client import SimpleHttpClient
Expand Down Expand Up @@ -673,17 +674,28 @@ async def update_room_membership(
content = {}

# Set the profile if not already done by the module.
if "avatar_url" not in content:
content["avatar_url"] = await self._hs.get_profile_handler().get_avatar_url(
requester.user,
)

if "displayname" not in content:
content[
"displayname"
] = await self._hs.get_profile_handler().get_displayname(
target_user_id,
)
if "avatar_url" not in content or "displayname" not in content:
try:
# Try to fetch the user's profile.
profile = await self._hs.get_profile_handler().get_profile(
target_user_id.to_string(),
)
except SynapseError as e:
if e.code == 404:
# If the profile couldn't be found, use default values.
profile = {
"displayname": target_user_id.localpart,
"avatar_url": None,
}
else:
raise
babolivier marked this conversation as resolved.
Show resolved Hide resolved

# Set the profile where it needs to be set.
if "avatar_url" not in content:
content["avatar_url"] = profile["avatar_url"]

if "displayname" not in content:
content["displayname"] = profile["displayname"]

event_id, _ = await self._hs.get_room_member_handler().update_membership(
requester=requester,
Expand Down
42 changes: 42 additions & 0 deletions tests/module_api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,28 @@ def test_update_membership(self):

self.assertEqual(channel.code, 200, channel.result)

# Make Peter invite Lesley to the room.
self.get_success(
defer.ensureDeferred(
self.module_api.update_room_membership(peter, lesley, room_id, "invite")
)
)

res = self.helper.get_state(
room_id=room_id,
event_type="m.room.member",
state_key=lesley,
tok=tok,
)

# Check the membership is correct.
self.assertEqual(res["membership"], "invite")

# Also check that the profile was correctly filled out, and that it's not
# Peter's.
self.assertEqual(res["displayname"], "Lesley May")
self.assertEqual(res["avatar_url"], "some_url")

# Make lesley join it.
self.get_success(
defer.ensureDeferred(
Expand Down Expand Up @@ -467,6 +489,26 @@ def test_update_membership(self):

self.get_failure(d, RuntimeError)

babolivier marked this conversation as resolved.
Show resolved Hide resolved
# Check that inviting a user that doesn't have a profile falls back to using a
# default (localpart + no avatar) profile.
simone = "@simone:" + self.hs.config.server.server_name
self.get_success(
defer.ensureDeferred(
self.module_api.update_room_membership(peter, simone, room_id, "invite")
)
)

res = self.helper.get_state(
room_id=room_id,
event_type="m.room.member",
state_key=simone,
tok=tok,
)

self.assertEqual(res["membership"], "invite")
self.assertEqual(res["displayname"], "simone")
self.assertIsNone(res["avatar_url"])


class ModuleApiWorkerTestCase(BaseMultiWorkerStreamTestCase):
"""For testing ModuleApi functionality in a multi-worker setup"""
Expand Down