summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2017-05-31 15:11:36 +0100
committerErik Johnston <erik@matrix.org>2017-05-31 15:11:36 +0100
commit350622a107c356da630eba09b63ed4b6de94b198 (patch)
treebfb6628b2b4271461a2a93c23ceaa1e45322defd
parentAdd comments (diff)
downloadsynapse-350622a107c356da630eba09b63ed4b6de94b198.tar.xz
Handle the server leaving a public room
-rw-r--r--synapse/handlers/user_directory.py23
-rw-r--r--synapse/state.py11
-rw-r--r--synapse/storage/schema/delta/42/user_dir.py4
-rw-r--r--synapse/storage/user_directory.py11
4 files changed, 46 insertions, 3 deletions
diff --git a/synapse/handlers/user_directory.py b/synapse/handlers/user_directory.py
index 88b79e3325..4e491a43e6 100644
--- a/synapse/handlers/user_directory.py
+++ b/synapse/handlers/user_directory.py
@@ -132,7 +132,9 @@ class UserDirectoyHandler(object):
     def _handle_intial_room(self, room_id):
         """Called when we initially fill out user_directory one room at a time
         """
-        # TODO: Check we're still joined to room
+        is_in_room = yield self.store.get_is_host_in_room(room_id, self.server_name)
+        if not is_in_room:
+            return
 
         is_public = yield self.store.is_room_world_readable_or_publicly_joinable(room_id)
         if not is_public:
@@ -229,7 +231,22 @@ class UserDirectoyHandler(object):
                 if change is None:
                     continue
 
-                if change:
+                if not change:
+                    # Need to check if the server left the room entirely, if so
+                    # we might need to remove all the users in that room
+                    is_in_room = yield self.store.get_is_host_in_room(
+                        room_id, self.server_name,
+                    )
+                    if not is_in_room:
+                        # Fetch all the users that we marked as being in user
+                        # directory due to being in the room and then check if
+                        # need to remove those users or not
+                        user_ids = yield self.store.get_users_in_dir_due_to_room(room_id)
+                        for user_id in user_ids:
+                            yield self._handle_remove_user(room_id, user_id)
+                        return
+
+                if change:  # The user joined
                     event = yield self.store.get_event(event_id)
                     profile = ProfileInfo(
                         avatar_url=event.content.get("avatar_url"),
@@ -237,7 +254,7 @@ class UserDirectoyHandler(object):
                     )
 
                     yield self._handle_new_user(room_id, state_key, profile)
-                else:
+                else:  # The user left
                     yield self._handle_remove_user(room_id, state_key)
 
     @defer.inlineCallbacks
diff --git a/synapse/state.py b/synapse/state.py
index 02fee47f39..dffa79e4c9 100644
--- a/synapse/state.py
+++ b/synapse/state.py
@@ -187,6 +187,17 @@ class StateHandler(object):
         defer.returnValue(joined_hosts)
 
     @defer.inlineCallbacks
+    def get_is_host_in_room(self, room_id, host, latest_event_ids=None):
+        if not latest_event_ids:
+            latest_event_ids = yield self.store.get_latest_event_ids_in_room(room_id)
+        logger.debug("calling resolve_state_groups from get_is_host_in_room")
+        entry = yield self.resolve_state_groups(room_id, latest_event_ids)
+        is_host_joined = yield self.store.is_host_joined(
+            room_id, host, entry.state_id, entry.state
+        )
+        defer.returnValue(is_host_joined)
+
+    @defer.inlineCallbacks
     def compute_event_context(self, event, old_state=None):
         """Build an EventContext structure for the event.
 
diff --git a/synapse/storage/schema/delta/42/user_dir.py b/synapse/storage/schema/delta/42/user_dir.py
index 57b89ba552..95a7a79fd3 100644
--- a/synapse/storage/schema/delta/42/user_dir.py
+++ b/synapse/storage/schema/delta/42/user_dir.py
@@ -41,6 +41,7 @@ CREATE TABLE user_directory (
 );
 
 CREATE INDEX user_directory_fts_idx ON user_directory USING gin(vector);
+CREATE INDEX user_directory_room_idx ON user_directory(room_id);
 CREATE INDEX user_directory_user_idx ON user_directory(user_id);
 """
 
@@ -48,6 +49,9 @@ CREATE INDEX user_directory_user_idx ON user_directory(user_id);
 SQLITE_TABLE = """
 CREATE VIRTUAL TABLE user_directory
     USING fts4 ( user_id, room_id, display_name, avatar_url, value );
+
+CREATE INDEX user_directory_room_idx ON user_directory(room_id);
+CREATE INDEX user_directory_user_idx ON user_directory(user_id);
 """
 
 
diff --git a/synapse/storage/user_directory.py b/synapse/storage/user_directory.py
index 83812bf092..0df979cb01 100644
--- a/synapse/storage/user_directory.py
+++ b/synapse/storage/user_directory.py
@@ -124,6 +124,17 @@ class UserDirectoryStore(SQLBaseStore):
         )
         self.get_user_in_directory.invalidate((user_id,))
 
+    def get_users_in_dir_due_to_room(self, room_id):
+        """Get all user_ids that are in the room directory becuase they're
+        in the given room_id
+        """
+        return self._simple_select_onecol(
+            table="user_directory",
+            keyvalues={"room_id": room_id},
+            retcol="user_id",
+            desc="get_users_in_dir_due_to_room",
+        )
+
     def get_all_rooms(self):
         """Get all room_ids we've ever known about
         """