diff --git a/constance/admin.py b/constance/admin.py index 14400d6..1ae7344 100644 --- a/constance/admin.py +++ b/constance/admin.py @@ -6,7 +6,10 @@ from django import forms from django.contrib import admin, messages from django.contrib.admin import widgets from django.contrib.admin.options import csrf_protect_m +from django.contrib.auth.models import Permission +from django.contrib.contenttypes.models import ContentType from django.conf.urls import patterns, url +from django.core.exceptions import PermissionDenied from django.forms import fields from django.http import HttpResponseRedirect from django.shortcuts import render_to_response @@ -66,6 +69,8 @@ class ConstanceAdmin(admin.ModelAdmin): @csrf_protect_m def changelist_view(self, request, extra_context=None): # First load a mapping between config name and default value + if not self.has_change_permission(request, None): + raise PermissionDenied default_initial = ((name, default) for name, (default, help_text) in settings.CONFIG.iteritems()) # Then update the mapping with actually values from the backend @@ -126,12 +131,35 @@ class ConstanceAdmin(admin.ModelAdmin): class Config(object): class Meta(object): app_label = 'constance' - module_name = 'config' + model_name = module_name = 'config' verbose_name_plural = 'config' get_ordered_objects = lambda x: False abstract = False swapped = False + + def get_change_permission(self): + return 'change_%s' % self.model_name + _meta = Meta() admin.site.register([Config], ConstanceAdmin) + + +def install_perm(): + """ + Creates a fake content type and permission + to be able to check for permissions + """ + if ContentType._meta.installed and Permission._meta.installed: + content_type, created = ContentType.objects.get_or_create( + name='config', + app_label='constance', + model='config') + + permission, created = Permission.objects.get_or_create( + name='Can change config', + content_type=content_type, + codename='change_config') + +install_perm() diff --git a/tests/settings.py b/tests/settings.py index f796cdc..3d2d8e7 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -20,9 +20,9 @@ DATABASES = { } INSTALLED_APPS = ( + 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.auth', - 'django.contrib.contenttypes', 'django.contrib.admin', 'south', @@ -46,3 +46,5 @@ CONSTANCE_CONFIG = { 'DATE_VALUE': (date(2010, 12, 24), 'Merry Chrismas'), 'TIME_VALUE': (time(23, 59, 59), 'And happy New Year'), } + +DEBUG = True diff --git a/tests/test_admin.py b/tests/test_admin.py index e665f62..b64c0b4 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -1,20 +1,46 @@ from django.contrib import admin -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Permission +from django.core.exceptions import PermissionDenied from django.test import TestCase, RequestFactory -from constance.admin import Config +from constance.admin import settings, Config, install_perm class TestAdmin(TestCase): model = Config def setUp(self): + install_perm() self.rf = RequestFactory() - self.user = User.objects.create_superuser('admin', 'nimda', 'a@a.cz') + self.superuser = User.objects.create_superuser('admin', 'nimda', 'a@a.cz') + self.normaluser = User.objects.create_user('normal', 'nimda', 'b@b.cz') + self.normaluser.is_staff = True + self.normaluser.save() self.options = admin.site._registry[self.model] - self.client.login(username=self.user, password='nimda') def test_changelist(self): + self.client.login(username='admin', password='nimda') request = self.rf.get('/admin/constance/config/') + request.user = self.superuser + response = self.options.changelist_view(request, {}) + self.assertEquals(response.status_code, 200) + + def test_custom_auth(self): + settings.SUPERUSER_ONLY = False + self.client.login(username='normal', password='nimda') + request = self.rf.get('/admin/constance/config/') + request.user = self.normaluser + self.assertRaises(PermissionDenied, + self.options.changelist_view, + request, {}) + self.assertFalse(request.user.has_perm('constance.change_config')) + + # reload user to reset permission cache + request = self.rf.get('/admin/constance/config/') + request.user = User.objects.get(pk=self.normaluser.pk) + + request.user.user_permissions.add(Permission.objects.get(codename='change_config')) + self.assertTrue(request.user.has_perm('constance.change_config')) + response = self.options.changelist_view(request, {}) self.assertEquals(response.status_code, 200)