Skip to content

Commit

Permalink
Merge branch 'django-cms:master' into feat/timed-publication
Browse files Browse the repository at this point in the history
  • Loading branch information
fsbraun authored Apr 24, 2024
2 parents 99282fe + f726bc2 commit 2724a99
Show file tree
Hide file tree
Showing 30 changed files with 639 additions and 143 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ jobs:
uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
if: ${{ matrix.language == 'javascript' || matrix.language == 'python' }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
python-version: '3.11'
cache: 'pip'
- name: Cache dependencies
uses: actions/[email protected].1
uses: actions/[email protected].2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.txt') }}
Expand All @@ -44,7 +44,7 @@ jobs:
python-version: '3.11'
cache: 'pip'
- name: Cache dependencies
uses: actions/[email protected].1
uses: actions/[email protected].2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.txt') }}
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@
Changelog
=========

2.0.1 (2024-03-29)
==================

* feat: Add content object level publish permissions by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/390
* fix: Create missing __init__.py in management folder by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/366
* fix #363: Better UX in versioning listview by @jrief in https://github.com/django-cms/djangocms-versioning/pull/364
* fix: Several fixes for the versioning forms: #382, #383, #384 by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/386
* fix: For Django CMS 4.1.1 and later do not automatically register versioned CMS Menu by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/388
* fix: Post requests from the side frame were sent to wrong URL by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/396
* fix: Consistent use of action buttons by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/392
* fix: Avoid duplication of placeholder checks for locked versions by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/393
* ci: Add testing against django main by @marksweb in https://github.com/django-cms/djangocms-versioning/pull/353
* ci: Improve efficiency of ruff workflow by @marksweb in https://github.com/django-cms/djangocms-versioning/pull/378
* Chore: update ruff and pre-commit hook by @raffaellasuardini in https://github.com/django-cms/djangocms-versioning/pull/381
* build(deps): bump actions/cache from 4.0.1 to 4.0.2 by @dependabot in https://github.com/django-cms/djangocms-versioning/pull/397

New Contributors

* @raffaellasuardini made their first contribution in https://github.com/django-cms/djangocms-versioning/pull/381
* @jrief made their first contribution in https://github.com/django-cms/djangocms-versioning/pull/364

2.0.0 (2023-12-29)
==================
Expand Down
2 changes: 1 addition & 1 deletion djangocms_versioning/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.0.0"
__version__ = "2.0.1"
40 changes: 15 additions & 25 deletions djangocms_versioning/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,9 @@ class VersionAdmin(ChangeListActionsMixin, admin.ModelAdmin, metaclass=MediaDefi
# def get_queryset(self, request):
# return super().get_queryset(request).prefetch_related('content')

class Media:
js = ["djangocms_versioning/js/versioning.js"]

def get_changelist(self, request, **kwargs):
return VersionChangeList

Expand Down Expand Up @@ -682,13 +685,13 @@ def _get_archive_link(self, obj, request, disabled=False):
icon="archive",
title=_("Archive"),
name="archive",
disabled=not obj.can_be_archived(),
disabled=not obj.check_archive.as_bool(request.user),
)

def _get_publish_link(self, obj, request):
"""Helper function to get the html link to the publish action
"""
if not obj.check_publish.as_bool(request.user):
if not obj.can_be_published():
# Don't display the link if it can't be published
return ""
publish_url = reverse(
Expand All @@ -701,14 +704,14 @@ def _get_publish_link(self, obj, request):
title=_("Publish"),
name="publish",
action="post",
disabled=not obj.can_be_published(),
disabled=not obj.check_publish.as_bool(request.user),
keepsideframe=False,
)

def _get_unpublish_link(self, obj, request, disabled=False):
"""Helper function to get the html link to the unpublish action
"""
if not obj.check_unpublish.as_bool(request.user):
if not obj.can_be_unpublished():
# Don't display the link if it can't be unpublished
return ""
unpublish_url = reverse(
Expand All @@ -720,15 +723,12 @@ def _get_unpublish_link(self, obj, request, disabled=False):
icon="unpublish",
title=_("Unpublish"),
name="unpublish",
disabled=not obj.can_be_unpublished(),
disabled=not obj.check_unpublish.as_bool(request.user),
)

def _get_edit_link(self, obj, request, disabled=False):
"""Helper function to get the html link to the edit action
"""
if not obj.check_edit_redirect.as_bool(request.user):
return ""

# Only show if no draft exists
if obj.state == PUBLISHED:
pks_for_grouper = obj.versionable.for_content_grouping_values(
Expand Down Expand Up @@ -758,14 +758,14 @@ def _get_edit_link(self, obj, request, disabled=False):
title=_("Edit") if icon == "pencil" else _("New Draft"),
name="edit",
action="post",
disabled=disabled,
disabled=not obj.check_edit_redirect.as_bool(request.user) or disabled,
keepsideframe=keepsideframe,
)

def _get_revert_link(self, obj, request, disabled=False):
"""Helper function to get the html link to the revert action
"""
if not obj.check_revert.as_bool(request.user):
if obj.state in (PUBLISHED, DRAFT):
# Don't display the link if it's a draft or published
return ""

Expand All @@ -778,13 +778,13 @@ def _get_revert_link(self, obj, request, disabled=False):
icon="undo",
title=_("Revert"),
name="revert",
disabled=disabled,
disabled=not obj.check_revert.as_bool(request.user) or disabled,
)

