summary refs log tree commit diff
path: root/tests/config/test_oauth_delegation.py
diff options
context:
space:
mode:
authorQuentin Gliech <quenting@element.io>2023-05-26 14:50:19 +0200
committerPatrick Cloke <clokep@users.noreply.github.com>2023-05-30 09:43:06 -0400
commit32a2f050042531ad4673b42789e833e9cd307740 (patch)
tree6df6ae800d27076ac4795d41c548b5ccad3d0016 /tests/config/test_oauth_delegation.py
parentReject tokens with multiple device scopes (diff)
downloadsynapse-32a2f050042531ad4673b42789e833e9cd307740.tar.xz
Make the config tests spawn the homeserver only when needed
Diffstat (limited to 'tests/config/test_oauth_delegation.py')
-rw-r--r--tests/config/test_oauth_delegation.py348
1 files changed, 154 insertions, 194 deletions
diff --git a/tests/config/test_oauth_delegation.py b/tests/config/test_oauth_delegation.py
index 6d294e0144..2ead721b00 100644
--- a/tests/config/test_oauth_delegation.py
+++ b/tests/config/test_oauth_delegation.py
@@ -12,15 +12,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from typing import Any, Dict
 from unittest.mock import Mock
 
 from synapse.config import ConfigError
+from synapse.config.homeserver import HomeServerConfig
 from synapse.module_api import ModuleApi
 from synapse.types import JsonDict
 
-from tests.server import get_clock
-from tests.unittest import HomeserverTestCase, override_config, skip_unless
+from tests.server import get_clock, setup_test_homeserver
+from tests.unittest import TestCase, skip_unless
+from tests.utils import default_config
 
 try:
     import authlib  # noqa: F401
@@ -51,45 +52,15 @@ class CustomAuthModule:
         )
 
 
-def _dict_merge(merge_dict: dict, into_dict: dict) -> None:
-    """Do a deep merge of two dicts
-
-    Recursively merges `merge_dict` into `into_dict`:
-      * For keys where both `merge_dict` and `into_dict` have a dict value, the values
-        are recursively merged
-      * For all other keys, the values in `into_dict` (if any) are overwritten with
-        the value from `merge_dict`.
-
-    Args:
-        merge_dict: dict to merge
-        into_dict: target dict to be modified
-    """
-    for k, v in merge_dict.items():
-        if k not in into_dict:
-            into_dict[k] = v
-            continue
-
-        current_val = into_dict[k]
-
-        if isinstance(v, dict) and isinstance(current_val, dict):
-            _dict_merge(v, current_val)
-            continue
-
-        # otherwise we just overwrite
-        into_dict[k] = v
-
-
 @skip_unless(HAS_AUTHLIB, "requires authlib")
-class MSC3861OAuthDelegation(HomeserverTestCase):
+class MSC3861OAuthDelegation(TestCase):
     """Test that the Homeserver fails to initialize if the config is invalid."""
 
     def setUp(self) -> None:
-        self.reactor, self.clock = get_clock()
-        self._hs_args = {"clock": self.clock, "reactor": self.reactor}
-
-    def default_config(self) -> Dict[str, Any]:
-        default_extra_config = {
+        self.config_dict: JsonDict = {
+            **default_config("test"),
             "public_baseurl": BASE_URL,
+            "enable_registration": False,
             "experimental_features": {
                 "msc3861": {
                     "enabled": True,
@@ -100,198 +71,187 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
                 }
             },
         }
-        _dict_merge(
-            {} if self._extra_config is None else self._extra_config,
-            default_extra_config,
-        )
-        self._extra_config = default_extra_config
-        return super().default_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-        }
-    )
+    def parse_config(self) -> HomeServerConfig:
+        config = HomeServerConfig()
+        config.parse_config_dict(self.config_dict, "", "")
+        return config
+
     def test_client_secret_post_works(self) -> None:
-        self.setup_test_homeserver()
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="client_secret_post",
+            client_secret=CLIENT_SECRET,
+        )
+
+        self.parse_config()
+
+    def test_client_secret_post_requires_client_secret(self) -> None:
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="client_secret_post",
+            client_secret=None,
+        )
+
+        with self.assertRaises(ConfigError):
+            self.parse_config()
+
+    def test_client_secret_basic_works(self) -> None:
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="client_secret_basic",
+            client_secret=CLIENT_SECRET,
+        )
+
+        self.parse_config()
+
+    def test_client_secret_basic_requires_client_secret(self) -> None:
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="client_secret_basic",
+            client_secret=None,
+        )
+
+        with self.assertRaises(ConfigError):
+            self.parse_config()
+
+    def test_client_secret_jwt_works(self) -> None:
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="client_secret_jwt",
+            client_secret=CLIENT_SECRET,
+        )
+
+        self.parse_config()
+
+    def test_client_secret_jwt_requires_client_secret(self) -> None:
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="client_secret_jwt",
+            client_secret=None,
+        )
+
+        with self.assertRaises(ConfigError):
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "experimental_features": {
-                "msc3861": {
-                    "client_auth_method": "invalid",
-                }
-            },
-        }
-    )
     def test_invalid_client_auth_method(self) -> None:
