summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorBrendan Abolivier <contact@brendanabolivier.com>2019-03-18 12:57:20 +0000
committerRichard van der Hoff <1389908+richvdh@users.noreply.github.com>2019-03-18 12:57:20 +0000
commit651ad8bc96d360500e7f5953d05ef418b51acc86 (patch)
treeeb02892a8aec9fb521e2fc5496d9e74985a04986 /tests
parentAdd ratelimiting on login (#4821) (diff)
downloadsynapse-651ad8bc96d360500e7f5953d05ef418b51acc86.tar.xz
Add ratelimiting on failed login attempts (#4865)
Diffstat (limited to 'tests')
-rw-r--r--tests/rest/client/v1/test_login.py45
-rw-r--r--tests/utils.py2
2 files changed, 47 insertions, 0 deletions
diff --git a/tests/rest/client/v1/test_login.py b/tests/rest/client/v1/test_login.py
index 4035f76cca..86312f1096 100644
--- a/tests/rest/client/v1/test_login.py
+++ b/tests/rest/client/v1/test_login.py
@@ -116,3 +116,48 @@ class LoginRestServletTestCase(unittest.HomeserverTestCase):
         self.render(request)
 
         self.assertEquals(channel.result["code"], b"200", channel.result)
+
+    def test_POST_ratelimiting_per_account_failed_attempts(self):
+        self.hs.config.rc_login_failed_attempts.burst_count = 5
+        self.hs.config.rc_login_failed_attempts.per_second = 0.17
+
+        self.register_user("kermit", "monkey")
+
+        for i in range(0, 6):
+            params = {
+                "type": "m.login.password",
+                "identifier": {
+                    "type": "m.id.user",
+                    "user": "kermit",
+                },
+                "password": "notamonkey",
+            }
+            request_data = json.dumps(params)
+            request, channel = self.make_request(b"POST", LOGIN_URL, request_data)
+            self.render(request)
+
+            if i == 5:
+                self.assertEquals(channel.result["code"], b"429", channel.result)
+                retry_after_ms = int(channel.json_body["retry_after_ms"])
+            else:
+                self.assertEquals(channel.result["code"], b"403", channel.result)
+
+        # Since we're ratelimiting at 1 request/min, retry_after_ms should be lower
+        # than 1min.
+        self.assertTrue(retry_after_ms < 6000)
+
+        self.reactor.advance(retry_after_ms / 1000.)
+
+        params = {
+            "type": "m.login.password",
+            "identifier": {
+                "type": "m.id.user",
+                "user": "kermit",
+            },
+            "password": "notamonkey",
+        }
+        request_data = json.dumps(params)
+        request, channel = self.make_request(b"POST", LOGIN_URL, params)
+        self.render(request)
+
+        self.assertEquals(channel.result["code"], b"403", channel.result)
diff --git a/tests/utils.py b/tests/utils.py
index a412736492..b58b674aa4 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -157,6 +157,8 @@ def default_config(name):
     config.rc_login_address.burst_count = 10000
     config.rc_login_account.per_second = 10000
     config.rc_login_account.burst_count = 10000
+    config.rc_login_failed_attempts.per_second = 10000
+    config.rc_login_failed_attempts.burst_count = 10000
     config.saml2_enabled = False
     config.public_baseurl = None
     config.default_identity_server = None