def add_view(self, request, form_url='', extra_context=None):
     """
     Ensure the user is not trying to add a published or visible page if
     they lack the necessary permissions.
     """
     if request.method == 'POST':
         lookup_perm = get_lookup_function(request.user, get_permissions())
         # In evaluating permissions for status and visibility, it's not
         # necessary to do more than raise a 403 if the user does not have
         # the necessary permissions; status and visibility are disabled
         # client side, so if they're not what they should be, the user is
         # doing something suspicious.
         if not lookup_perm('change_status'):
             form = self.get_form(request)(request.POST, request.FILES)
             if form.is_valid():
                 is_published_value = get_published_status_name()
                 if form.cleaned_data.get('status') == is_published_value:
                     raise PermissionDenied("Can't create published pages.")
         if not lookup_perm('change_visibility'):
             form = self.get_form(request)(request.POST, request.FILES)
             if form.is_valid():
                 is_public_value = get_public_visibility_name()
                 if form.cleaned_data.get('visibility') == is_public_value:
                     raise PermissionDenied("Can't create public pages.")
     return super(PageAdmin, self).add_view(request,
         form_url=form_url,
         extra_context=extra_context
     )
Beispiel #2
0
 def add_view(self, request, form_url='', extra_context=None):
     """
     Ensure the user is not trying to add a published or visible page if
     they lack the necessary permissions.
     """
     if request.method == 'POST':
         lookup_perm = get_lookup_function(request.user, get_permissions())
         # In evaluating permissions for status and visibility, it's not
         # necessary to do more than raise a 403 if the user does not have
         # the necessary permissions; status and visibility are disabled
         # client side, so if they're not what they should be, the user is
         # doing something suspicious.
         if not lookup_perm('change_status'):
             form = self.get_form(request)(request.POST, request.FILES)
             if form.is_valid():
                 is_published_value = get_published_status_name()
                 if form.cleaned_data.get('status') == is_published_value:
                     raise PermissionDenied("Can't create published pages.")
         if not lookup_perm('change_visibility'):
             form = self.get_form(request)(request.POST, request.FILES)
             if form.is_valid():
                 is_public_value = get_public_visibility_name()
                 if form.cleaned_data.get('visibility') == is_public_value:
                     raise PermissionDenied("Can't create public pages.")
     return super(PageAdmin, self).add_view(request,
                                            form_url=form_url,
                                            extra_context=extra_context)
Beispiel #3
0
    def render(self, context):
        permission_names = get_permissions()
        permissions = dict([(k, False) for k in permission_names.keys()])

        # Adding shortcut permission that combines ``view_private_pages`` and
        # `` view_draft_pages`` permissions.
        permissions['view_page'] = False
        try:
            user = self.user_var.resolve(context)
        except template.VariableDoesNotExist:
            # If user variable can't be resolved, all permissions are False.
            permissions = self._rename_permissions(permissions, "page")
            for permission_name, permission in permissions.items():
                context[permission_name] = permission
            return ''
        # If node variable can't be resolved, some permissions can still
        # be useful.
        try:
            node = self.node_var.resolve(context)
        except template.VariableDoesNotExist:
            node = None
            opts = get_pagemanager_model()._meta
        else:
            opts = node.__class__._meta

        lookup_perm = get_lookup_function(user,permission_names)

        # Shortcut: if the user is a superuser we can just set all permissions
        # to True and be done with it.
        if user.is_superuser:
            permissions = self._rename_permissions(
                permissions, opts.module_name
            )
            for permission_name, permission in permissions.items():
                context[permission_name] = True
            return ''

        # Determine visibility permissions.
        if node:
            if not node.is_visible() and lookup_perm('view_private_pages'):
                permissions['view_private_pages'] = True
            if not node.is_published() and lookup_perm('view_draft_pages'):
                permissions['view_draft_pages'] = True
            if (node.is_visible() or permissions['view_private_pages']) and \
                (node.is_published() or permissions['view_draft_pages']):
                permissions['view_page'] = True

        # Determine standard model permissions.
        for verb in ('add', 'change', 'delete'):
            permission_name = "%s_%s" % (verb, opts.module_name)
            if lookup_perm(permission_name):
                permissions[permission_name] = True
        # Commit all permissions to context:
        permissions = self._rename_permissions(permissions, opts.module_name)
        for permission_name, permission in permissions.items():
            context[permission_name] = permission
        return ''
    def change_view(self, request, object_id, extra_context=None):
        """
        Adds some initial permissions checks to ensure that users can't:

            1. view objects they don't have permissions on
            2. change item's publication status without needed permissions
            3. change item's visibility status without needed permissions

        """
        obj = self.get_object(request, unquote(object_id))
        obj_pages = obj.page.all()
        if len(obj_pages) == 1:
            page = obj_pages[0]
        else:
            val = obj_pages and "Zero" or "Multiple"
            raise ValueError((
                "%s pages relate to this layout. Only one page can "
                "relate to this layout and at least one page must do so."
            )) % val

        lookup_perm = get_lookup_function(request.user, get_permissions())
        # Reject users who don't have permission to view the page becuase
        # it's unpublished or invisible.
        if not page.is_visible() and not lookup_perm('view_private_pages'):
            # FIXME: remove details about exception after testing.
            raise PermissionDenied("Can't view invisible pages.")
        if not page.is_published() and not lookup_perm('view_draft_pages'):
            # FIXME: remove details about exception after testing.
            raise PermissionDenied("Can't view unpublished pages.")

        if request.method == 'POST':
            # If a user who doesn't have permissions to change is posting
            # data to this view, raise a PermissionDenied.
            if page.is_published() and not lookup_perm(
                'modify_published_pages'
            ):
                # FIXME: remove details about exception after testing.
                raise PermissionDenied("Can't modify published pages.")

            formset = self._get_page_formset(request)
            prefix = formset.get_default_prefix()
            ModelForm = self.get_form(request, obj)
            form = ModelForm(request.POST, request.FILES)
            changed_data = form.data
            opts = self.model._meta
            this_url = reverse(
                "admin:%s_%s_change" % (opts.app_label, opts.module_name),
                args=(object_id,)
            )

            def value_filter(name, prefix=None):
                def f(obj):
                    return obj.startswith(prefix) and obj.endswith(name)
                return f
            get_value_filter = partial(value_filter, prefix=prefix)

            # Verify that users can't change status if they don't have
            # permissions to do so.
            key_match = filter(get_value_filter('status'), changed_data)
            if key_match and changed_data[key_match[0]] != page.status:
                if not lookup_perm('change_status'):
                    message = (
                        "You don't have permission to change the status "
                        "of this page."
                    )
                    messages.add_message(request, messages.ERROR, message)
                    return HttpResponseRedirect(this_url)

            # Verify that users can't change visibility if they don't have
            # permissions to do so.
            key_match = filter(
                get_value_filter('visibility'),
                changed_data
            )
            if key_match and changed_data[key_match[0]] != page.visibility:
                if not lookup_perm('change_visibility'):
                    message = (
                        "You don't have permission to change the "
                        "visibility of this page."
                    )
                    messages.add_message(request, messages.ERROR, message)
                    return HttpResponseRedirect(this_url)

        # All permissions checks have passed.
        return super(PageLayoutAdmin, self).change_view(
            request,
            object_id,
            extra_context=None
        )