def _get_discard_link(self, obj, request, disabled=False):
"""Helper function to get the html link to the discard action
"""
if not obj.check_discard.as_bool(request.user):
if obj.state != DRAFT:
# Don't display the link if it's not a draft
return ""

Expand All @@ -797,7 +797,7 @@ def _get_discard_link(self, obj, request, disabled=False):
icon="bin",
title=_("Discard"),
name="discard",
disabled=disabled,
disabled=not obj.check_discard.as_bool(request.user) or disabled,
)

def _get_unlock_link(self, obj, request):
Expand All @@ -808,20 +808,14 @@ def _get_unlock_link(self, obj, request):
if not conf.LOCK_VERSIONS or obj.state != DRAFT or not version_is_locked(obj):
return ""

disabled = True
# Check whether the lock can be removed
# Check that the user has unlock permission
if request.user.has_perm("djangocms_versioning.delete_versionlock"):
disabled = False

unlock_url = reverse(f"admin:{obj._meta.app_label}_{self.model._meta.model_name}_unlock", args=(obj.pk,))
return self.admin_action_button(
unlock_url,
icon="unlock",
title=_("Unlock"),
name="unlock",
action="post",
disabled=disabled,
disabled=not obj.check_unlock.as_bool(request.user),
)

def get_actions_list(self):
Expand Down Expand Up @@ -978,7 +972,6 @@ def publish_view(self, request, object_id):

# Redirect to published?
if conf.ON_PUBLISH_REDIRECT == "published":
redirect_url = None
if hasattr(version.content, "get_absolute_url"):
redirect_url = version.content.get_absolute_url() or redirect_url

Expand Down Expand Up @@ -1323,10 +1316,7 @@ def changelist_view(self, request, extra_context=None):
# Check if custom breadcrumb template defined, otherwise
# fallback on default
breadcrumb_templates = [
"admin/djangocms_versioning/{app_label}/{model_name}/versioning_breadcrumbs.html".format(
app_label=breadcrumb_opts.app_label,
model_name=breadcrumb_opts.model_name,
),
f"admin/djangocms_versioning/{breadcrumb_opts.app_label}/{breadcrumb_opts.model_name}/versioning_breadcrumbs.html",
"admin/djangocms_versioning/versioning_breadcrumbs.html",
]
extra_context["breadcrumb_template"] = select_template(breadcrumb_templates)
Expand Down
5 changes: 4 additions & 1 deletion djangocms_versioning/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ def ready(self):
from cms.models import contentmodels, fields
from cms.signals import post_obj_operation, post_placeholder_operation

from .conf import LOCK_VERSIONS
from .handlers import (
update_modified_date,
update_modified_date_for_pagecontent,
update_modified_date_for_placeholder_source,
)
from .helpers import is_content_editable
from .helpers import is_content_editable, placeholder_content_is_unlocked_for_user

