Просмотр исходного кода

Tweak restrict() to accept only an action keyword

Jeremy Stretch 5 лет назад
Родитель
Сommit
5574aaa8cb
3 измененных файлов с 20 добавлено и 11 удалено
  1. 12 8
      netbox/utilities/api.py
  2. 6 2
      netbox/utilities/querysets.py
  3. 2 1
      netbox/utilities/views.py

+ 12 - 8
netbox/utilities/api.py

@@ -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')

+ 6 - 2
netbox/utilities/querysets.py

@@ -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

+ 2 - 1
netbox/utilities/views.py

@@ -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