summary refs log tree commit diff
path: root/synapse/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/handlers')
-rw-r--r--synapse/handlers/_base.py1
-rw-r--r--synapse/handlers/federation.py31
-rw-r--r--synapse/handlers/presence.py17
-rw-r--r--synapse/handlers/room.py49
4 files changed, 79 insertions, 19 deletions
diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py
index c2f4685c92..3f07b5aa4a 100644
--- a/synapse/handlers/_base.py
+++ b/synapse/handlers/_base.py
@@ -24,4 +24,5 @@ class BaseHandler(object):
         self.notifier = hs.get_notifier()
         self.room_lock = hs.get_room_lock_manager()
         self.state_handler = hs.get_state_handler()
+        self.distributor = hs.get_distributor()
         self.hs = hs
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index aa3bf273f7..16bac95331 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -32,6 +32,15 @@ logger = logging.getLogger(__name__)
 class FederationHandler(BaseHandler):
 
     """Handles events that originated from federation."""
+    def __init__(self, hs):
+        super(FederationHandler, self).__init__(hs)
+
+        self.distributor.observe(
+            "user_joined_room",
+            self._on_user_joined
+        )
+
+        self.waiting_for_join_list = {}
 
     @log_function
     @defer.inlineCallbacks
@@ -56,7 +65,7 @@ class FederationHandler(BaseHandler):
             content.update({"membership": Membership.JOIN})
             new_event = self.event_factory.create_event(
                 etype=RoomMemberEvent.TYPE,
-                target_user_id=event.user_id,
+                state_key=event.user_id,
                 room_id=event.room_id,
                 user_id=event.user_id,
                 membership=Membership.JOIN,
@@ -103,6 +112,13 @@ class FederationHandler(BaseHandler):
             if not backfilled:
                 yield self.notifier.on_new_room_event(event, store_id)
 
+        if event.type == RoomMemberEvent.TYPE:
+            if event.membership == Membership.JOIN:
+                user = self.hs.parse_userid(event.target_user_id)
+                self.distributor.fire(
+                    "user_joined_room", user=user, room_id=event.room_id
+                )
+
 
     @log_function
     @defer.inlineCallbacks
@@ -152,8 +168,10 @@ class FederationHandler(BaseHandler):
 
         yield federation.handle_new_event(new_event)
 
-        store_id = yield self.store.persist_event(new_event)
-        self.notifier.on_new_room_event(new_event, store_id)
+        # TODO (erikj): Time out here.
+        d = defer.Deferred()
+        self.waiting_for_join_list.setdefault((joinee, room_id), []).append(d)
+        yield d
 
         try:
             yield self.store.store_room(
@@ -166,3 +184,10 @@ class FederationHandler(BaseHandler):
 
 
         defer.returnValue(True)
+
+
+    @log_function
+    def _on_user_joined(self, user, room_id):
+        waiters = self.waiting_for_join_list.get((user.to_string(), room_id), [])
+        while waiters:
+            waiters.pop().callback(None)
diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py
index 540e114b82..471dc86163 100644
--- a/synapse/handlers/presence.py
+++ b/synapse/handlers/presence.py
@@ -142,6 +142,10 @@ class PresenceHandler(BaseHandler):
 
     @defer.inlineCallbacks
     def is_presence_visible(self, observer_user, observed_user):
+        defer.returnValue(True)
+        return
+        # FIXME (erikj): This code path absolutely kills the database.
+
         assert(observed_user.is_mine)
 
         if observer_user == observed_user:
@@ -155,12 +159,11 @@ class PresenceHandler(BaseHandler):
         if allowed_by_subscription:
             defer.returnValue(True)
 
-        rm_handler = self.homeserver.get_handlers().room_member_handler
-        for room_id in (yield rm_handler.get_rooms_for_user(observer_user)):
-            if observed_user in (yield rm_handler.get_room_members(room_id)):
-                defer.returnValue(True)
+        share_room = yield self.store.do_users_share_a_room(
+            [observer_user, observed_user]
+        )
 
-        defer.returnValue(False)
+        defer.returnValue(share_room)
 
     @defer.inlineCallbacks
     def get_state(self, target_user, auth_user):
@@ -187,6 +190,10 @@ class PresenceHandler(BaseHandler):
 
     @defer.inlineCallbacks
     def set_state(self, target_user, auth_user, state):
+        return
+        # TODO (erikj): Turn this back on. Why did we end up sending EDUs
+        # everywhere?
+
         if not target_user.is_mine:
             raise SynapseError(400, "User is not hosted on this Home Server")
 
diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py
index 6229ee9bfa..5489de841f 100644
--- a/synapse/handlers/room.py
+++ b/synapse/handlers/room.py
@@ -24,6 +24,7 @@ from synapse.api.events.room import (
     RoomConfigEvent
 )
 from synapse.api.streams.event import EventStream, EventsStreamData
+from synapse.handlers.presence import PresenceStreamData
 from synapse.util import stringutils
 from ._base import BaseHandler
 
@@ -257,21 +258,38 @@ class MessageHandler(BaseHandler):
             membership_list=[Membership.INVITE, Membership.JOIN]
         )
 
-        ret = []
+        rooms_ret = []
+
+        now_rooms_token = yield self.store.get_room_events_max_id()
+
+        # FIXME (erikj): Fix this.
+        presence_stream = PresenceStreamData(self.hs)
+        now_presence_token = yield presence_stream.max_token()
+        presence = yield presence_stream.get_rows(
+            user_id, 0, now_presence_token, None, None
+        )
+
+        # FIXME (erikj): We need to not generate this token,
+        now_token = "%s_%s" % (now_rooms_token, now_presence_token)
 
         for event in room_list:
             d = {
                 "room_id": event.room_id,
                 "membership": event.membership,
             }
-            ret.append(d)
+
+            if event.membership == Membership.INVITE:
+                d["inviter"] = event.user_id
+
+            rooms_ret.append(d)
 
             if event.membership != Membership.JOIN:
                 continue
             try:
                 messages, token = yield self.store.get_recent_events_for_room(
                     event.room_id,
-                    limit=50,
+                    limit=10,
+                    end_token=now_rooms_token,
                 )
 
                 d["messages"] = {
@@ -279,10 +297,17 @@ class MessageHandler(BaseHandler):
                     "start": token[0],
                     "end": token[1],
                 }
+
+                current_state = yield self.store.get_current_state(event.room_id)
+                d["state"] = [c.get_dict() for c in current_state]
             except:
                 logger.exception("Failed to get snapshot")
 
-        logger.debug("snapshot_all_rooms returning: %s", ret)
+        user = self.hs.parse_userid(user_id)
+
+        ret = {"rooms": rooms_ret, "presence": presence[0], "end": now_token}
+
+        # logger.debug("snapshot_all_rooms returning: %s", ret)
 
         defer.returnValue(ret)
 
@@ -374,7 +399,7 @@ class RoomCreationHandler(BaseHandler):
         content = {"membership": Membership.JOIN}
         join_event = self.event_factory.create_event(
             etype=RoomMemberEvent.TYPE,
-            target_user_id=user_id,
+            state_key=user_id,
             room_id=room_id,
             user_id=user_id,
             membership=Membership.JOIN,
@@ -502,9 +527,10 @@ class RoomMemberHandler(BaseHandler):
         Raises:
             SynapseError if there was a problem changing the membership.
         """
+        target_user_id = event.state_key
 
         prev_state = yield self.store.get_room_member(
-            event.target_user_id, event.room_id
+            target_user_id, event.room_id
         )
 
         if prev_state:
@@ -530,7 +556,7 @@ class RoomMemberHandler(BaseHandler):
                 yield self.auth.check(event, raises=True)
 
             prev_state = yield self.store.get_room_member(
-                event.target_user_id, event.room_id
+                target_user_id, event.room_id
             )
             if prev_state and prev_state.membership == event.membership:
                 # double same action, treat this event as a NOOP.
@@ -563,7 +589,7 @@ class RoomMemberHandler(BaseHandler):
         content.update({"membership": Membership.JOIN})
         new_event = self.event_factory.create_event(
             etype=RoomMemberEvent.TYPE,
-            target_user_id=joinee.to_string(),
+            state_key=joinee.to_string(),
             room_id=room_id,
             user_id=joinee.to_string(),
             membership=Membership.JOIN,
@@ -576,7 +602,7 @@ class RoomMemberHandler(BaseHandler):
 
     @defer.inlineCallbacks
     def _do_join(self, event, room_host=None, do_auth=True):
-        joinee = self.hs.parse_userid(event.target_user_id)
+        joinee = self.hs.parse_userid(event.state_key)
         # room_id = RoomID.from_string(event.room_id, self.hs)
         room_id = event.room_id
 
@@ -685,16 +711,17 @@ class RoomMemberHandler(BaseHandler):
 
         # If we're inviting someone, then we should also send it to that
         # HS.
+        target_user_id = event.state_key
         if membership == Membership.INVITE:
             host = UserID.from_string(
-                event.target_user_id, self.hs
+                target_user_id, self.hs
             ).domain
             destinations.append(host)
 
         # If we are joining a remote HS, include that.
         if membership == Membership.JOIN:
             host = UserID.from_string(
-                event.target_user_id, self.hs
+                target_user_id, self.hs
             ).domain
             destinations.append(host)