backends.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. from __future__ import unicode_literals
  2. from django.contrib.auth.backends import ModelBackend
  3. from django.core.exceptions import PermissionDenied
  4. from axes.attempts import is_already_locked
  5. from axes.utils import get_credentials, get_lockout_message
  6. class AxesModelBackend(ModelBackend):
  7. class RequestParameterRequired(Exception):
  8. msg = 'AxesModelBackend requires calls to authenticate to pass `request` as an argument.'
  9. def __init__(self):
  10. super(AxesModelBackend.RequestParameterRequired, self).__init__(
  11. AxesModelBackend.RequestParameterRequired.msg)
  12. def authenticate(self, request, username=None, password=None, **kwargs):
  13. """Checks user lock out status and raises PermissionDenied if user is not allowed to log in.
  14. Inserts errors directly to `return_context` that is supplied as a keyword argument.
  15. Use this on top of your AUTHENTICATION_BACKENDS list to prevent locked out users
  16. from being authenticated in the standard Django authentication flow.
  17. Note that this method does not log your user in and delegates login to other backends.
  18. :param request: see ModelBackend.authenticate
  19. :param kwargs: see ModelBackend.authenticate
  20. :keyword response_context: context dict that will be updated with error information
  21. :raises PermissionDenied: if user is already locked out
  22. :return: None
  23. """
  24. if request is None:
  25. raise AxesModelBackend.RequestParameterRequired()
  26. credentials = get_credentials(username=username, password=password, **kwargs)
  27. if is_already_locked(request, credentials):
  28. # locked out, don't try to authenticate, just update return_context and return
  29. # Its a bit weird to pass a context and expect a response value but its nice to get a "why" back.
  30. error_msg = get_lockout_message()
  31. response_context = kwargs.get('response_context', {})
  32. response_context['error'] = error_msg
  33. raise PermissionDenied(error_msg)
  34. # No-op