Skip to content

Commit

Permalink
Merge pull request #1138 from p-l-/command-reset-ip-username
Browse files Browse the repository at this point in the history
Add new management command `axes_reset_ip_username`
  • Loading branch information
aleksihakli authored Dec 8, 2023
2 parents 73e2964 + 6e64c62 commit 2a0fd0c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
19 changes: 19 additions & 0 deletions axes/management/commands/axes_reset_ip_username.py
Original file line number Diff line number Diff line change
@@ -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.")
4 changes: 3 additions & 1 deletion docs/3_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``
Expand All @@ -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.
Expand Down
15 changes: 13 additions & 2 deletions tests/test_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,22 @@ def setUp(self):
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):
Expand All @@ -87,6 +91,13 @@ def test_axes_reset_ip(self):
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)
Expand Down

0 comments on commit 2a0fd0c

Please sign in to comment.