예제 #1
0
def get_visible_page_objects(request, pages, site=None):
    """
     This code is basically a many-pages-at-once version of
     Page.has_view_permission.
     pages contains all published pages
     check if there is ANY restriction
     that needs a permission page visibility calculation
    """
    public_for = get_cms_setting('PUBLIC_FOR')
    can_see_unrestricted = public_for == 'all' or (public_for == 'staff'
                                                   and request.user.is_staff)
    is_auth_user = request.user.is_authenticated()

    restricted_pages = load_view_restrictions(request, pages)
    if not restricted_pages:
        if can_see_unrestricted:
            return pages
        elif not is_auth_user:
            return [
            ]  # Unauth user can't acquire global or user perm to see pages

    if get_cms_setting('PERMISSION') and not site:
        site = current_site(request)  # avoid one extra query when possible
    if has_global_page_permission(request, site, can_view=True):
        return pages

    has_global_perm = SimpleLazyObject(
        lambda: request.user.has_perm('cms.view_page'))
    user_groups = SimpleLazyObject(
        lambda: set(request.user.groups.values_list('pk', flat=True)))

    def has_permission_membership(page_id):
        """
        PagePermission user group membership tests
        """
        user_pk = request.user.pk
        for perm in restricted_pages[page_id]:
            if perm.user_id == user_pk or perm.group_id in user_groups:
                return True
        return False

    visible_pages = []
    for page in pages:
        to_add = False
        page_id = page.pk
        is_restricted = page_id in restricted_pages
        # restricted_pages contains as key any page.pk that is
        # affected by a permission grant_on
        if not is_restricted and can_see_unrestricted:
            to_add = True
        elif is_auth_user:
            # setting based handling of unrestricted pages
            # check group and user memberships to restricted pages
            if is_restricted and has_permission_membership(
                    page_id) or has_global_perm:
                to_add = True
        if to_add:
            visible_pages.append(page)

    return visible_pages
예제 #2
0
def get_visible_page_objects(request, pages, site=None):
    """
     This code is basically a many-pages-at-once version of
     Page.has_view_permission.
     pages contains all published pages
     check if there is ANY restriction
     that needs a permission page visibility calculation
    """
    public_for = get_cms_setting('PUBLIC_FOR')
    can_see_unrestricted = public_for == 'all' or (
        public_for == 'staff' and request.user.is_staff)
    is_auth_user = request.user.is_authenticated()

    restricted_pages = load_view_restrictions(request, pages)
    if not restricted_pages:
        if can_see_unrestricted:
            return pages
        elif not is_auth_user:
            return []  # Unauth user can't acquire global or user perm to see pages

    if get_cms_setting('PERMISSION') and not site:
        site = current_site(request)  # avoid one extra query when possible
    if has_global_page_permission(request, site, can_view=True):
        return pages

    has_global_perm = SimpleLazyObject(lambda: request.user.has_perm('cms.view_page'))
    user_groups = SimpleLazyObject(lambda: set(request.user.groups.values_list('pk', flat=True)))

    def has_permission_membership(page_id):
        """
        PagePermission user group membership tests
        """
        user_pk = request.user.pk
        for perm in restricted_pages[page_id]:
            if perm.user_id == user_pk or perm.group_id in user_groups:
                return True
        return False

    visible_pages = []
    for page in pages:
        to_add = False
        page_id = page.pk
        is_restricted = page_id in restricted_pages
        # restricted_pages contains as key any page.pk that is
        # affected by a permission grant_on
        if not is_restricted and can_see_unrestricted:
            to_add = True
        elif is_auth_user:
            # setting based handling of unrestricted pages
            # check group and user memberships to restricted pages
            if is_restricted and has_permission_membership(page_id) or has_global_perm:
                to_add = True
        if to_add:
            visible_pages.append(page)

    return visible_pages
