mirror of
https://github.com/jazzband/django-defender.git
synced 2026-03-16 22:10:32 +00:00
* Allow decoration of functions beyond the admin login * Exclude tests file from coverage * Allow installing django 1.11 * Add python 3.6 for testing
54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
from . import utils
|
|
|
|
import functools
|
|
|
|
|
|
def watch_login(status_code=302, msg=''):
|
|
"""
|
|
Used to decorate the django.contrib.admin.site.login method or
|
|
any other function you want to protect by brute forcing.
|
|
To make it work on normal functions just pass the status code that should
|
|
indicate a failure and/or a string that will be checked within the
|
|
response body.
|
|
"""
|
|
def decorated_login(func):
|
|
@functools.wraps(func)
|
|
def wrapper(request, *args, **kwargs):
|
|
# if the request is currently under lockout, do not proceed to the
|
|
# login function, go directly to lockout url, do not pass go, do not
|
|
# collect messages about this login attempt
|
|
if utils.is_already_locked(request):
|
|
return utils.lockout_response(request)
|
|
|
|
# call the login function
|
|
response = func(request, *args, **kwargs)
|
|
|
|
if request.method == 'POST':
|
|
# see if the login was successful
|
|
if status_code == 302: # standard Django login view
|
|
login_unsuccessful = (
|
|
response and
|
|
not response.has_header('location') and
|
|
response.status_code != status_code
|
|
)
|
|
else:
|
|
# If msg is not passed the last condition will be evaluated
|
|
# always to True so the first 2 will decide the result.
|
|
login_unsuccessful = (
|
|
response and response.status_code == status_code
|
|
and msg in response.content.decode('utf-8')
|
|
)
|
|
|
|
# ideally make this background task, but to keep simple, keeping
|
|
# it inline for now.
|
|
utils.add_login_attempt_to_db(request, not login_unsuccessful)
|
|
|
|
if utils.check_request(request, login_unsuccessful):
|
|
return response
|
|
|
|
return utils.lockout_response(request)
|
|
|
|
return response
|
|
|
|
return wrapper
|
|
return decorated_login
|