Skip to content

Commit

Permalink
Merge pull request matrix-org#33 from matrix-org/extract_rest_servlet…
Browse files Browse the repository at this point in the history
…_from_client_v1

Extract the client v1 base RestServlet to a separate class
  • Loading branch information
NegativeMjark committed Jan 23, 2015
2 parents f7cb604 + e0bf18a commit bda5d7d
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 72 deletions.
56 changes: 56 additions & 0 deletions synapse/http/servlet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Copyright 2014, 2015 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

""" This module contains base REST classes for constructing REST servlets. """

import logging


logger = logging.getLogger(__name__)


class RestServlet(object):

""" A Synapse REST Servlet.
An implementing class can either provide its own custom 'register' method,
or use the automatic pattern handling provided by the base class.
To use this latter, the implementing class instead provides a `PATTERN`
class attribute containing a pre-compiled regular expression. The automatic
register method will then use this method to register any of the following
instance methods associated with the corresponding HTTP method:
on_GET
on_PUT
on_POST
on_DELETE
on_OPTIONS
Automatically handles turning CodeMessageExceptions thrown by these methods
into the appropriate HTTP response.
"""

def register(self, http_server):
""" Register this servlet with the given HTTP server. """
if hasattr(self, "PATTERN"):
pattern = self.PATTERN

for method in ("GET", "PUT", "POST", "OPTIONS", "DELETE"):
if hasattr(self, "on_%s" % (method)):
method_handler = getattr(self, "on_%s" % (method))
http_server.register_path(method, pattern, method_handler)
else:
raise NotImplementedError("RestServlet must register something.")
4 changes: 2 additions & 2 deletions synapse/rest/client/v1/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
from synapse.api.errors import AuthError, SynapseError
from synapse.types import UserID

from base import RestServlet, client_path_pattern
from base import ClientV1RestServlet, client_path_pattern

import logging

logger = logging.getLogger(__name__)


class WhoisRestServlet(RestServlet):
class WhoisRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/admin/whois/(?P<user_id>[^/]*)")

@defer.inlineCallbacks
Expand Down
40 changes: 6 additions & 34 deletions synapse/rest/client/v1/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

""" This module contains base REST classes for constructing REST servlets. """
"""This module contains base REST classes for constructing client v1 servlets.
"""

from synapse.http.servlet import RestServlet
from synapse.api.urls import CLIENT_PREFIX
from .transactions import HttpTransactionStore
import re
Expand All @@ -37,44 +40,13 @@ def client_path_pattern(path_regex):
return re.compile("^" + CLIENT_PREFIX + path_regex)


class RestServlet(object):

