Skip to content

Commit

Permalink
Fixed #26954 -- Prevented ModelAdmin.has_module_permission()=False fr…
Browse files Browse the repository at this point in the history
…om blocking access to the app index page.
  • Loading branch information
halilkaya authored and timgraham committed Oct 13, 2016
1 parent 74a575e commit 2027d6a
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
4 changes: 1 addition & 3 deletions django/contrib/admin/sites.py
Expand Up @@ -4,7 +4,7 @@
from django.conf import settings
from django.contrib.admin import ModelAdmin, actions
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.http import Http404, HttpResponseRedirect
from django.template.response import TemplateResponse
Expand Down Expand Up @@ -399,8 +399,6 @@ def _build_app_dict(self, request, label=None):

has_module_perms = model_admin.has_module_permission(request)
if not has_module_perms:
if label:
raise PermissionDenied
continue

perms = model_admin.get_model_perms(request)
Expand Down
1 change: 1 addition & 0 deletions tests/admin_views/admin.py
Expand Up @@ -1019,3 +1019,4 @@ def get_formsets_with_inlines(self, request, obj=None):

site7 = admin.AdminSite(name="admin7")
site7.register(Article, ArticleAdmin2)
site7.register(Section)
29 changes: 18 additions & 11 deletions tests/admin_views/tests.py
Expand Up @@ -1926,21 +1926,20 @@ def test_disabled_staff_permissions_when_logged_in(self):
response = self.client.get(reverse('secure_view'), follow=True)
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
in the registry.
If a user has no module perms, the app list returns a 404.
"""
opts = Article._meta
change_user = User.objects.get(username='changeuser')
permission = get_perm(Article, get_permission_codename('change', opts))

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)
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
change_user.user_permissions.add(permission)
Expand Down Expand Up @@ -2002,30 +2001,38 @@ def test_overriding_has_module_permission(self):
In this case, it always returns False, so the module should not be
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')

self.client.force_login(self.superuser)
response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views')
self.assertNotContains(response, 'Articles')
self.assertContains(response, sections)
self.assertNotContains(response, articles)
self.client.logout()

self.client.force_login(self.adduser)
response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views')
self.assertNotContains(response, 'Articles')
self.assertNotContains(response, articles)
self.client.logout()

self.client.force_login(self.changeuser)
response = self.client.get(index_url)
self.assertNotContains(response, 'admin_views')
self.assertNotContains(response, 'Articles')
self.assertNotContains(response, articles)
self.client.logout()

self.client.force_login(self.deleteuser)
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):
"""
Expand Down

0 comments on commit 2027d6a

Please sign in to comment.