From 6e3245ffee435d62ee08542163c27e94f8c46d37 Mon Sep 17 00:00:00 2001 From: bgmiles Date: Tue, 26 Mar 2019 14:33:50 -0400 Subject: [PATCH 1/4] - Added helper function for making timestamps timezone aware if the UZE_TZ Django setting is true --- useraudit/models.py | 13 +++++++++++-- useraudit_testapp/tests.py | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/useraudit/models.py b/useraudit/models.py index 0a0f788..4e41162 100644 --- a/useraudit/models.py +++ b/useraudit/models.py @@ -2,6 +2,8 @@ import datetime import logging from django.db import models +from django.utils import timezone +from django.conf import settings from django.contrib.auth.signals import user_logged_in from .signals import password_has_expired, account_has_expired, login_failure_limit_reached @@ -20,16 +22,23 @@ class LoginAttemptLogger(object): def reset(self, username): defaults = { 'count': 0, - 'timestamp': datetime.datetime.now() + 'timestamp': self.generate_timestamp() } LoginAttempt.objects.update_or_create(username=username, defaults=defaults) def increment(self, username): obj, created = LoginAttempt.objects.get_or_create(username=username) obj.count += 1 - obj.timestamp = datetime.datetime.now() + obj.timestamp = self.generate_timestamp() obj.save() + def generate_timestamp(self): + use_tz = getattr(settings, "USE_TZ", False) + if use_tz: + return timezone.localtime() + else: + return datetime.datetime.now() + class Log(models.Model): class Meta: diff --git a/useraudit_testapp/tests.py b/useraudit_testapp/tests.py index f7973d8..94b7bca 100644 --- a/useraudit_testapp/tests.py +++ b/useraudit_testapp/tests.py @@ -18,7 +18,7 @@ import useraudit_testapp.urls import useraudit.password_expiry from useraudit.signals import login_failure_limit_reached, password_has_expired, account_has_expired, password_will_expire_warning -from useraudit.models import UserDeactivation +from useraudit.models import UserDeactivation, LoginAttempt # Saving a reference to the USER_MODEL set in the settings.py file # Our pre_save handler in password_expiry.py gets registered just for this sender @@ -451,6 +451,39 @@ def handler(sender, user=None, **kwargs): self.assertTrue(self.handler_called) +class LoginAttemtpsTimestampTestCase(TestCase): + username = "testuser" + password = "testuser" + + def setUp(self): + self.user = User.objects.create( + username=self.username, + email="testuser@localhost", + ) + self.user.set_password(self.password) + self.user.save() + + def tearDown(self): + self.user.delete() + + @override_settings(USE_TZ=False) + def test_timestamp_naive(self): + _ = authenticate(username=self.username, password="INCORRECT") + _ = authenticate(username=self.username, password="INCORRECT") + login_attempt = LoginAttempt.objects.get(username=self.username) + + is_naive = login_attempt.timestamp.tzinfo is None or login_attempt.tzinfo.utcoffset(login_attempt) is None + self.assertTrue(is_naive) + + @override_settings(USE_TZ=True) + def test_timestamp_aware(self): + _ = authenticate(username=self.username, password="INCORRECT") + _ = authenticate(username=self.username, password="INCORRECT") + login_attempt = LoginAttempt.objects.get(username=self.username) + + is_aware = login_attempt.timestamp.tzinfo is not None or login_attempt.tzinfo.utcoffset(login_attempt) is not None + self.assertTrue(is_aware) + class MiddlewareTestCase(TestCase): From f9136cb870cd5d2c4ff9fc0b6d180441b3152834 Mon Sep 17 00:00:00 2001 From: bgmiles Date: Tue, 26 Mar 2019 15:11:43 -0400 Subject: [PATCH 2/4] - Fixed test case for timezone aware timestamp --- useraudit_testapp/tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/useraudit_testapp/tests.py b/useraudit_testapp/tests.py index 94b7bca..38caa74 100644 --- a/useraudit_testapp/tests.py +++ b/useraudit_testapp/tests.py @@ -472,7 +472,8 @@ def test_timestamp_naive(self): _ = authenticate(username=self.username, password="INCORRECT") login_attempt = LoginAttempt.objects.get(username=self.username) - is_naive = login_attempt.timestamp.tzinfo is None or login_attempt.tzinfo.utcoffset(login_attempt) is None + timestamp = login_attempt.timestamp + is_naive = timestamp.tzinfo is None or timestamp.tzinfo.utcoffset(timestamp) is None self.assertTrue(is_naive) @override_settings(USE_TZ=True) @@ -481,7 +482,8 @@ def test_timestamp_aware(self): _ = authenticate(username=self.username, password="INCORRECT") login_attempt = LoginAttempt.objects.get(username=self.username) - is_aware = login_attempt.timestamp.tzinfo is not None or login_attempt.tzinfo.utcoffset(login_attempt) is not None + timestamp = login_attempt.timestamp + is_aware = timestamp.tzinfo is not None and timestamp.tzinfo.utcoffset(timestamp) is not None self.assertTrue(is_aware) From 368385593b2c5370e52379bbfc21142015d26b44 Mon Sep 17 00:00:00 2001 From: bgmiles Date: Wed, 27 Mar 2019 11:47:11 -0400 Subject: [PATCH 3/4] - Django always stores DateTimeField in UTC --- useraudit/models.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/useraudit/models.py b/useraudit/models.py index 4e41162..d2832f9 100644 --- a/useraudit/models.py +++ b/useraudit/models.py @@ -22,23 +22,16 @@ class LoginAttemptLogger(object): def reset(self, username): defaults = { 'count': 0, - 'timestamp': self.generate_timestamp() + 'timestamp': timezone.now() } LoginAttempt.objects.update_or_create(username=username, defaults=defaults) def increment(self, username): obj, created = LoginAttempt.objects.get_or_create(username=username) obj.count += 1 - obj.timestamp = self.generate_timestamp() + obj.timestamp = timezone.now() obj.save() - def generate_timestamp(self): - use_tz = getattr(settings, "USE_TZ", False) - if use_tz: - return timezone.localtime() - else: - return datetime.datetime.now() - class Log(models.Model): class Meta: From 8a2751dd89de27b555e9290576d326d3739ab15d Mon Sep 17 00:00:00 2001 From: bgmiles Date: Wed, 3 Apr 2019 11:04:32 -0400 Subject: [PATCH 4/4] - Removed import that is not used --- useraudit/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/useraudit/models.py b/useraudit/models.py index d2832f9..ab15423 100644 --- a/useraudit/models.py +++ b/useraudit/models.py @@ -3,7 +3,6 @@ import logging from django.db import models from django.utils import timezone -from django.conf import settings from django.contrib.auth.signals import user_logged_in from .signals import password_has_expired, account_has_expired, login_failure_limit_reached