summaryrefslogtreecommitdiff
path: root/tests/modeladmin
diff options
context:
space:
mode:
authorCarlton Gibson <carlton.gibson@noumenal.es>2018-06-18 21:07:29 +0200
committerTim Graham <timograham@gmail.com>2018-06-18 15:07:29 -0400
commit958c7b301ead79974db8edd5b9c6588a10a28ae7 (patch)
treef74015f227d8fc09b655d11868e9af764043dd86 /tests/modeladmin
parent6dd4edb1b4f5441c5f543e29395039839c50d10b (diff)
downloaddjango-958c7b301ead79974db8edd5b9c6588a10a28ae7.tar.gz
Fixed #29419 -- Allowed permissioning of admin actions.
Diffstat (limited to 'tests/modeladmin')
-rw-r--r--tests/modeladmin/test_actions.py57
-rw-r--r--tests/modeladmin/test_checks.py19
2 files changed, 76 insertions, 0 deletions
diff --git a/tests/modeladmin/test_actions.py b/tests/modeladmin/test_actions.py
new file mode 100644
index 0000000000..17b3c324d2
--- /dev/null
+++ b/tests/modeladmin/test_actions.py
@@ -0,0 +1,57 @@
+from django.contrib import admin
+from django.contrib.auth.models import Permission, User
+from django.contrib.contenttypes.models import ContentType
+from django.test import TestCase
+
+from .models import Band
+
+
+class AdminActionsTests(TestCase):
+
+ @classmethod
+ def setUpTestData(cls):
+ cls.superuser = User.objects.create_superuser(username='super', password='secret', email='super@example.com')
+ content_type = ContentType.objects.get_for_model(Band)
+ Permission.objects.create(name='custom', codename='custom_band', content_type=content_type)
+ for user_type in ('view', 'add', 'change', 'delete', 'custom'):
+ username = '%suser' % user_type
+ user = User.objects.create_user(username=username, password='secret', is_staff=True)
+ permission = Permission.objects.get(codename='%s_band' % user_type, content_type=content_type)
+ user.user_permissions.add(permission)
+ setattr(cls, username, user)
+
+ def test_get_actions_respects_permissions(self):
+ class MockRequest:
+ pass
+
+ class BandAdmin(admin.ModelAdmin):
+ actions = ['custom_action']
+
+ def custom_action(modeladmin, request, queryset):
+ pass
+
+ def has_custom_permission(self, request):
+ return request.user.has_perm('%s.custom_band' % self.opts.app_label)
+
+ ma = BandAdmin(Band, admin.AdminSite())
+ mock_request = MockRequest()
+ mock_request.GET = {}
+ cases = [
+ (None, self.viewuser, ['custom_action']),
+ ('view', self.superuser, ['delete_selected', 'custom_action']),
+ ('view', self.viewuser, ['custom_action']),
+ ('add', self.adduser, ['custom_action']),
+ ('change', self.changeuser, ['custom_action']),
+ ('delete', self.deleteuser, ['delete_selected', 'custom_action']),
+ ('custom', self.customuser, ['custom_action']),
+ ]
+ for permission, user, expected in cases:
+ with self.subTest(permission=permission, user=user):
+ if permission is None:
+ if hasattr(BandAdmin.custom_action, 'allowed_permissions'):
+ del BandAdmin.custom_action.allowed_permissions
+ else:
+ BandAdmin.custom_action.allowed_permissions = (permission,)
+ mock_request.user = user
+ actions = ma.get_actions(mock_request)
+ self.assertEqual(list(actions.keys()), expected)
diff --git a/tests/modeladmin/test_checks.py b/tests/modeladmin/test_checks.py
index 5a0433deb4..6a10441471 100644
--- a/tests/modeladmin/test_checks.py
+++ b/tests/modeladmin/test_checks.py
@@ -1290,3 +1290,22 @@ class AutocompleteFieldsTests(CheckTestCase):
site = AdminSite()
site.register(User, UserAdmin)
self.assertIsValid(Admin, ValidationTestModel, admin_site=site)
+
+
+class ActionsCheckTests(CheckTestCase):
+
+ def test_custom_permissions_require_matching_has_method(self):
+ def custom_permission_action(modeladmin, request, queryset):
+ pass
+
+ custom_permission_action.allowed_permissions = ('custom',)
+
+ class BandAdmin(ModelAdmin):
+ actions = (custom_permission_action,)
+
+ self.assertIsInvalid(
+ BandAdmin, Band,
+ 'BandAdmin must define a has_custom_permission() method for the '
+ 'custom_permission_action action.',
+ id='admin.E129',
+ )