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

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:
return
# TODO: Move this to a cleaner function
# Determine the required permission based on the request method
kwargs = {
'app_label': self.queryset.model._meta.app_label,
'model_name': self.queryset.model._meta.model_name
}
permission_required = TokenPermissions.perms_map[request.method][0] % kwargs
# TODO: Reconcile this with TokenPermissions.perms_map
action = {
'GET': 'view',
'OPTIONS': None,
'HEAD': 'view',
'POST': 'add',
'PUT': 'change',
'PATCH': 'change',
'DELETE': 'delete',
}[request.method]
# 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):
logger = logging.getLogger('netbox.api.views.ModelViewSet')

View File

@ -14,15 +14,19 @@ class DummyQuerySet:
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
permission.
:param queryset: Base QuerySet to be restricted
: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
# 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
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