Kaydet (Commit) 553617e6 authored tarafından Paulo's avatar Paulo Kaydeden (comit) Tim Graham

Fixed #29487 -- Accounted for object level permissions when calculating change…

Fixed #29487 -- Accounted for object level permissions when calculating change view's read-only fields.

Thanks Matthew Frazier for the report and fix.
üst 4fb7bd83
...@@ -1574,7 +1574,7 @@ class ModelAdmin(BaseModelAdmin): ...@@ -1574,7 +1574,7 @@ class ModelAdmin(BaseModelAdmin):
form = ModelForm(instance=obj) form = ModelForm(instance=obj)
formsets, inline_instances = self._create_formsets(request, obj, change=True) formsets, inline_instances = self._create_formsets(request, obj, change=True)
if not add and not self.has_change_permission(request): if not add and not self.has_change_permission(request, obj):
readonly_fields = flatten_fieldsets(self.get_fieldsets(request, obj)) readonly_fields = flatten_fieldsets(self.get_fieldsets(request, obj))
else: else:
readonly_fields = self.get_readonly_fields(request, obj) readonly_fields = self.get_readonly_fields(request, obj)
......
...@@ -1116,3 +1116,13 @@ site6.register(Article, ArticleAdmin6) ...@@ -1116,3 +1116,13 @@ site6.register(Article, ArticleAdmin6)
site6.register(Actor, ActorAdmin6) site6.register(Actor, ActorAdmin6)
site6.register(Chapter, ChapterAdmin6) site6.register(Chapter, ChapterAdmin6)
site6.register(Color, ColorAdmin6) site6.register(Color, ColorAdmin6)
class ArticleAdmin9(admin.ModelAdmin):
def has_change_permission(self, request, obj=None):
# Simulate that the user can't change a specific object.
return obj is None
site9 = admin.AdminSite(name='admin9')
site9.register(Article, ArticleAdmin9)
...@@ -1852,6 +1852,18 @@ class AdminViewPermissionsTest(TestCase): ...@@ -1852,6 +1852,18 @@ class AdminViewPermissionsTest(TestCase):
self.assertContains(response, 'login-form') self.assertContains(response, 'login-form')
self.client.get(reverse('admin:logout')) self.client.get(reverse('admin:logout'))
def test_change_view_without_object_change_permission(self):
"""
The object should be read-only if the user has permission to view it
and change objects of that type but not to change the current object.
"""
change_url = reverse('admin9:admin_views_article_change', args=(self.a1.pk,))
self.client.force_login(self.viewuser)
response = self.client.get(change_url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['title'], 'View article')
self.assertContains(response, '<a href="/test_admin/admin9/admin_views/article/" class="closelink">Close</a>')
def test_change_view_save_as_new(self): def test_change_view_save_as_new(self):
""" """
'Save as new' should raise PermissionDenied for users without the 'add' 'Save as new' should raise PermissionDenied for users without the 'add'
......
...@@ -16,6 +16,7 @@ urlpatterns = [ ...@@ -16,6 +16,7 @@ urlpatterns = [
url(r'^test_admin/admin7/', admin.site7.urls), url(r'^test_admin/admin7/', admin.site7.urls),
# All admin views accept `extra_context` to allow adding it like this: # All admin views accept `extra_context` to allow adding it like this:
url(r'^test_admin/admin8/', (admin.site.get_urls(), 'admin', 'admin-extra-context'), {'extra_context': {}}), url(r'^test_admin/admin8/', (admin.site.get_urls(), 'admin', 'admin-extra-context'), {'extra_context': {}}),
url(r'^test_admin/admin9/', admin.site9.urls),
url(r'^test_admin/has_permission_admin/', custom_has_permission_admin.site.urls), url(r'^test_admin/has_permission_admin/', custom_has_permission_admin.site.urls),
url(r'^test_admin/autocomplete_admin/', autocomplete_site.urls), url(r'^test_admin/autocomplete_admin/', autocomplete_site.urls),
] ]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment