Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 8fb9af5

Browse files
authored
Make reason and score optional for report_event (#10077)
Implements MSC2414: matrix-org/matrix-spec-proposals#2414 See #8551 Signed-off-by: Callum Brown <[email protected]>
1 parent f828a70 commit 8fb9af5

File tree

6 files changed

+105
-13
lines changed

6 files changed

+105
-13
lines changed

changelog.d/10077.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make reason and score parameters optional for reporting content. Implements [MSC2414](https://github.com/matrix-org/matrix-doc/pull/2414). Contributed by Callum Brown.

docs/admin_api/event_reports.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ The following fields are returned in the JSON response body:
7575
* `name`: string - The name of the room.
7676
* `event_id`: string - The ID of the reported event.
7777
* `user_id`: string - This is the user who reported the event and wrote the reason.
78-
* `reason`: string - Comment made by the `user_id` in this report. May be blank.
78+
* `reason`: string - Comment made by the `user_id` in this report. May be blank or `null`.
7979
* `score`: integer - Content is reported based upon a negative score, where -100 is
80-
"most offensive" and 0 is "inoffensive".
80+
"most offensive" and 0 is "inoffensive". May be `null`.
8181
* `sender`: string - This is the ID of the user who sent the original message/event that
8282
was reported.
8383
* `canonical_alias`: string - The canonical alias of the room. `null` if the room does not

synapse/rest/client/v2_alpha/report_event.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@
1616
from http import HTTPStatus
1717

1818
from synapse.api.errors import Codes, SynapseError
19-
from synapse.http.servlet import (
20-
RestServlet,
21-
assert_params_in_dict,
22-
parse_json_object_from_request,
23-
)
19+
from synapse.http.servlet import RestServlet, parse_json_object_from_request
2420

2521
from ._base import client_patterns
2622

@@ -42,15 +38,14 @@ async def on_POST(self, request, room_id, event_id):
4238
user_id = requester.user.to_string()
4339

4440
body = parse_json_object_from_request(request)
45-
assert_params_in_dict(body, ("reason", "score"))
4641

47-
if not isinstance(body["reason"], str):
42+
if not isinstance(body.get("reason", ""), str):
4843
raise SynapseError(
4944
HTTPStatus.BAD_REQUEST,
5045
"Param 'reason' must be a string",
5146
Codes.BAD_JSON,
5247
)
53-
if not isinstance(body["score"], int):
48+
if not isinstance(body.get("score", 0), int):
5449
raise SynapseError(
5550
HTTPStatus.BAD_REQUEST,
5651
"Param 'score' must be an integer",
@@ -61,7 +56,7 @@ async def on_POST(self, request, room_id, event_id):
6156
room_id=room_id,
6257
event_id=event_id,
6358
user_id=user_id,
64-
reason=body["reason"],
59+
reason=body.get("reason"),
6560
content=body,
6661
received_ts=self.clock.time_msec(),
6762
)

synapse/storage/databases/main/room.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,7 @@ async def add_event_report(
14981498
room_id: str,
14991499
event_id: str,
15001500
user_id: str,
1501-
reason: str,
1501+
reason: Optional[str],
15021502
content: JsonDict,
15031503
received_ts: int,
15041504
) -> None:

tests/rest/admin/test_event_reports.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def prepare(self, reactor, clock, hs):
6464
user_tok=self.admin_user_tok,
6565
)
6666
for _ in range(5):
67-
self._create_event_and_report(
67+
self._create_event_and_report_without_parameters(
6868
room_id=self.room_id2,
6969
user_tok=self.admin_user_tok,
7070
)
@@ -378,6 +378,19 @@ def _create_event_and_report(self, room_id, user_tok):
378378
)
379379
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
380380

381+
def _create_event_and_report_without_parameters(self, room_id, user_tok):
382+
"""Create and report an event, but omit reason and score"""
383+
resp = self.helper.send(room_id, tok=user_tok)
384+
event_id = resp["event_id"]
385+
386+
channel = self.make_request(
387+
"POST",
388+
"rooms/%s/report/%s" % (room_id, event_id),
389+
json.dumps({}),
390+
access_token=user_tok,
391+
)
392+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
393+
381394
def _check_fields(self, content):
382395
"""Checks that all attributes are present in an event report"""
383396
for c in content:
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright 2021 Callum Brown
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import json
16+
17+
import synapse.rest.admin
18+
from synapse.rest.client.v1 import login, room
19+
from synapse.rest.client.v2_alpha import report_event
20+
21+
from tests import unittest
22+
23+
24+
class ReportEventTestCase(unittest.HomeserverTestCase):
25+
servlets = [
26+
synapse.rest.admin.register_servlets,
27+
login.register_servlets,
28+
room.register_servlets,
29+
report_event.register_servlets,
30+
]
31+
32+
def prepare(self, reactor, clock, hs):
33+
self.admin_user = self.register_user("admin", "pass", admin=True)
34+
self.admin_user_tok = self.login("admin", "pass")
35+
self.other_user = self.register_user("user", "pass")
36+
self.other_user_tok = self.login("user", "pass")
37+
38+
self.room_id = self.helper.create_room_as(
39+
self.other_user, tok=self.other_user_tok, is_public=True
40+
)
41+
self.helper.join(self.room_id, user=self.admin_user, tok=self.admin_user_tok)
42+
resp = self.helper.send(self.room_id, tok=self.admin_user_tok)
43+
self.event_id = resp["event_id"]
44+
self.report_path = "rooms/{}/report/{}".format(self.room_id, self.event_id)
45+
46+
def test_reason_str_and_score_int(self):
47+
data = {"reason": "this makes me sad", "score": -100}
48+
self._assert_status(200, data)
49+
50+
def test_no_reason(self):
51+
data = {"score": 0}
52+
self._assert_status(200, data)
53+
54+
def test_no_score(self):
55+
data = {"reason": "this makes me sad"}
56+
self._assert_status(200, data)
57+
58+
def test_no_reason_and_no_score(self):
59+
data = {}
60+
self._assert_status(200, data)
61+
62+
def test_reason_int_and_score_str(self):
63+
data = {"reason": 10, "score": "string"}
64+
self._assert_status(400, data)
65+
66+
def test_reason_zero_and_score_blank(self):
67+
data = {"reason": 0, "score": ""}
68+
self._assert_status(400, data)
69+
70+
def test_reason_and_score_null(self):
71+
data = {"reason": None, "score": None}
72+
self._assert_status(400, data)
73+
74+
def _assert_status(self, response_status, data):
75+
channel = self.make_request(
76+
"POST",
77+
self.report_path,
78+
json.dumps(data),
79+
access_token=self.other_user_tok,
80+
)
81+
self.assertEqual(
82+
response_status, int(channel.result["code"]), msg=channel.result["body"]
83+
)

0 commit comments

Comments
 (0)