Skip to content

Commit

Permalink
Merge branch 'release/3.4.x' into fixes-5828
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG.txt
  • Loading branch information
SteinRobert committed Jun 23, 2018
2 parents b0102ee + fb03471 commit a7d5083
Show file tree
Hide file tree
Showing 32 changed files with 124 additions and 21 deletions.
6 changes: 3 additions & 3 deletions .github/CONTRIBUTING.rst
Expand Up @@ -25,7 +25,7 @@ For *feature requests*, please use our `developers' email list
Contribution documentation
**************************

We maintain comprehensive `contribution documentation <http://docs.django-cms.org/en/stable/contributing/>`_ - please
We maintain comprehensive `contribution documentation <http://docs.django-cms.org/en/latest/contributing/>`_ - please
familiarise yourself with it.


Expand All @@ -51,7 +51,7 @@ Code of conduct
***************

django CMS is governed by a `Code of Conduct
<http://docs.django-cms.org/en/stable/contributing/code_of_conduct.html>`_. All participants in our community and its
<http://docs.django-cms.org/en/latest/contributing/code_of_conduct.html>`_. All participants in our community and its
various forums are expected to abide by it.


Expand All @@ -75,4 +75,4 @@ You can also follow:
* the `Travis Continuous Integration build reports <https://travis-ci.org/divio/django-cms>`_
* the `@djangocms`_ Twitter account for general announcements

.. _@djangocms : https://twitter.com/djangocms
.. _@djangocms : https://twitter.com/djangocms
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -314,6 +314,7 @@ Contributors (based on gitlog, 503 unique authors):
* martinkosir
* Matas Dailyda
* Mateusz Dereniowski
* Mateusz Kamycki
* Mateusz Marzantowicz
* mathijs
* Matt Chisholm
Expand Down
13 changes: 11 additions & 2 deletions CHANGELOG.txt
@@ -1,4 +1,13 @@
=== 3.4.6 (unreleased) ===
=== 3.4.7 (unreleased) ===

