summary refs log tree commit diff
diff options
context:
space:
mode:
authorH. Shay <hillerys@element.io>2023-05-10 09:05:19 -0700
committerH. Shay <hillerys@element.io>2023-05-10 09:05:19 -0700
commit7568c726d34b4e8b3602a73acac45ef76aaa4117 (patch)
tree8a2ad35c4157864ea296e4e5b1aa60cd8014e409
parentconsolidate logic checking config and db to one place (diff)
downloadsynapse-7568c726d34b4e8b3602a73acac45ef76aaa4117.tar.xz
test activation both by config and admin api
-rw-r--r--tests/handlers/test_presence.py77
-rw-r--r--tests/push/test_http.py57
-rw-r--r--tests/rest/client/test_keys.py79
3 files changed, 186 insertions, 27 deletions
diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py
index ab763d6284..ba47e801a4 100644
--- a/tests/handlers/test_presence.py
+++ b/tests/handlers/test_presence.py
@@ -36,8 +36,7 @@ from synapse.handlers.presence import (
     handle_update,
 )
 from synapse.rest import admin
-from synapse.rest.admin.experimental_features import ExperimentalFeature
-from synapse.rest.client import room
+from synapse.rest.client import login, room
 from synapse.server import HomeServer
 from synapse.types import JsonDict, UserID, get_domain_from_id
 from synapse.util import Clock
@@ -515,14 +514,13 @@ class PresenceTimeoutTestCase(unittest.TestCase):
 
 
 class PresenceHandlerTestCase(BaseMultiWorkerStreamTestCase):
-    servlets = [
-        admin.register_servlets,
-    ]
+    servlets = [admin.register_servlets, login.register_servlets]
 
     def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
         self.presence_handler = hs.get_presence_handler()
         self.clock = hs.get_clock()
-        self.user = self.register_user("test", "pass")
+        self.user = self.register_user("test", "pass", True)
+        self.admin_user_tok = self.login("test", "pass")
 
     def test_external_process_timeout(self) -> None:
         """Test that if an external process doesn't update the records for a while
@@ -731,10 +729,11 @@ class PresenceHandlerTestCase(BaseMultiWorkerStreamTestCase):
         self.assertEqual(state.status_msg, status_msg)
 
     @parameterized.expand([(False,), (True,)])
-    def test_set_presence_from_syncing_keeps_busy(
+    def test_set_presence_from_syncing_keeps_busy_via_admin(
         self, test_with_workers: bool
     ) -> None:
-        """Test that presence set by syncing doesn't affect busy status
+        """Test that presence set by syncing doesn't affect busy status, with the busy status
+        enabled via the admin api.
 
         Args:
             test_with_workers: If True, check the presence state of the user by calling
@@ -742,13 +741,69 @@ class PresenceHandlerTestCase(BaseMultiWorkerStreamTestCase):
         """
         status_msg = "I'm busy!"
 
