mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-25 11:05:49 +03:00
Merge pull request #33 from matrix-org/extract_rest_servlet_from_client_v1
Extract the client v1 base RestServlet to a separate class
This commit is contained in:
commit
bda5d7d14f
12 changed files with 100 additions and 72 deletions
56
synapse/http/servlet.py
Normal file
56
synapse/http/servlet.py
Normal file
|
@ -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.")
|
|
@ -18,14 +18,14 @@ from twisted.internet import defer
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
@ -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.")
|
||||
|
|
|
@ -18,7 +18,7 @@ from twisted.internet import defer
|
|||
|
||||
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
|
||||
|
@ -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
|
||||
|
|
|
@ -18,7 +18,7 @@ from twisted.internet import defer
|
|||
|
||||
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
|
||||
|
||||
|
@ -26,7 +26,7 @@ import logging
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EventStreamRestServlet(RestServlet):
|
||||
class EventStreamRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/events$")
|
||||
|
||||
DEFAULT_LONGPOLL_TIME_MS = 30000
|
||||
|
@ -61,7 +61,7 @@ class EventStreamRestServlet(RestServlet):
|
|||
|
||||
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,12 +17,12 @@ from twisted.internet import defer
|
|||
|
||||
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"
|
||||
|
||||
|
@ -64,7 +64,7 @@ class LoginRestServlet(RestServlet):
|
|||
defer.returnValue((200, result))
|
||||
|
||||
|
||||
class LoginFallbackRestServlet(RestServlet):
|
||||
class LoginFallbackRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/login/fallback$")
|
||||
|
||||
def on_GET(self, request):
|
||||
|
@ -73,7 +73,7 @@ class LoginFallbackRestServlet(RestServlet):
|
|||
return (200, {})
|
||||
|
||||
|
||||
class PasswordResetRestServlet(RestServlet):
|
||||
class PasswordResetRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/login/reset")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
|
@ -19,7 +19,7 @@ from twisted.internet import defer
|
|||
|
||||
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
|
||||
|
@ -27,7 +27,7 @@ import logging
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PresenceStatusRestServlet(RestServlet):
|
||||
class PresenceStatusRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/presence/(?P<user_id>[^/]*)/status")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -72,7 +72,7 @@ class PresenceStatusRestServlet(RestServlet):
|
|||
return (200, {})
|
||||
|
||||
|
||||
class PresenceListRestServlet(RestServlet):
|
||||
class PresenceListRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/presence/list/(?P<user_id>[^/]*)")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
|
@ -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
|
||||
|
@ -55,7 +55,7 @@ class ProfileDisplaynameRestServlet(RestServlet):
|
|||
return (200, {})
|
||||
|
||||
|
||||
class ProfileAvatarURLRestServlet(RestServlet):
|
||||
class ProfileAvatarURLRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/profile/(?P<user_id>[^/]*)/avatar_url")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -88,7 +88,7 @@ class ProfileAvatarURLRestServlet(RestServlet):
|
|||
return (200, {})
|
||||
|
||||
|
||||
class ProfileRestServlet(RestServlet):
|
||||
class ProfileRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/profile/(?P<user_id>[^/]*)")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
|
@ -18,7 +18,7 @@ from twisted.internet import defer
|
|||
|
||||
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
|
||||
|
@ -42,7 +42,7 @@ else:
|
|||
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
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
""" This module contains REST servlets to do with rooms: /rooms/<paths> """
|
||||
from twisted.internet import defer
|
||||
|
||||
from base import RestServlet, client_path_pattern
|
||||
from base import ClientV1RestServlet, client_path_pattern
|
||||
from synapse.api.errors import SynapseError, Codes
|
||||
from synapse.streams.config import PaginationConfig
|
||||
from synapse.api.constants import EventTypes, Membership
|
||||
|
@ -30,7 +30,7 @@ import urllib
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RoomCreateRestServlet(RestServlet):
|
||||
class RoomCreateRestServlet(ClientV1RestServlet):
|
||||
# No PATTERN; we have custom dispatch rules here
|
||||
|
||||
def register(self, http_server):
|
||||
|
@ -94,7 +94,7 @@ class RoomCreateRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing for generic events
|
||||
class RoomStateEventRestServlet(RestServlet):
|
||||
class RoomStateEventRestServlet(ClientV1RestServlet):
|
||||
def register(self, http_server):
|
||||
# /room/$roomid/state/$eventtype
|
||||
no_state_key = "/rooms/(?P<room_id>[^/]*)/state/(?P<event_type>[^/]*)$"
|
||||
|
@ -163,7 +163,7 @@ class RoomStateEventRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing for generic events + feedback
|
||||
class RoomSendEventRestServlet(RestServlet):
|
||||
class RoomSendEventRestServlet(ClientV1RestServlet):
|
||||
|
||||
def register(self, http_server):
|
||||
# /rooms/$roomid/send/$event_type[/$txn_id]
|
||||
|
@ -206,7 +206,7 @@ class RoomSendEventRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing for room ID + alias joins
|
||||
class JoinRoomAliasServlet(RestServlet):
|
||||
class JoinRoomAliasServlet(ClientV1RestServlet):
|
||||
|
||||
def register(self, http_server):
|
||||
# /join/$room_identifier[/$txn_id]
|
||||
|
@ -265,7 +265,7 @@ class JoinRoomAliasServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing
|
||||
class PublicRoomListRestServlet(RestServlet):
|
||||
class PublicRoomListRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/publicRooms$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -276,7 +276,7 @@ class PublicRoomListRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing
|
||||
class RoomMemberListRestServlet(RestServlet):
|
||||
class RoomMemberListRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/rooms/(?P<room_id>[^/]*)/members$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -305,7 +305,7 @@ class RoomMemberListRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing
|
||||
class RoomMessageListRestServlet(RestServlet):
|
||||
class RoomMessageListRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/rooms/(?P<room_id>[^/]*)/messages$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -329,7 +329,7 @@ class RoomMessageListRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing
|
||||
class RoomStateRestServlet(RestServlet):
|
||||
class RoomStateRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/rooms/(?P<room_id>[^/]*)/state$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -345,7 +345,7 @@ class RoomStateRestServlet(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing
|
||||
class RoomInitialSyncRestServlet(RestServlet):
|
||||
class RoomInitialSyncRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/rooms/(?P<room_id>[^/]*)/initialSync$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -360,7 +360,7 @@ class RoomInitialSyncRestServlet(RestServlet):
|
|||
defer.returnValue((200, content))
|
||||
|
||||
|
||||
class RoomTriggerBackfill(RestServlet):
|
||||
class RoomTriggerBackfill(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/rooms/(?P<room_id>[^/]*)/backfill$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -379,7 +379,7 @@ class RoomTriggerBackfill(RestServlet):
|
|||
|
||||
|
||||
# TODO: Needs unit testing
|
||||
class RoomMembershipRestServlet(RestServlet):
|
||||
class RoomMembershipRestServlet(ClientV1RestServlet):
|
||||
|
||||
def register(self, http_server):
|
||||
# /rooms/$roomid/[invite|join|leave]
|
||||
|
@ -431,7 +431,7 @@ class RoomMembershipRestServlet(RestServlet):
|
|||
defer.returnValue(response)
|
||||
|
||||
|
||||
class RoomRedactEventRestServlet(RestServlet):
|
||||
class RoomRedactEventRestServlet(ClientV1RestServlet):
|
||||
def register(self, http_server):
|
||||
PATTERN = ("/rooms/(?P<room_id>[^/]*)/redact/(?P<event_id>[^/]*)")
|
||||
register_txn_path(self, PATTERN, http_server)
|
||||
|
@ -469,7 +469,7 @@ class RoomRedactEventRestServlet(RestServlet):
|
|||
defer.returnValue(response)
|
||||
|
||||
|
||||
class RoomTypingRestServlet(RestServlet):
|
||||
class RoomTypingRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern(
|
||||
"/rooms/(?P<room_id>[^/]*)/typing/(?P<user_id>[^/]*)$"
|
||||
)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
from twisted.internet import defer
|
||||
|
||||
from base import RestServlet, client_path_pattern
|
||||
from base import ClientV1RestServlet, client_path_pattern
|
||||
|
||||
|
||||
import hmac
|
||||
|
@ -23,7 +23,7 @@ import hashlib
|
|||
import base64
|
||||
|
||||
|
||||
class VoipRestServlet(RestServlet):
|
||||
class VoipRestServlet(ClientV1RestServlet):
|
||||
PATTERN = client_path_pattern("/voip/turnServer$")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
Loading…
Reference in a new issue