Port generic admin views (and thus wagtailsites) to use permission policies

This commit is contained in:
Matt Westcott 2016-01-11 21:16:53 +00:00 committed by Karl Hobley
parent 56181cf601
commit 04307e05b1
4 changed files with 44 additions and 28 deletions

View file

@ -9,36 +9,41 @@ from wagtail.wagtailadmin.utils import permission_denied
class PermissionCheckedMixin(object):
"""
Mixin for class-based views to enforce permission checks.
Subclasses should set either of the following class properties:
* permission_required (a single permission string)
* any_permission_required (a list of permission strings - the user must have
Mixin for class-based views to enforce permission checks according to
a permission policy (see wagtail.wagtailcore.permission_policies).
To take advantage of this, subclasses should set the class property:
* permission_policy (a policy object)
and either of:
* permission_required (an action name such as 'add', 'change' or 'delete')
* any_permission_required (a list of action names - the user must have
one or more of those permissions)
"""
permission_policy = None
permission_required = None
any_permission_required = None
def dispatch(self, request, *args, **kwargs):
if self.permission_required is not None:
if not request.user.has_perm(self.permission_required):
return permission_denied(request)
if self.permission_policy is not None:
if self.any_permission_required is not None:
has_permission = False
if self.permission_required is not None:
if not self.permission_policy.user_has_permission(
request.user, self.permission_required
):
return permission_denied(request)
for perm in self.any_permission_required:
if request.user.has_perm(perm):
has_permission = True
break
if not has_permission:
return permission_denied(request)
if self.any_permission_required is not None:
if not self.permission_policy.user_has_any_permission(
request.user, self.any_permission_required
):
return permission_denied(request)
return super(PermissionCheckedMixin, self).dispatch(request, *args, **kwargs)
class IndexView(PermissionCheckedMixin, View):
context_object_name = None
any_permission_required = ['add', 'change', 'delete']
def get_queryset(self):
return self.model.objects.all()
@ -49,7 +54,10 @@ class IndexView(PermissionCheckedMixin, View):
context = {
'view': self,
'object_list': object_list,
'can_add': self.request.user.has_perm(self.add_permission_name),
'can_add': (
self.permission_policy is None
or self.permission_policy.user_has_permission(self.request.user, 'add')
),
}
if self.context_object_name:
context[self.context_object_name] = object_list
@ -59,6 +67,7 @@ class IndexView(PermissionCheckedMixin, View):
class CreateView(PermissionCheckedMixin, View):
template_name = 'wagtailadmin/generic/create.html'
permission_required = 'add'
def get_add_url(self):
return reverse(self.add_url_name)
@ -90,6 +99,7 @@ class EditView(PermissionCheckedMixin, View):
page_title = __("Editing")
context_object_name = None
template_name = 'wagtailadmin/generic/edit.html'
permission_required = 'change'
def get_page_subtitle(self):
return str(self.instance)
@ -124,7 +134,10 @@ class EditView(PermissionCheckedMixin, View):
'view': self,
'object': self.instance,
'form': self.form,
'can_delete': self.request.user.has_perm(self.delete_permission_name),
'can_delete': (
self.permission_policy is None
or self.permission_policy.user_has_permission(self.request.user, 'delete')
),
}
if self.context_object_name:
context[self.context_object_name] = self.instance
@ -135,6 +148,7 @@ class EditView(PermissionCheckedMixin, View):
class DeleteView(PermissionCheckedMixin, View):
template_name = 'wagtailadmin/generic/confirm_delete.html'
context_object_name = None
permission_required = 'delete'
def get_page_subtitle(self):
return str(self.instance)

View file

@ -0,0 +1,4 @@
from wagtail.wagtailcore.models import Site
from wagtail.wagtailcore.permission_policies import ModelPermissionPolicy
site_permission_policy = ModelPermissionPolicy(Site)

View file

@ -1,24 +1,24 @@
from django.utils.translation import ugettext_lazy as __
from wagtail.wagtailcore.models import Site
from wagtail.wagtailcore.permissions import site_permission_policy
from wagtail.wagtailsites.forms import SiteForm
from wagtail.wagtailadmin.views.generic import IndexView, CreateView, EditView, DeleteView
class Index(IndexView):
any_permission_required = ['wagtailcore.add_site', 'wagtailcore.change_site', 'wagtailcore.delete_site']
permission_policy = site_permission_policy
model = Site
context_object_name = 'sites'
template_name = 'wagtailsites/index.html'
add_url_name = 'wagtailsites:add'
add_permission_name = 'wagtailcore.add_site'
page_title = __("Sites")
add_item_label = __("Add a site")
header_icon = 'site'
class Create(CreateView):
permission_required = 'wagtailcore.add_site'
permission_policy = site_permission_policy
form_class = SiteForm
page_title = __("Add site")
success_message = __("Site '{0}' created.")
@ -30,7 +30,7 @@ class Create(CreateView):
class Edit(EditView):
permission_required = 'wagtailcore.change_site'
permission_policy = site_permission_policy
model = Site
form_class = SiteForm
success_message = __("Site '{0}' updated.")
@ -39,14 +39,13 @@ class Edit(EditView):
edit_url_name = 'wagtailsites:edit'
index_url_name = 'wagtailsites:index'
delete_url_name = 'wagtailsites:delete'
delete_permission_name = 'wagtailcore.delete_site'
context_object_name = 'site'
template_name = 'wagtailsites/edit.html'
header_icon = 'site'
class Delete(DeleteView):
permission_required = 'wagtailcore.delete_site'
permission_policy = site_permission_policy
model = Site
success_message = __("Site '{0}' deleted.")
index_url_name = 'wagtailsites:index'

View file

@ -4,6 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Permission
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.permissions import site_permission_policy
from wagtail.wagtailadmin.menu import MenuItem
from wagtail.wagtailsites import urls
@ -18,10 +19,8 @@ def register_admin_urls():
class SitesMenuItem(MenuItem):
def is_shown(self, request):
return (
request.user.has_perm('wagtailcore.add_site')
or request.user.has_perm('wagtailcore.change_site')
or request.user.has_perm('wagtailcore.delete_site')
return site_permission_policy.user_has_any_permission(
request.user, ['add', 'change', 'delete']
)