Add DEFENDER_DISABLE_USERNAME_LOCKOUT

This commit is contained in:
Karimov Dmitriy 2016-06-20 09:20:47 +05:00
parent f5b40a1820
commit d85752970b
3 changed files with 23 additions and 6 deletions

View file

@ -310,6 +310,7 @@ record is created for the failed logins. [Default: ``3``]
[Default: ``False``]
* ``DEFENDER_LOCK_OUT_BY_IP_AND_USERNAME``: Boolean: Locks a user out based on a combination of IP and Username. This stops a user denying access to the application for all other users accessing the app from behind the same IP address. [Default: ``False``]
* ``DEFENDER_DISABLE_IP_LOCKOUT``: Boolean: If this is True, it will not lockout the users IP address, it will only lockout the username. [Default: False]
* ``DISABLE_USERNAME_LOCKOUT``: Boolean: If this is True, it will not lockout usernames, it will only lockout IP addresess. [Default: False]
* ``DEFENDER_COOLOFF_TIME``: Int: If set, defines a period of inactivity after which
old failed login attempts will be forgotten. An integer, will be interpreted as a
number of seconds. If ``0``, the locks will not expire. [Default: ``300``]

View file

@ -24,6 +24,10 @@ LOCKOUT_BY_IP_USERNAME = get_setting(
# there are too many login attempts.
DISABLE_IP_LOCKOUT = get_setting('DEFENDER_DISABLE_IP_LOCKOUT', False)
# If this is True, usernames will not get locked when
# there are too many login attempts.
DISABLE_USERNAME_LOCKOUT = get_setting('DEFENDER_DISABLE_USERNAME_LOCKOUT', False)
# use a specific username field to retrieve from login POST data
USERNAME_FORM_FIELD = get_setting('DEFENDER_USERNAME_FORM_FIELD', 'username')

View file

@ -97,6 +97,9 @@ def get_blocked_ips():
def get_blocked_usernames():
""" get a list of blocked usernames from redis """
if config.DISABLE_USERNAME_LOCKOUT:
# There are no blocked usernames since we disabled them.
return []
key = get_username_blocked_cache_key("*")
key_list = [redis_key.decode('utf-8')
for redis_key in REDIS_SERVER.keys(key)]
@ -156,6 +159,9 @@ def block_username(username):
if not username:
# no reason to continue when there is no username
return
if config.DISABLE_USERNAME_LOCKOUT:
# no need to block, we disabled it.
return
key = get_username_blocked_cache_key(username)
if config.COOLOFF_TIME:
REDIS_SERVER.set(key, 'blocked', config.COOLOFF_TIME)
@ -177,12 +183,12 @@ def record_failed_attempt(ip_address, username):
ip_block = True
user_block = False
user_count = increment_key(get_username_attempt_cache_key(username))
# if over the limit, add to block
if user_count > config.FAILURE_LIMIT:
block_username(username)
user_block = True
if not config.DISABLE_USERNAME_LOCKOUT:
user_count = increment_key(get_username_attempt_cache_key(username))
# if over the limit, add to block
if user_count > config.FAILURE_LIMIT:
block_username(username)
user_block = True
# if we have this turned on, then there is no reason to look at ip_block
# we will just look at user_block, and short circut the result since
@ -192,6 +198,10 @@ def record_failed_attempt(ip_address, username):
# we need to return False
return not user_block
if config.DISABLE_USERNAME_LOCKOUT:
# The same as DISABLE_IP_LOCKOUT
return not ip_block
# we want to make sure both the IP and user is blocked before we
# return False
# this is mostly used when a lot of your users are using proxies,
@ -267,6 +277,8 @@ def is_user_already_locked(username):
"""Is this username already locked?"""
if username is None:
return False
if config.DISABLE_USERNAME_LOCKOUT:
return False
return REDIS_SERVER.get(get_username_blocked_cache_key(username))