1# Copyright 2020 Dirk Klimpel 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 15import logging 16from http import HTTPStatus 17from typing import TYPE_CHECKING, Tuple 18 19from synapse.api.errors import Codes, NotFoundError, SynapseError 20from synapse.http.servlet import RestServlet, parse_integer, parse_string 21from synapse.http.site import SynapseRequest 22from synapse.rest.admin._base import admin_patterns, assert_requester_is_admin 23from synapse.types import JsonDict 24 25if TYPE_CHECKING: 26 from synapse.server import HomeServer 27 28logger = logging.getLogger(__name__) 29 30 31class EventReportsRestServlet(RestServlet): 32 """ 33 List all reported events that are known to the homeserver. Results are returned 34 in a dictionary containing report information. Supports pagination. 35 The requester must have administrator access in Synapse. 36 37 GET /_synapse/admin/v1/event_reports 38 returns: 39 200 OK with list of reports if success otherwise an error. 40 41 Args: 42 The parameters `from` and `limit` are required only for pagination. 43 By default, a `limit` of 100 is used. 44 The parameter `dir` can be used to define the order of results. 45 The parameter `user_id` can be used to filter by user id. 46 The parameter `room_id` can be used to filter by room id. 47 Returns: 48 A list of reported events and an integer representing the total number of 49 reported events that exist given this query 50 """ 51 52 PATTERNS = admin_patterns("/event_reports$") 53 54 def __init__(self, hs: "HomeServer"): 55 self.auth = hs.get_auth() 56 self.store = hs.get_datastore() 57 58 async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: 59 await assert_requester_is_admin(self.auth, request) 60 61 start = parse_integer(request, "from", default=0) 62 limit = parse_integer(request, "limit", default=100) 63 direction = parse_string(request, "dir", default="b") 64 user_id = parse_string(request, "user_id") 65 room_id = parse_string(request, "room_id") 66 67 if start < 0: 68 raise SynapseError( 69 HTTPStatus.BAD_REQUEST, 70 "The start parameter must be a positive integer.", 71 errcode=Codes.INVALID_PARAM, 72 ) 73 74 if limit < 0: 75 raise SynapseError( 76 HTTPStatus.BAD_REQUEST, 77 "The limit parameter must be a positive integer.", 78 errcode=Codes.INVALID_PARAM, 79 ) 80 81 if direction not in ("f", "b"): 82 raise SynapseError( 83 HTTPStatus.BAD_REQUEST, 84 "Unknown direction: %s" % (direction,), 85 errcode=Codes.INVALID_PARAM, 86 ) 87 88 event_reports, total = await self.store.get_event_reports_paginate( 89 start, limit, direction, user_id, room_id 90 ) 91 ret = {"event_reports": event_reports, "total": total} 92 if (start + limit) < total: 93 ret["next_token"] = start + len(event_reports) 94 95 return HTTPStatus.OK, ret 96 97 98class EventReportDetailRestServlet(RestServlet): 99 """ 100 Get a specific reported event that is known to the homeserver. Results are returned 101 in a dictionary containing report information. 102 The requester must have administrator access in Synapse. 103 104 GET /_synapse/admin/v1/event_reports/<report_id> 105 returns: 106 200 OK with details report if success otherwise an error. 107 108 Args: 109 The parameter `report_id` is the ID of the event report in the database. 110 Returns: 111 JSON blob of information about the event report 112 """ 113 114 PATTERNS = admin_patterns("/event_reports/(?P<report_id>[^/]*)$") 115 116 def __init__(self, hs: "HomeServer"): 117 self.auth = hs.get_auth() 118 self.store = hs.get_datastore() 119 120 async def on_GET( 121 self, request: SynapseRequest, report_id: str 122 ) -> Tuple[int, JsonDict]: 123 await assert_requester_is_admin(self.auth, request) 124 125 message = ( 126 "The report_id parameter must be a string representing a positive integer." 127 ) 128 try: 129 resolved_report_id = int(report_id) 130 except ValueError: 131 raise SynapseError( 132 HTTPStatus.BAD_REQUEST, message, errcode=Codes.INVALID_PARAM 133 ) 134 135 if resolved_report_id < 0: 136 raise SynapseError( 137 HTTPStatus.BAD_REQUEST, message, errcode=Codes.INVALID_PARAM 138 ) 139 140 ret = await self.store.get_event_report(resolved_report_id) 141 if not ret: 142 raise NotFoundError("Event report not found") 143 144 return HTTPStatus.OK, ret 145