summary refs log tree commit diff
path: root/synapse/rest
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/rest')
-rw-r--r--synapse/rest/__init__.py2
-rw-r--r--synapse/rest/admin.py2
-rw-r--r--synapse/rest/base.py4
-rw-r--r--synapse/rest/directory.py13
-rw-r--r--synapse/rest/login.py4
-rw-r--r--synapse/rest/presence.py9
-rw-r--r--synapse/rest/profile.py6
-rw-r--r--synapse/rest/register.py4
-rw-r--r--synapse/rest/room.py178
-rw-r--r--synapse/rest/transactions.py1
10 files changed, 111 insertions, 112 deletions
diff --git a/synapse/rest/__init__.py b/synapse/rest/__init__.py
index e391e5678d..a59630ec96 100644
--- a/synapse/rest/__init__.py
+++ b/synapse/rest/__init__.py
@@ -28,7 +28,7 @@ class RestServletFactory(object):
     speaking, they serve as wrappers around events and the handlers that
     process them.
 
-    See synapse.api.events for information on synapse events.
+    See synapse.events for information on synapse events.
     """
 
     def __init__(self, hs):
diff --git a/synapse/rest/admin.py b/synapse/rest/admin.py
index ed9b484623..d74c551512 100644
--- a/synapse/rest/admin.py
+++ b/synapse/rest/admin.py
@@ -35,7 +35,7 @@ class WhoisRestServlet(RestServlet):
         if not is_admin and target_user != auth_user:
             raise AuthError(403, "You are not a server admin")
 
-        if not target_user.is_mine:
+        if not self.hs.is_mine(target_user):
             raise SynapseError(400, "Can only whois a local user")
 
         ret = yield self.handlers.admin_handler.get_whois(target_user)
diff --git a/synapse/rest/base.py b/synapse/rest/base.py
index 79fc4dfb84..06eda2587c 100644
--- a/synapse/rest/base.py
+++ b/synapse/rest/base.py
@@ -63,12 +63,10 @@ class RestServlet(object):
         self.hs = hs
 
         self.handlers = hs.get_handlers()
-        self.event_factory = hs.get_event_factory()
+        self.builder_factory = hs.get_event_builder_factory()
         self.auth = hs.get_auth()
         self.txns = HttpTransactionStore()
 
-        self.validator = hs.get_event_validator()
-
     def register(self, http_server):
         """ Register this servlet with the given HTTP server. """
         if hasattr(self, "PATTERN"):
diff --git a/synapse/rest/directory.py b/synapse/rest/directory.py
index 35300c6a6f..868fa7abed 100644
--- a/synapse/rest/directory.py
+++ b/synapse/rest/directory.py
@@ -21,7 +21,6 @@ from base import RestServlet, client_path_pattern
 
 import json
 import logging
-import urllib
 
 
 logger = logging.getLogger(__name__)
@@ -36,9 +35,7 @@ class ClientDirectoryServer(RestServlet):
 
     @defer.inlineCallbacks
     def on_GET(self, request, room_alias):
-        room_alias = self.hs.parse_roomalias(
-            urllib.unquote(room_alias).decode("utf-8")
-        )
+        room_alias = self.hs.parse_roomalias(room_alias)
 
         dir_handler = self.handlers.directory_handler
         res = yield dir_handler.get_association(room_alias)
@@ -56,9 +53,7 @@ class ClientDirectoryServer(RestServlet):
 
         logger.debug("Got content: %s", content)
 
-        room_alias = self.hs.parse_roomalias(
-            urllib.unquote(room_alias).decode("utf-8")
-        )
+        room_alias = self.hs.parse_roomalias(room_alias)
 
         logger.debug("Got room name: %s", room_alias.to_string())
 
@@ -97,9 +92,7 @@ class ClientDirectoryServer(RestServlet):
 
         dir_handler = self.handlers.directory_handler
 
-        room_alias = self.hs.parse_roomalias(
-            urllib.unquote(room_alias).decode("utf-8")
-        )
+        room_alias = self.hs.parse_roomalias(room_alias)
 
         yield dir_handler.delete_association(
             user.to_string(), room_alias
diff --git a/synapse/rest/login.py b/synapse/rest/login.py
index ad71f6c61d..875da076af 100644
--- a/synapse/rest/login.py
+++ b/synapse/rest/login.py
@@ -47,8 +47,8 @@ class LoginRestServlet(RestServlet):
     @defer.inlineCallbacks
     def do_password_login(self, login_submission):
         if not login_submission["user"].startswith('@'):
-            login_submission["user"] = UserID.create_local(
-                login_submission["user"], self.hs).to_string()
+            login_submission["user"] = UserID.create(
+                login_submission["user"], self.hs.hostname).to_string()
 
         handler = self.handlers.login_handler
         token = yield handler.login(
diff --git a/synapse/rest/presence.py b/synapse/rest/presence.py
index 502ed0d4ca..9b42131628 100644
--- a/synapse/rest/presence.py
+++ b/synapse/rest/presence.py
@@ -22,7 +22,6 @@ from base import RestServlet, client_path_pattern
 
 import json
 import logging
-import urllib
 
 logger = logging.getLogger(__name__)
 
@@ -33,7 +32,6 @@ class PresenceStatusRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
         auth_user = yield self.auth.get_user_by_req(request)
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         state = yield self.handlers.presence_handler.get_state(
@@ -44,7 +42,6 @@ class PresenceStatusRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_PUT(self, request, user_id):
         auth_user = yield self.auth.get_user_by_req(request)
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         state = {}
@@ -80,10 +77,9 @@ class PresenceListRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
         auth_user = yield self.auth.get_user_by_req(request)
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
-        if not user.is_mine:
+        if not self.hs.is_mine(user):
             raise SynapseError(400, "User not hosted on this Home Server")
 
         if auth_user != user:
@@ -101,10 +97,9 @@ class PresenceListRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_POST(self, request, user_id):
         auth_user = yield self.auth.get_user_by_req(request)
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
-        if not user.is_mine:
+        if not self.hs.is_mine(user):
             raise SynapseError(400, "User not hosted on this Home Server")
 
         if auth_user != user:
diff --git a/synapse/rest/profile.py b/synapse/rest/profile.py
index 72e02d8dd8..351863ab5d 100644
--- a/synapse/rest/profile.py
+++ b/synapse/rest/profile.py
@@ -19,7 +19,6 @@ from twisted.internet import defer
 from base import RestServlet, client_path_pattern
 
 import json
-import urllib
 
 
 class ProfileDisplaynameRestServlet(RestServlet):
@@ -27,7 +26,6 @@ class ProfileDisplaynameRestServlet(RestServlet):
 
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         displayname = yield self.handlers.profile_handler.get_displayname(
@@ -39,7 +37,6 @@ class ProfileDisplaynameRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_PUT(self, request, user_id):
         auth_user = yield self.auth.get_user_by_req(request)
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         try:
@@ -62,7 +59,6 @@ class ProfileAvatarURLRestServlet(RestServlet):
 
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         avatar_url = yield self.handlers.profile_handler.get_avatar_url(
@@ -74,7 +70,6 @@ class ProfileAvatarURLRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_PUT(self, request, user_id):
         auth_user = yield self.auth.get_user_by_req(request)
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         try:
@@ -97,7 +92,6 @@ class ProfileRestServlet(RestServlet):
 
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
-        user_id = urllib.unquote(user_id)
         user = self.hs.parse_userid(user_id)
 
         displayname = yield self.handlers.profile_handler.get_displayname(
diff --git a/synapse/rest/register.py b/synapse/rest/register.py
index f25e23a158..4f0f5a7531 100644
--- a/synapse/rest/register.py
+++ b/synapse/rest/register.py
@@ -21,6 +21,8 @@ from synapse.api.constants import LoginType
 from base import RestServlet, client_path_pattern
 import synapse.util.stringutils as stringutils
 
+from synapse.util.async import run_on_reactor
+
 from hashlib import sha1
 import hmac
 import json
@@ -233,7 +235,7 @@ class RegisterRestServlet(RestServlet):
 
     @defer.inlineCallbacks
     def _do_password(self, request, register_json, session):
-        yield
+        yield run_on_reactor()
         if (self.hs.config.enable_registration_captcha and
                 not session[LoginType.RECAPTCHA]):
             # captcha should've been done by this stage!
diff --git a/synapse/rest/room.py b/synapse/rest/room.py
index 3147d7a60b..005a9f6f44 100644
--- a/synapse/rest/room.py
+++ b/synapse/rest/room.py
@@ -19,8 +19,7 @@ from twisted.internet import defer
 from base import RestServlet, client_path_pattern
 from synapse.api.errors import SynapseError, Codes
 from synapse.streams.config import PaginationConfig
-from synapse.api.events.room import RoomMemberEvent, RoomRedactionEvent
-from synapse.api.constants import Membership
+from synapse.api.constants import EventTypes, Membership
 
 import json
 import logging
@@ -129,9 +128,9 @@ class RoomStateEventRestServlet(RestServlet):
         msg_handler = self.handlers.message_handler
         data = yield msg_handler.get_room_data(
             user_id=user.to_string(),
-            room_id=urllib.unquote(room_id),
-            event_type=urllib.unquote(event_type),
-            state_key=urllib.unquote(state_key),
+            room_id=room_id,
+            event_type=event_type,
+            state_key=state_key,
         )
 
         if not data:
@@ -143,32 +142,23 @@ class RoomStateEventRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_PUT(self, request, room_id, event_type, state_key):
         user = yield self.auth.get_user_by_req(request)
-        event_type = urllib.unquote(event_type)
 
         content = _parse_json(request)
 
-        event = self.event_factory.create_event(
-            etype=event_type,  # already urldecoded
-            content=content,
-            room_id=urllib.unquote(room_id),
-            user_id=user.to_string(),
-            state_key=urllib.unquote(state_key)
-            )
+        event_dict = {
+            "type": event_type,
+            "content": content,
+            "room_id": room_id,
+            "sender": user.to_string(),
+        }
 
-        self.validator.validate(event)
+        if state_key is not None:
+            event_dict["state_key"] = state_key
 
-        if event_type == RoomMemberEvent.TYPE:
-            # membership events are special
-            handler = self.handlers.room_member_handler
-            yield handler.change_membership(event)
-            defer.returnValue((200, {}))
-        else:
-            # store random bits of state
-            msg_handler = self.handlers.message_handler
-            yield msg_handler.store_room_data(
-                event=event
-            )
-            defer.returnValue((200, {}))
+        msg_handler = self.handlers.message_handler
+        yield msg_handler.create_and_send_event(event_dict)
+
+        defer.returnValue((200, {}))
 
 
 # TODO: Needs unit testing for generic events + feedback
@@ -184,17 +174,15 @@ class RoomSendEventRestServlet(RestServlet):
         user = yield self.auth.get_user_by_req(request)
         content = _parse_json(request)
 
-        event = self.event_factory.create_event(
-            etype=urllib.unquote(event_type),
-            room_id=urllib.unquote(room_id),
-            user_id=user.to_string(),
-            content=content
-        )
-
-        self.validator.validate(event)
-
         msg_handler = self.handlers.message_handler
-        yield msg_handler.send_message(event)
+        event = yield msg_handler.create_and_send_event(
+            {
+                "type": event_type,
+                "content": content,
+                "room_id": room_id,
+                "sender": user.to_string(),
+            }
+        )
 
         defer.returnValue((200, {"event_id": event.event_id}))
 
@@ -235,14 +223,10 @@ class JoinRoomAliasServlet(RestServlet):
         identifier = None
         is_room_alias = False
         try:
-            identifier = self.hs.parse_roomalias(
-                urllib.unquote(room_identifier)
-            )
+            identifier = self.hs.parse_roomalias(room_identifier)
             is_room_alias = True
         except SynapseError:
-            identifier = self.hs.parse_roomid(
-                urllib.unquote(room_identifier)
-            )
+            identifier = self.hs.parse_roomid(room_identifier)
 
         # TODO: Support for specifying the home server to join with?
 
@@ -251,18 +235,17 @@ class JoinRoomAliasServlet(RestServlet):
             ret_dict = yield handler.join_room_alias(user, identifier)
             defer.returnValue((200, ret_dict))
         else:  # room id
-            event = self.event_factory.create_event(
-                etype=RoomMemberEvent.TYPE,
-                content={"membership": Membership.JOIN},
-                room_id=urllib.unquote(identifier.to_string()),
-                user_id=user.to_string(),
-                state_key=user.to_string()
+            msg_handler = self.handlers.message_handler
+            yield msg_handler.create_and_send_event(
+                {
+                    "type": EventTypes.Member,
+                    "content": {"membership": Membership.JOIN},
+                    "room_id": identifier.to_string(),
+                    "sender": user.to_string(),
+                    "state_key": user.to_string(),
+                }
             )
 
-            self.validator.validate(event)
-
-            handler = self.handlers.room_member_handler
-            yield handler.change_membership(event)
             defer.returnValue((200, {}))
 
     @defer.inlineCallbacks
@@ -301,7 +284,7 @@ class RoomMemberListRestServlet(RestServlet):
         user = yield self.auth.get_user_by_req(request)
         handler = self.handlers.room_member_handler
         members = yield handler.get_room_members_as_pagination_chunk(
-            room_id=urllib.unquote(room_id),
+            room_id=room_id,
             user_id=user.to_string())
 
         for event in members["chunk"]:
@@ -327,13 +310,13 @@ class RoomMessageListRestServlet(RestServlet):
     @defer.inlineCallbacks
     def on_GET(self, request, room_id):
         user = yield self.auth.get_user_by_req(request)
-        pagination_config = PaginationConfig.from_request(request,
-            default_limit=10,
+        pagination_config = PaginationConfig.from_request(
+            request, default_limit=10,
         )
         with_feedback = "feedback" in request.args
         handler = self.handlers.message_handler
         msgs = yield handler.get_messages(
-            room_id=urllib.unquote(room_id),
+            room_id=room_id,
             user_id=user.to_string(),
             pagin_config=pagination_config,
             feedback=with_feedback)
@@ -351,7 +334,7 @@ class RoomStateRestServlet(RestServlet):
         handler = self.handlers.message_handler
         # Get all the current state for this room
         events = yield handler.get_state_events(
-            room_id=urllib.unquote(room_id),
+            room_id=room_id,
             user_id=user.to_string(),
         )
         defer.returnValue((200, events))
@@ -366,7 +349,7 @@ class RoomInitialSyncRestServlet(RestServlet):
         user = yield self.auth.get_user_by_req(request)
         pagination_config = PaginationConfig.from_request(request)
         content = yield self.handlers.message_handler.room_initial_sync(
-            room_id=urllib.unquote(room_id),
+            room_id=room_id,
             user_id=user.to_string(),
             pagin_config=pagination_config,
         )
@@ -378,8 +361,10 @@ class RoomTriggerBackfill(RestServlet):
 
     @defer.inlineCallbacks
     def on_GET(self, request, room_id):
-        remote_server = urllib.unquote(request.args["remote"][0])
-        room_id = urllib.unquote(room_id)
+        remote_server = urllib.unquote(
+            request.args["remote"][0]
+        ).decode("UTF-8")
+
         limit = int(request.args["limit"][0])
 
         handler = self.handlers.federation_handler
@@ -414,18 +399,17 @@ class RoomMembershipRestServlet(RestServlet):
             if membership_action == "kick":
                 membership_action = "leave"
 
-        event = self.event_factory.create_event(
-            etype=RoomMemberEvent.TYPE,
-            content={"membership": unicode(membership_action)},
-            room_id=urllib.unquote(room_id),
-            user_id=user.to_string(),
-            state_key=state_key
+        msg_handler = self.handlers.message_handler
+        yield msg_handler.create_and_send_event(
+            {
+                "type": EventTypes.Member,
+                "content": {"membership": unicode(membership_action)},
+                "room_id": room_id,
+                "sender": user.to_string(),
+                "state_key": state_key,
+            }
         )
 
-        self.validator.validate(event)
-
-        handler = self.handlers.room_member_handler
-        yield handler.change_membership(event)
         defer.returnValue((200, {}))
 
     @defer.inlineCallbacks
@@ -453,18 +437,16 @@ class RoomRedactEventRestServlet(RestServlet):
         user = yield self.auth.get_user_by_req(request)
         content = _parse_json(request)
 
-        event = self.event_factory.create_event(
-            etype=RoomRedactionEvent.TYPE,
-            room_id=urllib.unquote(room_id),
-            user_id=user.to_string(),
-            content=content,
-            redacts=urllib.unquote(event_id),
-        )
-
-        self.validator.validate(event)
-
         msg_handler = self.handlers.message_handler
-        yield msg_handler.send_message(event)
+        event = yield msg_handler.create_and_send_event(
+            {
+                "type": EventTypes.Redaction,
+                "content": content,
+                "room_id": room_id,
+                "sender": user.to_string(),
+                "redacts": event_id,
+            }
+        )
 
         defer.returnValue((200, {"event_id": event.event_id}))
 
@@ -483,6 +465,39 @@ class RoomRedactEventRestServlet(RestServlet):
         defer.returnValue(response)
 
 
+class RoomTypingRestServlet(RestServlet):
+    PATTERN = client_path_pattern(
+        "/rooms/(?P<room_id>[^/]*)/typing/(?P<user_id>[^/]*)$"
+    )
+
+    @defer.inlineCallbacks
+    def on_PUT(self, request, room_id, user_id):
+        auth_user = yield self.auth.get_user_by_req(request)
+
+        room_id = urllib.unquote(room_id)
+        target_user = self.hs.parse_userid(urllib.unquote(user_id))
+
+        content = _parse_json(request)
+
+        typing_handler = self.handlers.typing_notification_handler
+
+        if content["typing"]:
+            yield typing_handler.started_typing(
+                target_user=target_user,
+                auth_user=auth_user,
+                room_id=room_id,
+                timeout=content.get("timeout", 30000),
+            )
+        else:
+            yield typing_handler.stopped_typing(
+                target_user=target_user,
+                auth_user=auth_user,
+                room_id=room_id,
+            )
+
+        defer.returnValue((200, {}))
+
+
 def _parse_json(request):
     try:
         content = json.loads(request.content.read())
@@ -538,3 +553,4 @@ def register_servlets(hs, http_server):
     RoomStateRestServlet(hs).register(http_server)
     RoomInitialSyncRestServlet(hs).register(http_server)
     RoomRedactEventRestServlet(hs).register(http_server)
+    RoomTypingRestServlet(hs).register(http_server)
diff --git a/synapse/rest/transactions.py b/synapse/rest/transactions.py
index 93c0122f30..31377bd41d 100644
--- a/synapse/rest/transactions.py
+++ b/synapse/rest/transactions.py
@@ -20,6 +20,7 @@ import logging
 logger = logging.getLogger(__name__)
 
 
+# FIXME: elsewhere we use FooStore to indicate something in the storage layer...
 class HttpTransactionStore(object):
 
     def __init__(self):