Skip to content

Commit

Permalink
Merge branch 'develop' of git://github.com/divio/django-cms into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
kezabelle committed Aug 6, 2011
2 parents 9816e49 + 824ca41 commit 1219d84
Show file tree
Hide file tree
Showing 14 changed files with 641 additions and 42 deletions.
2 changes: 1 addition & 1 deletion cms/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
__version__ = '2.2.dev0'
__version__ = '2.2b1.post1'

# patch settings
try:
Expand Down
1 change: 1 addition & 0 deletions cms/forms/widgets.py
Expand Up @@ -132,6 +132,7 @@ class Media:
js = [cms_static_url(path) for path in (
'js/libs/jquery.ui.core.js',
'js/libs/jquery.ui.sortable.js',
'js/plugin_editor.js',
)]
css = {
'all': [cms_static_url(path) for path in (
Expand Down
93 changes: 87 additions & 6 deletions cms/menu.py
@@ -1,13 +1,91 @@
# -*- coding: utf-8 -*-
from menus.menu_pool import menu_pool
from menus.base import Menu, NavigationNode, Modifier
from collections import defaultdict
from cms.apphook_pool import apphook_pool
from cms.models.moderatormodels import (ACCESS_DESCENDANTS,
ACCESS_PAGE_AND_DESCENDANTS, ACCESS_CHILDREN, ACCESS_PAGE_AND_CHILDREN)
from cms.models.permissionmodels import PagePermission, GlobalPagePermission
from cms.models.titlemodels import Title
from cms.utils import get_language_from_request
from cms.utils.i18n import get_fallback_languages
from cms.utils.moderator import get_page_queryset, get_title_queryset
from cms.utils.plugins import current_site
from django.conf import settings
from django.contrib.sites.models import Site
from cms.utils.i18n import get_fallback_languages
from cms.apphook_pool import apphook_pool
from cms.models.titlemodels import Title
from django.db.models.query_utils import Q
from menus.base import Menu, NavigationNode, Modifier
from menus.menu_pool import menu_pool


def get_visible_pages(request, pages, site=None):
# This code is basically a many-pages-at-once version of
# Page.has_view_permission, check there to see wtf is going on here.
if request.user.is_staff and settings.CMS_PUBLIC_FOR in ('staff', 'all'):
return [page.pk for page in pages]
page_ids = []

pages_perms_q = Q()
for page in pages:
page_q = Q(page__tree_id=page.tree_id) & (
Q(page=page)
| (Q(page__level__lt=page.level) & (Q(grant_on=ACCESS_DESCENDANTS) | Q(grant_on=ACCESS_PAGE_AND_DESCENDANTS)))
| (Q(page__level=page.level - 1) & (Q(grant_on=ACCESS_CHILDREN) | Q(grant_on=ACCESS_PAGE_AND_CHILDREN)))
)
pages_perms_q |= page_q
pages_perms_q &= Q(can_view=True)
page_permissions = PagePermission.objects.filter(pages_perms_q).select_related('page', 'group__users')

restricted_pages = defaultdict(list)
for perm in page_permissions:
restricted_pages[perm.page.pk].append(perm)

if site is None:
site = current_site(request)

if request.user.is_authenticated():
#return self.filter(Q(user=user) | Q(group__user=user))
global_page_perm_q = Q(
Q(user=request.user) | Q(group__user=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()

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(page):
"""
PagePermission tests
"""
for perm in restricted_pages[page.pk]:
if perm.user_id == request.user.pk:
return True
for perm in restricted_pages[page.pk]:
if not perm.group_id:
continue
if request.user.pk in perm.group.user_set.values_list('id', flat=True):
return True
return False

for page in pages:
is_restricted = page.pk in restricted_pages

if request.user.is_authenticated():
# a global permission was given to the request's user
if global_view_perms:
page_ids.append(page.pk)
# authenticated user, no restriction and public for all
elif settings.CMS_PUBLIC_FOR == 'all':
page_ids.append(page.pk)
elif has_permission(page):
page_ids.append(page.pk)
elif has_global_perm():
page_ids.append(page.pk)
elif not is_restricted and settings.CMS_PUBLIC_FOR == 'all':
# anonymous user, no restriction saved in database
page_ids.append(page.pk)
return page_ids

def page_to_node(page, home, cut):
'''
Expand Down Expand Up @@ -97,11 +175,14 @@ def get_nodes(self, request):
home_children = []
home = None
actual_pages = []

# cache view perms
visible_pages = get_visible_pages(request, pages, site)

for page in pages:
# Pages are ordered by tree_id, therefore the first page is the root
# of the page tree (a.k.a "home")
if not page.has_view_permission(request):
if page.pk not in visible_pages:
# Don't include pages the user doesn't have access to
continue
if not home:
Expand Down
37 changes: 18 additions & 19 deletions cms/models/pagemodel.py
@@ -1,8 +1,14 @@
# -*- coding: utf-8 -*-
import copy
from cms.exceptions import NoHomeFound
from cms.models.managers import PageManager, PagePermissionsPermissionManager
from cms.models.metaclasses import PageMetaClass
from cms.models.placeholdermodel import Placeholder
from cms.models.pluginmodel import CMSPlugin
from cms.publisher.errors import MpttPublisherCantPublish
from cms.utils import i18n, urlutils, page as page_utils
from cms.utils.copy_plugins import copy_plugins_to
from cms.utils.helpers import reversion_register
from datetime import datetime
from os.path import join

from django.conf import settings
from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
Expand All @@ -12,20 +18,14 @@
from django.db.models.fields.related import OneToOneRel
from django.shortcuts import get_object_or_404
from django.utils.translation import get_language, ugettext_lazy as _
from menus.menu_pool import menu_pool
from mptt.models import MPTTModel
from os.path import join
import copy


from cms.exceptions import NoHomeFound
from cms.models.managers import PageManager, PagePermissionsPermissionManager
from cms.models.metaclasses import PageMetaClass
from cms.models.placeholdermodel import Placeholder
from cms.models.pluginmodel import CMSPlugin

from cms.publisher.errors import MpttPublisherCantPublish
from cms.utils.copy_plugins import copy_plugins_to
from cms.utils.helpers import reversion_register
from cms.utils import i18n, urlutils, page as page_utils

from menus.menu_pool import menu_pool
from mptt.models import MPTTModel


class Page(MPTTModel):
Expand Down Expand Up @@ -713,15 +713,14 @@ def has_view_permission(self, request):

if request.user.is_authenticated():
site = current_site(request)
global_perms_q = Q(can_view=True) & Q(
Q(sites__in=[site]) | Q(sites__isnull=True)
)
global_view_perms = GlobalPagePermission.objects.with_user(
request.user).filter(can_view=True, sites__in=[site]).exists()
request.user).filter(global_perms_q).exists()
# a global permission was given to the request's user
if global_view_perms:
return True
# authenticated user, no restriction and public for all fallback
if (not is_restricted and not global_view_perms and
not settings.CMS_PUBLIC_FOR == 'all'):
return False
# authenticated user, no restriction and public for all
if (not is_restricted and not global_view_perms and
settings.CMS_PUBLIC_FOR == 'all'):
Expand Down
8 changes: 5 additions & 3 deletions cms/signals.py
Expand Up @@ -194,7 +194,7 @@ def pre_save_page(instance, raw, **kwargs):
pass


def post_save_page(instance, raw, created, **kwargs):
def post_save_page_moderator(instance, raw, created, **kwargs):
"""Helper post save signal, cleans old_page attribute.
"""
old_page = instance.old_page
Expand All @@ -204,12 +204,13 @@ def post_save_page(instance, raw, created, **kwargs):
# tell moderator something was happen with this page
from cms.utils.moderator import page_changed
page_changed(instance, old_page)

def post_save_page(instance, **kwargs):
for page in instance.get_descendants():
for title in page.title_set.all():
update_title(title)
title.save()


def update_placeholders(instance, **kwargs):
instance.rescan_placeholders()

Expand All @@ -219,7 +220,8 @@ def invalidate_menu_cache(instance, **kwargs):
if settings.CMS_MODERATOR:
# tell moderator, there is something happening with this page
signals.pre_save.connect(pre_save_page, sender=Page, dispatch_uid="cms.page.presave")
signals.post_save.connect(post_save_page, sender=Page, dispatch_uid="cms.page.postsave")
signals.post_save.connect(post_save_page_moderator, sender=Page, dispatch_uid="cms.page.postsave")
signals.post_save.connect(post_save_page, sender=Page)
signals.post_save.connect(update_placeholders, sender=Page)
signals.pre_save.connect(invalidate_menu_cache, sender=Page)
signals.pre_delete.connect(invalidate_menu_cache, sender=Page)
Expand Down
1 change: 1 addition & 0 deletions cms/test_utils/fixtures/menus.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from cms.api import create_page
from cms.models.pagemodel import Page
from cms.test_utils.util.context_managers import SettingsOverride
Expand Down
1 change: 1 addition & 0 deletions cms/test_utils/fixtures/navextenders.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from cms.api import create_page
from cms.models.pagemodel import Page
from cms.test_utils.util.context_managers import SettingsOverride
Expand Down
1 change: 1 addition & 0 deletions cms/test_utils/fixtures/templatetags.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from cms.api import create_page, create_title
from cms.test_utils.util.context_managers import SettingsOverride

Expand Down
6 changes: 4 additions & 2 deletions cms/test_utils/util/context_managers.py
Expand Up @@ -170,9 +170,11 @@ def __exit__(self, exc_type, exc_value, traceback):

final_queries = len(self.connection.queries)
executed = final_queries - self.starting_queries

queries = '\n'.join([q['sql'] for q in self.connection.queries[self.starting_queries:]])

self.test_case.assertEqual(
executed, self.num, "%d queries executed, %d expected" % (
executed, self.num
executed, self.num, "%d queries executed, %d expected. Queries executed:\n%s" % (
executed, self.num, queries
)
)

0 comments on commit 1219d84

Please sign in to comment.