diff --git a/synapse/rest/client/v1/admin.py b/synapse/rest/client/v1/admin.py
index 8fb08dc526..01c3f2eb04 100644
--- a/synapse/rest/client/v1/admin.py
+++ b/synapse/rest/client/v1/admin.py
@@ -14,19 +14,24 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from twisted.internet import defer
+import logging
from six.moves import http_client
+from twisted.internet import defer
+
from synapse.api.constants import Membership
-from synapse.api.errors import AuthError, SynapseError, Codes, NotFoundError
+from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError
+from synapse.http.servlet import (
+ assert_params_in_dict,
+ parse_json_object_from_request,
+ parse_integer,
+ parse_string
+)
from synapse.types import UserID, create_requester
-from synapse.http.servlet import parse_json_object_from_request
from .base import ClientV1RestServlet, client_path_patterns
-import logging
-
logger = logging.getLogger(__name__)
@@ -98,16 +103,8 @@ class PurgeMediaCacheRestServlet(ClientV1RestServlet):
if not is_admin:
raise AuthError(403, "You are not a server admin")
- before_ts = request.args.get("before_ts", None)
- if not before_ts:
- raise SynapseError(400, "Missing 'before_ts' arg")
-
- logger.info("before_ts: %r", before_ts[0])
-
- try:
- before_ts = int(before_ts[0])
- except Exception:
- raise SynapseError(400, "Invalid 'before_ts' arg")
+ before_ts = parse_integer(request, "before_ts", required=True)
+ logger.info("before_ts: %r", before_ts)
ret = yield self.media_repository.delete_old_remote_media(before_ts)
@@ -300,10 +297,8 @@ class ShutdownRoomRestServlet(ClientV1RestServlet):
raise AuthError(403, "You are not a server admin")
content = parse_json_object_from_request(request)
-
- new_room_user_id = content.get("new_room_user_id")
- if not new_room_user_id:
- raise SynapseError(400, "Please provide field `new_room_user_id`")
+ assert_params_in_dict(content, ["new_room_user_id"])
+ new_room_user_id = content["new_room_user_id"]
room_creator_requester = create_requester(new_room_user_id)
@@ -464,9 +459,8 @@ class ResetPasswordRestServlet(ClientV1RestServlet):
raise AuthError(403, "You are not a server admin")
params = parse_json_object_from_request(request)
+ assert_params_in_dict(params, ["new_password"])
new_password = params['new_password']
- if not new_password:
- raise SynapseError(400, "Missing 'new_password' arg")
logger.info("new_password: %r", new_password)
@@ -514,12 +508,9 @@ class GetUsersPaginatedRestServlet(ClientV1RestServlet):
raise SynapseError(400, "Can only users a local user")
order = "name" # order by name in user table
- start = request.args.get("start")[0]
- limit = request.args.get("limit")[0]
- if not limit:
- raise SynapseError(400, "Missing 'limit' arg")
- if not start:
- raise SynapseError(400, "Missing 'start' arg")
+ start = parse_integer(request, "start", required=True)
+ limit = parse_integer(request, "limit", required=True)
+
logger.info("limit: %s, start: %s", limit, start)
ret = yield self.handlers.admin_handler.get_users_paginate(
@@ -551,12 +542,9 @@ class GetUsersPaginatedRestServlet(ClientV1RestServlet):
order = "name" # order by name in user table
params = parse_json_object_from_request(request)
+ assert_params_in_dict(params, ["limit", "start"])
limit = params['limit']
start = params['start']
- if not limit:
- raise SynapseError(400, "Missing 'limit' arg")
- if not start:
- raise SynapseError(400, "Missing 'start' arg")
logger.info("limit: %s, start: %s", limit, start)
ret = yield self.handlers.admin_handler.get_users_paginate(
@@ -604,10 +592,7 @@ class SearchUsersRestServlet(ClientV1RestServlet):
if not self.hs.is_mine(target_user):
raise SynapseError(400, "Can only users a local user")
- term = request.args.get("term")[0]
- if not term:
- raise SynapseError(400, "Missing 'term' arg")
-
+ term = parse_string(request, "term", required=True)
logger.info("term: %s ", term)
ret = yield self.handlers.admin_handler.search_users(
diff --git a/synapse/rest/client/v1/base.py b/synapse/rest/client/v1/base.py
index 197335d7aa..c77d7aba68 100644
--- a/synapse/rest/client/v1/base.py
+++ b/synapse/rest/client/v1/base.py
@@ -16,14 +16,12 @@
"""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 synapse.rest.client.transactions import HttpTransactionCache
-
-import re
-
import logging
+import re
+from synapse.api.urls import CLIENT_PREFIX
+from synapse.http.servlet import RestServlet
+from synapse.rest.client.transactions import HttpTransactionCache
logger = logging.getLogger(__name__)
@@ -64,4 +62,4 @@ class ClientV1RestServlet(RestServlet):
self.hs = hs
self.builder_factory = hs.get_event_builder_factory()
self.auth = hs.get_auth()
- self.txns = HttpTransactionCache(hs.get_clock())
+ self.txns = HttpTransactionCache(hs)
diff --git a/synapse/rest/client/v1/directory.py b/synapse/rest/client/v1/directory.py
index 1c3933380f..69dcd618cb 100644
--- a/synapse/rest/client/v1/directory.py
+++ b/synapse/rest/client/v1/directory.py
@@ -14,17 +14,16 @@
# limitations under the License.
+import logging
+
from twisted.internet import defer
-from synapse.api.errors import AuthError, SynapseError, Codes
-from synapse.types import RoomAlias
+from synapse.api.errors import AuthError, Codes, SynapseError
from synapse.http.servlet import parse_json_object_from_request
+from synapse.types import RoomAlias
from .base import ClientV1RestServlet, client_path_patterns
-import logging
-
-
logger = logging.getLogger(__name__)
@@ -53,15 +52,14 @@ class ClientDirectoryServer(ClientV1RestServlet):
@defer.inlineCallbacks
def on_PUT(self, request, room_alias):
+ room_alias = RoomAlias.from_string(room_alias)
+
content = parse_json_object_from_request(request)
if "room_id" not in content:
- raise SynapseError(400, "Missing room_id key",
+ raise SynapseError(400, 'Missing params: ["room_id"]',
errcode=Codes.BAD_JSON)
logger.debug("Got content: %s", content)
-
- room_alias = RoomAlias.from_string(room_alias)
-
logger.debug("Got room name: %s", room_alias.to_string())
room_id = content["room_id"]
diff --git a/synapse/rest/client/v1/events.py b/synapse/rest/client/v1/events.py
index 701b6f549b..b70c9c2806 100644
--- a/synapse/rest/client/v1/events.py
+++ b/synapse/rest/client/v1/events.py
@@ -14,15 +14,15 @@
# limitations under the License.
"""This module contains REST servlets to do with event streaming, /events."""
+import logging
+
from twisted.internet import defer
from synapse.api.errors import SynapseError
-from synapse.streams.config import PaginationConfig
-from .base import ClientV1RestServlet, client_path_patterns
from synapse.events.utils import serialize_event
+from synapse.streams.config import PaginationConfig
-import logging
-
+from .base import ClientV1RestServlet, client_path_patterns
logger = logging.getLogger(__name__)
diff --git a/synapse/rest/client/v1/initial_sync.py b/synapse/rest/client/v1/initial_sync.py
index 478e21eea8..00a1a99feb 100644
--- a/synapse/rest/client/v1/initial_sync.py
+++ b/synapse/rest/client/v1/initial_sync.py
@@ -16,6 +16,8 @@
from twisted.internet import defer
from synapse.streams.config import PaginationConfig
+from synapse.http.servlet import parse_boolean
+
from .base import ClientV1RestServlet, client_path_patterns
@@ -32,7 +34,7 @@ class InitialSyncRestServlet(ClientV1RestServlet):
requester = yield self.auth.get_user_by_req(request)
as_client_event = "raw" not in request.args
pagination_config = PaginationConfig.from_request(request)
- include_archived = request.args.get("archived", None) == ["true"]
+ include_archived = parse_boolean(request, "archived", default=False)
content = yield self.initial_sync_handler.snapshot_all_rooms(
user_id=requester.user.to_string(),
pagin_config=pagination_config,
diff --git a/synapse/rest/client/v1/login.py b/synapse/rest/client/v1/login.py
index 88ca5184cd..cb85fa1436 100644
--- a/synapse/rest/client/v1/login.py
+++ b/synapse/rest/client/v1/login.py
@@ -13,30 +13,26 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from twisted.internet import defer
-
-from synapse.api.errors import SynapseError, LoginError, Codes
-from synapse.types import UserID
-from synapse.http.server import finish_request
-from synapse.http.servlet import parse_json_object_from_request
-from synapse.util.msisdn import phone_number_to_msisdn
-
-from .base import ClientV1RestServlet, client_path_patterns
-
-from canonicaljson import json
-
+import logging
import urllib
+import xml.etree.ElementTree as ET
+
from six.moves.urllib import parse as urlparse
-import logging
-from saml2 import BINDING_HTTP_POST
-from saml2 import config
+from canonicaljson import json
+from saml2 import BINDING_HTTP_POST, config
from saml2.client import Saml2Client
-import xml.etree.ElementTree as ET
-
+from twisted.internet import defer
from twisted.web.client import PartialDownloadError
+from synapse.api.errors import Codes, LoginError, SynapseError
+from synapse.http.server import finish_request
+from synapse.http.servlet import parse_json_object_from_request
+from synapse.types import UserID
+from synapse.util.msisdn import phone_number_to_msisdn
+
+from .base import ClientV1RestServlet, client_path_patterns
logger = logging.getLogger(__name__)
diff --git a/synapse/rest/client/v1/logout.py b/synapse/rest/client/v1/logout.py
index e092158cb7..430c692336 100644
--- a/synapse/rest/client/v1/logout.py
+++ b/synapse/rest/client/v1/logout.py
@@ -13,16 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
+
from twisted.internet import defer
-from synapse.api.auth import get_access_token_from_request
from synapse.api.errors import AuthError
from .base import ClientV1RestServlet, client_path_patterns
-import logging
-
-
logger = logging.getLogger(__name__)
@@ -52,7 +50,7 @@ class LogoutRestServlet(ClientV1RestServlet):
if requester.device_id is None:
# the acccess token wasn't associated with a device.
# Just delete the access token
- access_token = get_access_token_from_request(request)
+ access_token = self._auth.get_access_token_from_request(request)
yield self._auth_handler.delete_access_token(access_token)
else:
yield self._device_handler.delete_device(
diff --git a/synapse/rest/client/v1/presence.py b/synapse/rest/client/v1/presence.py
index 647994bd53..a14f0c807e 100644
--- a/synapse/rest/client/v1/presence.py
+++ b/synapse/rest/client/v1/presence.py
@@ -15,17 +15,18 @@
""" This module contains REST servlets to do with presence: /presence/<paths>
"""
+import logging
+
+from six import string_types
+
from twisted.internet import defer
-from synapse.api.errors import SynapseError, AuthError
-from synapse.types import UserID
+from synapse.api.errors import AuthError, SynapseError
from synapse.handlers.presence import format_user_presence_state
from synapse.http.servlet import parse_json_object_from_request
-from .base import ClientV1RestServlet, client_path_patterns
-
-from six import string_types
+from synapse.types import UserID
-import logging
+from .base import ClientV1RestServlet, client_path_patterns
logger = logging.getLogger(__name__)
diff --git a/synapse/rest/client/v1/profile.py b/synapse/rest/client/v1/profile.py
index e4e3611a14..a23edd8fe5 100644
--- a/synapse/rest/client/v1/profile.py
+++ b/synapse/rest/client/v1/profile.py
@@ -16,9 +16,10 @@
""" This module contains REST servlets to do with profile: /profile/<paths> """
from twisted.internet import defer
-from .base import ClientV1RestServlet, client_path_patterns
-from synapse.types import UserID
from synapse.http.servlet import parse_json_object_from_request
+from synapse.types import UserID
+
+from .base import ClientV1RestServlet, client_path_patterns
class ProfileDisplaynameRestServlet(ClientV1RestServlet):
diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py
index 6bb4821ec6..6e95d9bec2 100644
--- a/synapse/rest/client/v1/push_rule.py
+++ b/synapse/rest/client/v1/push_rule.py
@@ -16,16 +16,18 @@
from twisted.internet import defer
from synapse.api.errors import (
- SynapseError, UnrecognizedRequestError, NotFoundError, StoreError
+ NotFoundError,
+ StoreError,
+ SynapseError,
+ UnrecognizedRequestError,
)
-from .base import ClientV1RestServlet, client_path_patterns
-from synapse.storage.push_rule import (
- InconsistentRuleException, RuleNotFoundException
-)
-from synapse.push.clientformat import format_push_rules_for_user
+from synapse.http.servlet import parse_json_value_from_request, parse_string
from synapse.push.baserules import BASE_RULE_IDS
+from synapse.push.clientformat import format_push_rules_for_user
from synapse.push.rulekinds import PRIORITY_CLASS_MAP
-from synapse.http.servlet import parse_json_value_from_request
+from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException
+
+from .base import ClientV1RestServlet, client_path_patterns
class PushRuleRestServlet(ClientV1RestServlet):
@@ -73,13 +75,13 @@ class PushRuleRestServlet(ClientV1RestServlet):
except InvalidRuleException as e:
raise SynapseError(400, e.message)
- before = request.args.get("before", None)
+ before = parse_string(request, "before")
if before:
- before = _namespaced_rule_id(spec, before[0])
+ before = _namespaced_rule_id(spec, before)
- after = request.args.get("after", None)
+ after = parse_string(request, "after")
if after:
- after = _namespaced_rule_id(spec, after[0])
+ after = _namespaced_rule_id(spec, after)
try:
yield self.store.add_push_rule(
diff --git a/synapse/rest/client/v1/pusher.py b/synapse/rest/client/v1/pusher.py
index 40e523cc5f..182a68b1e2 100644
--- a/synapse/rest/client/v1/pusher.py
+++ b/synapse/rest/client/v1/pusher.py
@@ -13,20 +13,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
+
from twisted.internet import defer
-from synapse.api.errors import SynapseError, Codes
-from synapse.push import PusherConfigException
+from synapse.api.errors import Codes, StoreError, SynapseError
+from synapse.http.server import finish_request
from synapse.http.servlet import (
- parse_json_object_from_request, parse_string, RestServlet
+ RestServlet,
+ assert_params_in_dict,
+ parse_json_object_from_request,
+ parse_string,
)
-from synapse.http.server import finish_request
-from synapse.api.errors import StoreError
+from synapse.push import PusherConfigException
from .base import ClientV1RestServlet, client_path_patterns
-import logging
-
logger = logging.getLogger(__name__)
@@ -90,15 +92,11 @@ class PushersSetRestServlet(ClientV1RestServlet):
)
defer.returnValue((200, {}))
- reqd = ['kind', 'app_id', 'app_display_name',
- 'device_display_name', 'pushkey', 'lang', 'data']
- missing = []
- for i in reqd:
- if i not in content:
- missing.append(i)
- if len(missing):
- raise SynapseError(400, "Missing parameters: " + ','.join(missing),
- errcode=Codes.MISSING_PARAM)
+ assert_params_in_dict(
+ content,
+ ['kind', 'app_id', 'app_display_name',
+ 'device_display_name', 'pushkey', 'lang', 'data']
+ )
logger.debug("set pushkey %s to kind %s", content['pushkey'], content['kind'])
logger.debug("Got pushers request with body: %r", content)
@@ -147,7 +145,7 @@ class PushersRemoveRestServlet(RestServlet):
SUCCESS_HTML = "<html><body>You have been unsubscribed</body><html>"
def __init__(self, hs):
- super(RestServlet, self).__init__()
+ super(PushersRemoveRestServlet, self).__init__()
self.hs = hs
self.notifier = hs.get_notifier()
self.auth = hs.get_auth()
diff --git a/synapse/rest/client/v1/register.py b/synapse/rest/client/v1/register.py
index c10320dedf..25a143af8d 100644
--- a/synapse/rest/client/v1/register.py
+++ b/synapse/rest/client/v1/register.py
@@ -14,21 +14,19 @@
# limitations under the License.
"""This module contains REST servlets to do with registration: /register"""
+import hmac
+import logging
+from hashlib import sha1
+
from twisted.internet import defer
-from synapse.api.errors import SynapseError, Codes
-from synapse.api.constants import LoginType
-from synapse.api.auth import get_access_token_from_request
-from .base import ClientV1RestServlet, client_path_patterns
import synapse.util.stringutils as stringutils
-from synapse.http.servlet import parse_json_object_from_request
+from synapse.api.constants import LoginType
+from synapse.api.errors import Codes, SynapseError
+from synapse.http.servlet import assert_params_in_dict, parse_json_object_from_request
from synapse.types import create_requester
-from hashlib import sha1
-import hmac
-import logging
-
-from six import string_types
+from .base import ClientV1RestServlet, client_path_patterns
logger = logging.getLogger(__name__)
@@ -66,6 +64,7 @@ class RegisterRestServlet(ClientV1RestServlet):
# TODO: persistent storage
self.sessions = {}
self.enable_registration = hs.config.enable_registration
+ self.auth = hs.get_auth()
self.auth_handler = hs.get_auth_handler()
self.handlers = hs.get_handlers()
@@ -123,8 +122,7 @@ class RegisterRestServlet(ClientV1RestServlet):
session = (register_json["session"]
if "session" in register_json else None)
login_type = None
- if "type" not in register_json:
- raise SynapseError(400, "Missing 'type' key.")
+ assert_params_in_dict(register_json, ["type"])
try:
login_type = register_json["type"]
@@ -309,11 +307,9 @@ class RegisterRestServlet(ClientV1RestServlet):
@defer.inlineCallbacks
def _do_app_service(self, request, register_json, session):
- as_token = get_access_token_from_request(request)
-
- if "user" not in register_json:
- raise SynapseError(400, "Expected 'user' key.")
+ as_token = self.auth.get_access_token_from_request(request)
+ assert_params_in_dict(register_json, ["user"])
user_localpart = register_json["user"].encode("utf-8")
handler = self.handlers.registration_handler
@@ -330,12 +326,7 @@ class RegisterRestServlet(ClientV1RestServlet):
@defer.inlineCallbacks
def _do_shared_secret(self, request, register_json, session):
- if not isinstance(register_json.get("mac", None), string_types):
- raise SynapseError(400, "Expected mac.")
- if not isinstance(register_json.get("user", None), string_types):
- raise SynapseError(400, "Expected 'user' key.")
- if not isinstance(register_json.get("password", None), string_types):
- raise SynapseError(400, "Expected 'password' key.")
+ assert_params_in_dict(register_json, ["mac", "user", "password"])
if not self.hs.config.registration_shared_secret:
raise SynapseError(400, "Shared secret registration is not enabled")
@@ -399,7 +390,7 @@ class CreateUserRestServlet(ClientV1RestServlet):
def on_POST(self, request):
user_json = parse_json_object_from_request(request)
- access_token = get_access_token_from_request(request)
+ access_token = self.auth.get_access_token_from_request(request)
app_service = self.store.get_app_service_by_token(
access_token
)
@@ -418,11 +409,7 @@ class CreateUserRestServlet(ClientV1RestServlet):
@defer.inlineCallbacks
def _do_create(self, requester, user_json):
- if "localpart" not in user_json:
- raise SynapseError(400, "Expected 'localpart' key.")
-
- if "displayname" not in user_json:
- raise SynapseError(400, "Expected 'displayname' key.")
+ assert_params_in_dict(user_json, ["localpart", "displayname"])
localpart = user_json["localpart"].encode("utf-8")
displayname = user_json["displayname"].encode("utf-8")
diff --git a/synapse/rest/client/v1/room.py b/synapse/rest/client/v1/room.py
index e6ae5db79b..3d62447854 100644
--- a/synapse/rest/client/v1/room.py
+++ b/synapse/rest/client/v1/room.py
@@ -15,23 +15,28 @@
# limitations under the License.
""" This module contains REST servlets to do with rooms: /rooms/<paths> """
+import logging
+
+from six.moves.urllib import parse as urlparse
+
+from canonicaljson import json
+
from twisted.internet import defer
-from .base import ClientV1RestServlet, client_path_patterns
-from synapse.api.errors import SynapseError, Codes, AuthError
-from synapse.streams.config import PaginationConfig
from synapse.api.constants import EventTypes, Membership
+from synapse.api.errors import AuthError, Codes, SynapseError
from synapse.api.filtering import Filter
-from synapse.types import UserID, RoomID, RoomAlias, ThirdPartyInstanceID
-from synapse.events.utils import serialize_event, format_event_for_client_v2
+from synapse.events.utils import format_event_for_client_v2, serialize_event
from synapse.http.servlet import (
- parse_json_object_from_request, parse_string, parse_integer
+ assert_params_in_dict,
+ parse_integer,
+ parse_json_object_from_request,
+ parse_string,
)
+from synapse.streams.config import PaginationConfig
+from synapse.types import RoomAlias, RoomID, ThirdPartyInstanceID, UserID
-from six.moves.urllib import parse as urlparse
-
-import logging
-from canonicaljson import json
+from .base import ClientV1RestServlet, client_path_patterns
logger = logging.getLogger(__name__)
@@ -431,9 +436,9 @@ class RoomMessageListRestServlet(ClientV1RestServlet):
request, default_limit=10,
)
as_client_event = "raw" not in request.args
- filter_bytes = request.args.get("filter", None)
+ filter_bytes = parse_string(request, "filter")
if filter_bytes:
- filter_json = urlparse.unquote(filter_bytes[-1]).decode("UTF-8")
+ filter_json = urlparse.unquote(filter_bytes).decode("UTF-8")
event_filter = Filter(json.loads(filter_json))
else:
event_filter = None
@@ -526,7 +531,7 @@ class RoomEventContextServlet(ClientV1RestServlet):
def on_GET(self, request, room_id, event_id):
requester = yield self.auth.get_user_by_req(request, allow_guest=True)
- limit = int(request.args.get("limit", [10])[0])
+ limit = parse_integer(request, "limit", default=10)
results = yield self.handlers.room_context_handler.get_event_context(
requester.user,
@@ -632,8 +637,7 @@ class RoomMembershipRestServlet(ClientV1RestServlet):
target = requester.user
if membership_action in ["invite", "ban", "unban", "kick"]:
- if "user_id" not in content:
- raise SynapseError(400, "Missing user_id key.")
+ assert_params_in_dict(content, ["user_id"])
target = UserID.from_string(content["user_id"])
event_content = None
@@ -760,7 +764,7 @@ class SearchRestServlet(ClientV1RestServlet):
content = parse_json_object_from_request(request)
- batch = request.args.get("next_batch", [None])[0]
+ batch = parse_string(request, "next_batch")
results = yield self.handlers.search_handler.search(
requester.user,
content,
diff --git a/synapse/rest/client/v1/voip.py b/synapse/rest/client/v1/voip.py
index c43b30b73a..62f4c3d93e 100644
--- a/synapse/rest/client/v1/voip.py
+++ b/synapse/rest/client/v1/voip.py
@@ -13,16 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import base64
+import hashlib
+import hmac
+
from twisted.internet import defer
from .base import ClientV1RestServlet, client_path_patterns
-import hmac
-import hashlib
-import base64
-
-
class VoipRestServlet(ClientV1RestServlet):
PATTERNS = client_path_patterns("/voip/turnServer$")
|