diff --git a/changelog.d/17374.feature b/changelog.d/17374.feature
new file mode 100644
index 0000000000..3321f18947
--- /dev/null
+++ b/changelog.d/17374.feature
@@ -0,0 +1 @@
+Support [MSC4151](https://github.com/matrix-org/matrix-spec-proposals/pull/4151)'s stable report room API.
\ No newline at end of file
diff --git a/synapse/rest/client/reporting.py b/synapse/rest/client/reporting.py
index 97bd5d8c02..949f077035 100644
--- a/synapse/rest/client/reporting.py
+++ b/synapse/rest/client/reporting.py
@@ -20,11 +20,13 @@
#
import logging
+import re
from http import HTTPStatus
from typing import TYPE_CHECKING, Tuple
from synapse._pydantic_compat import StrictStr
from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError
+from synapse.api.urls import CLIENT_API_PREFIX
from synapse.http.server import HttpServer
from synapse.http.servlet import (
RestServlet,
@@ -105,18 +107,17 @@ class ReportEventRestServlet(RestServlet):
class ReportRoomRestServlet(RestServlet):
"""This endpoint lets clients report a room for abuse.
- Whilst MSC4151 is not yet merged, this unstable endpoint is enabled on matrix.org
- for content moderation purposes, and therefore backwards compatibility should be
- carefully considered when changing anything on this endpoint.
-
- More details on the MSC: https://github.com/matrix-org/matrix-spec-proposals/pull/4151
+ Introduced by MSC4151: https://github.com/matrix-org/matrix-spec-proposals/pull/4151
"""
- PATTERNS = client_patterns(
- "/org.matrix.msc4151/rooms/(?P<room_id>[^/]*)/report$",
- releases=[],
- v1=False,
- unstable=True,
+ # Cast the Iterable to a list so that we can `append` below.
+ PATTERNS = list(
+ client_patterns(
+ "/rooms/(?P<room_id>[^/]*)/report$",
+ releases=("v3",),
+ unstable=False,
+ v1=False,
+ )
)
def __init__(self, hs: "HomeServer"):
@@ -126,6 +127,16 @@ class ReportRoomRestServlet(RestServlet):
self.clock = hs.get_clock()
self.store = hs.get_datastores().main
+ # TODO: Remove the unstable variant after 2-3 releases
+ # https://github.com/element-hq/synapse/issues/17373
+ if hs.config.experimental.msc4151_enabled:
+ self.PATTERNS.append(
+ re.compile(
+ f"^{CLIENT_API_PREFIX}/unstable/org.matrix.msc4151"
+ "/rooms/(?P<room_id>[^/]*)/report$"
+ )
+ )
+
class PostBody(RequestBodyModel):
reason: StrictStr
@@ -153,6 +164,4 @@ class ReportRoomRestServlet(RestServlet):
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
ReportEventRestServlet(hs).register(http_server)
-
- if hs.config.experimental.msc4151_enabled:
- ReportRoomRestServlet(hs).register(http_server)
+ ReportRoomRestServlet(hs).register(http_server)
diff --git a/tests/rest/client/test_reporting.py b/tests/rest/client/test_reporting.py
index 009deb9cb0..723553979f 100644
--- a/tests/rest/client/test_reporting.py
+++ b/tests/rest/client/test_reporting.py
@@ -156,58 +156,31 @@ class ReportRoomTestCase(unittest.HomeserverTestCase):
self.room_id = self.helper.create_room_as(
self.other_user, tok=self.other_user_tok, is_public=True
)
- self.report_path = (
- f"/_matrix/client/unstable/org.matrix.msc4151/rooms/{self.room_id}/report"
- )
+ self.report_path = f"/_matrix/client/v3/rooms/{self.room_id}/report"
- @unittest.override_config(
- {
- "experimental_features": {"msc4151_enabled": True},
- }
- )
def test_reason_str(self) -> None:
data = {"reason": "this makes me sad"}
self._assert_status(200, data)
- @unittest.override_config(
- {
- "experimental_features": {"msc4151_enabled": True},
- }
- )
def test_no_reason(self) -> None:
data = {"not_reason": "for typechecking"}
self._assert_status(400, data)
- @unittest.override_config(
- {
- "experimental_features": {"msc4151_enabled": True},
- }
- )
def test_reason_nonstring(self) -> None:
data = {"reason": 42}
self._assert_status(400, data)
- @unittest.override_config(
- {
- "experimental_features": {"msc4151_enabled": True},
- }
- )
def test_reason_null(self) -> None:
data = {"reason": None}
self._assert_status(400, data)
- @unittest.override_config(
- {
- "experimental_features": {"msc4151_enabled": True},
- }
- )
def test_cannot_report_nonexistent_room(self) -> None:
"""
Tests that we don't accept event reports for rooms which do not exist.
"""
channel = self.make_request(
"POST",
- "/_matrix/client/unstable/org.matrix.msc4151/rooms/!bloop:example.org/report",
+ "/_matrix/client/v3/rooms/!bloop:example.org/report",
{"reason": "i am very sad"},
access_token=self.other_user_tok,
shorthand=False,
|