summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/federation/federation_server.py10
-rw-r--r--synapse/federation/transport/server.py12
-rw-r--r--synapse/handlers/federation.py7
-rw-r--r--tests/federation/transport/test_knocking.py11
4 files changed, 33 insertions, 7 deletions
diff --git a/synapse/federation/federation_server.py b/synapse/federation/federation_server.py

index 6a2631ee18..01aa285130 100644 --- a/synapse/federation/federation_server.py +++ b/synapse/federation/federation_server.py
@@ -568,7 +568,7 @@ class FederationServer(FederationBase): return {} async def on_make_knock_request( - self, origin: str, room_id: str, user_id: str, + self, origin: str, room_id: str, user_id: str, supported_versions: List[str] ) -> Dict[str, Union[EventBase, str]]: """We've received a /make_knock/ request, so we create a partial knock event for the room and hand that back, along with the room version, to the knocking @@ -579,16 +579,22 @@ class FederationServer(FederationBase): origin: The (verified) server name of the requesting server. room_id: The room to create the knock event in. user_id: The user to create the knock for. + supported_versions: The room versions supported by the requesting server. Returns: The partial knock event. """ origin_host, _ = parse_server_name(origin) await self.check_server_matches_acl(origin_host, room_id) - pdu = await self.handler.on_make_knock_request(origin, room_id, user_id) room_version = await self.store.get_room_version_id(room_id) + if room_version not in supported_versions: + logger.warning( + "Room version %s not in %s", room_version, supported_versions + ) + raise IncompatibleRoomVersionError(room_version=room_version) + pdu = await self.handler.on_make_knock_request(origin, room_id, user_id) time_now = self._clock.time_msec() return {"event": pdu.get_pdu_json(time_now), "room_version": room_version} diff --git a/synapse/federation/transport/server.py b/synapse/federation/transport/server.py
index 40d6af45cd..961d16ac5a 100644 --- a/synapse/federation/transport/server.py +++ b/synapse/federation/transport/server.py
@@ -15,7 +15,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - import functools import logging import re @@ -36,6 +35,7 @@ from synapse.http.servlet import ( parse_boolean_from_args, parse_integer_from_args, parse_json_object_from_request, + parse_list_from_args, parse_string_from_args, ) from synapse.logging.context import run_in_background @@ -550,7 +550,15 @@ class FederationMakeKnockServlet(BaseFederationServlet): PREFIX = FEDERATION_UNSTABLE_PREFIX + "/xyz.amorgan.knock" async def on_GET(self, origin, content, query, room_id, user_id): - content = await self.handler.on_make_knock_request(origin, room_id, user_id) + try: + # Retrieve the room versions the remote homeserver claims to support + supported_versions = parse_list_from_args(query, "ver", encoding="utf-8") + except KeyError: + raise SynapseError(400, "Missing required query parameter 'ver'") + + content = await self.handler.on_make_knock_request( + origin, room_id, user_id, supported_versions=supported_versions + ) return 200, content diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index a9ac4bd85e..87c8da0196 100644 --- a/synapse/handlers/federation.py +++ b/synapse/handlers/federation.py
@@ -1470,10 +1470,14 @@ class FederationHandler(BaseHandler): """ logger.debug("Knocking on room %s on behalf of user %s", room_id, knockee) + # Inform the remote server of the room versions we support + supported_room_versions = list(KNOWN_ROOM_VERSIONS.keys()) + # Ask the remote server to create a valid knock event for us. Once received, # we sign the event + params = {"ver": supported_room_versions} # type: Dict[str, Iterable[str]] origin, event, event_format_version = await self._make_and_verify_event( - target_hosts, room_id, knockee, Membership.KNOCK, content, + target_hosts, room_id, knockee, Membership.KNOCK, content, params=params ) # Record the room ID and its version so that we have a record of the room @@ -1875,6 +1879,7 @@ class FederationHandler(BaseHandler): raise SynapseError(403, "User not from origin", Codes.FORBIDDEN) room_version = await self.store.get_room_version_id(room_id) + builder = self.event_builder_factory.new( room_version, { diff --git a/tests/federation/transport/test_knocking.py b/tests/federation/transport/test_knocking.py
index 9e30037ea3..f60fdd7983 100644 --- a/tests/federation/transport/test_knocking.py +++ b/tests/federation/transport/test_knocking.py
@@ -229,8 +229,15 @@ class FederationKnockingTestCase( _, channel = self.make_request( "GET", - "/_matrix/federation/unstable/%s/make_knock/%s/%s" - % (KNOCK_UNSTABLE_IDENTIFIER, room_id, fake_knocking_user_id), + "/_matrix/federation/unstable/%s/make_knock/%s/%s?ver=%s" + % ( + KNOCK_UNSTABLE_IDENTIFIER, + room_id, + fake_knocking_user_id, + # Inform the remote that we support the room version of the room we're + # knocking on + RoomVersions.MSC2403_DEV.identifier, + ), ) self.assertEquals(200, channel.code, channel.result)