Parcourir la source

Fixes #845: Fix missing edit/delete buttons on object tables for non-superusers

Jeremy Stretch il y a 8 ans
Parent
commit
5d5d4ac714

+ 0 - 3
netbox/circuits/views.py

@@ -25,7 +25,6 @@ class ProviderListView(ObjectListView):
     filter = filters.ProviderFilter
     filter_form = forms.ProviderFilterForm
     table = tables.ProviderTable
-    edit_permissions = ['circuits.change_provider', 'circuits.delete_provider']
     template_name = 'circuits/provider_list.html'
 
 
@@ -87,7 +86,6 @@ class ProviderBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class CircuitTypeListView(ObjectListView):
     queryset = CircuitType.objects.annotate(circuit_count=Count('circuits'))
     table = tables.CircuitTypeTable
-    edit_permissions = ['circuits.change_circuittype', 'circuits.delete_circuittype']
     template_name = 'circuits/circuittype_list.html'
 
 
@@ -115,7 +113,6 @@ class CircuitListView(ObjectListView):
     filter = filters.CircuitFilter
     filter_form = forms.CircuitFilterForm
     table = tables.CircuitTable
-    edit_permissions = ['circuits.change_circuit', 'circuits.delete_circuit']
     template_name = 'circuits/circuit_list.html'
 
 

+ 0 - 9
netbox/dcim/views.py

@@ -137,7 +137,6 @@ class SiteListView(ObjectListView):
     filter = filters.SiteFilter
     filter_form = forms.SiteFilterForm
     table = tables.SiteTable
-    edit_permissions = ['dcim.change_rack', 'dcim.delete_rack']
     template_name = 'dcim/site_list.html'
 
 
@@ -204,7 +203,6 @@ class RackGroupListView(ObjectListView):
     filter = filters.RackGroupFilter
     filter_form = forms.RackGroupFilterForm
     table = tables.RackGroupTable
-    edit_permissions = ['dcim.change_rackgroup', 'dcim.delete_rackgroup']
     template_name = 'dcim/rackgroup_list.html'
 
 
@@ -231,7 +229,6 @@ class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class RackRoleListView(ObjectListView):
     queryset = RackRole.objects.annotate(rack_count=Count('racks'))
     table = tables.RackRoleTable
-    edit_permissions = ['dcim.change_rackrole', 'dcim.delete_rackrole']
     template_name = 'dcim/rackrole_list.html'
 
 
@@ -260,7 +257,6 @@ class RackListView(ObjectListView):
     filter = filters.RackFilter
     filter_form = forms.RackFilterForm
     table = tables.RackTable
-    edit_permissions = ['dcim.change_rack', 'dcim.delete_rack']
     template_name = 'dcim/rack_list.html'
 
 
@@ -328,7 +324,6 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class ManufacturerListView(ObjectListView):
     queryset = Manufacturer.objects.annotate(devicetype_count=Count('device_types'))
     table = tables.ManufacturerTable
-    edit_permissions = ['dcim.change_manufacturer', 'dcim.delete_manufacturer']
     template_name = 'dcim/manufacturer_list.html'
 
 
@@ -356,7 +351,6 @@ class DeviceTypeListView(ObjectListView):
     filter = filters.DeviceTypeFilter
     filter_form = forms.DeviceTypeFilterForm
     table = tables.DeviceTypeTable
-    edit_permissions = ['dcim.change_devicetype', 'dcim.delete_devicetype']
     template_name = 'dcim/devicetype_list.html'
 
 
@@ -550,7 +544,6 @@ class DeviceBayTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class DeviceRoleListView(ObjectListView):
     queryset = DeviceRole.objects.annotate(device_count=Count('devices'))
     table = tables.DeviceRoleTable
-    edit_permissions = ['dcim.change_devicerole', 'dcim.delete_devicerole']
     template_name = 'dcim/devicerole_list.html'
 
 
@@ -576,7 +569,6 @@ class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class PlatformListView(ObjectListView):
     queryset = Platform.objects.annotate(device_count=Count('devices'))
     table = tables.PlatformTable
-    edit_permissions = ['dcim.change_platform', 'dcim.delete_platform']
     template_name = 'dcim/platform_list.html'
 
 
@@ -605,7 +597,6 @@ class DeviceListView(ObjectListView):
     filter = filters.DeviceFilter
     filter_form = forms.DeviceFilterForm
     table = tables.DeviceTable
-    edit_permissions = ['dcim.change_device', 'dcim.delete_device']
     template_name = 'dcim/device_list.html'
 
 

+ 0 - 8
netbox/ipam/views.py

