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

Commit 69226c1

Browse files
authored
MSC3244 room capabilities implementation (#10283)
1 parent 794371b commit 69226c1

File tree

5 files changed

+93
-3
lines changed

5 files changed

+93
-3
lines changed

changelog.d/10283.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Initial support for MSC3244, Room version capabilities over the /capabilities API.

synapse/api/room_versions.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import Dict
15+
from typing import Callable, Dict, Optional
1616

1717
import attr
1818

@@ -208,5 +208,39 @@ class RoomVersions:
208208
RoomVersions.MSC3083,
209209
RoomVersions.V7,
210210
)
211-
# Note that we do not include MSC2043 here unless it is enabled in the config.
211+
}
212+
213+
214+
@attr.s(slots=True, frozen=True, auto_attribs=True)
215+
class RoomVersionCapability:
216+
"""An object which describes the unique attributes of a room version."""
217+
218+
identifier: str # the identifier for this capability
219+
preferred_version: Optional[RoomVersion]
220+
support_check_lambda: Callable[[RoomVersion], bool]
221+
222+
223+
MSC3244_CAPABILITIES = {
224+
cap.identifier: {
225+
"preferred": cap.preferred_version.identifier
226+
if cap.preferred_version is not None
227+
else None,
228+
"support": [
229+
v.identifier
230+
for v in KNOWN_ROOM_VERSIONS.values()
231+
if cap.support_check_lambda(v)
232+
],
233+
}
234+
for cap in (
235+
RoomVersionCapability(
236+
"knock",
237+
RoomVersions.V7,
238+
lambda room_version: room_version.msc2403_knocking,
239+
),
240+
RoomVersionCapability(
241+
"restricted",
242+
None,
243+
lambda room_version: room_version.msc3083_join_rules,
244+
),
245+
)
212246
}

synapse/config/experimental.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ def read_config(self, config: JsonDict, **kwargs):
3232

3333
# MSC2716 (backfill existing history)
3434
self.msc2716_enabled: bool = experimental.get("msc2716_enabled", False)
35+
36+
# MSC3244 (room version capabilities)
37+
self.msc3244_enabled: bool = experimental.get("msc3244_enabled", False)

synapse/rest/client/v2_alpha/capabilities.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import logging
1515
from typing import TYPE_CHECKING, Tuple
1616

17-
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
17+
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, MSC3244_CAPABILITIES
1818
from synapse.http.servlet import RestServlet
1919
from synapse.http.site import SynapseRequest
2020
from synapse.types import JsonDict
@@ -55,6 +55,12 @@ async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
5555
"m.change_password": {"enabled": change_password},
5656
}
5757
}
58+
59+
if self.config.experimental.msc3244_enabled:
60+
response["capabilities"]["m.room_versions"][
61+
"org.matrix.msc3244.room_capabilities"
62+
] = MSC3244_CAPABILITIES
63+
5864
return 200, response
5965

6066

tests/rest/client/v2_alpha/test_capabilities.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,49 @@ def test_get_change_password_capabilities_password_disabled(self):
102102

103103
self.assertEqual(channel.code, 200)
104104
self.assertFalse(capabilities["m.change_password"]["enabled"])
105+
106+
def test_get_does_not_include_msc3244_fields_by_default(self):
107+
localpart = "user"
108+
password = "pass"
109+
user = self.register_user(localpart, password)
110+
access_token = self.get_success(
111+
self.auth_handler.get_access_token_for_user_id(
112+
user, device_id=None, valid_until_ms=None
113+
)
114+
)
115+
116+
channel = self.make_request("GET", self.url, access_token=access_token)
117+
capabilities = channel.json_body["capabilities"]
118+
119+
self.assertEqual(channel.code, 200)
120+
self.assertNotIn(
121+
"org.matrix.msc3244.room_capabilities", capabilities["m.room_versions"]
122+
)
123+
124+
@override_config({"experimental_features": {"msc3244_enabled": True}})
125+
def test_get_does_include_msc3244_fields_when_enabled(self):
126+
localpart = "user"
127+
password = "pass"
128+
user = self.register_user(localpart, password)
129+
access_token = self.get_success(
130+
self.auth_handler.get_access_token_for_user_id(
131+
user, device_id=None, valid_until_ms=None
132+
)
133+
)
134+
135+
channel = self.make_request("GET", self.url, access_token=access_token)
136+
capabilities = channel.json_body["capabilities"]
137+
138+
self.assertEqual(channel.code, 200)
139+
for details in capabilities["m.room_versions"][
140+
"org.matrix.msc3244.room_capabilities"
141+
].values():
142+
if details["preferred"] is not None:
143+
self.assertTrue(
144+
details["preferred"] in KNOWN_ROOM_VERSIONS,
145+
str(details["preferred"]),
146+
)
147+
148+
self.assertGreater(len(details["support"]), 0)
149+
for room_version in details["support"]:
150+
self.assertTrue(room_version in KNOWN_ROOM_VERSIONS, str(room_version))

0 commit comments

Comments
 (0)