diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py
index bd229cf7e9..751bf599ae 100644
--- a/tests/api/test_auth.py
+++ b/tests/api/test_auth.py
@@ -484,23 +484,6 @@ class AuthTestCase(unittest.HomeserverTestCase):
ResourceLimitError,
)
- def test_reserved_threepid(self) -> None:
- self.auth_blocking._limit_usage_by_mau = True
- self.auth_blocking._max_mau_value = 1
- self.store.get_monthly_active_count = AsyncMock(return_value=2)
- threepid = {"medium": "email", "address": "reserved@server.com"}
- unknown_threepid = {"medium": "email", "address": "unreserved@server.com"}
- self.auth_blocking._mau_limits_reserved_threepids = [threepid]
-
- self.get_failure(self.auth_blocking.check_auth_blocking(), ResourceLimitError)
-
- self.get_failure(
- self.auth_blocking.check_auth_blocking(threepid=unknown_threepid),
- ResourceLimitError,
- )
-
- self.get_success(self.auth_blocking.check_auth_blocking(threepid=threepid))
-
def test_hs_disabled(self) -> None:
self.auth_blocking._hs_disabled = True
self.auth_blocking._hs_disabled_message = "Reason for being disabled"
diff --git a/tests/api/test_ratelimiting.py b/tests/api/test_ratelimiting.py
index a59e168db1..93f4f98916 100644
--- a/tests/api/test_ratelimiting.py
+++ b/tests/api/test_ratelimiting.py
@@ -1,6 +1,10 @@
+from typing import Optional
+
from synapse.api.ratelimiting import LimitExceededError, Ratelimiter
from synapse.appservice import ApplicationService
from synapse.config.ratelimiting import RatelimitSettings
+from synapse.module_api import RatelimitOverride
+from synapse.module_api.callbacks.ratelimit_callbacks import RatelimitModuleApiCallbacks
from synapse.types import create_requester
from tests import unittest
@@ -220,9 +224,7 @@ class TestRatelimiter(unittest.HomeserverTestCase):
self.assertIn("test_id_1", limiter.actions)
- self.get_success_or_raise(
- limiter.can_do_action(None, key="test_id_2", _time_now_s=10)
- )
+ self.reactor.advance(60)
self.assertNotIn("test_id_1", limiter.actions)
@@ -442,3 +444,49 @@ class TestRatelimiter(unittest.HomeserverTestCase):
limiter.can_do_action(requester=None, key="a", _time_now_s=20.0)
)
self.assertTrue(success)
+
+ def test_get_ratelimit_override_for_user_callback(self) -> None:
+ test_user_id = "@user:test"
+ test_limiter_name = "name"
+ callbacks = RatelimitModuleApiCallbacks(self.hs)
+ requester = create_requester(test_user_id)
+ limiter = Ratelimiter(
+ store=self.hs.get_datastores().main,
+ clock=self.clock,
+ cfg=RatelimitSettings(
+ test_limiter_name,
+ per_second=0.1,
+ burst_count=3,
+ ),
+ ratelimit_callbacks=callbacks,
+ )
+
+ # Observe four actions, exceeding the burst_count.
+ limiter.record_action(requester=requester, n_actions=4, _time_now_s=0.0)
+
+ # We should be prevented from taking a new action now.
+ success, _ = self.get_success_or_raise(
+ limiter.can_do_action(requester=requester, _time_now_s=0.0)
+ )
+ self.assertFalse(success)
+
+ # Now register a callback that overrides the ratelimit for this user
+ # and limiter name.
+ async def get_ratelimit_override_for_user(
+ user_id: str, limiter_name: str
+ ) -> Optional[RatelimitOverride]:
+ if user_id == test_user_id:
+ return RatelimitOverride(
+ per_second=0.1,
+ burst_count=10,
+ )
+ return None
+
+ callbacks.register_callbacks(
+ get_ratelimit_override_for_user=get_ratelimit_override_for_user
+ )
+
+ success, _ = self.get_success_or_raise(
+ limiter.can_do_action(requester=requester, _time_now_s=0.0)
+ )
+ self.assertTrue(success)
diff --git a/tests/api/test_urls.py b/tests/api/test_urls.py
new file mode 100644
index 0000000000..ce156a05dc
--- /dev/null
+++ b/tests/api/test_urls.py
@@ -0,0 +1,55 @@
+#
+# This file is licensed under the Affero General Public License (AGPL) version 3.
+#
+# Copyright (C) 2024 New Vector, Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# See the GNU Affero General Public License for more details:
+# <https://www.gnu.org/licenses/agpl-3.0.html>.
+#
+
+
+from twisted.test.proto_helpers import MemoryReactor
+
+from synapse.api.urls import LoginSSORedirectURIBuilder
+from synapse.server import HomeServer
+from synapse.util import Clock
+
+from tests.unittest import HomeserverTestCase
+
+# a (valid) url with some annoying characters in. %3D is =, %26 is &, %2B is +
+TRICKY_TEST_CLIENT_REDIRECT_URL = 'https://x?<ab c>&q"+%3D%2B"="fö%26=o"'
+
+
+class LoginSSORedirectURIBuilderTestCase(HomeserverTestCase):
+ def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
+ self.login_sso_redirect_url_builder = LoginSSORedirectURIBuilder(hs.config)
+
+ def test_no_idp_id(self) -> None:
+ self.assertEqual(
+ self.login_sso_redirect_url_builder.build_login_sso_redirect_uri(
+ idp_id=None, client_redirect_url="http://example.com/redirect"
+ ),
+ "https://test/_matrix/client/v3/login/sso/redirect?redirectUrl=http%3A%2F%2Fexample.com%2Fredirect",
+ )
+
+ def test_explicit_idp_id(self) -> None:
+ self.assertEqual(
+ self.login_sso_redirect_url_builder.build_login_sso_redirect_uri(
+ idp_id="oidc-github", client_redirect_url="http://example.com/redirect"
+ ),
+ "https://test/_matrix/client/v3/login/sso/redirect/oidc-github?redirectUrl=http%3A%2F%2Fexample.com%2Fredirect",
+ )
+
+ def test_tricky_redirect_uri(self) -> None:
+ self.assertEqual(
+ self.login_sso_redirect_url_builder.build_login_sso_redirect_uri(
+ idp_id="oidc-github",
+ client_redirect_url=TRICKY_TEST_CLIENT_REDIRECT_URL,
+ ),
+ "https://test/_matrix/client/v3/login/sso/redirect/oidc-github?redirectUrl=https%3A%2F%2Fx%3F%3Cab+c%3E%26q%22%2B%253D%252B%22%3D%22f%C3%B6%2526%3Do%22",
+ )
|