diff --git a/changelog.d/18263.feature b/changelog.d/18263.feature new file mode 100644 index 0000000000..da5830b654 --- /dev/null +++ b/changelog.d/18263.feature @@ -0,0 +1 @@ +Add experimental support for [MSC4277](https://github.com/matrix-org/matrix-spec-proposals/pull/4277). diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py index 0a963b121a..977355e3e0 100644 --- a/synapse/config/experimental.py +++ b/synapse/config/experimental.py @@ -560,3 +560,9 @@ 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) diff --git a/synapse/rest/client/reporting.py b/synapse/rest/client/reporting.py index c5037be8b7..e993797dd5 100644 --- a/synapse/rest/client/reporting.py +++ b/synapse/rest/client/reporting.py @@ -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,13 @@ 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: + return 200, {} # Hide existence + 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 +144,10 @@ 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: + return 200, {} # Hide existence + else: + raise NotFoundError("Room does not exist") await self.store.add_room_report( room_id=room_id, diff --git a/tests/rest/client/test_reporting.py b/tests/rest/client/test_reporting.py index 723553979f..e754f58aae 100644 --- a/tests/rest/client/test_reporting.py +++ b/tests/rest/client/test_reporting.py @@ -28,6 +28,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): @@ -80,6 +81,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. @@ -97,6 +103,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 @@ -192,6 +211,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",