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()