def revisions_unschedule(request, page_id, revision_id): page = get_object_or_404(Page, id=page_id).specific user_perms = UserPagePermissionsProxy(request.user) if not user_perms.for_page(page).can_unschedule(): raise PermissionDenied revision = get_object_or_404(page.revisions, id=revision_id) next_url = get_valid_next_url_from_request(request) subtitle = _('revision {0} of "{1}"').format(revision.id, page.get_admin_display_title()) if request.method == 'POST': revision.approved_go_live_at = None revision.save(update_fields=['approved_go_live_at']) messages.success(request, _('Revision {0} of "{1}" unscheduled.').format(revision.id, page.get_admin_display_title()), buttons=[ messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit')) ]) if next_url: return redirect(next_url) return redirect('wagtailadmin_pages:revisions_index', page.id) return render(request, 'wagtailadmin/pages/revisions/confirm_unschedule.html', { 'page': page, 'revision': revision, 'next': next_url, 'subtitle': subtitle })
def check(self, skip_permission_checks=False): from wagtail.core.models import UserPagePermissionsProxy # Essential data model checks if self.page._state.adding: raise CopyPageIntegrityError( 'Page.copy() called on an unsaved page') if self.to and self.recursive and (self.to.id == self.page.id or self.to.is_descendant_of( self.page)): raise CopyPageIntegrityError( "You cannot copy a tree branch recursively into itself") # Permission checks if self.user and not skip_permission_checks: to = self.to if to is None: to = self.page.get_parent() if not self.page.permissions_for_user(self.user).can_copy_to( to, self.recursive): raise CopyPagePermissionError( "You do not have permission to copy this page") if self.keep_live: destination_perms = UserPagePermissionsProxy( self.user).for_page(self.to) if not destination_perms.can_publish_subpage(): raise CopyPagePermissionError( "You do not have permission to publish a page at the destination" )
def publish(request, page_id): page = get_object_or_404(Page, id=page_id).specific user_perms = UserPagePermissionsProxy(request.user) if not user_perms.for_page(page).can_publish(): raise PermissionDenied next_url = pages.get_valid_next_url_from_request(request) if request.method == 'POST': page.get_latest_revision().publish() messages.success(request, _("Page '{0}' published.").format(page.get_admin_display_title()), buttons=[ messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit')) ]) if next_url: return redirect(next_url) return redirect('wagtailadmin_explore', page.get_parent().id) return render(request, 'wagtailadmin/pages/confirm_publish.html', { 'page': page, 'next': next_url, })
def _get_user_page_permissions(context): # Create a UserPagePermissionsProxy object to represent the user's global permissions, and # cache it in the context for the duration of the page request, if one does not exist already if 'user_page_permissions' not in context: context['user_page_permissions'] = UserPagePermissionsProxy(context['request'].user) return context['user_page_permissions']
def unpublish(request, page_id): page = get_object_or_404(Page, id=page_id).specific user_perms = UserPagePermissionsProxy(request.user) if not user_perms.for_page(page).can_unpublish(): raise PermissionDenied next_url = get_valid_next_url_from_request(request) if request.method == 'POST': include_descendants = request.POST.get("include_descendants", False) page.unpublish() if include_descendants: live_descendant_pages = page.get_descendants().live().specific() for live_descendant_page in live_descendant_pages: if user_perms.for_page(live_descendant_page).can_unpublish(): live_descendant_page.unpublish() messages.success(request, _("Page '{0}' unpublished.").format(page.get_admin_display_title()), buttons=[ messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit')) ]) if next_url: return redirect(next_url) return redirect('wagtailadmin_explore', page.get_parent().id) return render(request, 'wagtailadmin/pages/confirm_unpublish.html', { 'page': page, 'next': next_url, 'live_descendant_count': page.get_descendants().live().count(), })
def test_lock_page_for_moderator(self): user = get_user_model().objects.get(username='******') christmas_page = EventPage.objects.get(url_path='/home/events/christmas/') perms = UserPagePermissionsProxy(user).for_page(christmas_page) self.assertTrue(perms.can_lock())
def test_editable_pages_for_user_with_add_permission(self): event_editor = get_user_model().objects.get(username='******') homepage = Page.objects.get(url_path='/home/') christmas_page = EventPage.objects.get( url_path='/home/events/christmas/') unpublished_event_page = EventPage.objects.get( url_path='/home/events/tentative-unpublished-event/') someone_elses_event_page = EventPage.objects.get( url_path='/home/events/someone-elses-event/') user_perms = UserPagePermissionsProxy(event_editor) editable_pages = user_perms.editable_pages() can_edit_pages = user_perms.can_edit_pages() publishable_pages = user_perms.publishable_pages() can_publish_pages = user_perms.can_publish_pages() self.assertFalse(editable_pages.filter(id=homepage.id).exists()) self.assertTrue(editable_pages.filter(id=christmas_page.id).exists()) self.assertTrue( editable_pages.filter(id=unpublished_event_page.id).exists()) self.assertFalse( editable_pages.filter(id=someone_elses_event_page.id).exists()) self.assertTrue(can_edit_pages) self.assertFalse(publishable_pages.filter(id=homepage.id).exists()) self.assertFalse( publishable_pages.filter(id=christmas_page.id).exists()) self.assertFalse( publishable_pages.filter(id=unpublished_event_page.id).exists()) self.assertFalse( publishable_pages.filter(id=someone_elses_event_page.id).exists()) self.assertFalse(can_publish_pages)
def user_can_edit_any_pages(user): if not user.is_active: return False if user.is_superuser: return True else: return bool(UserPagePermissionsProxy(user).permissions)
def test_override_user_page_permission_proxy(self): custom_permission = 'wagtail.core.tests.test_page_permissions.CustomUserPagePermission' with self.settings( WAGTAIL_USER_PAGE_PERMISSION_PROXY=custom_permission): user = get_user_model().objects.get(username='******') permission_proxy = UserPagePermissionsProxy(user) self.assertIsInstance(permission_proxy, CustomUserPagePermission)
def publish(request, page_id): page = get_object_or_404(Page, id=page_id).specific user_perms = UserPagePermissionsProxy(request.user) if not user_perms.for_page(page).can_publish(): raise PermissionDenied next_url = get_valid_next_url_from_request(request) if request.method == 'POST': include_descendants = request.POST.get("include_descendants", False) page.save_revision().publish() if include_descendants: not_live_descendant_pages = ( page.get_descendants().not_live().specific()) for not_live_descendant_page in not_live_descendant_pages: if user_perms.for_page(not_live_descendant_page).can_publish(): not_live_descendant_page.save_revision().publish() if next_url: return redirect(next_url) return redirect('wagtailadmin_explore', page.get_parent().id) return render( request, 'wagtailadmin/pages/confirm_publish.html', { 'page': page, 'next': next_url, 'not_live_descendant_count': page.get_descendants().not_live().count() })
def test_editable_pages_for_non_editing_user(self): user = get_user_model().objects.get( email="*****@*****.**") homepage = Page.objects.get(url_path="/home/") christmas_page = EventPage.objects.get( url_path="/home/events/christmas/") unpublished_event_page = EventPage.objects.get( url_path="/home/events/tentative-unpublished-event/") someone_elses_event_page = EventPage.objects.get( url_path="/home/events/someone-elses-event/") user_perms = UserPagePermissionsProxy(user) editable_pages = user_perms.editable_pages() can_edit_pages = user_perms.can_edit_pages() publishable_pages = user_perms.publishable_pages() can_publish_pages = user_perms.can_publish_pages() self.assertFalse(editable_pages.filter(id=homepage.id).exists()) self.assertFalse(editable_pages.filter(id=christmas_page.id).exists()) self.assertFalse( editable_pages.filter(id=unpublished_event_page.id).exists()) self.assertFalse( editable_pages.filter(id=someone_elses_event_page.id).exists()) self.assertFalse(can_edit_pages) self.assertFalse(publishable_pages.filter(id=homepage.id).exists()) self.assertFalse( publishable_pages.filter(id=christmas_page.id).exists()) self.assertFalse( publishable_pages.filter(id=unpublished_event_page.id).exists()) self.assertFalse( publishable_pages.filter(id=someone_elses_event_page.id).exists()) self.assertFalse(can_publish_pages)
def test_with_user_no_permission(self): homepage = Page.objects.get(url_path='/home/') # event editor does not have permissions on homepage event_editor = get_user_model().objects.get(username='******') permission_proxy = UserPagePermissionsProxy(event_editor) result = can_choose_page(homepage, permission_proxy, self.desired_classes, user_perm='copy_to') self.assertFalse(result)
def get_queryset(self): pages = ( UserPagePermissionsProxy(self.request.user).editable_pages() | Page.objects.filter(locked_by=self.request.user) ).filter(locked=True) self.queryset = pages return super().get_queryset()
def get_valid_parent_pages(self, user): """ Identifies possible parent pages for the current user by first looking at allowed_parent_page_models() on self.model to limit options to the correct type of page, then checking permissions on those individual pages to make sure we have permission to add a subpage to it. """ # Get queryset of pages where this page type can be added allowed_parent_page_content_types = list( ContentType.objects.get_for_models( *self.model.allowed_parent_page_models()).values()) allowed_parent_pages = Page.objects.filter( content_type__in=allowed_parent_page_content_types) # Get queryset of pages where the user has permission to add subpages if user.is_superuser: pages_where_user_can_add = Page.objects.all() else: pages_where_user_can_add = Page.objects.none() user_perms = UserPagePermissionsProxy(user) for perm in user_perms.permissions.filter(permission_type='add'): # user has add permission on any subpage of perm.page # (including perm.page itself) pages_where_user_can_add |= Page.objects.descendant_of( perm.page, inclusive=True) # Combine them return allowed_parent_pages & pages_where_user_can_add
def test_lock_page_for_non_editing_user(self): user = get_user_model().objects.get(username='******') christmas_page = EventPage.objects.get(url_path='/home/events/christmas/') perms = UserPagePermissionsProxy(user).for_page(christmas_page) self.assertFalse(perms.can_lock())
def test_page_locked_for_unlocked_page(self): user = get_user_model().objects.get(email="*****@*****.**") christmas_page = EventPage.objects.get( url_path="/home/events/christmas/") perms = UserPagePermissionsProxy(user).for_page(christmas_page) self.assertFalse(perms.page_locked())
def register_account_notification_preferences(request): user_perms = UserPagePermissionsProxy(request.user) if user_perms.can_edit_pages() or user_perms.can_publish_pages(): return { 'url': reverse('wagtailadmin_account_notification_preferences'), 'label': _('Notification preferences'), 'help_text': _('Choose which email notifications to receive.'), }
def render(self): return render_to_string('wagtailadmin/home/locked_pages.html', { 'locked_pages': Page.objects.filter( locked=True, locked_by=self.request.user, ), 'can_remove_locks': UserPagePermissionsProxy(self.request.user).can_remove_locks() }, request=self.request)
def get_pages_with_reviews_for_user(cls, user): """ Return a queryset of pages which have reviews, for which the user has edit permission """ user_perms = UserPagePermissionsProxy(user) reviewed_pages = cls.objects.values_list('page_revision__page_id', flat=True).distinct() return user_perms.editable_pages().filter(pk__in=reviewed_pages)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) user_perms = UserPagePermissionsProxy(self.instance.user) if not user_perms.can_publish_pages(): del self.fields['submitted_notifications'] if not user_perms.can_edit_pages(): del self.fields['approved_notifications'] del self.fields['rejected_notifications']
def is_active(self): # Hide the panel if the user can't edit or publish pages user_perms = UserPagePermissionsProxy(self.request.user) if not user_perms.can_edit_pages() and not user_perms.can_publish_pages(): return False # Hide the panel if there are no notification preferences return self.get_form().fields
def get_context_data(self, parent_context): request = parent_context['request'] context = super().get_context_data(parent_context) user_perms = UserPagePermissionsProxy(request.user) context['page_revisions_for_moderation'] = ( user_perms.revisions_for_moderation().select_related('page', 'user').order_by('-created_at') ) context['request'] = request return context
def test_lock_page_for_editor(self): user = get_user_model().objects.get(email='*****@*****.**') christmas_page = EventPage.objects.get( url_path='/home/events/christmas/') perms = UserPagePermissionsProxy(user).for_page(christmas_page) self.assertFalse(perms.can_lock()) self.assertFalse(perms.can_unlock())
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update({ "page": self.page, "page_for_status": self.page_for_status, "content_type": self.page_content_type, "edit_handler": self.edit_handler, "errors_debug": self.errors_debug, "action_menu": PageActionMenu(self.request, view="edit", page=self.page), "preview_modes": self.page.preview_modes, "form": self.form, "next": self.next_url, "has_unsaved_changes": self.has_unsaved_changes, "page_locked": self.page_perms.page_locked(), "workflow_state": self.workflow_state if self.workflow_state and self.workflow_state.is_active else None, "current_task_state": self.page.current_workflow_task_state, "publishing_will_cancel_workflow": self.workflow_tasks and getattr(settings, "WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH", True), "locale": None, "translations": [], }) if getattr(settings, "WAGTAIL_I18N_ENABLED", False): user_perms = UserPagePermissionsProxy(self.request.user) context.update({ "locale": self.page.locale, "translations": [{ "locale": translation.locale, "url": reverse("wagtailadmin_pages:edit", args=[translation.id]), } for translation in self.page.get_translations().only( "id", "locale", "depth").select_related("locale") if user_perms.for_page(translation).can_edit()], }) return context
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update({ 'page': self.page, 'page_for_status': self.page_for_status, 'content_type': self.page_content_type, 'edit_handler': self.edit_handler, 'errors_debug': self.errors_debug, 'action_menu': PageActionMenu(self.request, view='edit', page=self.page), 'preview_modes': self.page.preview_modes, 'form': self.form, 'next': self.next_url, 'has_unsaved_changes': self.has_unsaved_changes, 'page_locked': self.page_perms.page_locked(), 'workflow_state': self.workflow_state if self.workflow_state and self.workflow_state.is_active else None, 'current_task_state': self.page.current_workflow_task_state, 'publishing_will_cancel_workflow': self.workflow_tasks and getattr(settings, 'WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH', True), 'locale': None, 'translations': [], }) if getattr(settings, 'WAGTAIL_I18N_ENABLED', False): user_perms = UserPagePermissionsProxy(self.request.user) context.update({ 'locale': self.page.locale, 'translations': [{ 'locale': translation.locale, 'url': reverse('wagtailadmin_pages:edit', args=[translation.id]), } for translation in self.page.get_translations().only( 'id', 'locale').select_related('locale') if user_perms.for_page(translation).can_edit()], }) return context
def test_lock_page_for_moderator_without_unlock_permission(self): user = get_user_model().objects.get(username='******') christmas_page = EventPage.objects.get(url_path='/home/events/christmas/') GroupPagePermission.objects.filter(group__name='Event moderators', permission_type='unlock').delete() perms = UserPagePermissionsProxy(user).for_page(christmas_page) self.assertTrue(perms.can_lock()) self.assertFalse(perms.can_unlock())
def get_forms_for_user(user): editable_forms = UserPagePermissionsProxy(user).editable_pages() ct = ContentType.objects.get_for_model(FormPage) editable_forms = editable_forms.filter(content_type=ct) # Apply hooks for fn in hooks.get_hooks('filter_form_submissions_for_user'): editable_forms = fn(user, editable_forms) return editable_forms
def get_queryset(self): pages = ((UserPagePermissionsProxy(self.request.user).editable_pages() | Page.objects.filter(locked_by=self.request.user)).filter( locked=True).specific(defer=True)) if getattr(settings, "WAGTAIL_I18N_ENABLED", False): pages = pages.select_related("locale") self.queryset = pages return super().get_queryset()
def test_page_locked_for_locked_page_with_global_lock_enabled(self): user = get_user_model().objects.get(username='******') christmas_page = EventPage.objects.get(url_path='/home/events/christmas/') # Lock the page christmas_page.locked = True christmas_page.locked_by = user christmas_page.locked_at = timezone.now() christmas_page.save() perms = UserPagePermissionsProxy(user).for_page(christmas_page) # The user who locked the page should now also see the page as locked self.assertTrue(perms.page_locked()) # Other users should see the page as locked, like before other_user = get_user_model().objects.get(username='******') other_perms = UserPagePermissionsProxy(other_user).for_page(christmas_page) self.assertTrue(other_perms.page_locked())
def test_lock_page_for_non_editing_user(self): user = get_user_model().objects.get( email="*****@*****.**") christmas_page = EventPage.objects.get( url_path="/home/events/christmas/") perms = UserPagePermissionsProxy(user).for_page(christmas_page) self.assertFalse(perms.can_lock()) self.assertFalse(perms.can_unlock())