# HG changeset patch # User Oscar Cortez # Date 1674671062 18000 # Wed Jan 25 13:24:22 2023 -0500 # Node ID 89fffb32473e64276ca1a114bd2291a08e078227 # Parent 839574bf40f57622b92c34d588853645f31a9137 Prevent redirect loop when MAX_DURATION is used - Refs #67 diff --git a/impersonate/middleware.py b/impersonate/middleware.py --- a/impersonate/middleware.py +++ b/impersonate/middleware.py @@ -2,7 +2,7 @@ from datetime import datetime, timedelta from django.http import HttpResponseNotAllowed -from django.shortcuts import redirect +from django.shortcuts import redirect, reverse from django.utils import timezone from django.utils.deprecation import MiddlewareMixin from django.utils.functional import SimpleLazyObject @@ -26,6 +26,9 @@ if '_impersonate' in request.session and request.user.is_authenticated: if settings.MAX_DURATION: + if request.path == reverse('impersonate-stop'): + return + if '_impersonate_start' not in request.session: return diff --git a/impersonate/tests.py b/impersonate/tests.py --- a/impersonate/tests.py +++ b/impersonate/tests.py @@ -150,6 +150,31 @@ _impersonate_start=datetime.now(timezone.utc).timestamp() ) + @override_settings(IMPERSONATE={'MAX_DURATION': 5, 'REDIRECT_URL': '/foo/'}) + def test_impersonate_timeout_not_redirect_loop(self): + ''' Test to ensure that when MAX_DURATION is reached dont create a redirect loop. + See Issue #67 + ''' + self._impersonated_request( + _impersonate_start=datetime.now(timezone.utc).timestamp() + ) + # new request to see if the redirect to stop + request = self.factory.get('/') + request.user = self.superuser + past_time = datetime.now(timezone.utc) - timedelta(hours=1) + request.session = { + '_impersonate': self.user, + '_impersonate_start': past_time.timestamp(), + } + request = self.middleware.process_request(request) + # Check does the redirect to stop the impersonate + self.assertEqual(request.status_code, 302) + self.assertEqual(request.url, reverse('impersonate-stop')) + # Check impersonate stop redirects to the REDIRECT_URL + request = self.client.get(reverse('impersonate-stop')) + self.assertEqual(request.status_code, 302) + self.assertEqual(request.url, '/foo/') + @override_settings(IMPERSONATE={'MAX_DURATION': 3600}) def test_reject_without_start_time(self): ''' Test to ensure that requests without a start time