Example #1
0
def get_user_sites_queryset(user):
    """
    Returns queryset of all sites available for given user.
    
    1.  For superuser always returns all sites.
    2.  For global user returns all sites he haves in global page permissions 
        together with any sites he is assigned to over an page.
    3.  For standard user returns just sites he is assigned to over pages.
    """
    qs = Site.objects.all()

    if user.is_superuser:
        return qs

    global_ids = (
        GlobalPagePermission.objects.with_user(user)
        .filter(Q(can_add=True) | Q(can_change=True))
        .values_list("id", flat=True)
    )

    query = Q()
    if global_ids:
        query = Q(globalpagepermission__id__in=global_ids)
        # haves some global permissions assigned
        if not qs.filter(query).exists():
            # haves global permissions, but none of sites is specified,
            # so he haves access to all sites
            return qs
    # add some pages if he has permission to add / change them
    query |= Q(
        Q(page__pagepermission__user=user) | Q(**{get_user_related_through_group("page__pagepermission__group"): user})
    ) & (Q(Q(page__pagepermission__can_add=True) | Q(page__pagepermission__can_change=True)))
    return qs.filter(query).distinct()
Example #2
0
def get_visible_pages(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')
    is_setting_public_all = public_for == 'all'
    is_setting_public_staff = public_for == 'staff'
    is_auth_user = request.user.is_authenticated()
    visible_page_ids = []
    restricted_pages = defaultdict(list)
    page_permissions = PagePermission.objects.filter(can_view=True).select_related('page', get_user_related_through_group('group'))

    for perm in page_permissions:

        # collect the pages that are affected by permissions
        if site and perm.page.site_id != site.pk:
            continue
        if perm is not None and perm not in restricted_pages[perm.page.pk]:
            # affective restricted pages gathering
            # using mptt functions 
            # add the page with the perm itself
            if perm.grant_on in [ACCESS_PAGE, ACCESS_PAGE_AND_CHILDREN, ACCESS_PAGE_AND_DESCENDANTS]:
                restricted_pages[perm.page.pk].append(perm)
                restricted_pages[perm.page.publisher_public_id].append(perm)
                # add children
            if perm.grant_on in [ACCESS_CHILDREN, ACCESS_PAGE_AND_CHILDREN]:
                child_ids = perm.page.get_children().values_list('id', 'publisher_public_id')
                for id, public_id in child_ids:
                    restricted_pages[id].append(perm)
                    restricted_pages[public_id].append(perm)
            # add descendants
            elif perm.grant_on in [ACCESS_DESCENDANTS, ACCESS_PAGE_AND_DESCENDANTS]:
                child_ids = perm.page.get_descendants().values_list('id', 'publisher_public_id')
                for id, public_id in child_ids:
                    restricted_pages[id].append(perm)
                    restricted_pages[public_id].append(perm)

    # anonymous
    # no restriction applied at all
    if (not is_auth_user and
        is_setting_public_all and
        not restricted_pages):
        return [page.pk for page in pages]

    if site is None:
        site = current_site(request)

    # authenticated user and global permission
    if is_auth_user:

        global_page_perm_q = Q(
            Q(user=request.user) | Q(**{get_user_related_through_group('group'): request.user})
        ) & Q(can_view=True) & Q(Q(sites__in=[site.pk]) | Q(sites__isnull=True))
        global_view_perms = GlobalPagePermission.objects.filter(global_page_perm_q).exists()

        #no page perms edge case - all visible
        if ((is_setting_public_all or (
                is_setting_public_staff and request.user.is_staff)) and
            not restricted_pages and
            not global_view_perms):
            return [page.pk for page in pages]
        #no page perms edge case - none visible
        elif (is_setting_public_staff and
            not request.user.is_staff and
            not restricted_pages and
            not global_view_perms):
            return []


    def has_global_perm():
        if has_global_perm.cache < 0:
            has_global_perm.cache = 1 if request.user.has_perm('cms.view_page') else 0
        return bool(has_global_perm.cache)

    has_global_perm.cache = -1

    def has_permission_membership(page):
        """
        PagePermission user group membership tests
        """
        user_pk = request.user.pk
        page_pk = page.pk
        has_perm = False
        for perm in restricted_pages[page_pk]:
            if perm.user_id == user_pk:
                has_perm = True
            if not perm.group_id:
                continue
            group_user_ids = perm.group.user_set.values_list('pk', flat=True)
            if user_pk in group_user_ids:
                has_perm = True
        return has_perm

    for page in pages:
        to_add = False
        # default to false, showing a restricted page is bad
        # explicitly check all the conditions
        # of settings and permissions
        is_restricted = page.pk in restricted_pages
        # restricted_pages contains as key any page.pk that is
        # affected by a permission grant_on
        if is_auth_user:
            # a global permission was given to the request's user
            if global_view_perms:
                to_add = True
            # setting based handling of unrestricted pages
            elif not is_restricted and (
                    is_setting_public_all or (
                        is_setting_public_staff and request.user.is_staff)
            ):
                # authenticated user, no restriction and public for all
                # or 
                # authenticated staff user, no restriction and public for staff
                to_add = True
            # check group and user memberships to restricted pages
            elif is_restricted and has_permission_membership(page):
                to_add = True
            elif has_global_perm():
                to_add = True
        # anonymous user, no restriction  
        elif not is_restricted and is_setting_public_all:
            to_add = True
            # store it
        if to_add:
            visible_page_ids.append(page.pk)
    return visible_page_ids
Example #3
0
 def with_user(self, user):
     """Get all objects for given user, also takes look if user is in some
     group.
     """
     return self.filter(Q(user=user) | Q(**{get_user_related_through_group('group'): user}))