예제 #3
0
    def set_items(self, request):
        site = self.current_site()
        # Get all the pages, ordered by tree ID (it's convenient to build the
        # tree using a stack now)
        pages = self.get_query_set(request).drafts().order_by(
            'tree_id', 'lft').select_related()

        # Get lists of page IDs for which the current user has
        # "permission to..." on the current site.
        perm_edit_ids = Page.permissions.get_change_id_list(request.user, site)
        perm_publish_ids = Page.permissions.get_publish_id_list(
            request.user, site)
        perm_advanced_settings_ids = Page.permissions.get_advanced_settings_id_list(
            request.user, site)
        perm_change_list_ids = Page.permissions.get_change_id_list(
            request.user, site)

        if perm_edit_ids and perm_edit_ids != Page.permissions.GRANT_ALL:
            pages = pages.filter(pk__in=perm_edit_ids)
            #pages = pages.filter(pk__in=perm_change_list_ids)

        root_pages = []
        # Cache view restrictions for the is_restricted template tag
        load_view_restrictions(request, pages)
        pages = list(pages)
        all_pages = pages[:]  # That is, basically, a copy.
        try:
            home_pk = Page.objects.drafts().get_home(site).pk
        except NoHomeFound:
            home_pk = 0

        # page moderator states
        pm_qs = PageModeratorState.objects.filter(
            page__in=pages).order_by('page')
        pm_states = defaultdict(list)
        for state in pm_qs:
            pm_states[state.page_id].append(state)

        public_page_id_set = Page.objects.public().filter(
            published=True, publisher_public__in=pages).values_list('id',
                                                                    flat=True)

        # Unfortunately we cannot use the MPTT builtin code for pre-caching
        # the children here, because MPTT expects the tree to be 'complete'
        # and otherwise complaints about 'invalid item order'
        cache_tree_children(pages)
        ids = dict((page.id, page) for page in pages)

        for page in pages:

            children = list(page.get_children())

            # If the parent page is not among the nodes shown, this node should
            # be a "root node". The filtering for this has already been made, so
            # using the ids dictionary means this check is constant time
            page.root_node = page.parent_id not in ids

            if get_cms_setting('PERMISSION'):
                # caching the permissions
                page.permission_edit_cache = perm_edit_ids == Page.permissions.GRANT_ALL or page.pk in perm_edit_ids
                page.permission_publish_cache = perm_publish_ids == Page.permissions.GRANT_ALL or page.pk in perm_publish_ids
                page.permission_advanced_settings_cache = perm_advanced_settings_ids == Page.permissions.GRANT_ALL or page.pk in perm_advanced_settings_ids
                page.permission_user_cache = request.user

            page._moderator_state_cache = pm_states[page.pk]
            page._public_published_cache = page.publisher_public_id in public_page_id_set
            if page.root_node or self.is_filtered():
                page.last = True
                if len(children):
                    # TODO: WTF!?!
                    # The last one is not the last... wait, what?
                    # children should NOT be a queryset. If it is, check that
                    # your django-mptt version is 0.5.1
                    children[-1].last = False
                page.menu_level = 0
                root_pages.append(page)
                if page.parent_id:
                    page.get_cached_ancestors(ascending=True)
                else:
                    page.ancestors_ascending = []
                page.home_pk_cache = home_pk

            # Because 'children' is the reverse-FK accessor for the 'parent'
            # FK from Page->Page, we have to use wrong English here and set
            # an attribute called 'childrens'. We are aware that this is WRONG
            # but what should we do?

            # If the queryset is filtered, do NOT set the 'childrens' attribute
            # since *ALL* pages will be in the 'root_pages' list and therefore
            # be displayed. (If the queryset is filtered, the result is not a
            # tree but rather a flat list).
            if self.is_filtered():
                page.childrens = []
            else:
                page.childrens = children

        for page in all_pages:
            page.title_cache = {}
            page.all_languages = []

        titles = Title.objects.filter(page__in=ids)
        insort = bisect.insort  # local copy to avoid globals lookup in the loop
        for title in titles:
            page = ids[title.page_id]
            page.title_cache[title.language] = title
            if not title.language in page.all_languages:
                insort(page.all_languages, title.language)
        self.root_pages = root_pages
