Add experimental support for MSC4277: Harmonizing the reporting endpoints (#18263)

[MSC4277](https://github.com/matrix-org/matrix-spec-proposals/pull/4277):
Harmonizing the reporting endpoints
This commit is contained in:
Johannes Marbach
2025-07-09 21:08:21 +02:00
committed by GitHub
parent 8c1e60045c
commit e1b429d88e
4 changed files with 59 additions and 6 deletions

View File

@@ -0,0 +1 @@
Add experimental support for [MSC4277](https://github.com/matrix-org/matrix-spec-proposals/pull/4277).

View File

@@ -561,6 +561,12 @@ class ExperimentalConfig(Config):
# MSC4076: Add `disable_badge_count`` to pusher configuration
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
# MSC4277: Harmonizing the reporting endpoints
#
# If enabled, ignore the score parameter and respond with HTTP 200 on
# reporting requests regardless of the subject's existence.
self.msc4277_enabled: bool = experimental.get("msc4277_enabled", False)
# MSC4235: Add `via` param to hierarchy endpoint
self.msc4235_enabled: bool = experimental.get("msc4235_enabled", False)

View File

@@ -69,7 +69,10 @@ class ReportEventRestServlet(RestServlet):
"Param 'reason' must be a string",
Codes.BAD_JSON,
)
if type(body.get("score", 0)) is not int: # noqa: E721
if (
not self.hs.config.experimental.msc4277_enabled
and type(body.get("score", 0)) is not int
): # noqa: E721
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'score' must be an integer",
@@ -85,10 +88,15 @@ class ReportEventRestServlet(RestServlet):
event = None
if event is None:
raise NotFoundError(
"Unable to report event: "
"it does not exist or you aren't able to see it."
)
if self.hs.config.experimental.msc4277_enabled:
# Respond with 200 and no content regardless of whether the event
# exists to prevent enumeration attacks.
return 200, {}
else:
raise NotFoundError(
"Unable to report event: "
"it does not exist or you aren't able to see it."
)
await self.store.add_event_report(
room_id=room_id,
@@ -138,7 +146,12 @@ class ReportRoomRestServlet(RestServlet):
room = await self.store.get_room(room_id)
if room is None:
raise NotFoundError("Room does not exist")
if self.hs.config.experimental.msc4277_enabled:
# Respond with 200 and no content regardless of whether the room
# exists to prevent enumeration attacks.
return 200, {}
else:
raise NotFoundError("Room does not exist")
await self.store.add_room_report(
room_id=room_id,

View File

@@ -29,6 +29,7 @@ from synapse.types import JsonDict
from synapse.util import Clock
from tests import unittest
from tests.unittest import override_config
class ReportEventTestCase(unittest.HomeserverTestCase):
@@ -81,6 +82,11 @@ class ReportEventTestCase(unittest.HomeserverTestCase):
data = {"reason": None, "score": None}
self._assert_status(400, data)
@override_config({"experimental_features": {"msc4277_enabled": True}})
def test_score_str(self) -> None:
data = {"score": "string"}
self._assert_status(200, data)
def test_cannot_report_nonexistent_event(self) -> None:
"""
Tests that we don't accept event reports for events which do not exist.
@@ -98,6 +104,19 @@ class ReportEventTestCase(unittest.HomeserverTestCase):
msg=channel.result["body"],
)
@override_config({"experimental_features": {"msc4277_enabled": True}})
def test_event_existence_hidden(self) -> None:
"""
Tests that the requester cannot infer the existence of an event.
"""
channel = self.make_request(
"POST",
f"rooms/{self.room_id}/report/$nonsenseeventid:test",
{"reason": "i am very sad"},
access_token=self.other_user_tok,
)
self.assertEqual(200, channel.code, msg=channel.result["body"])
def test_cannot_report_event_if_not_in_room(self) -> None:
"""
Tests that we don't accept event reports for events that exist, but for which
@@ -193,6 +212,20 @@ class ReportRoomTestCase(unittest.HomeserverTestCase):
msg=channel.result["body"],
)
@override_config({"experimental_features": {"msc4277_enabled": True}})
def test_room_existence_hidden(self) -> None:
"""
Tests that the requester cannot infer the existence of a room.
"""
channel = self.make_request(
"POST",
"/_matrix/client/v3/rooms/!bloop:example.org/report",
{"reason": "i am very sad"},
access_token=self.other_user_tok,
shorthand=False,
)
self.assertEqual(200, channel.code, msg=channel.result["body"])
def _assert_status(self, response_status: int, data: JsonDict) -> None:
channel = self.make_request(
"POST",