diff --git a/AUTHORS b/AUTHORS index 3c1cd81639..eff6e4c602 100644 --- a/AUTHORS +++ b/AUTHORS @@ -606,6 +606,7 @@ answer newbie questions, and generally made Django that much better: Jarek Zgoda Cheng Zhang Hannes Struß + Deric Crago A big THANK YOU goes to: diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 07d1ec7804..8345543707 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -2,7 +2,7 @@ from functools import update_wrapper from django.http import Http404, HttpResponseRedirect from django.contrib.admin import ModelAdmin, actions from django.contrib.admin.forms import AdminAuthenticationForm -from django.contrib.auth import REDIRECT_FIELD_NAME +from django.contrib.auth import logout as auth_logout, REDIRECT_FIELD_NAME from django.contrib.contenttypes import views as contenttype_views from django.views.decorators.csrf import csrf_protect from django.db.models.base import ModelBase @@ -193,6 +193,8 @@ class AdminSite(object): cacheable=True. """ def inner(request, *args, **kwargs): + if LOGIN_FORM_KEY in request.POST and request.user.is_authenticated(): + auth_logout(request) if not self.has_permission(request): if request.path == reverse('admin:logout', current_app=self.name): diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 5c9699792b..203d7d624b 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -6,7 +6,7 @@ import re import datetime try: from urllib.parse import urljoin -except ImportError: # Python 2 +except ImportError: # Python 2 from urlparse import urljoin from django.conf import settings, global_settings @@ -981,6 +981,32 @@ class AdminViewPermissionsTest(TestCase): login = self.client.post('/test_admin/admin/', dict(self.super_login, **new_next), QUERY_STRING=query_string) self.assertRedirects(login, redirect_url) + def testDoubleLoginIsNotAllowed(self): + """Regression test for #19327""" + response = self.client.get('/test_admin/admin/') + self.assertEqual(response.status_code, 200) + + # Establish a valid admin session + login = self.client.post('/test_admin/admin/', self.super_login) + self.assertRedirects(login, '/test_admin/admin/') + self.assertFalse(login.context) + + # Logging in with non-admin user fails + login = self.client.post('/test_admin/admin/', self.joepublic_login) + self.assertEqual(login.status_code, 200) + self.assertContains(login, ERROR_MESSAGE) + + # Establish a valid admin session + login = self.client.post('/test_admin/admin/', self.super_login) + self.assertRedirects(login, '/test_admin/admin/') + self.assertFalse(login.context) + + # Logging in with admin user while already logged in + login = self.client.post('/test_admin/admin/', self.super_login) + self.assertRedirects(login, '/test_admin/admin/') + self.assertFalse(login.context) + self.client.get('/test_admin/admin/logout/') + def testAddView(self): """Test add view restricts access and actually adds items.""" @@ -2547,7 +2573,7 @@ class AdminCustomQuerysetTest(TestCase): self.assertNotContains(response, 'Primary key = %s' % i) def test_changelist_view_count_queries(self): - #create 2 Person objects + # create 2 Person objects Person.objects.create(name='person1', gender=1) Person.objects.create(name='person2', gender=2)