From 1ea1f9b020a62c8aa857328bdd0f88778ec5fa62 Mon Sep 17 00:00:00 2001 From: Nick Smith Date: Fri, 4 Jul 2014 10:59:34 +0100 Subject: [PATCH] Limit GroupForm permissions queryset to hook-registered permissions --- wagtail/wagtailusers/forms.py | 24 +++++++++++++++++++++++- wagtail/wagtailusers/wagtail_hooks.py | 10 ++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailusers/forms.py b/wagtail/wagtailusers/forms.py index 81b352606..247d8ab62 100644 --- a/wagtail/wagtailusers/forms.py +++ b/wagtail/wagtailusers/forms.py @@ -2,8 +2,9 @@ from django import forms from django.contrib.auth.forms import UserCreationForm as BaseUserCreationForm from django.utils.translation import ugettext_lazy as _ from django.contrib.auth import get_user_model -from django.contrib.auth.models import Group +from django.contrib.auth.models import Group, Permission +from wagtail.wagtailadmin import hooks from wagtail.wagtailusers.models import UserProfile from wagtail.wagtailcore.models import UserPagePermissionsProxy @@ -138,6 +139,13 @@ class UserEditForm(forms.ModelForm): class GroupForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(GroupForm, self).__init__(*args, **kwargs) + self.registered_permissions = Permission.objects.none() + for fn in hooks.get_hooks('register_permissions'): + self.registered_permissions = self.registered_permissions | fn() + self.fields['permissions'].queryset = self.registered_permissions + required_css_class = "required" error_messages = { @@ -164,6 +172,20 @@ class GroupForm(forms.ModelForm): return name raise forms.ValidationError(self.error_messages['duplicate_name']) + def save(self): + # We go back to the object to read (in order to reapply) the + # permissions which were set on this group, but which are not + # accessible in the wagtail admin interface, as otherwise these would + # be clobbered by this form. + try: + untouchable_permissions = self.instance.permissions.exclude(pk__in=self.registered_permissions) + except AttributeError: + # this form is not bound; we're probably creating a new group + untouchable_permissions = Permission.objects.none() + group = super(GroupForm, self).save() + group.permissions.add(*untouchable_permissions) + return group + class NotificationPreferencesForm(forms.ModelForm): def __init__(self, *args, **kwargs): diff --git a/wagtail/wagtailusers/wagtail_hooks.py b/wagtail/wagtailusers/wagtail_hooks.py index 5a8195fa0..874de8b5b 100644 --- a/wagtail/wagtailusers/wagtail_hooks.py +++ b/wagtail/wagtailusers/wagtail_hooks.py @@ -1,5 +1,7 @@ from django.conf.urls import include, url from django.core import urlresolvers +from django.contrib.auth.models import Permission +from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailcore import hooks @@ -25,3 +27,11 @@ def construct_main_menu(request, menu_items): MenuItem(_('Groups'), urlresolvers.reverse('wagtailusers_groups_index'), classnames='icon icon-group', order=601) ) hooks.register('construct_main_menu', construct_main_menu) + + +def register_permissions(): + user_profile_content_types = ContentType.objects.filter(app_label='wagtailusers', model='userprofile') + auth_content_types = ContentType.objects.filter(app_label='auth', model__in=['group', 'user']) + relevant_content_types = user_profile_content_types | auth_content_types + return Permission.objects.filter(content_type__in=relevant_content_types) +hooks.register('register_permissions', register_permissions)