-        with self.assertRaises(ValueError):
-            self.setup_test_homeserver()
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="invalid",
+        )
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "experimental_features": {
-                "msc3861": {
-                    "client_auth_method": "private_key_jwt",
-                }
-            },
-        }
-    )
-    def test_invalid_private_key_jwt(self) -> None:
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
+
+    def test_private_key_jwt_requires_jwk(self) -> None:
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="private_key_jwt",
+        )
+
+        with self.assertRaises(ConfigError):
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "experimental_features": {
-                "msc3861": {
-                    "client_auth_method": "private_key_jwt",
-                    "jwk": {
-                        "p": "-frVdP_tZ-J_nIR6HNMDq1N7aunwm51nAqNnhqIyuA8ikx7LlQED1tt2LD3YEvYyW8nxE2V95HlCRZXQPMiRJBFOsbmYkzl2t-MpavTaObB_fct_JqcRtdXddg4-_ihdjRDwUOreq_dpWh6MIKsC3UyekfkHmeEJg5YpOTL15j8",
-                        "kty": "RSA",
-                        "q": "oFw-Enr_YozQB1ab-kawn4jY3yHi8B1nSmYT0s8oTCflrmps5BFJfCkHL5ij3iY15z0o2m0N-jjB1oSJ98O4RayEEYNQlHnTNTl0kRIWzpoqblHUIxVcahIpP_xTovBJzwi8XXoLGqHOOMA-r40LSyVgP2Ut8D9qBwV6_UfT0LU",
-                        "d": "WFkDPYo4b4LIS64D_QtQfGGuAObPvc3HFfp9VZXyq3SJR58XZRHE0jqtlEMNHhOTgbMYS3w8nxPQ_qVzY-5hs4fIanwvB64mAoOGl0qMHO65DTD_WsGFwzYClJPBVniavkLE2Hmpu8IGe6lGliN8vREC6_4t69liY-XcN_ECboVtC2behKkLOEASOIMuS7YcKAhTJFJwkl1dqDlliEn5A4u4xy7nuWQz3juB1OFdKlwGA5dfhDNglhoLIwNnkLsUPPFO-WB5ZNEW35xxHOToxj4bShvDuanVA6mJPtTKjz0XibjB36bj_nF_j7EtbE2PdGJ2KevAVgElR4lqS4ISgQ",
-                        "e": "AQAB",
-                        "kid": "test",
-                        "qi": "cPfNk8l8W5exVNNea4d7QZZ8Qr8LgHghypYAxz8PQh1fNa8Ya1SNUDVzC2iHHhszxxA0vB9C7jGze8dBrvnzWYF1XvQcqNIVVgHhD57R1Nm3dj2NoHIKe0Cu4bCUtP8xnZQUN4KX7y4IIcgRcBWG1hT6DEYZ4BxqicnBXXNXAUI",
-                        "dp": "dKlMHvslV1sMBQaKWpNb3gPq0B13TZhqr3-E2_8sPlvJ3fD8P4CmwwnOn50JDuhY3h9jY5L06sBwXjspYISVv8hX-ndMLkEeF3lrJeA5S70D8rgakfZcPIkffm3tlf1Ok3v5OzoxSv3-67Df4osMniyYwDUBCB5Oq1tTx77xpU8",
-                        "dq": "S4ooU1xNYYcjl9FcuJEEMqKsRrAXzzSKq6laPTwIp5dDwt2vXeAm1a4eDHXC-6rUSZGt5PbqVqzV4s-cjnJMI8YYkIdjNg4NSE1Ac_YpeDl3M3Colb5CQlU7yUB7xY2bt0NOOFp9UJZYJrOo09mFMGjy5eorsbitoZEbVqS3SuE",
-                        "n": "nJbYKqFwnURKimaviyDFrNLD3gaKR1JW343Qem25VeZxoMq1665RHVoO8n1oBm4ClZdjIiZiVdpyqzD5-Ow12YQgQEf1ZHP3CCcOQQhU57Rh5XvScTe5IxYVkEW32IW2mp_CJ6WfjYpfeL4azarVk8H3Vr59d1rSrKTVVinVdZer9YLQyC_rWAQNtHafPBMrf6RYiNGV9EiYn72wFIXlLlBYQ9Fx7bfe1PaL6qrQSsZP3_rSpuvVdLh1lqGeCLR0pyclA9uo5m2tMyCXuuGQLbA_QJm5xEc7zd-WFdux2eXF045oxnSZ_kgQt-pdN7AxGWOVvwoTf9am6mSkEdv6iw",
-                    },
-                }
-            },
-        }
-    )
     def test_private_key_jwt_works(self) -> None:
