manager: add basic usage of native django permissions (#59505)

This commit is contained in:
Frédéric Péters 2021-12-08 20:56:01 +01:00
parent a85d743b43
commit 75a5bac20a
6 changed files with 48 additions and 17 deletions

View File

@ -357,7 +357,7 @@ class Page(models.Model):
return False
def is_editable(self, user):
if user.is_superuser:
if user.has_perm('data.change_page'):
return True
group_ids = [x.id for x in user.groups.all()]
if self.edit_role_id in group_ids:
@ -439,7 +439,7 @@ class Page(models.Model):
pages_hierarchy.append(page_hierarchy)
group_ids = None # None = do not pay attention to groups
if follow_user_perms and not follow_user_perms.is_superuser:
if follow_user_perms and not follow_user_perms.has_perm('data.change_page'):
group_ids = [x.id for x in follow_user_perms.groups.all()]
pages_hierarchy.sort()

View File

@ -12,7 +12,7 @@
<li><a class="action-history" href="{% url 'combo-manager-page-history' pk=object.id %}">{% trans 'History' %}</a></li>
<li><a {% if page_has_subpages %}rel="popup" data-autoclose-dialog="true" {% endif %}class="action-export" href="{% url 'combo-manager-page-export' pk=object.id %}">{% trans 'Export' %}</a></li>
<li><a class="action-edit-page-variables" rel="popup" href="{% url 'combo-manager-page-edit-extra-variables' pk=object.id %}">{% trans "Edit extra page variables" %}</a></li>
{% if request.user.is_superuser %}
{% if perms.data.add_page %}
<li><a class="action-add-child" rel="popup" href="{% url 'combo-manager-page-add-child' pk=object.id %}">{% trans 'Add a child page' %}</a></li>
<li><a class="action-edit-roles" rel="popup" href="{% url 'combo-manager-page-edit-roles' pk=object.id %}">{% trans 'Manage edit roles' %}</a></li>
<li><a rel="popup" class="action-duplicate" href="{% url 'combo-manager-page-duplicate' pk=object.id %}">{% trans 'Duplicate' %}</a></li>

View File

@ -19,7 +19,7 @@ from django.conf.urls import url
from django.views.decorators.cache import never_cache
from combo.apps.assets import views as assets_views
from combo.urls_utils import staff_required
from combo.urls_utils import pages_admin_required
from .. import plugins
from . import views
@ -27,12 +27,12 @@ from . import views
urlpatterns = [
url(r'^$', views.homepage, name='combo-manager-homepage'),
url(r'^menu.json$', views.menu_json),
url(r'^site-export$', staff_required(views.site_export), name='combo-manager-site-export'),
url(r'^site-import$', staff_required(views.site_import), name='combo-manager-site-import'),
url(r'^site-export$', pages_admin_required(views.site_export), name='combo-manager-site-export'),
url(r'^site-import$', pages_admin_required(views.site_import), name='combo-manager-site-import'),
url(r'^site-settings$', views.site_settings, name='combo-manager-site-settings'),
url(
r'^cells/invalid-report/$',
staff_required(views.invalid_cell_report),
pages_admin_required(views.invalid_cell_report),
name='combo-manager-invalid-cell-report',
),
url(r'^pages/add/$', views.page_add, name='combo-manager-page-add'),
@ -69,25 +69,31 @@ urlpatterns = [
views.page_edit_extra_variables,
name='combo-manager-page-edit-extra-variables',
),
url(r'^pages/(?P<pk>\d+)/delete$', staff_required(views.page_delete), name='combo-manager-page-delete'),
url(
r'^pages/(?P<pk>\d+)/delete$',
pages_admin_required(views.page_delete),
name='combo-manager-page-delete',
),
url(r'^pages/(?P<pk>\d+)/export$', views.page_export, name='combo-manager-page-export'),
url(
r'^pages/(?P<pk>\d+)/add/$', staff_required(views.page_add_child), name='combo-manager-page-add-child'
r'^pages/(?P<pk>\d+)/add/$',
pages_admin_required(views.page_add_child),
name='combo-manager-page-add-child',
),
url(
r'^pages/(?P<pk>\d+)/duplicate$',
staff_required(views.page_duplicate),
pages_admin_required(views.page_duplicate),
name='combo-manager-page-duplicate',
),
url(
r'^pages/(?P<pk>\d+)/edit-roles/$',
staff_required(views.page_edit_roles),
pages_admin_required(views.page_edit_roles),
name='combo-manager-page-edit-roles',
),
url(r'^pages/(?P<pk>\d+)/history$', views.page_history, name='combo-manager-page-history'),
url(
r'^pages/(?P<page_pk>\d+)/history/(?P<pk>\d+)/$',
staff_required(views.snapshot_restore),
pages_admin_required(views.snapshot_restore),
name='combo-manager-snapshot-restore',
),
url(

View File

@ -81,7 +81,7 @@ from .forms import (
def can_add_page(user):
if user.is_superuser:
if user.has_perm('data.add_page'):
return True
group_ids = [x.id for x in user.groups.all()]
return bool(Page.objects.filter(subpages_edit_role_id__in=group_ids).exists())
@ -195,7 +195,7 @@ class PageAddView(CreateView):
template_name = 'combo/page_add.html'
def get_form_class(self):
if self.request.user.is_superuser:
if self.request.user.has_perm('data.add_page'):
return PageAddForm
elif can_add_page(self.request.user):
return PageRestrictedAddForm

View File

@ -59,7 +59,7 @@ def decorated_includes(func, includes, *args, **kwargs):
def manager_required(function=None, login_url=None):
def check_manager(user):
if user and user.is_superuser:
if user and user.has_perm('data.add_page'):
return True
if user and not user.is_anonymous:
from combo.data.models import Page
@ -92,3 +92,18 @@ def staff_required(function=None, login_url=None):
if function:
return actual_decorator(function)
return actual_decorator
def pages_admin_required(function=None, login_url=None):
def check_staff(user):
if user and not user.is_anonymous:
if user.has_perm('data.add_page'):
return True
raise PermissionDenied()
# As the last resort, show the login form
return False
actual_decorator = user_passes_test(check_staff, login_url=login_url)
if function:
return actual_decorator(function)
return actual_decorator

View File

@ -9,7 +9,7 @@ from unittest import mock
import pytest
from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.auth.models import Group, Permission
from django.core.files import File
from django.core.files.storage import default_storage
from django.core.serializers.base import DeserializationError
@ -2611,7 +2611,11 @@ def test_edit_link_list_order(app, admin_user):
assert item.order == new_order[i]
def test_restricted_page_edit(app, admin_user, john_doe):
def test_restricted_page_edit(app, admin_user, john_doe, jane_doe):
group = Group.objects.create(name='page manager')
group.permissions.add(Permission.objects.get(codename='add_page'))
group.permissions.add(Permission.objects.get(codename='change_page'))
jane_doe.groups.set([group])
group = Group.objects.create(name='foobar')
john_doe.groups.set([group])
@ -2645,6 +2649,12 @@ def test_restricted_page_edit(app, admin_user, john_doe):
resp = app.get('/manage/pages/%s/' % page4.id, status=200)
admin_links = [x.attrib['href'] for x in PyQuery(resp.text).find('a[href^="/manage/"]')]
# login as page manager, check it has the same permissions as the admin
app = login(app, username='jane.doe', password='jane.doe')
resp = app.get('/manage/pages/%s/' % page4.id, status=200)
manager_links = [x.attrib['href'] for x in PyQuery(resp.text).find('a[href^="/manage/"]')]
assert manager_links == admin_links
# back to normal user
app = login(app, username='john.doe', password='john.doe')
only_admin_links = [x for x in admin_links if x not in page_links]