简体   繁体   中英

How do you test django-axes with a Django unit test?

I'm using Django Axes with my Django project to ensure that if someone is trying to guess a password, their IP gets blocked for a while.

It's setup, and works great.

I want to write a Django test that makes sure that after X number of guesses, the user is really locked out.

The problem I'm having is that if you try to use the django test client to do a login as you normally would:

self.client.login(username="invalid_user", password="invalid_password")

Axes crashes, because it isn't getting a request arg:

Traceback (most recent call last):
  File "/opt/my_project/website/login_app/tests/test_views.py", line 71, in test_brute_force_attempts
    self.client.login(username="invalid_user", password="invalid_password")
  File "/opt/my_project/venv3/lib/python3.6/site-packages/django/test/client.py", line 602, in login
    user = authenticate(**credentials)
  File "/opt/my_project/venv3/lib/python3.6/site-packages/django/contrib/auth/__init__.py", line 73, in authenticate
    user = backend.authenticate(request, **credentials)
  File "/opt/my_project/venv3/lib/python3.6/site-packages/axes/helpers.py", line 411, in inner
    return func(*args, **kwargs)
  File "/opt/my_project/venv3/lib/python3.6/site-packages/axes/backends.py", line 39, in authenticate
    "AxesBackend requires a request as an argument to authenticate"
axes.exceptions.AxesBackendRequestParameterRequired: AxesBackend requires a request as an argument to authenticate

This is a known issue, and is discussed here: https://github.com/jazzband/django-axes/issues/433

As far as I can tell, you just need to pass self.client.login a request= arg, which it will pass to django.contrib.auth.authenticate , and it'll be happy. I can't figure out where to get this request within a test method. I tried this, but it didn't work either:

class TestBruteForceAttempts(TestCase):
    def test_brute_force_attempts(self):
        login_attempts_to_make = django_settings.AXES_FAILURE_LIMIT + 1 

        for i in range(login_attempts_to_make):
            self.client.login(request=self.client.request(), username="invalid_user", password="invalid_password")
            ...

Is there any way to test Django Axes from a Django unit test? I'm clearly doing something wrong.

As stated in the Django Axes documentation , rather than using client.login you can directly call the Django authenticate function passing a mock request.

Something like this should do the trick:

from django.contrib.auth import authenticate
from django.http import HttpRequest

class TestBruteForceAttempts(TestCase):
    def test_brute_force_attempts(self):
        login_attempts_to_make = django_settings.AXES_FAILURE_LIMIT + 1

        for i in range(login_attempts_to_make):
            request = HttpRequest()
            authenticate(request, username="invalid_user", password="invalid_password")

        # Assert IP is blocked

You probably need to specify some information in the request, for example a fixed IP.

Alternatively, here you can see how the test you need is implemented in Django Axes, you could use the same approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM