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

MSC3244 room capabilities implementation #10283

Merged
merged 7 commits into from
Jul 20, 2021
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/10283.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Initial support for MSC3244, Room version capabilities over the /capabilities API.
38 changes: 36 additions & 2 deletions synapse/api/room_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Dict
from typing import Callable, Dict, Optional

import attr

Expand Down Expand Up @@ -208,5 +208,39 @@ class RoomVersions:
RoomVersions.MSC3083,
RoomVersions.V7,
)
# Note that we do not include MSC2043 here unless it is enabled in the config.
}


@attr.s(slots=True, frozen=True, auto_attribs=True)
class RoomVersionCapability:
"""An object which describes the unique attributes of a room version."""

identifier: str # the identifier for this capability
preferred_version: Optional[RoomVersion]
support_check_lambda: Callable[[RoomVersion], bool]


MSC3244_CAPABILITIES = {
cap.identifier: {
"preferred": cap.preferred_version.identifier
if cap.preferred_version is not None
else None,
"support": [
v.identifier
for v in KNOWN_ROOM_VERSIONS.values()
if cap.support_check_lambda(v)
],
}
for cap in (
RoomVersionCapability(
"knock",
RoomVersions.V7,
lambda room_version: room_version.msc2403_knocking,
),
RoomVersionCapability(
"restricted",
None,
lambda room_version: room_version.msc3083_join_rules,
),
)
}
3 changes: 3 additions & 0 deletions synapse/config/experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ def read_config(self, config: JsonDict, **kwargs):

# MSC2716 (backfill existing history)
self.msc2716_enabled: bool = experimental.get("msc2716_enabled", False)

# MSC3244 (room version capabilities)
self.msc3244_enabled: bool = experimental.get("msc3244_enabled", False)
8 changes: 7 additions & 1 deletion synapse/rest/client/v2_alpha/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import logging
from typing import TYPE_CHECKING, Tuple

from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, MSC3244_CAPABILITIES
from synapse.http.servlet import RestServlet
from synapse.http.site import SynapseRequest
from synapse.types import JsonDict
Expand Down Expand Up @@ -55,6 +55,12 @@ async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
"m.change_password": {"enabled": change_password},
}
}

if self.config.experimental.msc3244_enabled:
response["capabilities"]["m.room_versions"][
"org.matrix.msc3244.room_capabilities"
] = MSC3244_CAPABILITIES

return 200, response


Expand Down
46 changes: 46 additions & 0 deletions tests/rest/client/v2_alpha/test_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,49 @@ def test_get_change_password_capabilities_password_disabled(self):

self.assertEqual(channel.code, 200)
self.assertFalse(capabilities["m.change_password"]["enabled"])

def test_get_does_not_include_msc3244_fields_by_default(self):
localpart = "user"
password = "pass"
user = self.register_user(localpart, password)
access_token = self.get_success(
self.auth_handler.get_access_token_for_user_id(
user, device_id=None, valid_until_ms=None
)
)

channel = self.make_request("GET", self.url, access_token=access_token)
capabilities = channel.json_body["capabilities"]

self.assertEqual(channel.code, 200)
self.assertNotIn(
"org.matrix.msc3244.room_capabilities", capabilities["m.room_versions"]
)

@override_config({"experimental_features": {"msc3244_enabled": True}})
def test_get_does_include_msc3244_fields_when_enabled(self):
localpart = "user"
password = "pass"
user = self.register_user(localpart, password)
access_token = self.get_success(
self.auth_handler.get_access_token_for_user_id(
user, device_id=None, valid_until_ms=None
)
)

channel = self.make_request("GET", self.url, access_token=access_token)
capabilities = channel.json_body["capabilities"]

self.assertEqual(channel.code, 200)
for details in capabilities["m.room_versions"][
"org.matrix.msc3244.room_capabilities"
].values():
if details["preferred"] is not None:
self.assertTrue(
details["preferred"] in KNOWN_ROOM_VERSIONS,
str(details["preferred"]),
)

self.assertGreater(len(details["support"]), 0)
for room_version in details["support"]:
self.assertTrue(room_version in KNOWN_ROOM_VERSIONS, str(room_version))