From 10332c175c829a21b6565bc5e865bca154ffb084 Mon Sep 17 00:00:00 2001 From: David Teller Date: Mon, 18 Jan 2021 15:02:22 +0100 Subject: New API /_synapse/admin/rooms/{roomId}/context/{eventId} Signed-off-by: David Teller --- tests/rest/admin/test_room.py | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tests/rest') diff --git a/tests/rest/admin/test_room.py b/tests/rest/admin/test_room.py index a0f32c5512..7e89eb4793 100644 --- a/tests/rest/admin/test_room.py +++ b/tests/rest/admin/test_room.py @@ -1430,6 +1430,54 @@ class JoinAliasRoomTestCase(unittest.HomeserverTestCase): self.assertEquals(200, int(channel.result["code"]), msg=channel.result["body"]) self.assertEqual(private_room_id, channel.json_body["joined_rooms"][0]) + def test_context(self): + """ + Test that, as admin, we can find the context of an event without having joined the room. + """ + + # Create a room. We're not part of it. + user_id = self.register_user("test", "test") + user_tok = self.login("test", "test") + room_id = self.helper.create_room_as(user_id, tok=user_tok) + + # Populate the room with events. + events = [] + for i in range(30): + events.append( + self.helper.send_event( + room_id, "com.example.test", content={"index": i}, tok=user_tok + ) + ) + + # Now let's fetch the context for this room. + midway = (len(events) - 1) // 2 + channel = self.make_request( + "GET", + "/_synapse/admin/v1/rooms/%s/context/%s" + % (room_id, events[midway]["event_id"]), + access_token=self.admin_user_tok, + ) + self.assertEquals(200, int(channel.result["code"]), msg=channel.result["body"]) + self.assertEquals( + channel.json_body["event"]["event_id"], events[midway]["event_id"] + ) + + for i, found_event in enumerate(channel.json_body["events_before"]): + for j, posted_event in enumerate(events): + if found_event["event_id"] == posted_event["event_id"]: + self.assertTrue(j < midway) + break + else: + self.fail("Event %s from events_before not found" % j) + + for i, found_event in enumerate(channel.json_body["events_after"]): + for j, posted_event in enumerate(events): + if found_event["event_id"] == posted_event["event_id"]: + self.assertTrue(j > midway) + break + else: + self.fail("Event %s from events_after not found" % j) + class MakeRoomAdminTestCase(unittest.HomeserverTestCase): servlets = [ -- cgit 1.4.1 From b859919acc3ad6c61ba26a3c9b1e36c75a30c3fe Mon Sep 17 00:00:00 2001 From: David Teller Date: Thu, 28 Jan 2021 12:18:07 +0100 Subject: FIXUP: Now testing that the user is admin! --- changelog.d/9150.feature | 5 +---- synapse/rest/admin/rooms.py | 3 ++- tests/rest/admin/test_room.py | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 6 deletions(-) (limited to 'tests/rest') diff --git a/changelog.d/9150.feature b/changelog.d/9150.feature index 86c4fd3d72..48a8148dee 100644 --- a/changelog.d/9150.feature +++ b/changelog.d/9150.feature @@ -1,4 +1 @@ -New API /_synapse/admin/rooms/{roomId}/context/{eventId} - -This API mirrors /_matrix/client/r0/rooms/{roomId}/context/{eventId} but lets administrators -inspect rooms. Designed to annotate abuse reports with context. +New API /_synapse/admin/rooms/{roomId}/context/{eventId}. diff --git a/synapse/rest/admin/rooms.py b/synapse/rest/admin/rooms.py index 6539655289..4393197549 100644 --- a/synapse/rest/admin/rooms.py +++ b/synapse/rest/admin/rooms.py @@ -578,7 +578,8 @@ class RoomEventContextServlet(RestServlet): self.auth = hs.get_auth() async def on_GET(self, request, room_id, event_id): - requester = await self.auth.get_user_by_req(request, allow_guest=True) + requester = await self.auth.get_user_by_req(request, allow_guest=False) + await assert_user_is_admin(self.auth, requester.user) limit = parse_integer(request, "limit", default=10) diff --git a/tests/rest/admin/test_room.py b/tests/rest/admin/test_room.py index 7e89eb4793..fd201993d3 100644 --- a/tests/rest/admin/test_room.py +++ b/tests/rest/admin/test_room.py @@ -1430,7 +1430,41 @@ class JoinAliasRoomTestCase(unittest.HomeserverTestCase): self.assertEquals(200, int(channel.result["code"]), msg=channel.result["body"]) self.assertEqual(private_room_id, channel.json_body["joined_rooms"][0]) - def test_context(self): + def test_context_as_non_admin(self): + """ + Test that, without being admin, one cannot use the context admin API + """ + # Create a room. + user_id = self.register_user("test", "test") + user_tok = self.login("test", "test") + + self.register_user("test_2", "test") + user_tok_2 = self.login("test_2", "test") + + room_id = self.helper.create_room_as(user_id, tok=user_tok) + + # Populate the room with events. + events = [] + for i in range(30): + events.append( + self.helper.send_event( + room_id, "com.example.test", content={"index": i}, tok=user_tok + ) + ) + + # Now attempt to find the context using the admin API without being admin. + midway = (len(events) - 1) // 2 + for tok in [user_tok, user_tok_2]: + channel = self.make_request( + "GET", + "/_synapse/admin/v1/rooms/%s/context/%s" + % (room_id, events[midway]["event_id"]), + access_token=tok, + ) + self.assertEquals(403, int(channel.result["code"]), msg=channel.result["body"]) + self.assertEqual(Codes.FORBIDDEN, channel.json_body["errcode"]) + + def test_context_as_admin(self): """ Test that, as admin, we can find the context of an event without having joined the room. """ -- cgit 1.4.1 From 31d072aea0a37ad5408995359b89080b5280f57d Mon Sep 17 00:00:00 2001 From: David Teller Date: Thu, 28 Jan 2021 16:53:40 +0100 Subject: FIXUP: linter --- synapse/handlers/room.py | 2 +- synapse/rest/admin/rooms.py | 5 +++++ tests/rest/admin/test_room.py | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'tests/rest') diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index e039cea024..99fd063084 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -53,7 +53,7 @@ from synapse.types import ( create_requester, ) from synapse.util import stringutils -from synapse.util.async_helpers import Linearizer, maybe_awaitable +from synapse.util.async_helpers import Linearizer from synapse.util.caches.response_cache import ResponseCache from synapse.util.stringutils import parse_and_validate_server_name from synapse.visibility import filter_events_for_client diff --git a/synapse/rest/admin/rooms.py b/synapse/rest/admin/rooms.py index 641e325581..c673ff07e7 100644 --- a/synapse/rest/admin/rooms.py +++ b/synapse/rest/admin/rooms.py @@ -15,9 +15,11 @@ import logging from http import HTTPStatus from typing import TYPE_CHECKING, List, Optional, Tuple +from urllib import parse as urlparse from synapse.api.constants import EventTypes, JoinRules, Membership from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError +from synapse.api.filtering import Filter from synapse.http.servlet import ( RestServlet, assert_params_in_dict, @@ -33,6 +35,7 @@ from synapse.rest.admin._base import ( ) from synapse.storage.databases.main.room import RoomSortOrder from synapse.types import JsonDict, RoomAlias, RoomID, UserID, create_requester +from synapse.util import json_decoder if TYPE_CHECKING: from synapse.server import HomeServer @@ -567,6 +570,7 @@ class ForwardExtremitiesRestServlet(RestServlet): extremities = await self.store.get_forward_extremities_for_room(room_id) return 200, {"count": len(extremities), "results": extremities} + class RoomEventContextServlet(RestServlet): """ Provide the context for an event. @@ -574,6 +578,7 @@ class RoomEventContextServlet(RestServlet): an abuse report and understand what happened during and immediately prior to this event. """ + PATTERNS = admin_patterns("/rooms/(?P[^/]*)/context/(?P[^/]*)$") def __init__(self, hs): diff --git a/tests/rest/admin/test_room.py b/tests/rest/admin/test_room.py index fd201993d3..f4f5569a89 100644 --- a/tests/rest/admin/test_room.py +++ b/tests/rest/admin/test_room.py @@ -1461,7 +1461,9 @@ class JoinAliasRoomTestCase(unittest.HomeserverTestCase): % (room_id, events[midway]["event_id"]), access_token=tok, ) - self.assertEquals(403, int(channel.result["code"]), msg=channel.result["body"]) + self.assertEquals( + 403, int(channel.result["code"]), msg=channel.result["body"] + ) self.assertEqual(Codes.FORBIDDEN, channel.json_body["errcode"]) def test_context_as_admin(self): -- cgit 1.4.1