예제 #4
0
    def set_items(self, request):
        site = self.current_site()
        # Get all the pages, ordered by tree ID (it's convenient to build the
        # tree using a stack now)
        pages = self.get_queryset(request).drafts().order_by('path').select_related('publisher_public')

        # Get lists of page IDs for which the current user has
        # "permission to..." on the current site.
        if get_cms_setting('PERMISSION'):
            perm_edit_ids = Page.permissions.get_change_id_list(request.user, site)
            perm_publish_ids = Page.permissions.get_publish_id_list(request.user, site)
            perm_advanced_settings_ids = Page.permissions.get_advanced_settings_id_list(request.user, site)
            restricted_ids = Page.permissions.get_restricted_id_list(site)
            if perm_edit_ids and perm_edit_ids != Page.permissions.GRANT_ALL:
                pages = pages.filter(pk__in=perm_edit_ids)

        root_pages = []
        # Cache view restrictions for the is_restricted template tag
        load_view_restrictions(request, pages)
        pages = list(pages)
        all_pages = pages[:] # That is, basically, a copy.
        # Unfortunately we cannot use the MPTT builtin code for pre-caching
        # the children here, because MPTT expects the tree to be 'complete'
        # and otherwise complaints about 'invalid item order'
        cache_tree_children(pages)
        ids = dict((page.id, page) for page in pages)
        parent_ids = {}
        for page in pages:
            if not page.parent_id in parent_ids:
                parent_ids[page.parent_id] = []
            parent_ids[page.parent_id].append(page)
        for page in pages:
            children = parent_ids.get(page.pk, [])
            # If the parent page is not among the nodes shown, this node should
            # be a "root node". The filtering for this has already been made, so
            # using the ids dictionary means this check is constant time
            page.root_node = page.parent_id not in ids

            if get_cms_setting('PERMISSION'):
                # caching the permissions
                page.permission_edit_cache = perm_edit_ids == Page.permissions.GRANT_ALL or page.pk in perm_edit_ids
                page.permission_publish_cache = perm_publish_ids == Page.permissions.GRANT_ALL or page.pk in perm_publish_ids
                page.permission_advanced_settings_cache = perm_advanced_settings_ids == Page.permissions.GRANT_ALL or page.pk in perm_advanced_settings_ids
                page.permission_user_cache = request.user
                page.permission_restricted = page.pk in restricted_ids
            if page.root_node or self.is_filtered():
                page.last = True
                if len(children):
                    # TODO: WTF!?!
                    # The last one is not the last... wait, what?
                    # children should NOT be a queryset. If it is, check that
                    # your django-mptt version is 0.5.1
                    children[-1].last = False
                page.menu_level = 0
                root_pages.append(page)
                if page.parent_id:
                    page.get_cached_ancestors()
                else:
                    page.ancestors_ascending = []

            # Because 'children' is the reverse-FK accessor for the 'parent'
            # FK from Page->Page, we have to use wrong English here and set
            # an attribute called 'childrens'. We are aware that this is WRONG
            # but what should we do?

            # If the queryset is filtered, do NOT set the 'childrens' attribute
            # since *ALL* pages will be in the 'root_pages' list and therefore
            # be displayed. (If the queryset is filtered, the result is not a
            # tree but rather a flat list).
            if self.is_filtered():
                page.childrens = []
            else:
                page.childrens = children

        for page in all_pages:
            page.title_cache = {}
            page.all_languages = []
            if page.publisher_public_id:
                page.publisher_public.title_cache = {}
                page.publisher_public.all_languages = []
                ids[page.publisher_public_id] = page.publisher_public

        titles = Title.objects.filter(page__in=ids)
        insort = bisect.insort # local copy to avoid globals lookup in the loop
        for title in titles:
            page = ids[title.page_id]
            page.title_cache[title.language] = title
            if not title.language in page.all_languages:
                insort(page.all_languages, title.language)
        site_id = self.current_site()
        languages = get_language_list(site_id)
        for page in all_pages:
            for lang in languages:
                if not lang in page.title_cache:
                    page.title_cache[lang] = EmptyTitle(lang)
        self.root_pages = root_pages