Add user permission tester to the admin page chooser panel

This commit is contained in:
Henk-Jan van Hasselaar 2017-03-23 14:56:16 +01:00 committed by Matt Westcott
parent ae487a22c8
commit 038511b7fe
4 changed files with 34 additions and 15 deletions

View file

@ -128,7 +128,7 @@ class CopyForm(forms.Form):
self.fields['new_parent_page'] = forms.ModelChoiceField(
initial=self.page.get_parent(),
queryset=Page.objects.all(),
widget=widgets.AdminPageChooser(can_choose_root=True),
widget=widgets.AdminPageChooser(can_choose_root=True, user_perms='copy_to'),
label=_("New parent page"),
help_text=_("This copy will be a child of this given parent page.")
)

View file

@ -1,4 +1,4 @@
function createPageChooser(id, pageTypes, openAtParentId, canChooseRoot) {
function createPageChooser(id, pageTypes, openAtParentId, canChooseRoot, userPerms) {
var chooserElement = $('#' + id + '-chooser');
var pageTitle = chooserElement.find('.title');
var input = $('#' + id);
@ -14,6 +14,9 @@ function createPageChooser(id, pageTypes, openAtParentId, canChooseRoot) {
if (canChooseRoot) {
urlParams.can_choose_root = 'true';
}
if (userPerms) {
urlParams.user_perms = userPerms;
}
ModalWorkflow({
url: initialUrl,

View file

@ -9,7 +9,7 @@ from wagtail.utils.pagination import paginate
from wagtail.wagtailadmin.forms import EmailLinkChooserForm, ExternalLinkChooserForm, SearchForm
from wagtail.wagtailadmin.modal_workflow import render_modal_workflow
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.models import Page, UserPagePermissionsProxy
from wagtail.wagtailcore.utils import resolve_model_string
@ -51,10 +51,27 @@ def filter_page_type(queryset, page_models):
return qs
def can_choose_page(page, permission_proxy, desired_classes, can_choose_root=True, user_perm=None):
"""Returns boolean indicating of the user can choose page.
will check if the root page can be selected and if user permissions
should be checked.
"""
if not issubclass(page.specific_class or Page, desired_classes) and not desired_classes == (Page, ):
return False
elif not can_choose_root and page.is_root():
return False
if user_perm == 'copy_to':
return permission_proxy.for_page(page).can_add_subpage()
return True
def browse(request, parent_page_id=None):
# A missing or empty page_type parameter indicates 'all page types'
# (i.e. descendants of wagtailcore.page)
page_type_string = request.GET.get('page_type') or 'wagtailcore.page'
user_perm = request.GET.get('user_perms', False)
try:
desired_classes = page_models_from_string(page_type_string)
except (ValueError, LookupError):
@ -91,11 +108,12 @@ def browse(request, parent_page_id=None):
can_choose_root = request.GET.get('can_choose_root', False)
# Do permission lookups for this user now, instead of for every page.
permission_proxy = UserPagePermissionsProxy(request.user)
# Parent page can be chosen if it is a instance of desired_classes
parent_page.can_choose = (
issubclass(parent_page.specific_class or Page, desired_classes) and
(can_choose_root or not parent_page.is_root())
)
parent_page.can_choose = can_choose_page(
parent_page, permission_proxy, desired_classes, can_choose_root, user_perm)
# Pagination
# We apply pagination first so we don't need to walk the entire list
@ -104,11 +122,7 @@ def browse(request, parent_page_id=None):
# Annotate each page with can_choose/can_decend flags
for page in pages:
if desired_classes == (Page, ):
page.can_choose = True
else:
page.can_choose = issubclass(page.specific_class or Page, desired_classes)
page.can_choose = can_choose_page(page, permission_proxy, desired_classes, can_choose_root, user_perm)
page.can_descend = page.get_children_count()
# Render

View file

@ -155,7 +155,7 @@ class AdminPageChooser(AdminChooser):
choose_another_text = _('Choose another page')
link_to_chosen_text = _('Edit this page')
def __init__(self, target_models=None, can_choose_root=False, **kwargs):
def __init__(self, target_models=None, can_choose_root=False, user_perms=None, **kwargs):
super(AdminPageChooser, self).__init__(**kwargs)
if target_models:
@ -163,6 +163,7 @@ class AdminPageChooser(AdminChooser):
if models:
self.choose_one_text += ' (' + models + ')'
self.user_perms = user_perms
self.target_models = list(target_models or [Page])
self.can_choose_root = can_choose_root
@ -202,7 +203,7 @@ class AdminPageChooser(AdminChooser):
parent = page.get_parent() if page else None
return "createPageChooser({id}, {model_names}, {parent}, {can_choose_root});".format(
return "createPageChooser({id}, {model_names}, {parent}, {can_choose_root}, {user_perms});".format(
id=json.dumps(id_),
model_names=json.dumps([
'{app}.{model}'.format(
@ -211,7 +212,8 @@ class AdminPageChooser(AdminChooser):
for model in self.target_models
]),
parent=json.dumps(parent.id if parent else None),
can_choose_root=('true' if self.can_choose_root else 'false')
can_choose_root=('true' if self.can_choose_root else 'false'),
user_perms=json.dumps(self.user_perms),
)