Source code for tcms.core.admin
# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib import admin
from django.contrib.auth import get_permission_codename
from django.contrib.sites.admin import SiteAdmin
from django.contrib.sites.models import Site
from django.http import HttpResponseRedirect
from django.urls import reverse
from django_comments.models import Comment
from guardian.admin import GuardedModelAdminMixin
[docs]
class KiwiSiteAdmin(SiteAdmin):
"""
Does not allow adding new or deleting sites.
Redirects to the edit form for the default object!
"""
[docs]
def add_view(self, request, form_url="", extra_context=None):
return HttpResponseRedirect(
reverse("admin:sites_site_change", args=[settings.SITE_ID])
)
[docs]
def delete_view(self, request, object_id, extra_context=None):
return HttpResponseRedirect(
reverse("admin:sites_site_change", args=[settings.SITE_ID])
)
# we don't want comments to be accessible via the admin interface
admin.site.unregister(Comment)
# site admin with limited functionality
admin.site.unregister(Site)
admin.site.register(Site, KiwiSiteAdmin)
# globally disable the 'Delete selected' action
# see https://github.com/kiwitcms/Kiwi/issues/221 and
# https://docs.djangoproject.com/en/2.0/ref/contrib/admin/actions/#disabling-actions
admin.site.disable_action("delete_selected")
[docs]
class ObjectPermissionsAdminMixin(GuardedModelAdminMixin):
"""
This class should be used in conjunction with admin.ModelAdmin or
its descendants and teaches Django to respect object-level permissions!
The trouble with ModelAdmin is that it doesn't pass the obj argument
to user.has_perm() and if it does (without doing an `or`) then
django.contrib.auth.backends.ModelBackend will return False and
cause all sort of things to fail.
For more information see:
https://github.com/django/django/pull/13418
https://code.djangoproject.com/ticket/13539#comment:21
"""
[docs]
def has_change_permission(self, request, obj=None):
opts = self.opts
codename = get_permission_codename("change", opts)
return (
request.user.has_perm(f"{opts.app_label}.{codename}")
or
# vvv this is the added bit
request.user.has_perm(f"{opts.app_label}.{codename}", obj=obj)
)
[docs]
def has_delete_permission(self, request, obj=None):
opts = self.opts
codename = get_permission_codename("delete", opts)
return (
request.user.has_perm(f"{opts.app_label}.{codename}")
or
# vvv this is the added bit
request.user.has_perm(f"{opts.app_label}.{codename}", obj=obj)
)
[docs]
def has_view_permission(self, request, obj=None):
opts = self.opts
codename_view = get_permission_codename("view", opts)
codename_change = get_permission_codename("change", opts)
return (
request.user.has_perm(f"{opts.app_label}.{codename_view}")
or request.user.has_perm(f"{opts.app_label}.{codename_change}")
or
# vvv these are the added bits
request.user.has_perm(f"{opts.app_label}.{codename_view}", obj=obj)
or request.user.has_perm(f"{opts.app_label}.{codename_change}", obj=obj)
)