# Add check to PlaceholderRelationField
fields.PlaceholderRelationField.default_checks += [is_content_editable]
if LOCK_VERSIONS:
fields.PlaceholderRelationField.default_checks += [placeholder_content_is_unlocked_for_user]

# Remove uniqueness constraint from PageContent model to allow for different versions
pagecontent_unique_together = tuple(
Expand Down
9 changes: 0 additions & 9 deletions djangocms_versioning/cms_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@

from . import indicators, versionables
from .admin import VersioningAdminMixin
from .conf import LOCK_VERSIONS
from .constants import INDICATOR_DESCRIPTIONS
from .datastructures import BaseVersionableItem, VersionableItem
from .exceptions import ConditionFailed
from .helpers import (
get_latest_admin_viewable_content,
inject_generic_relation_to_version,
is_editable,
placeholder_content_is_unlocked_for_user,
register_versionadmin_proxy,
replace_admin_for_models,
replace_manager,
Expand Down Expand Up @@ -160,12 +158,6 @@ def handle_admin_field_modifiers(self, cms_config):
for key in modifier.keys():
self.add_to_field_extension[key] = modifier[key]

def handle_locking(self):
if LOCK_VERSIONS:
from cms.models import fields

fields.PlaceholderRelationField.default_checks += [placeholder_content_is_unlocked_for_user]

def configure_app(self, cms_config):
if hasattr(cms_config, "extended_admin_field_modifiers"):
self.handle_admin_field_modifiers(cms_config)
Expand All @@ -188,7 +180,6 @@ def configure_app(self, cms_config):
self.handle_version_admin(cms_config)
self.handle_content_model_generic_relation(cms_config)
self.handle_content_model_manager(cms_config)
self.handle_locking()


def copy_page_content(original_content):
Expand Down
4 changes: 2 additions & 2 deletions djangocms_versioning/cms_toolbars.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ def _add_unlock_button(self):
if LOCK_VERSIONS and self._is_versioned():
item = ButtonList(side=self.toolbar.RIGHT)
proxy_model = self._get_proxy_model()
version = Version.objects.get_for_content(self.toolbar.obj)
if version.check_unlock.as_bool(self.request.user):
version = Version.objects.filter_by_content_grouping_values(self.toolbar.obj).filter(state=DRAFT).first()
if version and version.check_unlock.as_bool(self.request.user):
unlock_url = reverse(
f"admin:{proxy_model._meta.app_label}_{proxy_model.__name__.lower()}_unlock",
args=(version.pk,),
Expand Down
19 changes: 19 additions & 0 deletions djangocms_versioning/conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,22 @@ def inner(version, user):
else:
raise ConditionFailed(message)
return inner

def user_can_unlock(message: str) -> callable:
def inner(version, user):
if not user.has_perm("djangocms_versioning.delete_versionlock"):
raise ConditionFailed(message)
return inner

def user_can_publish(message: str) -> callable:
def inner(version, user):
if not version.has_publish_permission(user):
raise ConditionFailed(message)
return inner


def user_can_change(message: str) -> callable:
def inner(version, user):
if not version.has_change_permission(user):
raise ConditionFailed(message)
return inner
5 changes: 3 additions & 2 deletions djangocms_versioning/conf.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from cms import __version__ as CMS_VERSION
from django.conf import settings

ENABLE_MENU_REGISTRATION = getattr(
settings, "DJANGOCMS_VERSIONING_ENABLE_MENU_REGISTRATION", True
settings, "DJANGOCMS_VERSIONING_ENABLE_MENU_REGISTRATION", CMS_VERSION <= "4.1.0"
)

USERNAME_FIELD = getattr(
Expand Down Expand Up @@ -31,4 +32,4 @@
ON_PUBLISH_REDIRECT = getattr(
settings, "DJANGOCMS_VERISONING_ON_PUBLISH_REDIRECT", "published"
)
# Allowed values: "versions", "published", "preview"
#: Allowed values: "versions", "published", "preview"
Loading

0 comments on commit 2724a99

Please sign in to comment.