Implement GET /_matrix/client/r0/rooms/{roomId}/aliases (#6939)

per matrix-org/matrix-doc#2432
This commit is contained in:
Richard van der Hoff 2020-02-18 16:23:25 +00:00 committed by GitHub
parent 3f1cd14791
commit adfaea8c69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 128 additions and 11 deletions

1
changelog.d/6939.feature Normal file
View file

@ -0,0 +1 @@
Implement `GET /_matrix/client/r0/rooms/{roomId}/aliases` endpoint as per [MSC2432](https://github.com/matrix-org/matrix-doc/pull/2432).

View file

@ -16,6 +16,7 @@
import logging
import string
from typing import List
from twisted.internet import defer
@ -28,7 +29,7 @@ from synapse.api.errors import (
StoreError,
SynapseError,
)
from synapse.types import RoomAlias, UserID, get_domain_from_id
from synapse.types import Requester, RoomAlias, UserID, get_domain_from_id
from ._base import BaseHandler
@ -452,3 +453,17 @@ class DirectoryHandler(BaseHandler):
yield self.store.set_room_is_public_appservice(
room_id, appservice_id, network_id, visibility == "public"
)
async def get_aliases_for_room(
self, requester: Requester, room_id: str
) -> List[str]:
"""
Get a list of the aliases that currently point to this room on this server
"""
# allow access to server admins and current members of the room
is_admin = await self.auth.is_server_admin(requester.user)
if not is_admin:
await self.auth.check_joined_room(room_id, requester.user.to_string())
aliases = await self.store.get_aliases_for_room(room_id)
return aliases

View file

@ -45,6 +45,10 @@ from synapse.storage.state import StateFilter
from synapse.streams.config import PaginationConfig
from synapse.types import RoomAlias, RoomID, StreamToken, ThirdPartyInstanceID, UserID
MYPY = False
if MYPY:
import synapse.server
logger = logging.getLogger(__name__)
@ -843,6 +847,24 @@ class RoomTypingRestServlet(RestServlet):
return 200, {}
class RoomAliasListServlet(RestServlet):
PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/aliases", unstable=False)
def __init__(self, hs: "synapse.server.HomeServer"):
super().__init__()
self.auth = hs.get_auth()
self.directory_handler = hs.get_handlers().directory_handler
async def on_GET(self, request, room_id):
requester = await self.auth.get_user_by_req(request)
alias_list = await self.directory_handler.get_aliases_for_room(
requester, room_id
)
return 200, {"aliases": alias_list}
class SearchRestServlet(RestServlet):
PATTERNS = client_patterns("/search$", v1=True)
@ -931,6 +953,7 @@ def register_servlets(hs, http_server):
JoinedRoomsRestServlet(hs).register(http_server)
RoomEventServlet(hs).register(http_server)
RoomEventContextServlet(hs).register(http_server)
RoomAliasListServlet(hs).register(http_server)
def register_deprecated_servlets(hs, http_server):

View file

@ -28,8 +28,9 @@ from twisted.internet import defer
import synapse.rest.admin
from synapse.api.constants import EventContentFields, EventTypes, Membership
from synapse.handlers.pagination import PurgeStatus
from synapse.rest.client.v1 import login, profile, room
from synapse.rest.client.v1 import directory, login, profile, room
from synapse.rest.client.v2_alpha import account
from synapse.types import JsonDict, RoomAlias
from synapse.util.stringutils import random_string
from tests import unittest
@ -1726,3 +1727,70 @@ class ContextTestCase(unittest.HomeserverTestCase):
self.assertEqual(len(events_after), 2, events_after)
self.assertDictEqual(events_after[0].get("content"), {}, events_after[0])
self.assertEqual(events_after[1].get("content"), {}, events_after[1])
class DirectoryTestCase(unittest.HomeserverTestCase):
servlets = [
synapse.rest.admin.register_servlets_for_client_rest_resource,
directory.register_servlets,
login.register_servlets,
room.register_servlets,
]
def prepare(self, reactor, clock, homeserver):
self.room_owner = self.register_user("room_owner", "test")
self.room_owner_tok = self.login("room_owner", "test")
self.room_id = self.helper.create_room_as(
self.room_owner, tok=self.room_owner_tok
)
def test_no_aliases(self):
res = self._get_aliases(self.room_owner_tok)
self.assertEqual(res["aliases"], [])
def test_not_in_room(self):
self.register_user("user", "test")
user_tok = self.login("user", "test")
res = self._get_aliases(user_tok, expected_code=403)
self.assertEqual(res["errcode"], "M_FORBIDDEN")
def test_with_aliases(self):
alias1 = self._random_alias()
alias2 = self._random_alias()
self._set_alias_via_directory(alias1)
self._set_alias_via_directory(alias2)
res = self._get_aliases(self.room_owner_tok)
self.assertEqual(set(res["aliases"]), {alias1, alias2})
def _get_aliases(self, access_token: str, expected_code: int = 200) -> JsonDict:
"""Calls the endpoint under test. returns the json response object."""
request, channel = self.make_request(
"GET",
"/_matrix/client/r0/rooms/%s/aliases" % (self.room_id,),
access_token=access_token,
)
self.render(request)
self.assertEqual(channel.code, expected_code, channel.result)
res = channel.json_body
self.assertIsInstance(res, dict)
if expected_code == 200:
self.assertIsInstance(res["aliases"], list)
return res
def _random_alias(self) -> str:
return RoomAlias(random_string(5), self.hs.hostname).to_string()
def _set_alias_via_directory(self, alias: str, expected_code: int = 200):
url = "/_matrix/client/r0/directory/room/" + alias
data = {"room_id": self.room_id}
request_data = json.dumps(data)
request, channel = self.make_request(
"PUT", url, request_data, access_token=self.room_owner_tok
)
self.render(request)
self.assertEqual(channel.code, expected_code, channel.result)

View file

@ -21,6 +21,7 @@ import hmac
import inspect
import logging
import time
from typing import Optional, Tuple, Type, TypeVar, Union
from mock import Mock
@ -42,7 +43,13 @@ from synapse.server import HomeServer
from synapse.types import Requester, UserID, create_requester
from synapse.util.ratelimitutils import FederationRateLimiter
from tests.server import get_clock, make_request, render, setup_test_homeserver
from tests.server import (
FakeChannel,
get_clock,
make_request,
render,
setup_test_homeserver,
)
from tests.test_utils.logging_setup import setup_logging
from tests.utils import default_config, setupdb
@ -71,6 +78,9 @@ def around(target):
return _around
T = TypeVar("T")
class TestCase(unittest.TestCase):
"""A subclass of twisted.trial's TestCase which looks for 'loglevel'
attributes on both itself and its individual test methods, to override the
@ -334,14 +344,14 @@ class HomeserverTestCase(TestCase):
def make_request(
self,
method,
path,
content=b"",
access_token=None,
request=SynapseRequest,
shorthand=True,
federation_auth_origin=None,
):
method: Union[bytes, str],
path: Union[bytes, str],
content: Union[bytes, dict] = b"",
access_token: Optional[str] = None,
request: Type[T] = SynapseRequest,
shorthand: bool = True,
federation_auth_origin: str = None,
) -> Tuple[T, FakeChannel]:
"""
Create a SynapseRequest at the path using the method and containing the
given content.