Tweak restrict() to accept only an action keyword

This commit is contained in:
Jeremy Stretch 2020-06-01 10:45:49 -04:00
parent e23b2c4c4f
commit 5574aaa8cb
3 changed files with 20 additions and 11 deletions

View File

@ -330,16 +330,20 @@ class ModelViewSet(_ModelViewSet):
if not request.user.is_authenticated or request.user.is_superuser: if not request.user.is_authenticated or request.user.is_superuser:
return return
# TODO: Move this to a cleaner function # TODO: Reconcile this with TokenPermissions.perms_map
# Determine the required permission based on the request method action = {
kwargs = { 'GET': 'view',
'app_label': self.queryset.model._meta.app_label, 'OPTIONS': None,
'model_name': self.queryset.model._meta.model_name 'HEAD': 'view',
} 'POST': 'add',
permission_required = TokenPermissions.perms_map[request.method][0] % kwargs 'PUT': 'change',
'PATCH': 'change',
'DELETE': 'delete',
}[request.method]
# Restrict the view's QuerySet to allow only the permitted objects # Restrict the view's QuerySet to allow only the permitted objects
self.queryset = self.queryset.restrict(request.user, permission_required) if action:
self.queryset = self.queryset.restrict(request.user, action)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
logger = logging.getLogger('netbox.api.views.ModelViewSet') logger = logging.getLogger('netbox.api.views.ModelViewSet')

View File

@ -14,15 +14,19 @@ class DummyQuerySet:
class RestrictedQuerySet(QuerySet): class RestrictedQuerySet(QuerySet):
def restrict(self, user, permission_required): def restrict(self, user, action):
""" """
Filter the QuerySet to return only objects on which the specified user has been granted the specified Filter the QuerySet to return only objects on which the specified user has been granted the specified
permission. permission.
:param queryset: Base QuerySet to be restricted :param queryset: Base QuerySet to be restricted
:param user: User instance :param user: User instance
:param permission_required: Name of the required permission (e.g. "dcim.view_site") :param action: The action which must be permitted (e.g. "view" for "dcim.view_site")
""" """
# Resolve the full name of the required permission
app_label = self.model._meta.app_label
model_name = self.model._meta.model_name
permission_required = f'{app_label}.{action}_{model_name}'
# Determine what constraints (if any) have been placed on this user for this action and model # Determine what constraints (if any) have been placed on this user for this action and model
# TODO: Find a better way to ensure permissions are cached # TODO: Find a better way to ensure permissions are cached

View File

@ -66,7 +66,8 @@ class ObjectPermissionRequiredMixin(AccessMixin):
# Update the view's QuerySet to filter only the permitted objects # Update the view's QuerySet to filter only the permitted objects
if user.is_authenticated and not user.is_superuser: if user.is_authenticated and not user.is_superuser:
self.queryset = self.queryset.restrict(user, permission_required) action = permission_required.split('.')[1].split('_')[0]
self.queryset = self.queryset.restrict(user, action)
return True return True