diff --git a/synapse/rest/__init__.py b/synapse/rest/__init__.py
index c38cf27690..c29896bde9 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):
|