Beispiel #5
0
    def change_view(self, request, object_id, extra_context=None):
        """
        Adds some initial permissions checks to ensure that users can't:

            1. view objects they don't have permissions on
            2. change item's publication status without needed permissions
            3. change item's visibility status without needed permissions

        """
        obj = self.get_object(request, unquote(object_id))
        obj_pages = obj.page.all()
        if len(obj_pages) == 1:
            page = obj_pages[0]
        else:
            val = obj_pages and "Multiple" or "Zero"
            raise ValueError(
                ("%s pages relate to this layout. Only one page can "
                 "relate to this layout and at least one page must do so.") %
                val)

        lookup_perm = get_lookup_function(request.user, get_permissions())
        # Reject users who don't have permission to view the page becuase
        # it's unpublished or invisible.
        if not page.is_visible() and not lookup_perm('view_private_pages'):
            # FIXME: remove details about exception after testing.
            raise PermissionDenied("Can't view invisible pages.")
        if not page.is_published() and not lookup_perm('view_draft_pages'):
            # FIXME: remove details about exception after testing.
            raise PermissionDenied("Can't view unpublished pages.")

        if request.method == 'POST':
            # If a user who doesn't have permissions to change is posting
            # data to this view, raise a PermissionDenied.
            if page.is_published(
            ) and not lookup_perm('modify_published_pages'):
                # FIXME: remove details about exception after testing.
                raise PermissionDenied("Can't modify published pages.")

            formset = self._get_page_formset(request)
            prefix = formset.get_default_prefix()
            ModelForm = self.get_form(request, obj)
            form = ModelForm(request.POST, request.FILES)
            changed_data = form.data
            opts = self.model._meta
            this_url = reverse("admin:%s_%s_change" %
                               (opts.app_label, opts.module_name),
                               args=(object_id, ))

            def value_filter(name, prefix=None):
                def f(obj):
                    return obj.startswith(prefix) and obj.endswith(name)

                return f

            get_value_filter = partial(value_filter, prefix=prefix)

            # Verify that users can't change status if they don't have
            # permissions to do so.
            key_match = filter(get_value_filter('status'), changed_data)
            if key_match and changed_data[key_match[0]] != page.status:
                if not lookup_perm('change_status'):
                    message = (
                        "You don't have permission to change the status "
                        "of this page.")
                    messages.add_message(request, messages.ERROR, message)
                    return HttpResponseRedirect(this_url)

            # Verify that users can't change visibility if they don't have
            # permissions to do so.
            key_match = filter(get_value_filter('visibility'), changed_data)
            if key_match and changed_data[key_match[0]] != page.visibility:
                if not lookup_perm('change_visibility'):
                    message = ("You don't have permission to change the "
                               "visibility of this page.")
                    messages.add_message(request, messages.ERROR, message)
                    return HttpResponseRedirect(this_url)
            # Fire the custom signal for page editing in the admin.
            signals.page_edited.send(sender=self, page=page, created=False)

        # All permissions checks have passed.
        return super(PageLayoutAdmin, self).change_view(request,
                                                        object_id,
                                                        extra_context=None)