diff --git a/changelog.d/10881.bugfix b/changelog.d/10881.bugfix
new file mode 100644
index 0000000000..0a8905cc46
--- /dev/null
+++ b/changelog.d/10881.bugfix
@@ -0,0 +1 @@
+Fix application service users being subject to MAU blocking if MAU had been reached, even if configured not to be blocked.
diff --git a/synapse/api/auth_blocking.py b/synapse/api/auth_blocking.py
index a3b95f4de0..08fe160c98 100644
--- a/synapse/api/auth_blocking.py
+++ b/synapse/api/auth_blocking.py
@@ -81,7 +81,7 @@ class AuthBlocking:
# We never block the server from doing actions on behalf of
# users.
return
- elif requester.app_service and not self._track_appservice_user_ips:
+ if requester.app_service and not self._track_appservice_user_ips:
# If we're authenticated as an appservice then we only block
# auth if `track_appservice_user_ips` is set, as that option
# implicitly means that application services are part of MAU
diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py
index 8a4ef13054..cccff7af26 100644
--- a/tests/api/test_auth.py
+++ b/tests/api/test_auth.py
@@ -25,7 +25,9 @@ from synapse.api.errors import (
MissingClientTokenError,
ResourceLimitError,
)
+from synapse.appservice import ApplicationService
from synapse.storage.databases.main.registration import TokenLookupResult
+from synapse.types import Requester
from tests import unittest
from tests.test_utils import simple_async_mock
@@ -290,6 +292,66 @@ class AuthTestCase(unittest.HomeserverTestCase):
# Real users not allowed
self.get_failure(self.auth.check_auth_blocking(), ResourceLimitError)
+ def test_blocking_mau__appservice_requester_allowed_when_not_tracking_ips(self):
+ self.auth_blocking._max_mau_value = 50
+ self.auth_blocking._limit_usage_by_mau = True
+ self.auth_blocking._track_appservice_user_ips = False
+
+ self.store.get_monthly_active_count = simple_async_mock(100)
+ self.store.user_last_seen_monthly_active = simple_async_mock()
+ self.store.is_trial_user = simple_async_mock()
+
+ appservice = ApplicationService(
+ "abcd",
+ self.hs.config.server_name,
+ id="1234",
+ namespaces={
+ "users": [{"regex": "@_appservice.*:sender", "exclusive": True}]
+ },
+ sender="@appservice:sender",
+ )
+ requester = Requester(
+ user="@appservice:server",
+ access_token_id=None,
+ device_id="FOOBAR",
+ is_guest=False,
+ shadow_banned=False,
+ app_service=appservice,
+ authenticated_entity="@appservice:server",
+ )
+ self.get_success(self.auth.check_auth_blocking(requester=requester))
+
+ def test_blocking_mau__appservice_requester_disallowed_when_tracking_ips(self):
+ self.auth_blocking._max_mau_value = 50
+ self.auth_blocking._limit_usage_by_mau = True
+ self.auth_blocking._track_appservice_user_ips = True
+
+ self.store.get_monthly_active_count = simple_async_mock(100)
+ self.store.user_last_seen_monthly_active = simple_async_mock()
+ self.store.is_trial_user = simple_async_mock()
+
+ appservice = ApplicationService(
+ "abcd",
+ self.hs.config.server_name,
+ id="1234",
+ namespaces={
+ "users": [{"regex": "@_appservice.*:sender", "exclusive": True}]
+ },
+ sender="@appservice:sender",
+ )
+ requester = Requester(
+ user="@appservice:server",
+ access_token_id=None,
+ device_id="FOOBAR",
+ is_guest=False,
+ shadow_banned=False,
+ app_service=appservice,
+ authenticated_entity="@appservice:server",
+ )
+ self.get_failure(
+ self.auth.check_auth_blocking(requester=requester), ResourceLimitError
+ )
+
def test_reserved_threepid(self):
self.auth_blocking._limit_usage_by_mau = True
self.auth_blocking._max_mau_value = 1
|