-        self.setup_test_homeserver()
+        self.config_dict["experimental_features"]["msc3861"].update(
+            client_auth_method="private_key_jwt",
+            jwk={
+                "p": "-frVdP_tZ-J_nIR6HNMDq1N7aunwm51nAqNnhqIyuA8ikx7LlQED1tt2LD3YEvYyW8nxE2V95HlCRZXQPMiRJBFOsbmYkzl2t-MpavTaObB_fct_JqcRtdXddg4-_ihdjRDwUOreq_dpWh6MIKsC3UyekfkHmeEJg5YpOTL15j8",
+                "kty": "RSA",
+                "q": "oFw-Enr_YozQB1ab-kawn4jY3yHi8B1nSmYT0s8oTCflrmps5BFJfCkHL5ij3iY15z0o2m0N-jjB1oSJ98O4RayEEYNQlHnTNTl0kRIWzpoqblHUIxVcahIpP_xTovBJzwi8XXoLGqHOOMA-r40LSyVgP2Ut8D9qBwV6_UfT0LU",
+                "d": "WFkDPYo4b4LIS64D_QtQfGGuAObPvc3HFfp9VZXyq3SJR58XZRHE0jqtlEMNHhOTgbMYS3w8nxPQ_qVzY-5hs4fIanwvB64mAoOGl0qMHO65DTD_WsGFwzYClJPBVniavkLE2Hmpu8IGe6lGliN8vREC6_4t69liY-XcN_ECboVtC2behKkLOEASOIMuS7YcKAhTJFJwkl1dqDlliEn5A4u4xy7nuWQz3juB1OFdKlwGA5dfhDNglhoLIwNnkLsUPPFO-WB5ZNEW35xxHOToxj4bShvDuanVA6mJPtTKjz0XibjB36bj_nF_j7EtbE2PdGJ2KevAVgElR4lqS4ISgQ",
+                "e": "AQAB",
+                "kid": "test",
+                "qi": "cPfNk8l8W5exVNNea4d7QZZ8Qr8LgHghypYAxz8PQh1fNa8Ya1SNUDVzC2iHHhszxxA0vB9C7jGze8dBrvnzWYF1XvQcqNIVVgHhD57R1Nm3dj2NoHIKe0Cu4bCUtP8xnZQUN4KX7y4IIcgRcBWG1hT6DEYZ4BxqicnBXXNXAUI",
+                "dp": "dKlMHvslV1sMBQaKWpNb3gPq0B13TZhqr3-E2_8sPlvJ3fD8P4CmwwnOn50JDuhY3h9jY5L06sBwXjspYISVv8hX-ndMLkEeF3lrJeA5S70D8rgakfZcPIkffm3tlf1Ok3v5OzoxSv3-67Df4osMniyYwDUBCB5Oq1tTx77xpU8",
+                "dq": "S4ooU1xNYYcjl9FcuJEEMqKsRrAXzzSKq6laPTwIp5dDwt2vXeAm1a4eDHXC-6rUSZGt5PbqVqzV4s-cjnJMI8YYkIdjNg4NSE1Ac_YpeDl3M3Colb5CQlU7yUB7xY2bt0NOOFp9UJZYJrOo09mFMGjy5eorsbitoZEbVqS3SuE",
+                "n": "nJbYKqFwnURKimaviyDFrNLD3gaKR1JW343Qem25VeZxoMq1665RHVoO8n1oBm4ClZdjIiZiVdpyqzD5-Ow12YQgQEf1ZHP3CCcOQQhU57Rh5XvScTe5IxYVkEW32IW2mp_CJ6WfjYpfeL4azarVk8H3Vr59d1rSrKTVVinVdZer9YLQyC_rWAQNtHafPBMrf6RYiNGV9EiYn72wFIXlLlBYQ9Fx7bfe1PaL6qrQSsZP3_rSpuvVdLh1lqGeCLR0pyclA9uo5m2tMyCXuuGQLbA_QJm5xEc7zd-WFdux2eXF045oxnSZ_kgQt-pdN7AxGWOVvwoTf9am6mSkEdv6iw",
+            },
+        )
+        self.parse_config()
 
     def test_registration_cannot_be_enabled(self) -> None:
+        self.config_dict["enable_registration"] = True
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "password_config": {
-                "enabled": True,
-            },
-        }
-    )
     def test_password_config_cannot_be_enabled(self) -> None:
+        self.config_dict["password_config"] = {"enabled": True}
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "oidc_providers": [
-                {
-                    "idp_id": "microsoft",
-                    "idp_name": "Microsoft",
-                    "issuer": "https://login.microsoftonline.com/<tenant id>/v2.0",
-                    "client_id": "<client id>",
-                    "client_secret": "<client secret>",
-                    "scopes": ["openid", "profile"],
-                    "authorization_endpoint": "https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/authorize",
-                    "token_endpoint": "https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token",
-                    "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo",
-                }
-            ],
-        }
-    )
     def test_oidc_sso_cannot_be_enabled(self) -> None:
+        self.config_dict["oidc_providers"] = [
+            {
+                "idp_id": "microsoft",
+                "idp_name": "Microsoft",
+                "issuer": "https://login.microsoftonline.com/<tenant id>/v2.0",
+                "client_id": "<client id>",
+                "client_secret": "<client secret>",
+                "scopes": ["openid", "profile"],
+                "authorization_endpoint": "https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/authorize",
+                "token_endpoint": "https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token",
+                "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo",
+            }
+        ]
+
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "cas_config": {
-                "enabled": True,
-                "server_url": "https://cas-server.com",
-                "displayname_attribute": "name",
-                "required_attributes": {"userGroup": "staff", "department": "None"},
-            },
-        }
-    )
     def test_cas_sso_cannot_be_enabled(self) -> None:
+        self.config_dict["cas_config"] = {
+            "enabled": True,
+            "server_url": "https://cas-server.com",
+            "displayname_attribute": "name",
+            "required_attributes": {"userGroup": "staff", "department": "None"},
+        }
+
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "modules": [
-                {
-                    "module": f"{__name__}.{CustomAuthModule.__qualname__}",
-                    "config": {},
-                }
-            ],
-        }
-    )
     def test_auth_providers_cannot_be_enabled(self) -> None:
+        self.config_dict["modules"] = [
+            {
+                "module": f"{__name__}.{CustomAuthModule.__qualname__}",
+                "config": {},
+            }
+        ]
+
+        # This requires actually setting up an HS, as the module will be run on setup,
+        # which should raise as the module tries to register an auth provider
+        config = self.parse_config()
+        reactor, clock = get_clock()
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            setup_test_homeserver(
+                self.addCleanup, reactor=reactor, clock=clock, config=config
+            )
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "jwt_config": {
-                "enabled": True,
-                "secret": "my-secret-token",
-                "algorithm": "HS256",
-            },
-        }
-    )
     def test_jwt_auth_cannot_be_enabled(self) -> None:
+        self.config_dict["jwt_config"] = {
+            "enabled": True,
+            "secret": "my-secret-token",
+            "algorithm": "HS256",
+        }
+
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "experimental_features": {
-                "msc3882_enabled": True,
-            },
-        }
-    )
     def test_msc3882_auth_cannot_be_enabled(self) -> None:
+        self.config_dict["experimental_features"]["msc3882_enabled"] = True
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "recaptcha_public_key": "test",
-            "recaptcha_private_key": "test",
-            "enable_registration_captcha": True,
-        }
-    )
     def test_captcha_cannot_be_enabled(self) -> None:
+        self.config_dict.update(
+            enable_registration_captcha=True,
+            recaptcha_public_key="test",
+            recaptcha_private_key="test",
+        )
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "refresh_token_lifetime": "24h",
-            "refreshable_access_token_lifetime": "10m",
-            "nonrefreshable_access_token_lifetime": "24h",
-        }
-    )
     def test_refreshable_tokens_cannot_be_enabled(self) -> None:
+        self.config_dict.update(
+            refresh_token_lifetime="24h",
+            refreshable_access_token_lifetime="10m",
+            nonrefreshable_access_token_lifetime="24h",
+        )
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()
 
-    @override_config(
-        {
-            "enable_registration": False,
-            "session_lifetime": "24h",
-        }
-    )
     def test_session_lifetime_cannot_be_set(self) -> None:
+        self.config_dict["session_lifetime"] = "24h"
         with self.assertRaises(ConfigError):
-            self.setup_test_homeserver()
+            self.parse_config()