Преглед изворни кода

Introduce restrict_form_fields() to automatically restrict field querysets based on user

Jeremy Stretch пре 5 година
родитељ
комит
edc65a6a34
2 измењених фајлова са 14 додато и 1 уклоњено
  1. 11 0
      netbox/utilities/forms.py
  2. 3 1
      netbox/utilities/views.py

+ 11 - 0
netbox/utilities/forms.py

@@ -15,6 +15,7 @@ from django.forms import BoundField
 from django.forms.models import fields_for_model
 from django.forms.models import fields_for_model
 from django.urls import reverse
 from django.urls import reverse
 
 
+from utilities.querysets import RestrictedQuerySet
 from .choices import ColorChoices, unpack_grouped_choices
 from .choices import ColorChoices, unpack_grouped_choices
 from .validators import EnhancedURLValidator
 from .validators import EnhancedURLValidator
 
 
@@ -138,6 +139,16 @@ def form_from_model(model, fields):
     return type('FormFromModel', (forms.Form,), form_fields)
     return type('FormFromModel', (forms.Form,), form_fields)
 
 
 
 
+def restrict_form_fields(form, user, action='view'):
+    """
+    Restrict all form fields which reference a RestrictedQuerySet. This ensures that users see only permitted objects
+    as available choices.
+    """
+    for field in form.fields.values():
+        if hasattr(field, 'queryset') and issubclass(field.queryset.__class__, RestrictedQuerySet):
+            field.queryset = field.queryset.restrict(user, action)
+
+
 #
 #
 # Widgets
 # Widgets
 #
 #

+ 3 - 1
netbox/utilities/views.py

@@ -28,7 +28,7 @@ from django_tables2 import RequestConfig
 from extras.models import CustomField, CustomFieldValue, ExportTemplate
 from extras.models import CustomField, CustomFieldValue, ExportTemplate
 from extras.querysets import CustomFieldQueryset
 from extras.querysets import CustomFieldQueryset
 from utilities.exceptions import AbortTransaction
 from utilities.exceptions import AbortTransaction
-from utilities.forms import BootstrapMixin, BulkRenameForm, CSVDataField, TableConfigForm
+from utilities.forms import BootstrapMixin, BulkRenameForm, CSVDataField, TableConfigForm, restrict_form_fields
 from utilities.permissions import get_permission_for_model, resolve_permission
 from utilities.permissions import get_permission_for_model, resolve_permission
 from utilities.utils import csv_format, prepare_cloned_fields
 from utilities.utils import csv_format, prepare_cloned_fields
 from .error_handlers import handle_protectederror
 from .error_handlers import handle_protectederror
@@ -352,6 +352,7 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
         # Parse initial data manually to avoid setting field values as lists
         # Parse initial data manually to avoid setting field values as lists
         initial_data = {k: request.GET[k] for k in request.GET}
         initial_data = {k: request.GET[k] for k in request.GET}
         form = self.model_form(instance=obj, initial=initial_data)
         form = self.model_form(instance=obj, initial=initial_data)
+        restrict_form_fields(form, request.user)
 
 
         return render(request, self.template_name, {
         return render(request, self.template_name, {
             'obj': obj,
             'obj': obj,
@@ -368,6 +369,7 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
             files=request.FILES,
             files=request.FILES,
             instance=obj
             instance=obj
         )
         )
+        restrict_form_fields(form, request.user)
 
 
         if form.is_valid():
         if form.is_valid():
             logger.debug("Form validation was successful")
             logger.debug("Form validation was successful")