1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Introduced ObjectPermissionRequiredMixin

This commit is contained in:
Jeremy Stretch
2020-05-11 11:51:11 -04:00
parent 6624fc6076
commit 4b5d64939d
2 changed files with 42 additions and 1 deletions

View File

@ -21,6 +21,7 @@ from extras.models import Graph
from extras.views import ObjectConfigContextView from extras.views import ObjectConfigContextView
from ipam.models import Prefix, VLAN from ipam.models import Prefix, VLAN
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
from netbox.authentication import ObjectPermissionRequiredMixin
from utilities.forms import ConfirmationForm from utilities.forms import ConfirmationForm
from utilities.paginator import EnhancedPaginator from utilities.paginator import EnhancedPaginator
from utilities.utils import csv_format from utilities.utils import csv_format
@ -185,7 +186,7 @@ class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Sites # Sites
# #
class SiteListView(PermissionRequiredMixin, ObjectListView): class SiteListView(ObjectPermissionRequiredMixin, ObjectListView):
permission_required = 'dcim.view_site' permission_required = 'dcim.view_site'
queryset = Site.objects.prefetch_related('region', 'tenant') queryset = Site.objects.prefetch_related('region', 'tenant')
filterset = filters.SiteFilterSet filterset = filters.SiteFilterSet

View File

@ -0,0 +1,40 @@
from django.contrib.auth.mixins import AccessMixin
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from users.models import ObjectPermission
class ObjectPermissionRequiredMixin(AccessMixin):
permission_required = None
def has_permission(self):
# First, check whether the user has a model-level permission assigned
if self.request.user.has_perm(self.permission_required):
return True
# If not, check for an object-level permission
app, codename = self.permission_required.split('.')
action, model_name = codename.split('_')
model = self.queryset.model
obj_permissions = ObjectPermission.objects.filter(
Q(users=self.request.user) | Q(groups__user=self.request.user),
model=ContentType.objects.get_for_model(model),
**{f'can_{action}': True}
)
if obj_permissions:
# Update the view's QuerySet to filter only the permitted objects
# TODO: Do this more efficiently
for perm in obj_permissions:
self.queryset = self.queryset.filter(**perm.attrs)
return True
return False
def dispatch(self, request, *args, **kwargs):
if not self.has_permission():
return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs)