From 2e292403814c2129cf95fc7d435916687be02733 Mon Sep 17 00:00:00 2001 From: Camilo Nova Date: Sat, 20 Apr 2013 18:39:59 -0500 Subject: [PATCH] Fixed an issue when a user on django 1.4 logout --- axes/decorators.py | 2 +- axes/signals.py | 38 ++++++++++++++++++-------------------- axes/tests.py | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/axes/decorators.py b/axes/decorators.py index 8510ff2..19ff487 100644 --- a/axes/decorators.py +++ b/axes/decorators.py @@ -133,7 +133,7 @@ def is_user_lockable(request): try: profile = user.get_profile() - except SiteProfileNotAvailable, ObjectDoesNotExist: + except (SiteProfileNotAvailable, ObjectDoesNotExist): # no profile return True diff --git a/axes/signals.py b/axes/signals.py index c7865d5..54e6b3d 100644 --- a/axes/signals.py +++ b/axes/signals.py @@ -1,36 +1,34 @@ -from django.dispatch import Signal, receiver +from django.dispatch import receiver +from django.dispatch import Signal +from django.utils.timezone import now from django.contrib.auth.signals import user_logged_out from django.core.exceptions import ObjectDoesNotExist + from axes.models import AccessLog -# django 1.4 has a new timezone aware now() use if available. -try: - from django.utils.timezone import now -except ImportError: - # fall back to none timezone aware now() - from datetime import datetime - now = datetime.now user_locked_out = Signal(providing_args=['request', 'username', 'ip_address']) + @receiver(user_logged_out) def log_user_lockout(sender, request, user, signal, *args, **kwargs): - """ When a user logs out, update the access log""" + """ When a user logs out, update the access log + """ if not user: return - access_log = None - access_logs = AccessLog.objects.filter(username=_get_username(user), - logout_time__isnull=True).order_by("-attempt_time") + try: + username = user.get_username() + except AttributeError: + # Django < 1.5 + username = user.username - if len(access_logs) > 0: + access_logs = AccessLog.objects.filter( + username=username, + logout_time__isnull=True, + ).order_by('-attempt_time') + + if access_logs: access_log = access_logs[0] - - if access_log: access_log.logout_time = now() access_log.save() - -def _get_username(user): - """With Django 1.5 for username can be used another field, for example e-mail.""" - return getattr(user, 'username', user.get_username()) - diff --git a/axes/tests.py b/axes/tests.py index 5a9f8b8..fe5aade 100644 --- a/axes/tests.py +++ b/axes/tests.py @@ -8,6 +8,7 @@ from django.test.utils import override_settings from axes.decorators import FAILURE_LIMIT from axes.decorators import LOGIN_FORM_KEY +from axes.models import AccessLog class AccessAttemptTest(TestCase): @@ -103,8 +104,27 @@ class AccessAttemptTest(TestCase): 'password': valid_username, 'this_is_the_login_form': 1, }) + self.assertNotIn(LOGIN_FORM_KEY, response.content) + def test_valid_logout(self): + """Tests a valid logout and make sure the logout_time is updated + """ + valid_username = self._random_username(existing_username=True) + response = self.client.post(reverse('admin:index'), { + 'username': valid_username, + 'password': valid_username, + 'this_is_the_login_form': 1, + }, follow=True) + + self.assertEquals(AccessLog.objects.latest('id').logout_time, None) + + response = self.client.get(reverse('admin:logout')) + + self.assertNotEquals(AccessLog.objects.latest('id').logout_time, None) + + self.assertIn('Logged out', response.content) + def test_long_user_agent_valid(self): """Tests if can handle a long user agent """