Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.2.X] Fixed #11513 -- Ensure that the redirect at the end of an obj…

…ect change won't redirect to a page for which the user doesn't have permission. Thanks to rlaager for the report and draft patch, and to Julien Phalip for the final patch.

Backport of r15584 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15586 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 626ad2c9ab9e02db8e3f19bd51654d749e84af02 1 parent 3202d2a
Russell Keith-Magee freakboy3742 authored
8 django/contrib/admin/options.py
View
@@ -749,7 +749,13 @@ def response_change(self, request, obj):
return HttpResponseRedirect("../add/")
else:
self.message_user(request, msg)
- return HttpResponseRedirect("../")
+ # Figure out where to redirect. If the user has change permission,
+ # redirect to the change-list page for this object. Otherwise,
+ # redirect to the admin index.
+ if self.has_change_permission(request, None):
+ return HttpResponseRedirect('../')
+ else:
+ return HttpResponseRedirect('../../../')
def response_action(self, request, queryset):
"""
8 tests/regressiontests/admin_views/models.py
View
@@ -232,6 +232,13 @@ def get_changelist_formset(self, request, **kwargs):
return super(PersonAdmin, self).get_changelist_formset(request,
formset=BasePersonModelFormSet, **kwargs)
+class RowLevelChangePermissionModel(models.Model):
+ name = models.CharField(max_length=100, blank=True)
+
+class RowLevelChangePermissionModelAdmin(admin.ModelAdmin):
+ def has_change_permission(self, request, obj=None):
+ """ Only allow changing objects with even id number """
+ return request.user.is_staff and (obj is not None) and (obj.id % 2 == 0)
class Persona(models.Model):
"""
@@ -698,6 +705,7 @@ class FoodDeliveryAdmin(admin.ModelAdmin):
admin.site.register(WorkHour, WorkHourAdmin)
admin.site.register(Reservation)
admin.site.register(FoodDelivery, FoodDeliveryAdmin)
+admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
# That way we cover all four cases:
38 tests/regressiontests/admin_views/tests.py
View
@@ -31,7 +31,7 @@
Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast,
Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
Category, Post, Plot, FunkyTag, WorkHour, Employee, Inquisition,
- Actor, FoodDelivery)
+ Actor, FoodDelivery, RowLevelChangePermissionModel)
class AdminViewBasicTest(TestCase):
@@ -707,6 +707,42 @@ def testChangeView(self):
'Plural error message not found in response to post with multiple errors.')
self.client.get('/test_admin/admin/logout/')
+ # Test redirection when using row-level change permissions. Refs #11513.
+ RowLevelChangePermissionModel.objects.create(name="odd id")
+ RowLevelChangePermissionModel.objects.create(name="even id")
+ for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]:
+ self.client.get('/test_admin/admin/')
+ self.client.post('/test_admin/admin/', login_dict)
+ request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
+ self.assertEqual(request.status_code, 403)
+ request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
+ self.assertEquals(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
+ self.assertEqual(request.status_code, 403)
+ request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
+ self.assertEqual(request.status_code, 200)
+ request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'})
+ self.assertEquals(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
+ self.assertRedirects(request, '/test_admin/admin/')
+ self.client.get('/test_admin/admin/logout/')
+ for login_dict in [self.joepublic_login, self.no_username_login]:
+ self.client.get('/test_admin/admin/')
+ self.client.post('/test_admin/admin/', login_dict)
+ request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
+ self.assertEqual(request.status_code, 200)
+ self.assertContains(request, 'login-form')
+ request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
+ self.assertEquals(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
+ self.assertEqual(request.status_code, 200)
+ self.assertContains(request, 'login-form')
+ request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
+ self.assertEqual(request.status_code, 200)
+ self.assertContains(request, 'login-form')
+ request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed again'})
+ self.assertEquals(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
+ self.assertEqual(request.status_code, 200)
+ self.assertContains(request, 'login-form')
+ self.client.get('/test_admin/admin/logout/')
+
def testCustomModelAdminTemplates(self):
self.client.get('/test_admin/admin/')
self.client.post('/test_admin/admin/', self.super_login)
Please sign in to comment.
Something went wrong with that request. Please try again.