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

Update module API "update room membership" method to allow for remote joins #13441

1 change: 1 addition & 0 deletions changelog.d/13441.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add remote join capability to the module API "update_room_membership" method (in a backwards compatible manner).
babolivier marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 4 additions & 4 deletions synapse/module_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -929,10 +929,12 @@ async def update_room_membership(
room_id: str,
new_membership: str,
content: Optional[JsonDict] = None,
remote_room_hosts: Optional[List[str]] = None,
) -> EventBase:
"""Updates the membership of a user to the given value.

Added in Synapse v1.46.0.
Changed in Synapse v1.65.0: Added the 'remote_room_hosts' parameter.

Args:
sender: The user performing the membership change. Must be a user local to
Expand All @@ -946,6 +948,7 @@ async def update_room_membership(
https://spec.matrix.org/unstable/client-server-api/#mroommember for the
list of allowed values.
content: Additional values to include in the resulting event's content.
remote_room_hosts: Remote servers to use for remote joins/knocks/etc.

Returns:
The newly created membership event.
Expand Down Expand Up @@ -1005,15 +1008,12 @@ async def update_room_membership(
room_id=room_id,
action=new_membership,
content=content,
remote_room_hosts=remote_room_hosts,
)

# Try to retrieve the resulting event.
event = await self._hs.get_datastores().main.get_event(event_id)

# update_membership is supposed to always return after the event has been
# successfully persisted.
assert event is not None

return event

async def create_and_send_event_into_room(self, event_dict: JsonDict) -> EventBase:
Expand Down
29 changes: 29 additions & 0 deletions tests/module_api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from twisted.internet import defer

from synapse.api.constants import EduTypes, EventTypes
from synapse.api.errors import NotFoundError
from synapse.events import EventBase
from synapse.federation.units import Transaction
from synapse.handlers.presence import UserPresenceState
Expand Down Expand Up @@ -532,6 +533,34 @@ def test_update_membership(self):
self.assertEqual(res["displayname"], "simone")
self.assertIsNone(res["avatar_url"])

def test_update_room_membership_remote_join(self):
"""Test that the module API can join a remote room."""
# Necessary to fake a remote join.
fake_stream_id = 1
mocked_remote_join = simple_async_mock(
return_value=("fake-event-id", fake_stream_id)
)
self.hs.get_room_member_handler()._remote_join = mocked_remote_join
fake_remote_host = f"{self.module_api.server_name}-remote"

# Given that the join is to be faked, we expect the relevant join event not to
# be persisted and the module API method to raise that.
self.get_failure(
defer.ensureDeferred(
self.module_api.update_room_membership(
sender=f"@user:{self.module_api.server_name}",
target=f"@user:{self.module_api.server_name}",
room_id=f"!nonexistent:{fake_remote_host}",
new_membership="join",
remote_room_hosts=[fake_remote_host],
)
),
NotFoundError,
)

# Check that a remote join was attempted.
self.assertEqual(mocked_remote_join.call_count, 1)

def test_get_room_state(self):
"""Tests that a module can retrieve the state of a room through the module API."""
user_id = self.register_user("peter", "hackme")
Expand Down