Make reason and score optional for report_event (#10077)
Implements MSC2414: https://github.com/matrix-org/matrix-doc/pull/2414 See #8551 Signed-off-by: Callum Brown <callum@calcuode.com>
This commit is contained in:
parent
f828a70be3
commit
8fb9af570f
|
@ -0,0 +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.
|
|
@ -75,9 +75,9 @@ The following fields are returned in the JSON response body:
|
|||
* `name`: string - The name of the room.
|
||||
* `event_id`: string - The ID of the reported event.
|
||||
* `user_id`: string - This is the user who reported the event and wrote the reason.
|
||||
* `reason`: string - Comment made by the `user_id` in this report. May be blank.
|
||||
* `reason`: string - Comment made by the `user_id` in this report. May be blank or `null`.
|
||||
* `score`: integer - Content is reported based upon a negative score, where -100 is
|
||||
"most offensive" and 0 is "inoffensive".
|
||||
"most offensive" and 0 is "inoffensive". May be `null`.
|
||||
* `sender`: string - This is the ID of the user who sent the original message/event that
|
||||
was reported.
|
||||
* `canonical_alias`: string - The canonical alias of the room. `null` if the room does not
|
||||
|
|
|
@ -16,11 +16,7 @@ import logging
|
|||
from http import HTTPStatus
|
||||
|
||||
from synapse.api.errors import Codes, SynapseError
|
||||
from synapse.http.servlet import (
|
||||
RestServlet,
|
||||
assert_params_in_dict,
|
||||
parse_json_object_from_request,
|
||||
)
|
||||
from synapse.http.servlet import RestServlet, parse_json_object_from_request
|
||||
|
||||
from ._base import client_patterns
|
||||
|
||||
|
@ -42,15 +38,14 @@ class ReportEventRestServlet(RestServlet):
|
|||
user_id = requester.user.to_string()
|
||||
|
||||
body = parse_json_object_from_request(request)
|
||||
assert_params_in_dict(body, ("reason", "score"))
|
||||
|
||||
if not isinstance(body["reason"], str):
|
||||
if not isinstance(body.get("reason", ""), str):
|
||||
raise SynapseError(
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
"Param 'reason' must be a string",
|
||||
Codes.BAD_JSON,
|
||||
)
|
||||
if not isinstance(body["score"], int):
|
||||
if not isinstance(body.get("score", 0), int):
|
||||
raise SynapseError(
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
"Param 'score' must be an integer",
|
||||
|
@ -61,7 +56,7 @@ class ReportEventRestServlet(RestServlet):
|
|||
room_id=room_id,
|
||||
event_id=event_id,
|
||||
user_id=user_id,
|
||||
reason=body["reason"],
|
||||
reason=body.get("reason"),
|
||||
content=body,
|
||||
received_ts=self.clock.time_msec(),
|
||||
)
|
||||
|
|
|
@ -1498,7 +1498,7 @@ class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore, SearchStore):
|
|||
room_id: str,
|
||||
event_id: str,
|
||||
user_id: str,
|
||||
reason: str,
|
||||
reason: Optional[str],
|
||||
content: JsonDict,
|
||||
received_ts: int,
|
||||
) -> None:
|
||||
|
|
|
@ -64,7 +64,7 @@ class EventReportsTestCase(unittest.HomeserverTestCase):
|
|||
user_tok=self.admin_user_tok,
|
||||
)
|
||||
for _ in range(5):
|
||||
self._create_event_and_report(
|
||||
self._create_event_and_report_without_parameters(
|
||||
room_id=self.room_id2,
|
||||
user_tok=self.admin_user_tok,
|
||||
)
|
||||
|
@ -378,6 +378,19 @@ class EventReportsTestCase(unittest.HomeserverTestCase):
|
|||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
|
||||
def _create_event_and_report_without_parameters(self, room_id, user_tok):
|
||||
"""Create and report an event, but omit reason and score"""
|
||||
resp = self.helper.send(room_id, tok=user_tok)
|
||||
event_id = resp["event_id"]
|
||||
|
||||
channel = self.make_request(
|
||||
"POST",
|
||||
"rooms/%s/report/%s" % (room_id, event_id),
|
||||
json.dumps({}),
|
||||
access_token=user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
|
||||
def _check_fields(self, content):
|
||||
"""Checks that all attributes are present in an event report"""
|
||||
for c in content:
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# Copyright 2021 Callum Brown
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
|
||||
import synapse.rest.admin
|
||||
from synapse.rest.client.v1 import login, room
|
||||
from synapse.rest.client.v2_alpha import report_event
|
||||
|
||||
from tests import unittest
|
||||
|
||||
|
||||
class ReportEventTestCase(unittest.HomeserverTestCase):
|
||||
servlets = [
|
||||
synapse.rest.admin.register_servlets,
|
||||
login.register_servlets,
|
||||
room.register_servlets,
|
||||
report_event.register_servlets,
|
||||
]
|
||||
|
||||
def prepare(self, reactor, clock, hs):
|
||||
self.admin_user = self.register_user("admin", "pass", admin=True)
|
||||
self.admin_user_tok = self.login("admin", "pass")
|
||||
self.other_user = self.register_user("user", "pass")
|
||||
self.other_user_tok = self.login("user", "pass")
|
||||
|
||||
self.room_id = self.helper.create_room_as(
|
||||
self.other_user, tok=self.other_user_tok, is_public=True
|
||||
)
|
||||
self.helper.join(self.room_id, user=self.admin_user, tok=self.admin_user_tok)
|
||||
resp = self.helper.send(self.room_id, tok=self.admin_user_tok)
|
||||
self.event_id = resp["event_id"]
|
||||
self.report_path = "rooms/{}/report/{}".format(self.room_id, self.event_id)
|
||||
|
||||
def test_reason_str_and_score_int(self):
|
||||
data = {"reason": "this makes me sad", "score": -100}
|
||||
self._assert_status(200, data)
|
||||
|
||||
def test_no_reason(self):
|
||||
data = {"score": 0}
|
||||
self._assert_status(200, data)
|
||||
|
||||
def test_no_score(self):
|
||||
data = {"reason": "this makes me sad"}
|
||||
self._assert_status(200, data)
|
||||
|
||||
def test_no_reason_and_no_score(self):
|
||||
data = {}
|
||||
self._assert_status(200, data)
|
||||
|
||||
def test_reason_int_and_score_str(self):
|
||||
data = {"reason": 10, "score": "string"}
|
||||
self._assert_status(400, data)
|
||||
|
||||
def test_reason_zero_and_score_blank(self):
|
||||
data = {"reason": 0, "score": ""}
|
||||
self._assert_status(400, data)
|
||||
|
||||
def test_reason_and_score_null(self):
|
||||
data = {"reason": None, "score": None}
|
||||
self._assert_status(400, data)
|
||||
|
||||
def _assert_status(self, response_status, data):
|
||||
channel = self.make_request(
|
||||
"POST",
|
||||
self.report_path,
|
||||
json.dumps(data),
|
||||
access_token=self.other_user_tok,
|
||||
)
|
||||
self.assertEqual(
|
||||
response_status, int(channel.result["code"]), msg=channel.result["body"]
|
||||
)
|
Loading…
Reference in New Issue