diff --git a/zerver/tests/test_external.py b/zerver/tests/test_external.py index b27571667d..8d67703bc6 100644 --- a/zerver/tests/test_external.py +++ b/zerver/tests/test_external.py @@ -244,6 +244,13 @@ class RateLimitTests(ZulipTestCase): self.assert_length(outbox, 0) + @rate_limit_rule(1, 5, domain="sends_email_by_ip") + def test_register_account_rate_limiting(self) -> None: + self.do_test_hit_ratelimits( + lambda: self.client_post("/register/", {"email": "new@zulip.com"}), + is_json=False, + ) + @rate_limit_rule(1, 5, domain="sends_email_by_ip") def test_combined_ip_limits(self) -> None: # Alternate requests to /new/ and /accounts/find/ diff --git a/zerver/views/registration.py b/zerver/views/registration.py index 0bd5b67ab7..0ca177054d 100644 --- a/zerver/views/registration.py +++ b/zerver/views/registration.py @@ -668,6 +668,17 @@ def accounts_home( if request.method == "POST": form = HomepageForm(request.POST, realm=realm, from_multiuse_invite=from_multiuse_invite) if form.is_valid(): + try: + rate_limit_request_by_ip(request, domain="sends_email_by_ip") + except RateLimited as e: + assert e.secs_to_freedom is not None + return render( + request, + "zerver/rate_limit_exceeded.html", + context={"retry_after": int(e.secs_to_freedom)}, + status=429, + ) + email = form.cleaned_data["email"] try: