Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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's `update_room_membership` method (in a backwards compatible manner).
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