-        # set busy state in db
+        # activate busy state via admin api
+        url = f"/_synapse/admin/v1/experimental_features/{self.user}"
+        channel = self.make_request(
+            "PUT",
+            url,
+            content={
+                "features": {"msc3026": True},
+            },
+            access_token=self.admin_user_tok,
+        )
+        self.assertEqual(channel.code, 200)
+
+        # By default, we call /sync against the main process.
+        worker_to_sync_against = self.hs
+        if test_with_workers:
+            # Create a worker and use it to handle /sync traffic instead.
+            # This is used to test that presence changes get replicated from workers
+            # to the main process correctly.
+            worker_to_sync_against = self.make_worker_hs(
+                "synapse.app.generic_worker", {"worker_name": "presence_writer"}
+            )
+
+        # Set presence to BUSY
+        self._set_presencestate_with_status_msg(
+            self.user, PresenceState.BUSY, status_msg
+        )
+
+        # Perform a sync with a presence state other than busy. This should NOT change
+        # our presence status; we only change from busy if we explicitly set it via
+        # /presence/*.
         self.get_success(
-            self.hs.get_datastores().main.set_features_for_user(
-                self.user, {ExperimentalFeature.MSC3026: True}
+            worker_to_sync_against.get_presence_handler().user_syncing(
+                self.user, True, PresenceState.ONLINE
             )
         )
 
+        # Check against the main process that the user's presence did not change.
+        state = self.get_success(
+            self.presence_handler.get_state(UserID.from_string(self.user))
+        )
+        # we should still be busy
+        self.assertEqual(state.state, PresenceState.BUSY)
+
+    @parameterized.expand([(False,), (True,)])
+    @unittest.override_config(
+        {
+            "experimental_features": {
+                "msc3026_enabled": True,
+            },
+        }
+    )
+    def test_set_presence_from_syncing_keeps_busy_via_config(
+        self, test_with_workers: bool
+    ) -> None:
+        """Test that presence set by syncing doesn't affect busy status, with the busy status
+        enabled via the config
+
+        Args:
+            test_with_workers: If True, check the presence state of the user by calling
+                /sync against a worker, rather than the main process.
+        """
+        status_msg = "I'm busy!"
+
         # By default, we call /sync against the main process.
         worker_to_sync_against = self.hs
         if test_with_workers:
diff --git a/tests/push/test_http.py b/tests/push/test_http.py
index 97bc48f246..42f24a530d 100644
--- a/tests/push/test_http.py
+++ b/tests/push/test_http.py
@@ -20,9 +20,9 @@ from twisted.test.proto_helpers import MemoryReactor
 import synapse.rest.admin
 from synapse.logging.context import make_deferred_yieldable
 from synapse.push import PusherConfig, PusherConfigException
-from synapse.rest.admin.experimental_features import ExperimentalFeature
 from synapse.rest.client import login, push_rule, pusher, receipts, room
 from synapse.server import HomeServer
+from synapse.storage.databases.main.experimental_features import ExperimentalFeature
 from synapse.types import JsonDict
 from synapse.util import Clock
 
@@ -37,6 +37,7 @@ class HTTPPusherTests(HomeserverTestCase):
         receipts.register_servlets,
         push_rule.register_servlets,
         pusher.register_servlets,
+        synapse.rest.admin.register_servlets,
     ]
     user_id = True
     hijack_auth = False
@@ -820,20 +821,60 @@ class HTTPPusherTests(HomeserverTestCase):
         self.helper.send(room, body="Hello", tok=access_token)
         self.assertEqual(len(self.push_attempts), 1)
 
-    def test_disable(self) -> None:
-        """Tests that disabling a pusher means it's not pushed to anymore."""
+    @override_config({"experimental_features": {"msc3881_enabled": True}})
+    def test_disable_via_config(self) -> None:
+        """Tests that disabling a pusher means it's not pushed to anymore, with the
+        ability to disable a pusher enabled via the config.
+        """
         user_id, access_token = self._make_user_with_pusher("user")
         other_user_id, other_access_token = self._make_user_with_pusher("otheruser")
 
         room = self.helper.create_room_as(user_id, tok=access_token)
         self.helper.join(room=room, user=other_user_id, tok=other_access_token)
 
-        # enable msc3881 per_user flag
-        self.get_success(
-            self.hs.get_datastores().main.set_features_for_user(
-                user_id, {ExperimentalFeature.MSC3881: True}
-            )
+        # Send a message and check that it generated a push.
+        self.helper.send(room, body="Hi!", tok=other_access_token)
+        self.assertEqual(len(self.push_attempts), 1)
+
+        # Disable the pusher.
+        self._set_pusher(user_id, access_token, enabled=False)
+
+        # Send another message and check that it did not generate a push.
+        self.helper.send(room, body="Hi!", tok=other_access_token)
+        self.assertEqual(len(self.push_attempts), 1)
+
+        # Get the pushers for the user and check that it is marked as disabled.
+        channel = self.make_request("GET", "/pushers", access_token=access_token)
+        self.assertEqual(channel.code, 200)
+        self.assertEqual(len(channel.json_body["pushers"]), 1)
+
+        enabled = channel.json_body["pushers"][0]["org.matrix.msc3881.enabled"]
+        self.assertFalse(enabled)
+        self.assertTrue(isinstance(enabled, bool))
+
+    def test_disable_via_admin(self) -> None:
+        """Tests that disabling a pusher means it's not pushed to anymore,
+        with the ability to disable a pusher enabled via the admin api.
+        """
+        user_id, access_token = self._make_user_with_pusher("user")
+        other_user_id, other_access_token = self._make_user_with_pusher("otheruser")
+        self.register_user("admin", "pass", True)
+        admin_tok = self.login("admin", "pass")
+
+        room = self.helper.create_room_as(user_id, tok=access_token)
+        self.helper.join(room=room, user=other_user_id, tok=other_access_token)
+
+        # enable msc3881 per_user flag via the admin api
+        url = f"/_synapse/admin/v1/experimental_features/{user_id}"
+        channel = self.make_request(
+            "PUT",
+            url,
+            content={
+                "features": {"msc3881": True},
+            },
+            access_token=admin_tok,
         )
+        self.assertEqual(channel.code, 200)
 
         # Send a message and check that it generated a push.
         self.helper.send(room, body="Hi!", tok=other_access_token)
diff --git a/tests/rest/client/test_keys.py b/tests/rest/client/test_keys.py
index ef2800ee54..46ab0b505f 100644
--- a/tests/rest/client/test_keys.py
+++ b/tests/rest/client/test_keys.py
@@ -23,7 +23,6 @@ from signedjson.sign import sign_json
 
 from synapse.api.errors import Codes
 from synapse.rest import admin
-from synapse.rest.admin.experimental_features import ExperimentalFeature
 from synapse.rest.client import keys, login
 from synapse.types import JsonDict
 
@@ -37,6 +36,7 @@ class KeyQueryTestCase(unittest.HomeserverTestCase):
         keys.register_servlets,
         admin.register_servlets_for_client_rest_resource,
         login.register_servlets,
+        admin.register_servlets,
     ]
 
     def test_rejects_device_id_ice_key_outside_of_list(self) -> None:
