From c7e79aeaf2afcf36041e13f9d79c8a4e9b26cb4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksi=20H=C3=A4kli?= Date: Sun, 23 Dec 2018 16:04:56 +0100 Subject: [PATCH 1/4] Remove unused AccessAttempt.trusted flag Fixes #344 --- axes/admin.py | 1 - axes/attempts.py | 25 ++++++++----------- .../0005_remove_accessattempt_trusted.py | 17 +++++++++++++ axes/models.py | 14 +++++------ 4 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 axes/migrations/0005_remove_accessattempt_trusted.py diff --git a/axes/admin.py b/axes/admin.py index 9c61ced..af416b3 100644 --- a/axes/admin.py +++ b/axes/admin.py @@ -47,7 +47,6 @@ class AccessAttemptAdmin(admin.ModelAdmin): 'user_agent', 'ip_address', 'username', - 'trusted', 'http_accept', 'path_info', 'attempt_time', diff --git a/axes/attempts.py b/axes/attempts.py index 4fe7725..bfbbbad 100644 --- a/axes/attempts.py +++ b/axes/attempts.py @@ -23,15 +23,15 @@ def _query_user_attempts(request, credentials=None): elif settings.AXES_USE_USER_AGENT: ua = request.META.get('HTTP_USER_AGENT', '')[:255] attempts = AccessAttempt.objects.filter( - user_agent=ua, ip_address=ip, username=username, trusted=True + user_agent=ua, ip_address=ip, username=username ) else: attempts = AccessAttempt.objects.filter( - ip_address=ip, username=username, trusted=True + ip_address=ip, username=username ) if not attempts: - params = {'trusted': False} + params = {} if settings.AXES_ONLY_USER_FAILURES: params['username'] = username @@ -109,18 +109,13 @@ def get_user_attempts(request, credentials=None): for attempt in attempts: if attempt.attempt_time + cool_off < timezone.now(): - if attempt.trusted: - attempt.failures_since_start = 0 - attempt.save() - get_axes_cache().set(cache_hash_key, 0, cache_timeout) - else: - attempt.delete() - force_reload = True - failures_cached = get_axes_cache().get(cache_hash_key) - if failures_cached is not None: - get_axes_cache().set( - cache_hash_key, failures_cached - 1, cache_timeout - ) + attempt.delete() + force_reload = True + failures_cached = get_axes_cache().get(cache_hash_key) + if failures_cached is not None: + get_axes_cache().set( + cache_hash_key, failures_cached - 1, cache_timeout + ) # If objects were deleted, we need to update the queryset to reflect this, # so force a reload. diff --git a/axes/migrations/0005_remove_accessattempt_trusted.py b/axes/migrations/0005_remove_accessattempt_trusted.py new file mode 100644 index 0000000..10db717 --- /dev/null +++ b/axes/migrations/0005_remove_accessattempt_trusted.py @@ -0,0 +1,17 @@ +# Generated by Django 2.1.4 on 2018-12-23 09:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('axes', '0004_auto_20181024_1538'), + ] + + operations = [ + migrations.RemoveField( + model_name='accessattempt', + name='trusted', + ), + ] diff --git a/axes/models.py b/axes/models.py index bc13844..2a6c1de 100644 --- a/axes/models.py +++ b/axes/models.py @@ -24,13 +24,6 @@ class CommonAccess(models.Model): db_index=True, ) - # Once a user logs in from an ip, that combination is trusted and not - # locked out in case of a distributed attack - trusted = models.BooleanField( - default=False, - db_index=True, - ) - http_accept = models.CharField( _('HTTP Accept'), max_length=1025, @@ -78,6 +71,13 @@ class AccessAttempt(CommonAccess): class AccessLog(CommonAccess): + # Once a user logs in from an ip, that combination is trusted and not + # locked out in case of a distributed attack + trusted = models.BooleanField( + default=False, + db_index=True, + ) + logout_time = models.DateTimeField( _('Logout Time'), null=True, From a785e3c58cbb5ce11b7db4c3b52788a684c71e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksi=20H=C3=A4kli?= Date: Tue, 25 Dec 2018 18:44:16 +0100 Subject: [PATCH 2/4] Run deploy to Jazzband only once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aleksi Häkli --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 76dbf43..d69a9c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ deploy: distributions: sdist bdist_wheel password: secure: TCH5tGIggL2wsWce2svMwpEpPiwVOYqq1R3uSBTexszleP0OafNq/wZk2KZEReR5w1Aq68qp5F5Eeh2ZjJTq4f9M4LtTvqQzrmyNP55DYk/uB1rBJm9b4gBgMtAknxdI2g7unkhQEDo4suuPCVofM7rrDughySNpmvlUQYDttHQ= + skip_existing: true on: tags: true repo: jazzband/django-axes From e42948f00672134b456721bf3a073df7e97aa427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksi=20H=C3=A4kli?= Date: Tue, 25 Dec 2018 18:46:35 +0100 Subject: [PATCH 3/4] Clean up .travis.yml field ordering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changing username or password will generate a convoluted patch if they are on multiple different lines if they are not grouped Signed-off-by: Aleksi Häkli --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d69a9c2..d99a75a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,10 +31,10 @@ after_success: deploy: provider: pypi user: jazzband - server: https://jazzband.co/projects/django-axes/upload - distributions: sdist bdist_wheel password: secure: TCH5tGIggL2wsWce2svMwpEpPiwVOYqq1R3uSBTexszleP0OafNq/wZk2KZEReR5w1Aq68qp5F5Eeh2ZjJTq4f9M4LtTvqQzrmyNP55DYk/uB1rBJm9b4gBgMtAknxdI2g7unkhQEDo4suuPCVofM7rrDughySNpmvlUQYDttHQ= + server: https://jazzband.co/projects/django-axes/upload + distributions: sdist bdist_wheel skip_existing: true on: tags: true From d9d6c313096033036db6372beb21babe199cf78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksi=20H=C3=A4kli?= Date: Tue, 25 Dec 2018 18:51:33 +0100 Subject: [PATCH 4/4] Improve README structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aleksi Häkli --- README.rst | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 8d90844..e72c604 100644 --- a/README.rst +++ b/README.rst @@ -25,11 +25,31 @@ sort of a geeky pun, since ``axes`` can be read interpreted as: definition) your website. Hilarious, right? That's what I thought too! +Documentation +------------- + For more information see the documentation at: https://django-axes.readthedocs.io/ -If you have questions or have trouble using the app please file a bug report -at: + +Issues +------ + +If you have questions or have trouble using the app please file a bug report at: https://github.com/jazzband/django-axes/issues + + +Contributing +------------ + +Open issues and pull requests against the ``development`` branch. + +Please separate proposed changes into small, different patches by type +so that they can be merged faster into upstream and released quicker: + +* Feature +* Bugfix +* Documentation +* Code style and whitespace