diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index 10b82af0a4..d3ce7f181d 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -139,7 +139,7 @@ class AdminSite(object):
Returns True if the given HttpRequest has permission to view
*at least one* page in the admin site.
"""
- return request.user.is_staff
+ return request.user.is_active and request.user.is_staff
def check_dependencies(self):
"""
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
index a9d281641a..d1216a114e 100644
--- a/django/contrib/admin/templates/admin/base.html
+++ b/django/contrib/admin/templates/admin/base.html
@@ -22,7 +22,7 @@
{% block branding %}{% endblock %}
- {% if user.is_staff %}
+ {% if user.is_active and user.is_staff %}
{% trans 'Welcome,' %}
{% firstof user.first_name user.username %}.
diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py
index d28186e4e7..fc8582b1b8 100644
--- a/django/contrib/admin/views/decorators.py
+++ b/django/contrib/admin/views/decorators.py
@@ -28,7 +28,7 @@ def staff_member_required(view_func):
member, displaying the login page if necessary.
"""
def _checklogin(request, *args, **kwargs):
- if request.user.is_staff:
+ if request.user.is_active and request.user.is_staff:
# The user is valid. Continue to the admin page.
return view_func(request, *args, **kwargs)
diff --git a/django/contrib/auth/tests/auth_backends.py b/django/contrib/auth/tests/auth_backends.py
index af15d0b03b..3ab80f623c 100644
--- a/django/contrib/auth/tests/auth_backends.py
+++ b/django/contrib/auth/tests/auth_backends.py
@@ -29,6 +29,11 @@ class BackendTest(TestCase):
user.is_superuser = False
user.save()
self.assertEqual(user.has_perm('auth.test'), False)
+ user.is_staff = True
+ user.is_superuser = True
+ user.is_active = False
+ user.save()
+ self.assertEqual(user.has_perm('auth.test'), False)
def test_custom_perms(self):
user = User.objects.get(username='test')
diff --git a/django/core/xheaders.py b/django/core/xheaders.py
index 34335f12c5..b650a3a6d4 100644
--- a/django/core/xheaders.py
+++ b/django/core/xheaders.py
@@ -18,7 +18,7 @@ def populate_xheaders(request, response, model, object_id):
"""
from django.conf import settings
if (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
- or (hasattr(request, 'user') and request.user.is_authenticated()
+ or (hasattr(request, 'user') and request.user.is_active
and request.user.is_staff)):
response['X-Object-Type'] = "%s.%s" % (model._meta.app_label, model._meta.object_name.lower())
response['X-Object-Id'] = str(object_id)
diff --git a/django/middleware/doc.py b/django/middleware/doc.py
index 2b4e6827f8..4f91503c43 100644
--- a/django/middleware/doc.py
+++ b/django/middleware/doc.py
@@ -12,7 +12,8 @@ class XViewMiddleware(object):
indicating the view function. This is used by the documentation module
to lookup the view function for an arbitrary page.
"""
- if request.method == 'HEAD' and (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or request.user.is_staff):
+ if request.method == 'HEAD' and (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or
+ (request.user.is_active and request.user.is_staff)):
response = http.HttpResponse()
response['X-View'] = "%s.%s" % (view_func.__module__, view_func.__name__)
return response
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 899fff80bc..06cb3deef8 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -602,6 +602,20 @@ class AdminViewPermissionsTest(TestCase):
self.failUnlessEqual(logged.object_id, u'1')
self.client.get('/test_admin/admin/logout/')
+ def testDisabledPermissionsWhenLoggedIn(self):
+ self.client.login(username='super', password='secret')
+ superuser = User.objects.get(username='super')
+ superuser.is_active = False
+ superuser.save()
+
+ response = self.client.get('/test_admin/admin/')
+ self.assertContains(response, 'id="login-form"')
+ self.assertNotContains(response, 'Log out')
+
+ response = self.client.get('/test_admin/admin/secure-view/')
+ open('/home/maniac/Desktop/response.html', 'w').write(response.content)
+ self.assertContains(response, 'id="login-form"')
+
class AdminViewStringPrimaryKeyTest(TestCase):
fixtures = ['admin-views-users.xml', 'string-primary-key.xml']
@@ -622,7 +636,7 @@ class AdminViewStringPrimaryKeyTest(TestCase):
response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/history/' % quote(self.pk))
self.assertContains(response, escape(self.pk))
self.failUnlessEqual(response.status_code, 200)
-
+
def test_get_change_view(self):
"Retrieving the object using urlencoded form of primary key should work"
response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(self.pk))
diff --git a/tests/urls.py b/tests/urls.py
index 6704829231..4d123a2e8a 100644
--- a/tests/urls.py
+++ b/tests/urls.py
@@ -35,4 +35,7 @@ urlpatterns = patterns('',
# conditional get views
(r'condition/', include('regressiontests.conditional_processing.urls')),
+
+ # special headers views
+ (r'special_headers/', include('regressiontests.special_headers.urls')),
)