@@ -207,21 +207,84 @@ class KeyQueryTestCase(unittest.HomeserverTestCase):
     @override_config(
         {
             "ui_auth": {"session_timeout": "15s"},
+            "experimental_features": {"msc3967_enabled": True},
         }
     )
-    def test_device_signing_with_msc3967(self) -> None:
-        """Device signing key follows MSC3967 behaviour when enabled."""
+    def test_device_signing_with_msc3967_via_config(self) -> None:
+        """Device signing key follows MSC3967 behaviour when enabled in config."""
         password = "wonderland"
         device_id = "ABCDEFGHI"
         alice_id = self.register_user("alice", password)
         alice_token = self.login("alice", password, device_id=device_id)
 
-        # enable msc3967 in db
-        self.get_success(
-            self.hs.get_datastores().main.set_features_for_user(
-                alice_id, {ExperimentalFeature.MSC3967: True}
-            )
+        keys1 = self.make_device_keys(alice_id, device_id)
+
+        # Initial request should succeed as no existing keys are present.
+        channel = self.make_request(
+            "POST",
+            "/_matrix/client/v3/keys/device_signing/upload",
+            keys1,
+            alice_token,
+        )
+        self.assertEqual(channel.code, HTTPStatus.OK, channel.result)
+
+        keys2 = self.make_device_keys(alice_id, device_id)
+
+        # Subsequent request should require UIA as keys already exist even though session_timeout is set.
+        channel = self.make_request(
+            "POST",
+            "/_matrix/client/v3/keys/device_signing/upload",
+            keys2,
+            alice_token,
+        )
+        self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.result)
+
+        # Grab the session
+        session = channel.json_body["session"]
+        # Ensure that flows are what is expected.
+        self.assertIn({"stages": ["m.login.password"]}, channel.json_body["flows"])
+
+        # add UI auth
+        keys2["auth"] = {
+            "type": "m.login.password",
+            "identifier": {"type": "m.id.user", "user": alice_id},
+            "password": password,
+            "session": session,
+        }
+
+        # Request should complete
+        channel = self.make_request(
+            "POST",
+            "/_matrix/client/v3/keys/device_signing/upload",
+            keys2,
+            alice_token,
+        )
+        self.assertEqual(channel.code, HTTPStatus.OK, channel.result)
+
+    @override_config(
+        {
+            "ui_auth": {"session_timeout": "15s"},
+        }
+    )
+    def test_device_signing_with_msc3967_via_admin(self) -> None:
+        """Device signing key follows MSC3967 behaviour when enabled for user via admin api."""
+        password = "wonderland"
+        device_id = "ABCDEFGHI"
+        alice_id = self.register_user("alice", password)
+        alice_token = self.login("alice", password, device_id=device_id)
+        self.register_user("admin", "pass", True)
+        admin_tok = self.login("admin", "pass")
+
+        url = f"/_synapse/admin/v1/experimental_features/{alice_id}"
+        channel = self.make_request(
+            "PUT",
+            url,
+            content={
+                "features": {"msc3967": True},
+            },
+            access_token=admin_tok,
         )
+        self.assertEqual(channel.code, 200)
 
         keys1 = self.make_device_keys(alice_id, device_id)