Merge pull request #1138 from p-l-/command-reset-ip-username

Add new management command `axes_reset_ip_username`
This commit is contained in:
Aleksi Häkli 2023-12-08 19:39:40 +02:00 committed by GitHub
commit 2a0fd0cfad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 3 deletions

View file

@ -0,0 +1,19 @@
from django.core.management.base import BaseCommand
from axes.utils import reset
class Command(BaseCommand):
help = "Reset all access attempts and lockouts for a given IP address and username"
def add_arguments(self, parser):
parser.add_argument("ip", type=str)
parser.add_argument("username", type=str)
def handle(self, *args, **options):
count = reset(ip=options["ip"], username=options["username"])
if count:
self.stdout.write(f"{count} attempts removed.")
else:
self.stdout.write("No attempts found.")

View file

@ -80,7 +80,7 @@ Resetting attempts from command line
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Axes offers a command line interface with
``axes_reset``, ``axes_reset_ip``, and ``axes_reset_username``
``axes_reset``, ``axes_reset_ip``, ``axes_reset_username``, and ``axes_reset_ip_username``
management commands with the Django ``manage.py`` or ``django-admin`` command helpers:
- ``python manage.py axes_reset``
@ -89,6 +89,8 @@ management commands with the Django ``manage.py`` or ``django-admin`` command he
will clear lockouts and records for the given IP addresses.
- ``python manage.py axes_reset_username [username ...]``
will clear lockouts and records for the given usernames.
- ``python manage.py axes_reset_ip_username [ip] [username]``
will clear lockouts and records for the given IP address and username.
- ``python manage.py axes_reset_logs (age)``
will reset (i.e. delete) AccessLog records that are older
than the given age where the default is 30 days.

View file

@ -56,18 +56,22 @@ class ManagementCommandTestCase(AxesTestCase):
username="john.doe", ip_address="10.0.0.2", failures_since_start="15"
)
AccessAttempt.objects.create(
username="richard.doe", ip_address="10.0.0.4", failures_since_start="12"
)
def test_axes_list_attempts(self):
out = StringIO()
call_command("axes_list_attempts", stdout=out)
expected = "10.0.0.1\tjane.doe\t4\n10.0.0.2\tjohn.doe\t15\n"
expected = "10.0.0.1\tjane.doe\t4\n10.0.0.2\tjohn.doe\t15\n10.0.0.4\trichard.doe\t12\n"
self.assertEqual(expected, out.getvalue())
def test_axes_reset(self):
out = StringIO()
call_command("axes_reset", stdout=out)
expected = "2 attempts removed.\n"
expected = "3 attempts removed.\n"
self.assertEqual(expected, out.getvalue())
def test_axes_reset_not_found(self):
@ -87,6 +91,13 @@ class ManagementCommandTestCase(AxesTestCase):
expected = "1 attempts removed.\n"
self.assertEqual(expected, out.getvalue())
def test_axes_reset_ip_username(self):
out = StringIO()
call_command("axes_reset_ip_username", "10.0.0.4", "richard.doe", stdout=out)
expected = "1 attempts removed.\n"
self.assertEqual(expected, out.getvalue())
def test_axes_reset_ip_not_found(self):
out = StringIO()
call_command("axes_reset_ip", "10.0.0.3", stdout=out)