Remove the requirement to authenticate for /admin/server_version. (#5122)

This endpoint isn't much use for its intended purpose if you first need to get
yourself an admin's auth token.

I've restricted it to the `/_synapse/admin` path to make it a bit easier to
lock down for those concerned about exposing this information. I don't imagine
anyone is using it in anger currently.
This commit is contained in:
Richard van der Hoff 2019-05-07 09:29:30 +01:00 committed by GitHub
parent 3fdff14207
commit 59e2d2694d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 38 deletions

1
changelog.d/5122.misc Normal file
View file

@ -0,0 +1 @@
Remove the requirement to authenticate for /admin/server_version.

View file

@ -10,8 +10,6 @@ The api is::
GET /_synapse/admin/v1/server_version GET /_synapse/admin/v1/server_version
including an ``access_token`` of a server admin.
It returns a JSON body like the following: It returns a JSON body like the following:
.. code:: json .. code:: json

View file

@ -88,21 +88,16 @@ class UsersRestServlet(RestServlet):
class VersionServlet(RestServlet): class VersionServlet(RestServlet):
PATTERNS = historical_admin_path_patterns("/server_version") PATTERNS = (re.compile("^/_synapse/admin/v1/server_version$"), )
def __init__(self, hs): def __init__(self, hs):
self.auth = hs.get_auth() self.res = {
@defer.inlineCallbacks
def on_GET(self, request):
yield assert_requester_is_admin(self.auth, request)
ret = {
'server_version': get_version_string(synapse), 'server_version': get_version_string(synapse),
'python_version': platform.python_version(), 'python_version': platform.python_version(),
} }
defer.returnValue((200, ret)) def on_GET(self, request):
return 200, self.res
class UserRegisterServlet(RestServlet): class UserRegisterServlet(RestServlet):
@ -830,6 +825,7 @@ class AdminRestResource(JsonResource):
register_servlets_for_client_rest_resource(hs, self) register_servlets_for_client_rest_resource(hs, self)
SendServerNoticeServlet(hs).register(self) SendServerNoticeServlet(hs).register(self)
VersionServlet(hs).register(self)
def register_servlets_for_client_rest_resource(hs, http_server): def register_servlets_for_client_rest_resource(hs, http_server):
@ -847,7 +843,6 @@ def register_servlets_for_client_rest_resource(hs, http_server):
QuarantineMediaInRoom(hs).register(http_server) QuarantineMediaInRoom(hs).register(http_server)
ListMediaInRoom(hs).register(http_server) ListMediaInRoom(hs).register(http_server)
UserRegisterServlet(hs).register(http_server) UserRegisterServlet(hs).register(http_server)
VersionServlet(hs).register(http_server)
DeleteGroupAdminRestServlet(hs).register(http_server) DeleteGroupAdminRestServlet(hs).register(http_server)
AccountValidityRenewServlet(hs).register(http_server) AccountValidityRenewServlet(hs).register(http_server)
# don't add more things here: new servlets should only be exposed on # don't add more things here: new servlets should only be exposed on

View file

@ -21,6 +21,8 @@ from mock import Mock
import synapse.rest.admin import synapse.rest.admin
from synapse.api.constants import UserTypes from synapse.api.constants import UserTypes
from synapse.http.server import JsonResource
from synapse.rest.admin import VersionServlet
from synapse.rest.client.v1 import events, login, room from synapse.rest.client.v1 import events, login, room
from synapse.rest.client.v2_alpha import groups from synapse.rest.client.v2_alpha import groups
@ -28,20 +30,15 @@ from tests import unittest
class VersionTestCase(unittest.HomeserverTestCase): class VersionTestCase(unittest.HomeserverTestCase):
url = '/_synapse/admin/v1/server_version'
servlets = [ def create_test_json_resource(self):
synapse.rest.admin.register_servlets_for_client_rest_resource, resource = JsonResource(self.hs)
login.register_servlets, VersionServlet(self.hs).register(resource)
] return resource
url = '/_matrix/client/r0/admin/server_version'
def test_version_string(self): def test_version_string(self):
self.register_user("admin", "pass", admin=True) request, channel = self.make_request("GET", self.url, shorthand=False)
self.admin_token = self.login("admin", "pass")
request, channel = self.make_request("GET", self.url,
access_token=self.admin_token)
self.render(request) self.render(request)
self.assertEqual(200, int(channel.result["code"]), self.assertEqual(200, int(channel.result["code"]),
@ -49,17 +46,6 @@ class VersionTestCase(unittest.HomeserverTestCase):
self.assertEqual({'server_version', 'python_version'}, self.assertEqual({'server_version', 'python_version'},
set(channel.json_body.keys())) set(channel.json_body.keys()))
def test_inaccessible_to_non_admins(self):
self.register_user("unprivileged-user", "pass", admin=False)
user_token = self.login("unprivileged-user", "pass")
request, channel = self.make_request("GET", self.url,
access_token=user_token)
self.render(request)
self.assertEqual(403, int(channel.result['code']),
msg=channel.result['body'])
class UserRegisterTestCase(unittest.HomeserverTestCase): class UserRegisterTestCase(unittest.HomeserverTestCase):

View file

@ -181,10 +181,7 @@ class HomeserverTestCase(TestCase):
raise Exception("A homeserver wasn't returned, but %r" % (self.hs,)) raise Exception("A homeserver wasn't returned, but %r" % (self.hs,))
# Register the resources # Register the resources
self.resource = JsonResource(self.hs) self.resource = self.create_test_json_resource()
for servlet in self.servlets:
servlet(self.hs, self.resource)
from tests.rest.client.v1.utils import RestHelper from tests.rest.client.v1.utils import RestHelper
@ -230,6 +227,23 @@ class HomeserverTestCase(TestCase):
hs = self.setup_test_homeserver() hs = self.setup_test_homeserver()
return hs return hs
def create_test_json_resource(self):
"""
Create a test JsonResource, with the relevant servlets registerd to it
The default implementation calls each function in `servlets` to do the
registration.
Returns:
JsonResource:
"""
resource = JsonResource(self.hs)
for servlet in self.servlets:
servlet(self.hs, resource)
return resource
def default_config(self, name="test"): def default_config(self, name="test"):
""" """
Get a default HomeServer config object. Get a default HomeServer config object.