summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/api/auth.py5
-rw-r--r--synapse/api/constants.py7
-rw-r--r--synapse/storage/prepare_database.py2
-rw-r--r--synapse/storage/registration.py14
-rw-r--r--synapse/storage/user_directory.py31
5 files changed, 45 insertions, 14 deletions
diff --git a/synapse/api/auth.py b/synapse/api/auth.py
index 34382e4e3c..8250157ebd 100644
--- a/synapse/api/auth.py
+++ b/synapse/api/auth.py
@@ -791,9 +791,10 @@ class Auth(object):
             threepid should never be set at the same time.
         """
 
-        # Never fail an auth check for the server notices users
+        # Never fail an auth check for the server notices users or support user
         # This can be a problem where event creation is prohibited due to blocking
-        if user_id == self.hs.config.server_notices_mxid:
+        if (user_id == self.hs.config.server_notices_mxid or
+                user_id == self.hs.config.support_user_id):
             return
 
         if self.hs.config.hs_disabled:
diff --git a/synapse/api/constants.py b/synapse/api/constants.py
index f20e0fcf0b..f6f2d6bd6f 100644
--- a/synapse/api/constants.py
+++ b/synapse/api/constants.py
@@ -105,7 +105,6 @@ class RoomVersions(object):
     VDH_TEST = "vdh-test-version"
     STATE_V2_TEST = "state-v2-test"
 
-
 # the version we will give rooms which are created on this server
 DEFAULT_ROOM_VERSION = RoomVersions.V1
 
@@ -119,3 +118,9 @@ KNOWN_ROOM_VERSIONS = {
 
 ServerNoticeMsgType = "m.server_notice"
 ServerNoticeLimitReached = "m.server_notice.usage_limit_reached"
+
+
+# Allows for user type specific behaviour, if we'd had a crystal ball would
+# probably have included admin and guest, normal users are type None
+class UserTypes(object):
+    SUPPORT = "support"
diff --git a/synapse/storage/prepare_database.py b/synapse/storage/prepare_database.py
index bd740e1e45..94b07ce641 100644
--- a/synapse/storage/prepare_database.py
+++ b/synapse/storage/prepare_database.py
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
 
 # Remember to update this number every time a change is made to database
 # schema files, so the users will be informed on server restarts.
-SCHEMA_VERSION = 52
+SCHEMA_VERSION = 53
 
 dir_path = os.path.abspath(os.path.dirname(__file__))
 
diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py
index 80d76bf9d7..46322ba7d4 100644
--- a/synapse/storage/registration.py
+++ b/synapse/storage/registration.py
@@ -24,6 +24,8 @@ from synapse.storage import background_updates
 from synapse.storage._base import SQLBaseStore
 from synapse.util.caches.descriptors import cached, cachedInlineCallbacks
 
+from synapse.api.constants import UserTypes
+
 
 class RegistrationWorkerStore(SQLBaseStore):
     def __init__(self, db_conn, hs):
@@ -450,6 +452,18 @@ class RegistrationStore(RegistrationWorkerStore,
 
         defer.returnValue(res if res else False)
 
+    @cachedInlineCallbacks()
+    def is_support_user(self, user_id):
+        res = yield self._simple_select_one_onecol(
+            table="users",
+            keyvalues={"name": user_id},
+            retcol="user_type",
+            allow_none=True,
+            desc="is_support_user",
+        )
+
+        defer.returnValue(res if res == UserTypes.SUPPORT else False)
+
     @defer.inlineCallbacks
     def user_add_threepid(self, user_id, medium, address, validated_at, added_at):
         yield self._simple_upsert("user_threepids", {
diff --git a/synapse/storage/user_directory.py b/synapse/storage/user_directory.py
index 4502ac49c4..c8a780c048 100644
--- a/synapse/storage/user_directory.py
+++ b/synapse/storage/user_directory.py
@@ -16,7 +16,7 @@
 import logging
 import re
 
-from six import iteritems
+from six import iteritems, iterkeys
 
 from twisted.internet import defer
 
@@ -31,6 +31,10 @@ logger = logging.getLogger(__name__)
 
 
 class UserDirectoryStore(SQLBaseStore):
+    def __init__(self, dbconn, hs):
+        super(UserDirectoryStore, self).__init__(dbconn, hs)
+        self.store = hs.get_datastore()
+
     @cachedInlineCallbacks(cache_context=True)
     def is_room_world_readable_or_publicly_joinable(self, room_id, cache_context):
         """Check if the room is either world_readable or publically joinable
@@ -64,10 +68,9 @@ class UserDirectoryStore(SQLBaseStore):
                 or publically joinable
             user_ids (list(str)): Users to add
         """
-
-        support_id = self.hs.config.support_user_id
-        if support_id in user_ids:
-            user_ids.remove(support_id)
+        for u in user_ids:
+            if self.store.is_support_user(u):
+                user_ids.remove(u)
 
         yield self._simple_insert_many(
             table="users_in_public_rooms",
@@ -91,7 +94,13 @@ class UserDirectoryStore(SQLBaseStore):
             users_with_profile (dict): Users to add to directory in the form of
                 mapping of user_id -> ProfileInfo
         """
-        users_with_profile.pop(self.hs.config.support_user_id, None)
+        # remove users of type UserType.SUPPORT
+        user_ids_to_pop = []
+        for user_id in iterkeys(users_with_profile):
+            if self.store.is_support_user(user_id):
+                user_ids_to_pop.append(user_id)
+        for u in user_ids_to_pop:
+            users_with_profile.pop(u, None)
 
         if isinstance(self.database_engine, PostgresEngine):
             # We weight the loclpart most highly, then display name and finally
@@ -153,7 +162,8 @@ class UserDirectoryStore(SQLBaseStore):
 
     @defer.inlineCallbacks
     def update_user_in_user_dir(self, user_id, room_id):
-        if user_id != self.hs.config.support_user_id:
+
+        if not self.store.is_support_user(user_id):
             yield self._simple_update_one(
                 table="user_directory",
                 keyvalues={"user_id": user_id},
@@ -164,7 +174,7 @@ class UserDirectoryStore(SQLBaseStore):
 
     def update_profile_in_user_dir(self, user_id, display_name, avatar_url, room_id):
         def _update_profile_in_user_dir_txn(txn):
-            if user_id == self.hs.config.support_user_id:
+            if self.store.is_support_user(user_id):
                 return
             new_entry = self._simple_upsert_txn(
                 txn,
@@ -229,7 +239,7 @@ class UserDirectoryStore(SQLBaseStore):
 
     @defer.inlineCallbacks
     def update_user_in_public_user_list(self, user_id, room_id):
-        if user_id != self.hs.config.support_user_id:
+        if not self.store.is_support_user(user_id):
             yield self._simple_update_one(
                 table="users_in_public_rooms",
                 keyvalues={"user_id": user_id},
@@ -352,7 +362,8 @@ class UserDirectoryStore(SQLBaseStore):
             support_user = self.hs.config.support_user_id
 
             if support_user is not None:
-                user_id_tuples = [u for u in user_id_tuples if support_user not in u]
+                user_id_tuples = [u for u in user_id_tuples
+                                  if not self.store.is_support_user(u)]
 
             self._simple_insert_many_txn(
                 txn,