Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Implement GET /_matrix/client/r0/rooms/{roomId}/aliases (#6939)
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh authored Feb 18, 2020
1 parent 3f1cd14 commit adfaea8
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 11 deletions.
1 change: 1 addition & 0 deletions changelog.d/6939.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement `GET /_matrix/client/r0/rooms/{roomId}/aliases` endpoint as per [MSC2432](https://github.com/matrix-org/matrix-doc/pull/2432).
17 changes: 16 additions & 1 deletion synapse/handlers/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import logging
import string
from typing import List

from twisted.internet import defer

Expand All @@ -28,7 +29,7 @@
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

Expand Down Expand Up @@ -452,3 +453,17 @@ def edit_published_appservice_room_list(
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
23 changes: 23 additions & 0 deletions synapse/rest/client/v1/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
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__)


Expand Down Expand Up @@ -843,6 +847,24 @@ async def on_PUT(self, request, room_id, user_id):
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)

Expand Down Expand Up @@ -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):
Expand Down
70 changes: 69 additions & 1 deletion tests/rest/client/v1/test_rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
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
Expand Down Expand Up @@ -1726,3 +1727,70 @@ def test_erased_sender(self):
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)
28 changes: 19 additions & 9 deletions tests/unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import inspect
import logging
import time
from typing import Optional, Tuple, Type, TypeVar, Union

from mock import Mock

Expand All @@ -42,7 +43,13 @@
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

Expand Down Expand Up @@ -71,6 +78,9 @@ def new(*args, **kwargs):
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
Expand Down Expand Up @@ -334,14 +344,14 @@ def prepare(self, reactor, clock, homeserver):

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.
Expand Down

0 comments on commit adfaea8

Please sign in to comment.