10000 Fixed #6428 -- Force page nodes to render based on the request page instead of request mode by czpython · Pull Request #6549 · django-cms/django-cms · GitHub
[go: up one dir, main page]

Skip to content

Fixed #6428 -- Force page nodes to render based on the request page instead of request mode #6549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
10000 Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* Fixed a bug where setting the ``on_delete`` option on ``PlaceholderField``
and ``PageField`` fields would be ignored.
* Fixed a bug when deleting a modal from changelist inside a modal
* Fixed a bug where the menu would render draft pages even if the page on the request
was a public page. This happens when a user without change permissions requests edit mode.


=== 3.5.2 (2018-04-11) ===
Expand Down
22 changes: 22 additions & 0 deletions cms/tests/test_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,28 @@ def test_show_menu_cache_key_leak(self):
tpl.render(context)
self.assertEqual(CacheKey.objects.count(), 1)

def test_menu_nodes_request_page_takes_precedence(self):
"""
Tests a condition where the user requests a draft page
but the page object on the request is a public page.
This can happen when the user has no permissions to edit
the requested draft page.
"""
public_page = self.get_page(1)
draft_page = public_page.publisher_public
edit_on_path = draft_page.get_absolute_url() + '?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')

with self.login_user_context(self.get_superuser()):
context = self.get_context(path=edit_on_path, page=public_page)
context['request'].session['cms_edit'] = True
Template("{% load menu_tags %}{% show_menu %}").render(context)
# All nodes should be public nodes because the request page is public
nodes = [node for node in context['children']]
node_ids = [node.id for node in nodes]
page_count = Page.objects.public().filter(pk__in=node_ids).count()
self.assertEqual(len(node_ids), page_count, msg='Not all pages in the public menu are public')
self.assertEqual(nodes[0].selected, True)

def test_menu_cache_draft_only(self):
# Tests that the cms uses a separate cache for draft & live
public_page = self.get_page(1)
Expand Down
12 changes: 11 additions & 1 deletion menus/menu_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ def __init__(self, pool, request):
self.request = request
self.request_language = get_language_from_request(request, check_path=True)
self.site = Site.objects.get_current(request)
self.draft_mode_active = use_draft(request)

@property
def cache_key(self):
Expand All @@ -121,6 +120,17 @@ def cache_key(self):
key += ':public'
return key

@cached_property
def draft_mode_active(self):
try:
# Under certain conditions, the request page won't match
# the requested state.
# For example, user requests draft page but gets public.
_use_draft = self.request.current_page.publisher_is_draft
except AttributeError:
_use_draft = use_draft(self.request)
return _use_draft

@cached_property
def is_cached(self):
db_cache_key_lookup = CacheKey.objects.filter(
Expand Down
0