""" A Synapse REST Servlet.
An implementing class can either provide its own custom 'register' method,
or use the automatic pattern handling provided by the base class.
To use this latter, the implementing class instead provides a `PATTERN`
class attribute containing a pre-compiled regular expression. The automatic
register method will then use this method to register any of the following
instance methods associated with the corresponding HTTP method:
on_GET
on_PUT
on_POST
on_DELETE
on_OPTIONS
Automatically handles turning CodeMessageExceptions thrown by these methods
into the appropriate HTTP response.
class ClientV1RestServlet(RestServlet):
"""A base Synapse REST Servlet for the client version 1 API.
"""

def __init__(self, hs):
self.hs = hs

self.handlers = hs.get_handlers()
self.builder_factory = hs.get_event_builder_factory()
self.auth = hs.get_auth()
self.txns = HttpTransactionStore()

def register(self, http_server):
""" Register this servlet with the given HTTP server. """
if hasattr(self, "PATTERN"):
pattern = self.PATTERN

for method in ("GET", "PUT", "POST", "OPTIONS", "DELETE"):
if hasattr(self, "on_%s" % (method)):
method_handler = getattr(self, "on_%s" % (method))
http_server.register_path(method, pattern, method_handler)
else:
raise NotImplementedError("RestServlet must register something.")
4 changes: 2 additions & 2 deletions synapse/rest/client/v1/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from synapse.api.errors import AuthError, SynapseError, Codes
from synapse.types import RoomAlias
from .base import RestServlet, client_path_pattern
from .base import ClientV1RestServlet, client_path_pattern

import json
import logging
Expand All @@ -31,7 +31,7 @@ def register_servlets(hs, http_server):
ClientDirectoryServer(hs).register(http_server)


class ClientDirectoryServer(RestServlet):
class ClientDirectoryServer(ClientV1RestServlet):
PATTERN = client_path_pattern("/directory/room/(?P<room_alias>[^/]*)$")

@defer.inlineCallbacks
Expand Down
6 changes: 3 additions & 3 deletions synapse/rest/client/v1/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

from synapse.api.errors import SynapseError
from synapse.streams.config import PaginationConfig
from .base import RestServlet, client_path_pattern
from .base import ClientV1RestServlet, client_path_pattern

import logging


logger = logging.getLogger(__name__)


class EventStreamRestServlet(RestServlet):
class EventStreamRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/events$")

DEFAULT_LONGPOLL_TIME_MS = 30000
Expand Down Expand Up @@ -61,7 +61,7 @@ def on_OPTIONS(self, request):


# TODO: Unit test gets, with and without auth, with different kinds of events.
class EventRestServlet(RestServlet):
class EventRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/events/(?P<event_id>[^/]*)$")

@defer.inlineCallbacks
Expand Down
4 changes: 2 additions & 2 deletions synapse/rest/client/v1/initial_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
from twisted.internet import defer

from synapse.streams.config import PaginationConfig
from base import RestServlet, client_path_pattern
from base import ClientV1RestServlet, client_path_pattern


# TODO: Needs unit testing
class InitialSyncRestServlet(RestServlet):
class InitialSyncRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/initialSync$")

@defer.inlineCallbacks
Expand Down
8 changes: 4 additions & 4 deletions synapse/rest/client/v1/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

from synapse.api.errors import SynapseError
from synapse.types import UserID
from base import RestServlet, client_path_pattern
from base import ClientV1RestServlet, client_path_pattern

import json


class LoginRestServlet(RestServlet):
class LoginRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/login$")
PASS_TYPE = "m.login.password"

Expand Down Expand Up @@ -64,7 +64,7 @@ def do_password_login(self, login_submission):
defer.returnValue((200, result))


class LoginFallbackRestServlet(RestServlet):
class LoginFallbackRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/login/fallback$")

def on_GET(self, request):
Expand All @@ -73,7 +73,7 @@ def on_GET(self, request):
return (200, {})


class PasswordResetRestServlet(RestServlet):
class PasswordResetRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/login/reset")

@defer.inlineCallbacks
Expand Down
6 changes: 3 additions & 3 deletions synapse/rest/client/v1/presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@

from synapse.api.errors import SynapseError
from synapse.types import UserID
from .base import RestServlet, client_path_pattern
from .base import ClientV1RestServlet, client_path_pattern

import json
import logging

logger = logging.getLogger(__name__)


class PresenceStatusRestServlet(RestServlet):
class PresenceStatusRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/presence/(?P<user_id>[^/]*)/status")

@defer.inlineCallbacks
Expand Down Expand Up @@ -72,7 +72,7 @@ def on_OPTIONS(self, request):
return (200, {})


class PresenceListRestServlet(RestServlet):
class PresenceListRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/presence/list/(?P<user_id>[^/]*)")

@defer.inlineCallbacks
Expand Down
8 changes: 4 additions & 4 deletions synapse/rest/client/v1/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
""" This module contains REST servlets to do with profile: /profile/<paths> """
from twisted.internet import defer

from .base import RestServlet, client_path_pattern
from .base import ClientV1RestServlet, client_path_pattern
from synapse.types import UserID

import json


class ProfileDisplaynameRestServlet(RestServlet):
class ProfileDisplaynameRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/profile/(?P<user_id>[^/]*)/displayname")

@defer.inlineCallbacks
Expand Down Expand Up @@ -55,7 +55,7 @@ def on_OPTIONS(self, request, user_id):
return (200, {})


class ProfileAvatarURLRestServlet(RestServlet):
class ProfileAvatarURLRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/profile/(?P<user_id>[^/]*)/avatar_url")

@defer.inlineCallbacks
Expand Down Expand Up @@ -88,7 +88,7 @@ def on_OPTIONS(self, request, user_id):
return (200, {})


class ProfileRestServlet(RestServlet):
class ProfileRestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/profile/(?P<user_id>[^/]*)")

@defer.inlineCallbacks
Expand Down
4 changes: 2 additions & 2 deletions synapse/rest/client/v1/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from synapse.api.errors import SynapseError, Codes
from synapse.api.constants import LoginType
from base import RestServlet, client_path_pattern
from base import ClientV1RestServlet, client_path_pattern
import synapse.util.stringutils as stringutils

from synapse.util.async import run_on_reactor
Expand All @@ -42,7 +42,7 @@
compare_digest = lambda a, b: a == b


class RegisterRestServlet(RestServlet):
class RegisterRestServlet(ClientV1RestServlet):
"""Handles registration with the home server.
This servlet is in control of the registration flow; the registration
Expand Down
Loading

0 comments on commit bda5d7d

Please sign in to comment.