diff options
author | H. Shay <hillerys@element.io> | 2023-05-10 09:05:19 -0700 |
---|---|---|
committer | H. Shay <hillerys@element.io> | 2023-05-10 09:05:19 -0700 |
commit | 7568c726d34b4e8b3602a73acac45ef76aaa4117 (patch) | |
tree | 8a2ad35c4157864ea296e4e5b1aa60cd8014e409 | |
parent | consolidate logic checking config and db to one place (diff) | |
download | synapse-7568c726d34b4e8b3602a73acac45ef76aaa4117.tar.xz |
test activation both by config and admin api
-rw-r--r-- | tests/handlers/test_presence.py | 77 | ||||
-rw-r--r-- | tests/push/test_http.py | 57 | ||||
-rw-r--r-- | tests/rest/client/test_keys.py | 79 |
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) |