Fixed #26954 -- Prevented ModelAdmin.has_module_permission()=False from blocking access to the app index page.

This commit is contained in:
Halil Kaya 2016-08-02 01:07:50 +03:00 committed by Tim Graham
parent 74a575eb72
commit 2027d6acf7
3 changed files with 20 additions and 14 deletions

View File

@ -4,7 +4,7 @@ from django.apps import apps
from django.conf import settings from django.conf import settings
from django.contrib.admin import ModelAdmin, actions from django.contrib.admin import ModelAdmin, actions
from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.core.exceptions import ImproperlyConfigured
from django.db.models.base import ModelBase from django.db.models.base import ModelBase
from django.http import Http404, HttpResponseRedirect from django.http import Http404, HttpResponseRedirect
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
@ -399,8 +399,6 @@ class AdminSite(object):
has_module_perms = model_admin.has_module_permission(request) has_module_perms = model_admin.has_module_permission(request)
if not has_module_perms: if not has_module_perms:
if label:
raise PermissionDenied
continue continue
perms = model_admin.get_model_perms(request) perms = model_admin.get_model_perms(request)

View File

@ -1019,3 +1019,4 @@ site2.register(Person, save_as_continue=False)
site7 = admin.AdminSite(name="admin7") site7 = admin.AdminSite(name="admin7")
site7.register(Article, ArticleAdmin2) site7.register(Article, ArticleAdmin2)
site7.register(Section)

View File

@ -1926,10 +1926,9 @@ class AdminViewPermissionsTest(TestCase):
response = self.client.get(reverse('secure_view'), follow=True) response = self.client.get(reverse('secure_view'), follow=True)
self.assertContains(response, 'id="login-form"') self.assertContains(response, 'id="login-form"')
def test_app_index_fail_early(self): def test_app_list_permissions(self):
""" """
If a user has no module perms, avoid iterating over all the modeladmins If a user has no module perms, the app list returns a 404.
in the registry.
""" """
opts = Article._meta opts = Article._meta
change_user = User.objects.get(username='changeuser') change_user = User.objects.get(username='changeuser')
@ -1937,10 +1936,10 @@ class AdminViewPermissionsTest(TestCase):
self.client.force_login(self.changeuser) self.client.force_login(self.changeuser)
# the user has no module permissions, because this module doesn't exist # the user has no module permissions
change_user.user_permissions.remove(permission) change_user.user_permissions.remove(permission)
response = self.client.get(reverse('admin:app_list', args=('admin_views',))) response = self.client.get(reverse('admin:app_list', args=('admin_views',)))
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
# the user now has module permissions # the user now has module permissions
change_user.user_permissions.add(permission) change_user.user_permissions.add(permission)
@ -2002,30 +2001,38 @@ class AdminViewPermissionsTest(TestCase):
In this case, it always returns False, so the module should not be In this case, it always returns False, so the module should not be
displayed on the admin index page for any users. displayed on the admin index page for any users.
""" """
articles = Article._meta.verbose_name_plural.title()
sections = Section._meta.verbose_name_plural.title()
index_url = reverse('admin7:index') index_url = reverse('admin7:index')
self.client.force_login(self.superuser) self.client.force_login(self.superuser)
response = self.client.get(index_url) response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views') self.assertContains(response, sections)
self.assertNotContains(response, 'Articles') self.assertNotContains(response, articles)
self.client.logout() self.client.logout()
self.client.force_login(self.adduser) self.client.force_login(self.adduser)
response = self.client.get(index_url) response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views') self.assertNotContains(response, 'admin_views')
self.assertNotContains(response, 'Articles') self.assertNotContains(response, articles)
self.client.logout() self.client.logout()
self.client.force_login(self.changeuser) self.client.force_login(self.changeuser)
response = self.client.get(index_url) response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views') self.assertNotContains(response, 'admin_views')
self.assertNotContains(response, 'Articles') self.assertNotContains(response, articles)
self.client.logout() self.client.logout()
self.client.force_login(self.deleteuser) self.client.force_login(self.deleteuser)
response = self.client.get(index_url) response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views') self.assertNotContains(response, articles)
self.assertNotContains(response, 'Articles')
# The app list displays Sections but not Articles as the latter has
# ModelAdmin.has_module_permission() = False.
self.client.force_login(self.superuser)
response = self.client.get(reverse('admin7:app_list', args=('admin_views',)))
self.assertContains(response, sections)
self.assertNotContains(response, articles)
def test_post_save_message_no_forbidden_links_visible(self): def test_post_save_message_no_forbidden_links_visible(self):
""" """