From fdbde59b0780ebb439ff9a7316c9941efcaf1f7f Mon Sep 17 00:00:00 2001 From: Mateusz Mandera Date: Tue, 17 Aug 2021 18:02:32 +0200 Subject: [PATCH] rate_limit: Add management command to reset auth rate limit. The auth attempt rate limit is quite low (on purpose), so this can be a common scenario where a user asks their admin to reset the limit instead of waiting. We should provide a tool for administrators to handle such requests without fiddling around with code in manage.py shell. --- docs/production/management-commands.md | 3 +++ .../commands/clear_auth_rate_limit_history.py | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 zerver/management/commands/clear_auth_rate_limit_history.py diff --git a/docs/production/management-commands.md b/docs/production/management-commands.md index 2035ecd365..fb83d1dade 100644 --- a/docs/production/management-commands.md +++ b/docs/production/management-commands.md @@ -132,6 +132,9 @@ There are dozens of useful management commands under For most purposes, deactivating users is preferred, since that does not alter message history for other users. See the `./manage.py delete_user --help` documentation for details. +* `./manage.py clear_auth_rate_limit_history`: If a user failed authenticaton + attempts too many times and further attempts are disallowed by the rate limiter, + this can be used to reset the limit. All of our management commands have internal documentation available via `manage.py command_name --help`. diff --git a/zerver/management/commands/clear_auth_rate_limit_history.py b/zerver/management/commands/clear_auth_rate_limit_history.py new file mode 100644 index 0000000000..48fe6614c0 --- /dev/null +++ b/zerver/management/commands/clear_auth_rate_limit_history.py @@ -0,0 +1,22 @@ +from argparse import ArgumentParser +from typing import Any + +from django.core.management.base import CommandError + +from zerver.lib.management import ZulipBaseCommand +from zproject.backends import RateLimitedAuthenticationByUsername + + +class Command(ZulipBaseCommand): + help = """Reset the rate limit for authentication attempts for username.""" + + def add_arguments(self, parser: ArgumentParser) -> None: + parser.add_argument("-u", "--username", help="Username to reset the rate limit for.") + + def handle(self, *args: Any, **options: Any) -> None: + if not options["username"]: + self.print_help("./manage.py", "clear_auth_rate_limit_history") + raise CommandError("Please enter a username") + + username = options["username"] + RateLimitedAuthenticationByUsername(username).clear_history()