@@ -95,7 +95,6 @@ class VRFListView(ObjectListView):
     filter = filters.VRFFilter
     filter_form = forms.VRFFilterForm
     table = tables.VRFTable
-    edit_permissions = ['ipam.change_vrf', 'ipam.delete_vrf']
     template_name = 'ipam/vrf_list.html'
 
 
@@ -160,7 +159,6 @@ class RIRListView(ObjectListView):
     filter = filters.RIRFilter
     filter_form = forms.RIRFilterForm
     table = tables.RIRTable
-    edit_permissions = ['ipam.change_rir', 'ipam.delete_rir']
     template_name = 'ipam/rir_list.html'
 
     def alter_queryset(self, request):
@@ -267,7 +265,6 @@ class AggregateListView(ObjectListView):
     filter = filters.AggregateFilter
     filter_form = forms.AggregateFilterForm
     table = tables.AggregateTable
-    edit_permissions = ['ipam.change_aggregate', 'ipam.delete_aggregate']
     template_name = 'ipam/aggregate_list.html'
 
     def extra_context(self):
@@ -351,7 +348,6 @@ class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class RoleListView(ObjectListView):
     queryset = Role.objects.all()
     table = tables.RoleTable
-    edit_permissions = ['ipam.change_role', 'ipam.delete_role']
     template_name = 'ipam/role_list.html'
 
 
@@ -379,7 +375,6 @@ class PrefixListView(ObjectListView):
     filter = filters.PrefixFilter
     filter_form = forms.PrefixFilterForm
     table = tables.PrefixTable
-    edit_permissions = ['ipam.change_prefix', 'ipam.delete_prefix']
     template_name = 'ipam/prefix_list.html'
 
     def alter_queryset(self, request):
@@ -510,7 +505,6 @@ class IPAddressListView(ObjectListView):
     filter = filters.IPAddressFilter
     filter_form = forms.IPAddressFilterForm
     table = tables.IPAddressTable
-    edit_permissions = ['ipam.change_ipaddress', 'ipam.delete_ipaddress']
     template_name = 'ipam/ipaddress_list.html'
 
 
@@ -680,7 +674,6 @@ class VLANGroupListView(ObjectListView):
     filter = filters.VLANGroupFilter
     filter_form = forms.VLANGroupFilterForm
     table = tables.VLANGroupTable
-    edit_permissions = ['ipam.change_vlangroup', 'ipam.delete_vlangroup']
     template_name = 'ipam/vlangroup_list.html'
 
 
@@ -709,7 +702,6 @@ class VLANListView(ObjectListView):
     filter = filters.VLANFilter
     filter_form = forms.VLANFilterForm
     table = tables.VLANTable
-    edit_permissions = ['ipam.change_vlan', 'ipam.delete_vlan']
     template_name = 'ipam/vlan_list.html'
 
 

+ 0 - 2
netbox/secrets/views.py

@@ -22,7 +22,6 @@ from .models import SecretRole, Secret, UserKey
 class SecretRoleListView(ObjectListView):
     queryset = SecretRole.objects.annotate(secret_count=Count('secrets'))
     table = tables.SecretRoleTable
-    edit_permissions = ['secrets.change_secretrole', 'secrets.delete_secretrole']
     template_name = 'secrets/secretrole_list.html'
 
 
@@ -51,7 +50,6 @@ class SecretListView(ObjectListView):
     filter = filters.SecretFilter
     filter_form = forms.SecretFilterForm
     table = tables.SecretTable
-    edit_permissions = ['secrets.change_secret', 'secrets.delete_secret']
     template_name = 'secrets/secret_list.html'
 
 

+ 0 - 1
netbox/templates/ipam/ipaddress_list.html

@@ -1,5 +1,4 @@
 {% extends '_base.html' %}
-{% load render_table from django_tables2 %}
 {% load helpers %}
 
 {% block title %}IP Addresses{% endblock %}

+ 5 - 5
netbox/templates/utilities/obj_table.html

@@ -1,6 +1,6 @@
 {% load render_table from django_tables2 %}
 {% load helpers %}
-{% if table.model|user_can_change:request.user or table.model|user_can_delete:request.user %}
+{% if permissions.change or permissions.delete %}
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         <input type="hidden" name="return_url" value="{% if return_url %}{{ return_url }}{% else %}{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}{% endif %}" />
@@ -14,12 +14,12 @@
                         </label>
                     </div>
                     <div class="pull-right">
-                        {% if bulk_edit_url and table.model|user_can_change:request.user %}
+                        {% if bulk_edit_url and permissions.change %}
                             <button type="submit" name="_edit" formaction="{% url bulk_edit_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-warning btn-sm" disabled="disabled">
                                 <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit All
                             </button>
                         {% endif %}