* Removed extra quotation mark from the sideframe button template
* Fixed a bug where xframe options were processed by clickjacking middleware
when page was served from cache, rather then get this value from cache
* Fixed a bug where cached page permissions overrides global permissions
* Fixed broken wizard page creation when no language is set within the template context (see #5828).


=== 3.4.6 (2018-03-26) ===

* Changed the way drag and drop works in the page tree. The page has to be
selected first before moving.
Expand All @@ -12,7 +21,7 @@
* Fixed an ``AttributeError`` raised when adding or removing apphooks in Django 1.11.
* Fixed an ``InconsistentMigrationHistory`` error raised when the contenttypes app
has a pending migration after the user has applied the ``0010_migrate_use_structure`` migration.
* Fixed broken wizard page creation when no language is set within the template context (see #5828).
* Fixed a bug where plugins rendered multiple times won't be editable


=== 3.4.5 (2017-10-12) ===
Expand Down
2 changes: 1 addition & 1 deletion cms/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-

__version__ = '3.4.5'
__version__ = '3.4.6'

default_app_config = 'cms.apps.CMSConfig'

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
Binary file removed cms/static/cms/fonts/3.4.5/django-cms-iconfont.woff2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
12 changes: 6 additions & 6 deletions cms/static/cms/sass/components/_iconography.scss
Expand Up @@ -4,12 +4,12 @@
// default font file generated by gulp
@font-face {
font-family: "django-cms-iconfont";
src: url("../../fonts/3.4.5/django-cms-iconfont.eot");
src: url("../../fonts/3.4.5/django-cms-iconfont.eot#iefix") format("eot"),
url("../../fonts/3.4.5/django-cms-iconfont.woff2") format("woff2"),
url("../../fonts/3.4.5/django-cms-iconfont.woff") format("woff"),
url("../../fonts/3.4.5/django-cms-iconfont.ttf") format("truetype"),
url("../../fonts/3.4.5/django-cms-iconfont.svg#django-cms-iconfont") format("svg");
src: url("../../fonts/3.4.6/django-cms-iconfont.eot");
src: url("../../fonts/3.4.6/django-cms-iconfont.eot#iefix") format("eot"),
url("../../fonts/3.4.6/django-cms-iconfont.woff2") format("woff2"),
url("../../fonts/3.4.6/django-cms-iconfont.woff") format("woff"),
url("../../fonts/3.4.6/django-cms-iconfont.ttf") format("truetype"),
url("../../fonts/3.4.6/django-cms-iconfont.svg#django-cms-iconfont") format("svg");
font-weight: normal;
font-style: normal;
}
Expand Down
2 changes: 1 addition & 1 deletion cms/templates/cms/toolbar/items/button_sideframe.html
@@ -1 +1 @@
<a href="{{ url }}" class="cms-btn{% if active %} cms-btn-active{% endif %}{% if disabled %} cms-btn-disabled{% endif %} {{ extra_classes|join:' ' }}" " data-rel="sideframe"{% if on_close %} data-on-close="{{ on_close }}"{% endif %}>{{ name }}</a>
<a href="{{ url }}" class="cms-btn{% if active %} cms-btn-active{% endif %}{% if disabled %} cms-btn-disabled{% endif %} {{ extra_classes|join:' ' }}" data-rel="sideframe"{% if on_close %} data-on-close="{{ on_close }}"{% endif %}>{{ name }}</a>
34 changes: 34 additions & 0 deletions cms/tests/test_page.py
Expand Up @@ -1009,6 +1009,40 @@ def test_top_level_page_inherited_xframe_options_are_applied(self):
resp = self.client.get(page.get_absolute_url('en'))
self.assertEqual(resp.get('X-Frame-Options'), 'SAMEORIGIN')

def test_xframe_options_with_cms_page_cache_and_clickjacking_middleware(self):
# Refs: 6346
if getattr(settings, 'MIDDLEWARE', None):
override = {
'MIDDLEWARE': settings.MIDDLEWARE + [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
}
else:
override = {
'MIDDLEWARE_CLASSES': settings.MIDDLEWARE_CLASSES + [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
}

override['CMS_PAGE_CACHE'] = True

with self.settings(**override):
page = create_page(
'test page 1',
'nav_playground.html',
'en',
published=True,
xframe_options=Page.X_FRAME_OPTIONS_ALLOW,
)

# Normal response from render_page
resp = self.client.get(page.get_absolute_url('en'))
self.assertEqual(resp.get('X-Frame-Options'), None)

# Response from page cache
resp = self.client.get(page.get_absolute_url('en'))
self.assertEqual(resp.get('X-Frame-Options'), None)


class PreviousFilteredSiblingsTests(CMSTestCase):

Expand Down
32 changes: 30 additions & 2 deletions cms/tests/test_permissions.py
Expand Up @@ -5,11 +5,19 @@
from cms.api import create_page, assign_user_to_page
from cms.cache.permissions import (get_permission_cache, set_permission_cache,
clear_user_permission_cache)
from cms.models.permissionmodels import GlobalPagePermission
from cms.test_utils.testcases import CMSTestCase
from cms.utils.page_permissions import get_change_id_list
from cms.utils.page_permissions import get_change_id_list, user_can_publish_page


@override_settings(CMS_PERMISSION=True)
@override_settings(
CMS_PERMISSION=True,
CMS_CACHE_DURATIONS={
'menus': 60,
'content': 60,
'permissions': 60,
},
)
class PermissionCacheTests(CMSTestCase):

def setUp(self):
Expand Down Expand Up @@ -65,3 +73,23 @@ def test_permission_manager(self):
self.home_page.save()
cached_permissions = get_permission_cache(self.user_normal, "change_page")
self.assertIsNone(cached_permissions)

def test_cached_permission_precedence(self):
# refs - https://github.com/divio/django-cms/issues/6335
# cached page permissions should not override global permissions
page = create_page(
"test page",
"nav_playground.html",
"en",
created_by=self.user_super,
)
page_permission = GlobalPagePermission.objects.create(
can_change=True,
can_publish=True,
user=self.user_normal,
)
page_permission.sites.add(Site.objects.get_current())
set_permission_cache(self.user_normal, "publish_page", [])

can_publish = user_can_publish_page(self.user_normal, page)
self.assertTrue(can_publish)
6 changes: 3 additions & 3 deletions cms/utils/page_permissions.py
Expand Up @@ -50,6 +50,9 @@ def _get_page_ids_for_action(user, site, action, check_global=True, use_cache=Tr
# just return grant all mark
return GRANT_ALL_PERMISSIONS

if check_global and has_global_permission(user, site, action=action, use_cache=use_cache):
return GRANT_ALL_PERMISSIONS

if use_cache:
# read from cache if possible
cached = get_permission_cache(user, action)
Expand All @@ -61,9 +64,6 @@ def _get_page_ids_for_action(user, site, action, check_global=True, use_cache=Tr
if cached is not None:
return cached

if check_global and has_global_permission(user, site, action=action, use_cache=use_cache):
return GRANT_ALL_PERMISSIONS

page_actions = get_page_actions(user, site)
page_ids = list(page_actions[action])
set_permission_cache(user, action, page_ids)
Expand Down
1 change: 1 addition & 0 deletions cms/views.py
Expand Up @@ -37,6 +37,7 @@ def details(request, slug):
if cache_content is not None:
content, headers, expires_datetime = cache_content
response = HttpResponse(content)
response.xframe_options_exempt = True
response._headers = headers
# Recalculate the max-age header for this cached response
max_age = int(
Expand Down
2 changes: 2 additions & 0 deletions docs/how_to/apphooks.rst
Expand Up @@ -60,6 +60,8 @@ then your ``MyApphook`` class should include::
If you fail to this, then any templates in the application that invoke URLs using the form ``{% url 'myapp:index' %}``
or views that call (for example) ``reverse('myapp:index')`` will throw a ``NoReverseMatch`` error.

If you had already assigned a page to your aplication prior to setting the ``app_name`` attribute, you'll also need to edit its *Advanced settings* and specify your ``app_name`` in the *Application instance name* field that now appears, to avoid the ``NoReverseMatch`` error (the instance name is filled automatically in new pages).

*Unless* the class that defines the apphook specifies an ``app_name``, it can be attached only to one page at a time.
Attempting to apply it a second time will cause an error. See :ref:`multi_apphook` for more on having multiple apphook
instances.
Expand Down
27 changes: 27 additions & 0 deletions docs/upgrade/3.4.6.rst
@@ -0,0 +1,27 @@
.. _upgrade-to-3.4.6:

###################
3.4.6 release notes
###################



*******************
What's new in 3.4.6
*******************

Bug Fixes
=========

* Changed the way drag and drop works in the page tree. The page has to be
selected first before moving.
* Fixed a bug where the cms alias plugin leaks context into the rendered aliased plugins.
* Fixed a bug where users without the "Change advanced settings" permission could still
change a page's template.
* Added ``on_delete`` to ``ForeignKey`` and ``OneToOneField`` to silence Django
deprecation warnings.
* Fixed a bug where the sitemap would ignore the ``public`` setting of the site languages
and thus display hidden languages.
* Fixed an ``AttributeError`` raised when adding or removing apphooks in Django 1.11.
* Fixed an ``InconsistentMigrationHistory`` error raised when the contenttypes app
has a pending migration after the user has applied the ``0010_migrate_use_structure`` migration.
1 change: 1 addition & 0 deletions docs/upgrade/index.rst
Expand Up @@ -13,6 +13,7 @@ makes changes to your database.
.. toctree::
:maxdepth: 1

3.4.6
3.4.5
3.4.4
3.4.3
Expand Down

0 comments on commit a7d5083

Please sign in to comment.