mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-27 22:34:55 +00:00
Implement MSC4497
This commit is contained in:
@@ -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.
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user