-                        {% if bulk_delete_url and table.model|user_can_delete:request.user %}
+                        {% if bulk_delete_url and permissions.delete %}
                             <button type="submit" name="_delete" formaction="{% url bulk_delete_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-sm" disabled="disabled">
                                 <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete All
                             </button>
@@ -30,12 +30,12 @@
         {% endif %}
         {% render_table table table_template|default:'table.html' %}
         {% block extra_actions %}{% endblock %}
-        {% if bulk_edit_url and table.model|user_can_change:request.user %}
+        {% if bulk_edit_url and permissions.change %}
             <button type="submit" name="_edit" formaction="{% url bulk_edit_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-warning btn-sm">
                 <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit Selected
             </button>
         {% endif %}
-        {% if bulk_delete_url and table.model|user_can_delete:request.user %}
+        {% if bulk_delete_url and permissions.delete %}
             <button type="submit" name="_delete" formaction="{% url bulk_delete_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-sm">
                 <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete Selected
             </button>

+ 0 - 2
netbox/tenancy/views.py

@@ -21,7 +21,6 @@ from . import filters, forms, tables
 class TenantGroupListView(ObjectListView):
     queryset = TenantGroup.objects.annotate(tenant_count=Count('tenants'))
     table = tables.TenantGroupTable
-    edit_permissions = ['tenancy.change_tenantgroup', 'tenancy.delete_tenantgroup']
     template_name = 'tenancy/tenantgroup_list.html'
 
 
@@ -49,7 +48,6 @@ class TenantListView(ObjectListView):
     filter = filters.TenantFilter
     filter_form = forms.TenantFilterForm
     table = tables.TenantTable
-    edit_permissions = ['tenancy.change_tenant', 'tenancy.delete_tenant']
     template_name = 'tenancy/tenant_list.html'
 
 

+ 0 - 4
netbox/utilities/tables.py

@@ -17,10 +17,6 @@ class BaseTable(tables.Table):
             'class': 'table table-hover',
         }
 
-    @property
-    def model(self):
-        return self._meta.model
-
 
 class ToggleColumn(tables.CheckBoxColumn):
 

+ 0 - 18
netbox/utilities/templatetags/helpers.py

@@ -44,24 +44,6 @@ def startswith(value, arg):
     return str(value).startswith(arg)
 
 
-@register.filter()
-def user_can_add(model, user):
-    perm_name = '{}:add_{}'.format(model._meta.app_label, model.__class__.__name__.lower())
-    return user.has_perm(perm_name)
-
-
-@register.filter()
-def user_can_change(model, user):
-    perm_name = '{}:change_{}'.format(model._meta.app_label, model.__class__.__name__.lower())
-    return user.has_perm(perm_name)
-
-
-@register.filter()
-def user_can_delete(model, user):
-    perm_name = '{}:delete_{}'.format(model._meta.app_label, model.__class__.__name__.lower())
-    return user.has_perm(perm_name)
-
-
 #
 # Tags
 #

+ 6 - 3
netbox/utilities/views.py

@@ -46,14 +46,12 @@ class ObjectListView(View):
     filter: A django-filter FilterSet that is applied to the queryset
     filter_form: The form used to render filter options
     table: The django-tables2 Table used to render the objects list
-    edit_permissions: Editing controls are displayed only if the user has these permissions
     template_name: The name of the template
     """
     queryset = None
     filter = None
     filter_form = None
     table = None
-    edit_permissions = []
     template_name = None
 
     def get(self, request):
@@ -95,14 +93,19 @@ class ObjectListView(View):
         # Provide a hook to tweak the queryset based on the request immediately prior to rendering the object list
         self.queryset = self.alter_queryset(request)
 
+        # Compile user model permissions for access from within the template
+        perm_base_name = '{}.{{}}_{}'.format(model._meta.app_label, model._meta.model_name)
+        permissions = {p: request.user.has_perm(perm_base_name.format(p)) for p in ['add', 'change', 'delete']}
+
         # Construct the table based on the user's permissions
         table = self.table(self.queryset)
-        if 'pk' in table.base_columns and any([request.user.has_perm(perm) for perm in self.edit_permissions]):
+        if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
             table.base_columns['pk'].visible = True
         RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(table)
 
         context = {
             'table': table,
+            'permissions': permissions,
             'filter_form': self.filter_form(request.GET, label_suffix='') if self.filter_form else None,
             'export_templates': ExportTemplate.objects.filter(content_type=object_ct),
         }