Skip to content

Commit

Permalink
Make reason and score optional for report_event
Browse files Browse the repository at this point in the history
Implements MSC2414: matrix-org/matrix-spec-proposals#2414

Signed-off-by: Callum Brown <callum@calcuode.com>
  • Loading branch information
govynnus committed May 27, 2021
1 parent f42e4c4 commit 7eb2543
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 13 deletions.
1 change: 1 addition & 0 deletions changelog.d/10077.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make reason and score parameters optional for reporting content. Implements MSC2414. Contributed by Callum Brown.
4 changes: 2 additions & 2 deletions docs/admin_api/event_reports.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 4 additions & 9 deletions synapse/rest/client/v2_alpha/report_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@
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

Expand All @@ -42,15 +38,14 @@ async def on_POST(self, request, room_id, event_id):
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",
Expand All @@ -61,7 +56,7 @@ async def on_POST(self, request, room_id, event_id):
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(),
)
Expand Down
2 changes: 1 addition & 1 deletion synapse/storage/databases/main/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ async def add_event_report(
room_id: str,
event_id: str,
user_id: str,
reason: str,
reason: Optional[str],
content: JsonDict,
received_ts: int,
) -> None:
Expand Down
15 changes: 14 additions & 1 deletion tests/rest/admin/test_event_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def prepare(self, reactor, clock, hs):
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,
)
Expand Down Expand Up @@ -378,6 +378,19 @@ def _create_event_and_report(self, room_id, user_tok):
)
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:
Expand Down
83 changes: 83 additions & 0 deletions tests/rest/client/v2_alpha/test_report_event.py
Original file line number Diff line number Diff line change
@@ -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"]
)

0 comments on commit 7eb2543

Please sign in to comment.