Implement MSC4497

This commit is contained in:
Half-Shot
2026-06-30 17:48:47 +01:00
parent 4e9f7757f1
commit 73922e12f1
4 changed files with 46 additions and 1 deletions
+2
View File
@@ -0,0 +1,2 @@
Implemement MSC4497: Filter state events by type in /state endpoint. Requests to `/_matrix/client/v3/rooms/!../state` can now be
made with a `cc.koja.types` key to filter to only specific state types.
+3
View File
@@ -622,3 +622,6 @@ class ExperimentalConfig(Config):
# MSC4455: Preview URL capability
# Tracked in: https://github.com/element-hq/synapse/issues/19719
self.msc4452_enabled: bool = experimental.get("msc4452_enabled", False)
# MSC4497: State event type filter
self.msc4497_state_event_type_filter: bool = experimental.get("msc4497_state_event_type_filter", False)
+12 -1
View File
@@ -25,7 +25,7 @@ import logging
import re
from enum import Enum
from http import HTTPStatus
from typing import TYPE_CHECKING, Awaitable
from typing import TYPE_CHECKING, Awaitable, Mapping, Sequence
from urllib import parse as urlparse
import attr
@@ -69,6 +69,7 @@ from synapse.http.servlet import (
parse_json,
parse_json_object_from_request,
parse_string,
parse_string_from_args,
parse_strings_from_args,
)
from synapse.http.site import SynapseRequest
@@ -990,15 +991,25 @@ class RoomStateRestServlet(RestServlet):
super().__init__()
self.message_handler = hs.get_message_handler()
self.auth = hs.get_auth()
self.experimental_config = hs.config.experimental
@cancellable
async def on_GET(
self, request: SynapseRequest, room_id: str
) -> tuple[int, list[JsonDict]]:
requester = await self.auth.get_user_by_req(request, allow_guest=True)
args: Mapping[bytes, Sequence[bytes]] = request.args # type: ignore
type_filter = (
parse_strings_from_args(args, "cc.koja.types", required=False)
if self.experimental_config.msc4497_state_event_type_filter
else None
)
# Get all the current state for this room
events = await self.message_handler.get_state_events(
room_id=room_id,
state_filter=StateFilter.from_types((x, None) for x in type_filter)
if type_filter is not None
else None,
requester=requester,
)
return 200, events
+29
View File
@@ -601,6 +601,35 @@ class RoomStateTestCase(RoomBase):
self.assertEqual(channel.json_body["state_key"], self.user_id)
self.assertTrue(type(channel.json_body["origin_server_ts"]) is int)
def test_get_state_type_filter_single(self) -> None:
"""MSC4497: filtering by a single type returns only that event type."""
self.hs.config.experimental.msc4497_state_event_type_filter = True
room_id = self.helper.create_room_as(self.user_id)
channel = self.make_request(
"GET",
"/rooms/%s/state?cc.koja.types=m.room.create" % room_id,
)
self.assertEqual(channel.code, HTTPStatus.OK, channel.result["body"])
self.assertEqual(
[event["type"] for event in channel.json_list],
["m.room.create"],
)
def test_get_state_type_filter_multiple(self) -> None:
"""MSC4497: filtering by multiple types returns only those event types."""
self.hs.config.experimental.msc4497_state_event_type_filter = True
room_id = self.helper.create_room_as(self.user_id)
channel = self.make_request(
"GET",
"/rooms/%s/state?cc.koja.types=m.room.create&cc.koja.types=m.room.member"
% room_id,
)
self.assertEqual(channel.code, HTTPStatus.OK, channel.result["body"])
self.assertCountEqual(
[event["type"] for event in channel.json_list],
["m.room.create", "m.room.member"],
)
class RoomsMemberListTestCase(RoomBase):
"""Tests /rooms/$room_id/members/list REST events."""