Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[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 authored
8  django/contrib/admin/options.py
@@ -749,7 +749,13 @@ def response_change(self, request, obj):
749 749
             return HttpResponseRedirect("../add/")
750 750
         else:
751 751
             self.message_user(request, msg)
752  
-            return HttpResponseRedirect("../")
  752
+            # Figure out where to redirect. If the user has change permission,
  753
+            # redirect to the change-list page for this object. Otherwise,
  754
+            # redirect to the admin index.
  755
+            if self.has_change_permission(request, None):
  756
+                return HttpResponseRedirect('../')
  757
+            else:
  758
+                return HttpResponseRedirect('../../../')
753 759
 
754 760
     def response_action(self, request, queryset):
755 761
         """
8  tests/regressiontests/admin_views/models.py
@@ -232,6 +232,13 @@ def get_changelist_formset(self, request, **kwargs):
232 232
         return super(PersonAdmin, self).get_changelist_formset(request,
233 233
             formset=BasePersonModelFormSet, **kwargs)
234 234
 
  235
+class RowLevelChangePermissionModel(models.Model):
  236
+    name = models.CharField(max_length=100, blank=True)
  237
+
  238
+class RowLevelChangePermissionModelAdmin(admin.ModelAdmin):
  239
+    def has_change_permission(self, request, obj=None):
  240
+        """ Only allow changing objects with even id number """
  241
+        return request.user.is_staff and (obj is not None) and (obj.id % 2 == 0)
235 242
 
236 243
 class Persona(models.Model):
237 244
     """
@@ -698,6 +705,7 @@ class FoodDeliveryAdmin(admin.ModelAdmin):
698 705
 admin.site.register(WorkHour, WorkHourAdmin)
699 706
 admin.site.register(Reservation)
700 707
 admin.site.register(FoodDelivery, FoodDeliveryAdmin)
  708
+admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
701 709
 
702 710
 # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
703 711
 # That way we cover all four cases:
38  tests/regressiontests/admin_views/tests.py
@@ -31,7 +31,7 @@
31 31
     Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast,
32 32
     Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
33 33
     Category, Post, Plot, FunkyTag, WorkHour, Employee, Inquisition,
34  
-    Actor, FoodDelivery)
  34
+    Actor, FoodDelivery, RowLevelChangePermissionModel)
35 35
 
36 36
 
37 37
 class AdminViewBasicTest(TestCase):
@@ -707,6 +707,42 @@ def testChangeView(self):
707 707
                         'Plural error message not found in response to post with multiple errors.')
708 708
         self.client.get('/test_admin/admin/logout/')
709 709
 
  710
+        # Test redirection when using row-level change permissions. Refs #11513.
  711
+        RowLevelChangePermissionModel.objects.create(name="odd id")
  712
+        RowLevelChangePermissionModel.objects.create(name="even id")
  713
+        for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]:
  714
+            self.client.get('/test_admin/admin/')
  715
+            self.client.post('/test_admin/admin/', login_dict)
  716
+            request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
  717
+            self.assertEqual(request.status_code, 403)
  718
+            request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
  719
+            self.assertEquals(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
  720
+            self.assertEqual(request.status_code, 403)
  721
+            request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
  722
+            self.assertEqual(request.status_code, 200)
  723
+            request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'})
  724
+            self.assertEquals(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
  725
+            self.assertRedirects(request, '/test_admin/admin/')
  726
+            self.client.get('/test_admin/admin/logout/')
  727
+        for login_dict in [self.joepublic_login, self.no_username_login]:
  728
+            self.client.get('/test_admin/admin/')
  729
+            self.client.post('/test_admin/admin/', login_dict)
  730
+            request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
  731
+            self.assertEqual(request.status_code, 200)
  732
+            self.assertContains(request, 'login-form')
  733
+            request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
  734
+            self.assertEquals(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
  735
+            self.assertEqual(request.status_code, 200)
  736
+            self.assertContains(request, 'login-form')
  737
+            request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
  738
+            self.assertEqual(request.status_code, 200)
  739
+            self.assertContains(request, 'login-form')
  740
+            request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed again'})
  741
+            self.assertEquals(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
  742
+            self.assertEqual(request.status_code, 200)
  743
+            self.assertContains(request, 'login-form')
  744
+            self.client.get('/test_admin/admin/logout/')
  745
+
710 746
     def testCustomModelAdminTemplates(self):
711 747
         self.client.get('/test_admin/admin/')
712 748
         self.client.post('/test_admin/admin/', self.super_login)

0 notes on commit 626ad2c

Please sign in to comment.
Something went wrong with that request. Please try again.