Transition ObjectListView to use ObjectPermissionRequiredMixin

This commit is contained in:
Jeremy Stretch 2020-05-21 13:22:09 -04:00
parent cc6e74dfd5
commit 993ee8c900
8 changed files with 69 additions and 112 deletions

View File

@ -23,8 +23,7 @@ from .models import Circuit, CircuitTermination, CircuitType, Provider
# Providers # Providers
# #
class ProviderListView(PermissionRequiredMixin, ObjectListView): class ProviderListView(ObjectListView):
permission_required = 'circuits.view_provider'
queryset = Provider.objects.annotate(count_circuits=Count('circuits')) queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
filterset = filters.ProviderFilterSet filterset = filters.ProviderFilterSet
filterset_form = forms.ProviderFilterForm filterset_form = forms.ProviderFilterForm
@ -107,8 +106,7 @@ class ProviderBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Circuit Types # Circuit Types
# #
class CircuitTypeListView(PermissionRequiredMixin, ObjectListView): class CircuitTypeListView(ObjectListView):
permission_required = 'circuits.view_circuittype'
queryset = CircuitType.objects.annotate(circuit_count=Count('circuits')) queryset = CircuitType.objects.annotate(circuit_count=Count('circuits'))
table = tables.CircuitTypeTable table = tables.CircuitTypeTable
@ -143,8 +141,7 @@ class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Circuits # Circuits
# #
class CircuitListView(PermissionRequiredMixin, ObjectListView): class CircuitListView(ObjectListView):
permission_required = 'circuits.view_circuit'
_terminations = CircuitTermination.objects.filter(circuit=OuterRef('pk')) _terminations = CircuitTermination.objects.filter(circuit=OuterRef('pk'))
queryset = Circuit.objects.prefetch_related( queryset = Circuit.objects.prefetch_related(
'provider', 'type', 'tenant', 'terminations__site' 'provider', 'type', 'tenant', 'terminations__site'

View File

@ -141,8 +141,7 @@ class BulkDisconnectView(GetReturnURLMixin, View):
# Regions # Regions
# #
class RegionListView(PermissionRequiredMixin, ObjectListView): class RegionListView(ObjectListView):
permission_required = 'dcim.view_region'
queryset = Region.objects.add_related_count( queryset = Region.objects.add_related_count(
Region.objects.all(), Region.objects.all(),
Site, Site,
@ -186,8 +185,7 @@ class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Sites # Sites
# #
class SiteListView(ObjectPermissionRequiredMixin, ObjectListView): class SiteListView(ObjectListView):
permission_required = 'dcim.view_site'
queryset = Site.objects.prefetch_related('region', 'tenant') queryset = Site.objects.prefetch_related('region', 'tenant')
filterset = filters.SiteFilterSet filterset = filters.SiteFilterSet
filterset_form = forms.SiteFilterForm filterset_form = forms.SiteFilterForm
@ -267,8 +265,7 @@ class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Rack groups # Rack groups
# #
class RackGroupListView(PermissionRequiredMixin, ObjectListView): class RackGroupListView(ObjectListView):
permission_required = 'dcim.view_rackgroup'
queryset = RackGroup.objects.add_related_count( queryset = RackGroup.objects.add_related_count(
RackGroup.objects.all(), RackGroup.objects.all(),
Rack, Rack,
@ -312,8 +309,7 @@ class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Rack roles # Rack roles
# #
class RackRoleListView(PermissionRequiredMixin, ObjectListView): class RackRoleListView(ObjectListView):
permission_required = 'dcim.view_rackrole'
queryset = RackRole.objects.annotate(rack_count=Count('racks')) queryset = RackRole.objects.annotate(rack_count=Count('racks'))
table = tables.RackRoleTable table = tables.RackRoleTable
@ -348,8 +344,7 @@ class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Racks # Racks
# #
class RackListView(PermissionRequiredMixin, ObjectListView): class RackListView(ObjectListView):
permission_required = 'dcim.view_rack'
queryset = Rack.objects.prefetch_related( queryset = Rack.objects.prefetch_related(
'site', 'group', 'tenant', 'role', 'devices__device_type' 'site', 'group', 'tenant', 'role', 'devices__device_type'
).annotate( ).annotate(
@ -476,8 +471,7 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Rack reservations # Rack reservations
# #
class RackReservationListView(PermissionRequiredMixin, ObjectListView): class RackReservationListView(ObjectListView):
permission_required = 'dcim.view_rackreservation'
queryset = RackReservation.objects.prefetch_related('rack__site') queryset = RackReservation.objects.prefetch_related('rack__site')
filterset = filters.RackReservationFilterSet filterset = filters.RackReservationFilterSet
filterset_form = forms.RackReservationFilterForm filterset_form = forms.RackReservationFilterForm
@ -561,8 +555,7 @@ class RackReservationBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Manufacturers # Manufacturers
# #
class ManufacturerListView(PermissionRequiredMixin, ObjectListView): class ManufacturerListView(ObjectListView):
permission_required = 'dcim.view_manufacturer'
queryset = Manufacturer.objects.annotate( queryset = Manufacturer.objects.annotate(
devicetype_count=Count('device_types', distinct=True), devicetype_count=Count('device_types', distinct=True),
inventoryitem_count=Count('inventory_items', distinct=True), inventoryitem_count=Count('inventory_items', distinct=True),
@ -601,8 +594,7 @@ class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Device types # Device types
# #
class DeviceTypeListView(PermissionRequiredMixin, ObjectListView): class DeviceTypeListView(ObjectListView):
permission_required = 'dcim.view_devicetype'
queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')) queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
filterset = filters.DeviceTypeFilterSet filterset = filters.DeviceTypeFilterSet
filterset_form = forms.DeviceTypeFilterForm filterset_form = forms.DeviceTypeFilterForm
@ -1026,8 +1018,7 @@ class DeviceBayTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Device roles # Device roles
# #
class DeviceRoleListView(PermissionRequiredMixin, ObjectListView): class DeviceRoleListView(ObjectListView):
permission_required = 'dcim.view_devicerole'
queryset = DeviceRole.objects.all() queryset = DeviceRole.objects.all()
table = tables.DeviceRoleTable table = tables.DeviceRoleTable
@ -1062,8 +1053,7 @@ class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Platforms # Platforms
# #
class PlatformListView(PermissionRequiredMixin, ObjectListView): class PlatformListView(ObjectListView):
permission_required = 'dcim.view_platform'
queryset = Platform.objects.all() queryset = Platform.objects.all()
table = tables.PlatformTable table = tables.PlatformTable
@ -1098,8 +1088,7 @@ class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Devices # Devices
# #
class DeviceListView(PermissionRequiredMixin, ObjectListView): class DeviceListView(ObjectListView):
permission_required = 'dcim.view_device'
queryset = Device.objects.prefetch_related( queryset = Device.objects.prefetch_related(
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6' 'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6'
) )
@ -1323,8 +1312,7 @@ class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Console ports # Console ports
# #
class ConsolePortListView(PermissionRequiredMixin, ObjectListView): class ConsolePortListView(ObjectListView):
permission_required = 'dcim.view_consoleport'
queryset = ConsolePort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = ConsolePort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.ConsolePortFilterSet filterset = filters.ConsolePortFilterSet
filterset_form = forms.ConsolePortFilterForm filterset_form = forms.ConsolePortFilterForm
@ -1379,8 +1367,7 @@ class ConsolePortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Console server ports # Console server ports
# #
class ConsoleServerPortListView(PermissionRequiredMixin, ObjectListView): class ConsoleServerPortListView(ObjectListView):
permission_required = 'dcim.view_consoleserverport'
queryset = ConsoleServerPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = ConsoleServerPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.ConsoleServerPortFilterSet filterset = filters.ConsoleServerPortFilterSet
filterset_form = forms.ConsoleServerPortFilterForm filterset_form = forms.ConsoleServerPortFilterForm
@ -1447,8 +1434,7 @@ class ConsoleServerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Power ports # Power ports
# #
class PowerPortListView(PermissionRequiredMixin, ObjectListView): class PowerPortListView(ObjectListView):
permission_required = 'dcim.view_powerport'
queryset = PowerPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = PowerPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.PowerPortFilterSet filterset = filters.PowerPortFilterSet
filterset_form = forms.PowerPortFilterForm filterset_form = forms.PowerPortFilterForm
@ -1503,8 +1489,7 @@ class PowerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Power outlets # Power outlets
# #
class PowerOutletListView(PermissionRequiredMixin, ObjectListView): class PowerOutletListView(ObjectListView):
permission_required = 'dcim.view_poweroutlet'
queryset = PowerOutlet.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = PowerOutlet.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.PowerOutletFilterSet filterset = filters.PowerOutletFilterSet
filterset_form = forms.PowerOutletFilterForm filterset_form = forms.PowerOutletFilterForm
@ -1571,8 +1556,7 @@ class PowerOutletBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Interfaces # Interfaces
# #
class InterfaceListView(PermissionRequiredMixin, ObjectListView): class InterfaceListView(ObjectListView):
permission_required = 'dcim.view_interface'
queryset = Interface.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = Interface.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.InterfaceFilterSet filterset = filters.InterfaceFilterSet
filterset_form = forms.InterfaceFilterForm filterset_form = forms.InterfaceFilterForm
@ -1676,8 +1660,7 @@ class InterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Front ports # Front ports
# #
class FrontPortListView(PermissionRequiredMixin, ObjectListView): class FrontPortListView(ObjectListView):
permission_required = 'dcim.view_frontport'
queryset = FrontPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = FrontPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.FrontPortFilterSet filterset = filters.FrontPortFilterSet
filterset_form = forms.FrontPortFilterForm filterset_form = forms.FrontPortFilterForm
@ -1744,8 +1727,7 @@ class FrontPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Rear ports # Rear ports
# #
class RearPortListView(PermissionRequiredMixin, ObjectListView): class RearPortListView(ObjectListView):
permission_required = 'dcim.view_rearport'
queryset = RearPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable') queryset = RearPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
filterset = filters.RearPortFilterSet filterset = filters.RearPortFilterSet
filterset_form = forms.RearPortFilterForm filterset_form = forms.RearPortFilterForm
@ -1812,8 +1794,7 @@ class RearPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Device bays # Device bays
# #
class DeviceBayListView(PermissionRequiredMixin, ObjectListView): class DeviceBayListView(ObjectListView):
permission_required = 'dcim.view_devicebay'
queryset = DeviceBay.objects.prefetch_related( queryset = DeviceBay.objects.prefetch_related(
'device', 'device__site', 'installed_device', 'installed_device__site' 'device', 'device__site', 'installed_device', 'installed_device__site'
) )
@ -2045,8 +2026,7 @@ class DeviceBulkAddDeviceBayView(PermissionRequiredMixin, BulkComponentCreateVie
# Cables # Cables
# #
class CableListView(PermissionRequiredMixin, ObjectListView): class CableListView(ObjectListView):
permission_required = 'dcim.view_cable'
queryset = Cable.objects.prefetch_related( queryset = Cable.objects.prefetch_related(
'termination_a', 'termination_b' 'termination_a', 'termination_b'
) )
@ -2215,7 +2195,7 @@ class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Connections # Connections
# #
class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView): class ConsoleConnectionsListView(ObjectListView):
permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport') permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport')
queryset = ConsolePort.objects.prefetch_related( queryset = ConsolePort.objects.prefetch_related(
'device', 'connected_endpoint__device' 'device', 'connected_endpoint__device'
@ -2247,7 +2227,7 @@ class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
return '\n'.join(csv_data) return '\n'.join(csv_data)
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView): class PowerConnectionsListView(ObjectListView):
permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet') permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet')
queryset = PowerPort.objects.prefetch_related( queryset = PowerPort.objects.prefetch_related(
'device', '_connected_poweroutlet__device' 'device', '_connected_poweroutlet__device'
@ -2279,8 +2259,7 @@ class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
return '\n'.join(csv_data) return '\n'.join(csv_data)
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView): class InterfaceConnectionsListView(ObjectListView):
permission_required = 'dcim.view_interface'
queryset = Interface.objects.prefetch_related( queryset = Interface.objects.prefetch_related(
'device', 'cable', '_connected_interface__device' 'device', 'cable', '_connected_interface__device'
).filter( ).filter(
@ -2319,8 +2298,7 @@ class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
# Inventory items # Inventory items
# #
class InventoryItemListView(PermissionRequiredMixin, ObjectListView): class InventoryItemListView(ObjectListView):
permission_required = 'dcim.view_inventoryitem'
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer') queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
filterset = filters.InventoryItemFilterSet filterset = filters.InventoryItemFilterSet
filterset_form = forms.InventoryItemFilterForm filterset_form = forms.InventoryItemFilterForm
@ -2376,8 +2354,7 @@ class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Virtual chassis # Virtual chassis
# #
class VirtualChassisListView(PermissionRequiredMixin, ObjectListView): class VirtualChassisListView(ObjectListView):
permission_required = 'dcim.view_virtualchassis'
queryset = VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members')) queryset = VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members'))
table = tables.VirtualChassisTable table = tables.VirtualChassisTable
filterset = filters.VirtualChassisFilterSet filterset = filters.VirtualChassisFilterSet
@ -2644,8 +2621,7 @@ class VirtualChassisBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Power panels # Power panels
# #
class PowerPanelListView(PermissionRequiredMixin, ObjectListView): class PowerPanelListView(ObjectListView):
permission_required = 'dcim.view_powerpanel'
queryset = PowerPanel.objects.prefetch_related( queryset = PowerPanel.objects.prefetch_related(
'site', 'rack_group' 'site', 'rack_group'
).annotate( ).annotate(
@ -2724,8 +2700,7 @@ class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Power feeds # Power feeds
# #
class PowerFeedListView(PermissionRequiredMixin, ObjectListView): class PowerFeedListView(ObjectListView):
permission_required = 'dcim.view_powerfeed'
queryset = PowerFeed.objects.prefetch_related( queryset = PowerFeed.objects.prefetch_related(
'power_panel', 'rack' 'power_panel', 'rack'
) )

View File

@ -25,8 +25,7 @@ from .tables import ConfigContextTable, ObjectChangeTable, TagTable, TaggedItemT
# Tags # Tags
# #
class TagListView(PermissionRequiredMixin, ObjectListView): class TagListView(ObjectListView):
permission_required = 'extras.view_tag'
queryset = Tag.objects.annotate( queryset = Tag.objects.annotate(
items=Count('extras_taggeditem_items', distinct=True) items=Count('extras_taggeditem_items', distinct=True)
).order_by( ).order_by(
@ -106,8 +105,7 @@ class TagBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Config contexts # Config contexts
# #
class ConfigContextListView(PermissionRequiredMixin, ObjectListView): class ConfigContextListView(ObjectListView):
permission_required = 'extras.view_configcontext'
queryset = ConfigContext.objects.all() queryset = ConfigContext.objects.all()
filterset = filters.ConfigContextFilterSet filterset = filters.ConfigContextFilterSet
filterset_form = forms.ConfigContextFilterForm filterset_form = forms.ConfigContextFilterForm
@ -200,8 +198,7 @@ class ObjectConfigContextView(View):
# Change logging # Change logging
# #
class ObjectChangeListView(PermissionRequiredMixin, ObjectListView): class ObjectChangeListView(ObjectListView):
permission_required = 'extras.view_objectchange'
queryset = ObjectChange.objects.prefetch_related('user', 'changed_object_type') queryset = ObjectChange.objects.prefetch_related('user', 'changed_object_type')
filterset = filters.ObjectChangeFilterSet filterset = filters.ObjectChangeFilterSet
filterset_form = forms.ObjectChangeFilterForm filterset_form = forms.ObjectChangeFilterForm

View File

@ -113,8 +113,7 @@ def add_available_vlans(vlan_group, vlans):
# VRFs # VRFs
# #
class VRFListView(PermissionRequiredMixin, ObjectListView): class VRFListView(ObjectListView):
permission_required = 'ipam.view_vrf'
queryset = VRF.objects.prefetch_related('tenant') queryset = VRF.objects.prefetch_related('tenant')
filterset = filters.VRFFilterSet filterset = filters.VRFFilterSet
filterset_form = forms.VRFFilterForm filterset_form = forms.VRFFilterForm
@ -182,8 +181,7 @@ class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# RIRs # RIRs
# #
class RIRListView(PermissionRequiredMixin, ObjectListView): class RIRListView(ObjectListView):
permission_required = 'ipam.view_rir'
queryset = RIR.objects.annotate(aggregate_count=Count('aggregates')) queryset = RIR.objects.annotate(aggregate_count=Count('aggregates'))
filterset = filters.RIRFilterSet filterset = filters.RIRFilterSet
filterset_form = forms.RIRFilterForm filterset_form = forms.RIRFilterForm
@ -290,8 +288,7 @@ class RIRBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Aggregates # Aggregates
# #
class AggregateListView(PermissionRequiredMixin, ObjectListView): class AggregateListView(ObjectListView):
permission_required = 'ipam.view_aggregate'
queryset = Aggregate.objects.prefetch_related('rir').annotate( queryset = Aggregate.objects.prefetch_related('rir').annotate(
child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ()) child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ())
) )
@ -409,8 +406,7 @@ class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Prefix/VLAN roles # Prefix/VLAN roles
# #
class RoleListView(PermissionRequiredMixin, ObjectListView): class RoleListView(ObjectListView):
permission_required = 'ipam.view_role'
queryset = Role.objects.all() queryset = Role.objects.all()
table = tables.RoleTable table = tables.RoleTable
@ -445,8 +441,7 @@ class RoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Prefixes # Prefixes
# #
class PrefixListView(ObjectPermissionRequiredMixin, ObjectListView): class PrefixListView(ObjectListView):
permission_required = 'ipam.view_prefix'
queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role') queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
filterset = filters.PrefixFilterSet filterset = filters.PrefixFilterSet
filterset_form = forms.PrefixFilterForm filterset_form = forms.PrefixFilterForm
@ -638,8 +633,7 @@ class PrefixBulkDeleteView(ObjectPermissionRequiredMixin, BulkDeleteView):
# IP addresses # IP addresses
# #
class IPAddressListView(PermissionRequiredMixin, ObjectListView): class IPAddressListView(ObjectListView):
permission_required = 'ipam.view_ipaddress'
queryset = IPAddress.objects.prefetch_related( queryset = IPAddress.objects.prefetch_related(
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device', 'interface__virtual_machine' 'vrf__tenant', 'tenant', 'nat_inside', 'interface__device', 'interface__virtual_machine'
) )
@ -813,8 +807,7 @@ class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# VLAN groups # VLAN groups
# #
class VLANGroupListView(PermissionRequiredMixin, ObjectListView): class VLANGroupListView(ObjectListView):
permission_required = 'ipam.view_vlangroup'
queryset = VLANGroup.objects.prefetch_related('site').annotate(vlan_count=Count('vlans')) queryset = VLANGroup.objects.prefetch_related('site').annotate(vlan_count=Count('vlans'))
filterset = filters.VLANGroupFilterSet filterset = filters.VLANGroupFilterSet
filterset_form = forms.VLANGroupFilterForm filterset_form = forms.VLANGroupFilterForm
@ -889,8 +882,7 @@ class VLANGroupVLANsView(PermissionRequiredMixin, View):
# VLANs # VLANs
# #
class VLANListView(PermissionRequiredMixin, ObjectListView): class VLANListView(ObjectListView):
permission_required = 'ipam.view_vlan'
queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role').prefetch_related('prefixes') queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role').prefetch_related('prefixes')
filterset = filters.VLANFilterSet filterset = filters.VLANFilterSet
filterset_form = forms.VLANFilterForm filterset_form = forms.VLANFilterForm
@ -985,8 +977,7 @@ class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Services # Services
# #
class ServiceListView(PermissionRequiredMixin, ObjectListView): class ServiceListView(ObjectListView):
permission_required = 'ipam.view_service'
queryset = Service.objects.prefetch_related('device', 'virtual_machine') queryset = Service.objects.prefetch_related('device', 'virtual_machine')
filterset = filters.ServiceFilterSet filterset = filters.ServiceFilterSet
filterset_form = forms.ServiceFilterForm filterset_form = forms.ServiceFilterForm

View File

@ -30,8 +30,7 @@ def get_session_key(request):
# Secret roles # Secret roles
# #
class SecretRoleListView(PermissionRequiredMixin, ObjectListView): class SecretRoleListView(ObjectListView):
permission_required = 'secrets.view_secretrole'
queryset = SecretRole.objects.annotate(secret_count=Count('secrets')) queryset = SecretRole.objects.annotate(secret_count=Count('secrets'))
table = tables.SecretRoleTable table = tables.SecretRoleTable
@ -66,8 +65,7 @@ class SecretRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Secrets # Secrets
# #
class SecretListView(PermissionRequiredMixin, ObjectListView): class SecretListView(ObjectListView):
permission_required = 'secrets.view_secret'
queryset = Secret.objects.prefetch_related('role', 'device') queryset = Secret.objects.prefetch_related('role', 'device')
filterset = filters.SecretFilterSet filterset = filters.SecretFilterSet
filterset_form = forms.SecretFilterForm filterset_form = forms.SecretFilterForm

View File

@ -18,8 +18,7 @@ from .models import Tenant, TenantGroup
# Tenant groups # Tenant groups
# #
class TenantGroupListView(PermissionRequiredMixin, ObjectListView): class TenantGroupListView(ObjectListView):
permission_required = 'tenancy.view_tenantgroup'
queryset = TenantGroup.objects.add_related_count( queryset = TenantGroup.objects.add_related_count(
TenantGroup.objects.all(), TenantGroup.objects.all(),
Tenant, Tenant,
@ -60,8 +59,7 @@ class TenantGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Tenants # Tenants
# #
class TenantListView(PermissionRequiredMixin, ObjectListView): class TenantListView(ObjectListView):
permission_required = 'tenancy.view_tenant'
queryset = Tenant.objects.prefetch_related('group') queryset = Tenant.objects.prefetch_related('group')
filterset = filters.TenantFilterSet filterset = filters.TenantFilterSet
filterset_form = forms.TenantFilterForm filterset_form = forms.TenantFilterForm

View File

@ -27,6 +27,7 @@ from extras.querysets import CustomFieldQueryset
from users.models import ObjectPermission from users.models import ObjectPermission
from utilities.exceptions import AbortTransaction from utilities.exceptions import AbortTransaction
from utilities.forms import BootstrapMixin, CSVDataField, TableConfigForm from utilities.forms import BootstrapMixin, CSVDataField, TableConfigForm
from utilities.permissions import get_permission_for_model
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
from .forms import ConfirmationForm, ImportForm from .forms import ConfirmationForm, ImportForm
@ -45,11 +46,15 @@ class ObjectPermissionRequiredMixin(AccessMixin):
""" """
permission_required = None permission_required = None
def get_required_permission(self):
return self.permission_required
def has_permission(self): def has_permission(self):
user = self.request.user user = self.request.user
permission_required = self.get_required_permission()
# First, check that the user is granted the required permission at either the model or object level. # First, check that the user is granted the required permission at either the model or object level.
if not user.has_perm(self.permission_required): if not user.has_perm(permission_required):
return False return False
# Superusers implicitly have all permissions # Superusers implicitly have all permissions
@ -58,23 +63,18 @@ class ObjectPermissionRequiredMixin(AccessMixin):
# Determine whether the permission is model-level or object-level. Model-level permissions grant the # Determine whether the permission is model-level or object-level. Model-level permissions grant the
# specified action to *all* objects, so no further action is needed. # specified action to *all* objects, so no further action is needed.
if self.permission_required in {*user._user_perm_cache, *user._group_perm_cache}: if permission_required in {*user._user_perm_cache, *user._group_perm_cache}:
return True return True
# If the permission is granted only at the object level, filter the view's queryset to return only objects # If the permission is granted only at the object level, filter the view's queryset to return only objects
# on which the user is permitted to perform the specified action. # on which the user is permitted to perform the specified action.
attrs = ObjectPermission.objects.get_attr_constraints(user, self.permission_required) attrs = ObjectPermission.objects.get_attr_constraints(user, permission_required)
if attrs: if attrs:
# Update the view's QuerySet to filter only the permitted objects # Update the view's QuerySet to filter only the permitted objects
self.queryset = self.queryset.filter(attrs) self.queryset = self.queryset.filter(attrs)
return True return True
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if self.permission_required is None:
raise ImproperlyConfigured(
'{0} is missing the permission_required attribute. Define {0}.permission_required, or override '
'{0}.get_permission_required().'.format(self.__class__.__name__)
)
if not hasattr(self, 'queryset'): if not hasattr(self, 'queryset'):
raise ImproperlyConfigured( raise ImproperlyConfigured(
@ -118,15 +118,15 @@ class GetReturnURLMixin(object):
# Generic views # Generic views
# #
class ObjectListView(View): class ObjectListView(ObjectPermissionRequiredMixin, View):
""" """
List a series of objects. List a series of objects.
queryset: The queryset of objects to display :param queryset: The queryset of objects to display
filter: A django-filter FilterSet that is applied to the queryset :param filter: A django-filter FilterSet that is applied to the queryset
filter_form: The form used to render filter options :param filter_form: The form used to render filter options
table: The django-tables2 Table used to render the objects list :param table: The django-tables2 Table used to render the objects list
template_name: The name of the template :param template_name: The name of the template
""" """
queryset = None queryset = None
filterset = None filterset = None
@ -135,6 +135,11 @@ class ObjectListView(View):
template_name = 'utilities/obj_list.html' template_name = 'utilities/obj_list.html'
action_buttons = ('add', 'import', 'export') action_buttons = ('add', 'import', 'export')
def get_required_permission(self):
if getattr(self, 'permission_required') is not None:
return self.permission_required
return get_permission_for_model(self.queryset.model, 'view')
def queryset_to_yaml(self): def queryset_to_yaml(self):
""" """
Export the queryset of objects as concatenated YAML documents. Export the queryset of objects as concatenated YAML documents.

View File

@ -22,8 +22,7 @@ from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
# Cluster types # Cluster types
# #
class ClusterTypeListView(PermissionRequiredMixin, ObjectListView): class ClusterTypeListView(ObjectListView):
permission_required = 'virtualization.view_clustertype'
queryset = ClusterType.objects.annotate(cluster_count=Count('clusters')) queryset = ClusterType.objects.annotate(cluster_count=Count('clusters'))
table = tables.ClusterTypeTable table = tables.ClusterTypeTable
@ -58,8 +57,7 @@ class ClusterTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Cluster groups # Cluster groups
# #
class ClusterGroupListView(PermissionRequiredMixin, ObjectListView): class ClusterGroupListView(ObjectListView):
permission_required = 'virtualization.view_clustergroup'
queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters')) queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters'))
table = tables.ClusterGroupTable table = tables.ClusterGroupTable
@ -94,8 +92,7 @@ class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
# Clusters # Clusters
# #
class ClusterListView(PermissionRequiredMixin, ObjectListView): class ClusterListView(ObjectListView):
permission_required = 'virtualization.view_cluster'
queryset = Cluster.objects.prefetch_related('type', 'group', 'site', 'tenant') queryset = Cluster.objects.prefetch_related('type', 'group', 'site', 'tenant')
table = tables.ClusterTable table = tables.ClusterTable
filterset = filters.ClusterFilterSet filterset = filters.ClusterFilterSet
@ -251,8 +248,7 @@ class ClusterRemoveDevicesView(PermissionRequiredMixin, View):
# Virtual machines # Virtual machines
# #
class VirtualMachineListView(PermissionRequiredMixin, ObjectListView): class VirtualMachineListView(ObjectListView):
permission_required = 'virtualization.view_virtualmachine'
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role', 'primary_ip4', 'primary_ip6') queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role', 'primary_ip4', 'primary_ip6')
filterset = filters.VirtualMachineFilterSet filterset = filters.VirtualMachineFilterSet
filterset_form = forms.VirtualMachineFilterForm filterset_form = forms.VirtualMachineFilterForm