mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 12:12:53 -06:00
Enforce view permissions for UI views
This commit is contained in:
parent
ea6815b9bb
commit
e710ccb0e6
@ -4,13 +4,15 @@ from django.test import Client, TestCase
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from circuits.models import Circuit, CircuitType, Provider
|
from circuits.models import Circuit, CircuitType, Provider
|
||||||
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
|
|
||||||
class ProviderTestCase(TestCase):
|
class ProviderTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['circuits.view_provider'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
Provider.objects.bulk_create([
|
Provider.objects.bulk_create([
|
||||||
Provider(name='Provider 1', slug='provider-1', asn=65001),
|
Provider(name='Provider 1', slug='provider-1', asn=65001),
|
||||||
@ -38,8 +40,9 @@ class ProviderTestCase(TestCase):
|
|||||||
class CircuitTypeTestCase(TestCase):
|
class CircuitTypeTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['circuits.view_circuittype'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
CircuitType.objects.bulk_create([
|
CircuitType.objects.bulk_create([
|
||||||
CircuitType(name='Circuit Type 1', slug='circuit-type-1'),
|
CircuitType(name='Circuit Type 1', slug='circuit-type-1'),
|
||||||
@ -58,8 +61,9 @@ class CircuitTypeTestCase(TestCase):
|
|||||||
class CircuitTestCase(TestCase):
|
class CircuitTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['circuits.view_circuit'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
provider = Provider(name='Provider 1', slug='provider-1', asn=65001)
|
provider = Provider(name='Provider 1', slug='provider-1', asn=65001)
|
||||||
provider.save()
|
provider.save()
|
||||||
@ -84,8 +88,8 @@ class CircuitTestCase(TestCase):
|
|||||||
response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)))
|
response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_provider(self):
|
def test_circuit(self):
|
||||||
|
|
||||||
provider = Provider.objects.first()
|
circuit = Circuit.objects.first()
|
||||||
response = self.client.get(provider.get_absolute_url())
|
response = self.client.get(circuit.get_absolute_url())
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
@ -20,7 +20,8 @@ from .models import Circuit, CircuitTermination, CircuitType, Provider
|
|||||||
# Providers
|
# Providers
|
||||||
#
|
#
|
||||||
|
|
||||||
class ProviderListView(ObjectListView):
|
class ProviderListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'circuits.view_provider'
|
||||||
queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
|
queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
|
||||||
filter = filters.ProviderFilter
|
filter = filters.ProviderFilter
|
||||||
filter_form = forms.ProviderFilterForm
|
filter_form = forms.ProviderFilterForm
|
||||||
@ -28,7 +29,8 @@ class ProviderListView(ObjectListView):
|
|||||||
template_name = 'circuits/provider_list.html'
|
template_name = 'circuits/provider_list.html'
|
||||||
|
|
||||||
|
|
||||||
class ProviderView(View):
|
class ProviderView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'circuits.view_provider'
|
||||||
|
|
||||||
def get(self, request, slug):
|
def get(self, request, slug):
|
||||||
|
|
||||||
@ -93,7 +95,8 @@ class ProviderBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Circuit Types
|
# Circuit Types
|
||||||
#
|
#
|
||||||
|
|
||||||
class CircuitTypeListView(ObjectListView):
|
class CircuitTypeListView(PermissionRequiredMixin, 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
|
||||||
template_name = 'circuits/circuittype_list.html'
|
template_name = 'circuits/circuittype_list.html'
|
||||||
@ -128,7 +131,8 @@ class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Circuits
|
# Circuits
|
||||||
#
|
#
|
||||||
|
|
||||||
class CircuitListView(ObjectListView):
|
class CircuitListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'circuits.view_circuit'
|
||||||
queryset = Circuit.objects.select_related(
|
queryset = Circuit.objects.select_related(
|
||||||
'provider', 'type', 'tenant'
|
'provider', 'type', 'tenant'
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
@ -140,7 +144,8 @@ class CircuitListView(ObjectListView):
|
|||||||
template_name = 'circuits/circuit_list.html'
|
template_name = 'circuits/circuit_list.html'
|
||||||
|
|
||||||
|
|
||||||
class CircuitView(View):
|
class CircuitView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'circuits.view_circuit'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
@ -9,13 +8,15 @@ from dcim.models import (
|
|||||||
Cable, Device, DeviceRole, DeviceType, Interface, InventoryItem, Manufacturer, Platform, Rack, RackGroup,
|
Cable, Device, DeviceRole, DeviceType, Interface, InventoryItem, Manufacturer, Platform, Rack, RackGroup,
|
||||||
RackReservation, RackRole, Site, Region, VirtualChassis,
|
RackReservation, RackRole, Site, Region, VirtualChassis,
|
||||||
)
|
)
|
||||||
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
|
|
||||||
class RegionTestCase(TestCase):
|
class RegionTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_region'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
# Create three Regions
|
# Create three Regions
|
||||||
for i in range(1, 4):
|
for i in range(1, 4):
|
||||||
@ -32,8 +33,9 @@ class RegionTestCase(TestCase):
|
|||||||
class SiteTestCase(TestCase):
|
class SiteTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_site'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
region = Region(name='Region 1', slug='region-1')
|
region = Region(name='Region 1', slug='region-1')
|
||||||
region.save()
|
region.save()
|
||||||
@ -64,8 +66,9 @@ class SiteTestCase(TestCase):
|
|||||||
class RackGroupTestCase(TestCase):
|
class RackGroupTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_rackgroup'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -84,11 +87,12 @@ class RackGroupTestCase(TestCase):
|
|||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
|
||||||
class RackTypeTestCase(TestCase):
|
class RackRoleTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_rackrole'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
RackRole.objects.bulk_create([
|
RackRole.objects.bulk_create([
|
||||||
RackRole(name='Rack Role 1', slug='rack-role-1'),
|
RackRole(name='Rack Role 1', slug='rack-role-1'),
|
||||||
@ -107,12 +111,9 @@ class RackTypeTestCase(TestCase):
|
|||||||
class RackReservationTestCase(TestCase):
|
class RackReservationTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_rackreservation'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
User = get_user_model()
|
|
||||||
user = User(username='testuser', email='testuser@example.com')
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -137,8 +138,9 @@ class RackReservationTestCase(TestCase):
|
|||||||
class RackTestCase(TestCase):
|
class RackTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_rack'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -169,8 +171,9 @@ class RackTestCase(TestCase):
|
|||||||
class ManufacturerTypeTestCase(TestCase):
|
class ManufacturerTypeTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_manufacturer'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
Manufacturer.objects.bulk_create([
|
Manufacturer.objects.bulk_create([
|
||||||
Manufacturer(name='Manufacturer 1', slug='manufacturer-1'),
|
Manufacturer(name='Manufacturer 1', slug='manufacturer-1'),
|
||||||
@ -189,8 +192,9 @@ class ManufacturerTypeTestCase(TestCase):
|
|||||||
class DeviceTypeTestCase(TestCase):
|
class DeviceTypeTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_devicetype'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1')
|
manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1')
|
||||||
manufacturer.save()
|
manufacturer.save()
|
||||||
@ -221,8 +225,9 @@ class DeviceTypeTestCase(TestCase):
|
|||||||
class DeviceRoleTestCase(TestCase):
|
class DeviceRoleTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_devicerole'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
DeviceRole.objects.bulk_create([
|
DeviceRole.objects.bulk_create([
|
||||||
DeviceRole(name='Device Role 1', slug='device-role-1'),
|
DeviceRole(name='Device Role 1', slug='device-role-1'),
|
||||||
@ -241,8 +246,9 @@ class DeviceRoleTestCase(TestCase):
|
|||||||
class PlatformTestCase(TestCase):
|
class PlatformTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_platform'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
Platform.objects.bulk_create([
|
Platform.objects.bulk_create([
|
||||||
Platform(name='Platform 1', slug='platform-1'),
|
Platform(name='Platform 1', slug='platform-1'),
|
||||||
@ -261,8 +267,9 @@ class PlatformTestCase(TestCase):
|
|||||||
class DeviceTestCase(TestCase):
|
class DeviceTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_device'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -303,8 +310,9 @@ class DeviceTestCase(TestCase):
|
|||||||
class InventoryItemTestCase(TestCase):
|
class InventoryItemTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_inventoryitem'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -337,18 +345,13 @@ class InventoryItemTestCase(TestCase):
|
|||||||
response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)))
|
response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_inventoryitem(self):
|
|
||||||
|
|
||||||
inventoryitem = InventoryItem.objects.first()
|
|
||||||
response = self.client.get(inventoryitem.get_absolute_url())
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
|
|
||||||
class CableTestCase(TestCase):
|
class CableTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_cable'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -401,11 +404,12 @@ class CableTestCase(TestCase):
|
|||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineTestCase(TestCase):
|
class VirtualChassisTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['dcim.view_virtualchassis'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site.objects.create(name='Site 1', slug='site-1')
|
site = Site.objects.create(name='Site 1', slug='site-1')
|
||||||
manufacturer = Manufacturer.objects.create(name='Manufacturer', slug='manufacturer-1')
|
manufacturer = Manufacturer.objects.create(name='Manufacturer', slug='manufacturer-1')
|
||||||
@ -450,9 +454,3 @@ class VirtualMachineTestCase(TestCase):
|
|||||||
|
|
||||||
response = self.client.get(url)
|
response = self.client.get(url)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_virtualchassis(self):
|
|
||||||
|
|
||||||
virtualchassis = VirtualChassis.objects.first()
|
|
||||||
response = self.client.get(virtualchassis.get_absolute_url())
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
@ -138,7 +138,8 @@ class BulkDisconnectView(GetReturnURLMixin, View):
|
|||||||
# Regions
|
# Regions
|
||||||
#
|
#
|
||||||
|
|
||||||
class RegionListView(ObjectListView):
|
class RegionListView(PermissionRequiredMixin, 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,
|
||||||
@ -182,7 +183,8 @@ class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Sites
|
# Sites
|
||||||
#
|
#
|
||||||
|
|
||||||
class SiteListView(ObjectListView):
|
class SiteListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_site'
|
||||||
queryset = Site.objects.select_related('region', 'tenant')
|
queryset = Site.objects.select_related('region', 'tenant')
|
||||||
filter = filters.SiteFilter
|
filter = filters.SiteFilter
|
||||||
filter_form = forms.SiteFilterForm
|
filter_form = forms.SiteFilterForm
|
||||||
@ -190,7 +192,8 @@ class SiteListView(ObjectListView):
|
|||||||
template_name = 'dcim/site_list.html'
|
template_name = 'dcim/site_list.html'
|
||||||
|
|
||||||
|
|
||||||
class SiteView(View):
|
class SiteView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_site'
|
||||||
|
|
||||||
def get(self, request, slug):
|
def get(self, request, slug):
|
||||||
|
|
||||||
@ -254,7 +257,8 @@ class SiteBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
# Rack groups
|
# Rack groups
|
||||||
#
|
#
|
||||||
|
|
||||||
class RackGroupListView(ObjectListView):
|
class RackGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_rackgroup'
|
||||||
queryset = RackGroup.objects.select_related('site').annotate(rack_count=Count('racks'))
|
queryset = RackGroup.objects.select_related('site').annotate(rack_count=Count('racks'))
|
||||||
filter = filters.RackGroupFilter
|
filter = filters.RackGroupFilter
|
||||||
filter_form = forms.RackGroupFilterForm
|
filter_form = forms.RackGroupFilterForm
|
||||||
@ -292,7 +296,8 @@ class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Rack roles
|
# Rack roles
|
||||||
#
|
#
|
||||||
|
|
||||||
class RackRoleListView(ObjectListView):
|
class RackRoleListView(PermissionRequiredMixin, 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
|
||||||
template_name = 'dcim/rackrole_list.html'
|
template_name = 'dcim/rackrole_list.html'
|
||||||
@ -327,7 +332,8 @@ class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Racks
|
# Racks
|
||||||
#
|
#
|
||||||
|
|
||||||
class RackListView(ObjectListView):
|
class RackListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_rack'
|
||||||
queryset = Rack.objects.select_related(
|
queryset = Rack.objects.select_related(
|
||||||
'site', 'group', 'tenant', 'role'
|
'site', 'group', 'tenant', 'role'
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
@ -341,10 +347,11 @@ class RackListView(ObjectListView):
|
|||||||
template_name = 'dcim/rack_list.html'
|
template_name = 'dcim/rack_list.html'
|
||||||
|
|
||||||
|
|
||||||
class RackElevationListView(View):
|
class RackElevationListView(PermissionRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
Display a set of rack elevations side-by-side.
|
Display a set of rack elevations side-by-side.
|
||||||
"""
|
"""
|
||||||
|
permission_required = 'dcim.view_rack'
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
|
||||||
@ -382,7 +389,8 @@ class RackElevationListView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class RackView(View):
|
class RackView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_rack'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -454,7 +462,8 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Rack reservations
|
# Rack reservations
|
||||||
#
|
#
|
||||||
|
|
||||||
class RackReservationListView(ObjectListView):
|
class RackReservationListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_rackreservation'
|
||||||
queryset = RackReservation.objects.all()
|
queryset = RackReservation.objects.all()
|
||||||
filter = filters.RackReservationFilter
|
filter = filters.RackReservationFilter
|
||||||
filter_form = forms.RackReservationFilterForm
|
filter_form = forms.RackReservationFilterForm
|
||||||
@ -510,7 +519,8 @@ class RackReservationBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Manufacturers
|
# Manufacturers
|
||||||
#
|
#
|
||||||
|
|
||||||
class ManufacturerListView(ObjectListView):
|
class ManufacturerListView(PermissionRequiredMixin, 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),
|
||||||
platform_count=Count('platforms', distinct=True),
|
platform_count=Count('platforms', distinct=True),
|
||||||
@ -548,7 +558,8 @@ class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Device types
|
# Device types
|
||||||
#
|
#
|
||||||
|
|
||||||
class DeviceTypeListView(ObjectListView):
|
class DeviceTypeListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_devicetype'
|
||||||
queryset = DeviceType.objects.select_related('manufacturer').annotate(instance_count=Count('instances'))
|
queryset = DeviceType.objects.select_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||||
filter = filters.DeviceTypeFilter
|
filter = filters.DeviceTypeFilter
|
||||||
filter_form = forms.DeviceTypeFilterForm
|
filter_form = forms.DeviceTypeFilterForm
|
||||||
@ -556,7 +567,8 @@ class DeviceTypeListView(ObjectListView):
|
|||||||
template_name = 'dcim/devicetype_list.html'
|
template_name = 'dcim/devicetype_list.html'
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeView(View):
|
class DeviceTypeView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_devicetype'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -812,7 +824,8 @@ class DeviceBayTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Device roles
|
# Device roles
|
||||||
#
|
#
|
||||||
|
|
||||||
class DeviceRoleListView(ObjectListView):
|
class DeviceRoleListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_devicerole'
|
||||||
queryset = DeviceRole.objects.all()
|
queryset = DeviceRole.objects.all()
|
||||||
table = tables.DeviceRoleTable
|
table = tables.DeviceRoleTable
|
||||||
template_name = 'dcim/devicerole_list.html'
|
template_name = 'dcim/devicerole_list.html'
|
||||||
@ -847,7 +860,8 @@ class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Platforms
|
# Platforms
|
||||||
#
|
#
|
||||||
|
|
||||||
class PlatformListView(ObjectListView):
|
class PlatformListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_platform'
|
||||||
queryset = Platform.objects.all()
|
queryset = Platform.objects.all()
|
||||||
table = tables.PlatformTable
|
table = tables.PlatformTable
|
||||||
template_name = 'dcim/platform_list.html'
|
template_name = 'dcim/platform_list.html'
|
||||||
@ -882,7 +896,8 @@ class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Devices
|
# Devices
|
||||||
#
|
#
|
||||||
|
|
||||||
class DeviceListView(ObjectListView):
|
class DeviceListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_device'
|
||||||
queryset = Device.objects.select_related(
|
queryset = Device.objects.select_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'
|
||||||
)
|
)
|
||||||
@ -892,7 +907,8 @@ class DeviceListView(ObjectListView):
|
|||||||
template_name = 'dcim/device_list.html'
|
template_name = 'dcim/device_list.html'
|
||||||
|
|
||||||
|
|
||||||
class DeviceView(View):
|
class DeviceView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_device'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -972,7 +988,8 @@ class DeviceView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class DeviceInventoryView(View):
|
class DeviceInventoryView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_device'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -993,7 +1010,7 @@ class DeviceInventoryView(View):
|
|||||||
|
|
||||||
|
|
||||||
class DeviceStatusView(PermissionRequiredMixin, View):
|
class DeviceStatusView(PermissionRequiredMixin, View):
|
||||||
permission_required = 'dcim.napalm_read'
|
permission_required = ('dcim.view_device', 'dcim.napalm_read')
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -1006,7 +1023,7 @@ class DeviceStatusView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
|
|
||||||
class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
||||||
permission_required = 'dcim.napalm_read'
|
permission_required = ('dcim.view_device', 'dcim.napalm_read')
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -1023,7 +1040,7 @@ class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
|
|
||||||
class DeviceConfigView(PermissionRequiredMixin, View):
|
class DeviceConfigView(PermissionRequiredMixin, View):
|
||||||
permission_required = 'dcim.napalm_read'
|
permission_required = ('dcim.view_device', 'dcim.napalm_read')
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -1035,7 +1052,8 @@ class DeviceConfigView(PermissionRequiredMixin, View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class DeviceConfigContextView(ObjectConfigContextView):
|
class DeviceConfigContextView(PermissionRequiredMixin, ObjectConfigContextView):
|
||||||
|
permission_required = 'dcim.view_device'
|
||||||
object_class = Device
|
object_class = Device
|
||||||
base_template = 'dcim/device.html'
|
base_template = 'dcim/device.html'
|
||||||
|
|
||||||
@ -1258,7 +1276,8 @@ class PowerOutletBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Interfaces
|
# Interfaces
|
||||||
#
|
#
|
||||||
|
|
||||||
class InterfaceView(View):
|
class InterfaceView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_interface'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -1639,7 +1658,8 @@ class DeviceBulkAddDeviceBayView(PermissionRequiredMixin, BulkComponentCreateVie
|
|||||||
# Cables
|
# Cables
|
||||||
#
|
#
|
||||||
|
|
||||||
class CableListView(ObjectListView):
|
class CableListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_cable'
|
||||||
queryset = Cable.objects.prefetch_related(
|
queryset = Cable.objects.prefetch_related(
|
||||||
'termination_a', 'termination_b'
|
'termination_a', 'termination_b'
|
||||||
)
|
)
|
||||||
@ -1649,7 +1669,8 @@ class CableListView(ObjectListView):
|
|||||||
template_name = 'dcim/cable_list.html'
|
template_name = 'dcim/cable_list.html'
|
||||||
|
|
||||||
|
|
||||||
class CableView(View):
|
class CableView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_cable'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -1660,10 +1681,11 @@ class CableView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class CableTraceView(View):
|
class CableTraceView(PermissionRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
Trace a cable path beginning from the given termination.
|
Trace a cable path beginning from the given termination.
|
||||||
"""
|
"""
|
||||||
|
permission_required = 'dcim.view_cable'
|
||||||
|
|
||||||
def get(self, request, model, pk):
|
def get(self, request, model, pk):
|
||||||
|
|
||||||
@ -1792,7 +1814,8 @@ class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Connections
|
# Connections
|
||||||
#
|
#
|
||||||
|
|
||||||
class ConsoleConnectionsListView(ObjectListView):
|
class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport')
|
||||||
queryset = ConsolePort.objects.select_related(
|
queryset = ConsolePort.objects.select_related(
|
||||||
'device', 'connected_endpoint__device'
|
'device', 'connected_endpoint__device'
|
||||||
).filter(
|
).filter(
|
||||||
@ -1822,7 +1845,8 @@ class ConsoleConnectionsListView(ObjectListView):
|
|||||||
return csv_data
|
return csv_data
|
||||||
|
|
||||||
|
|
||||||
class PowerConnectionsListView(ObjectListView):
|
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet')
|
||||||
queryset = PowerPort.objects.select_related(
|
queryset = PowerPort.objects.select_related(
|
||||||
'device', '_connected_poweroutlet__device'
|
'device', '_connected_poweroutlet__device'
|
||||||
).filter(
|
).filter(
|
||||||
@ -1852,7 +1876,8 @@ class PowerConnectionsListView(ObjectListView):
|
|||||||
return csv_data
|
return csv_data
|
||||||
|
|
||||||
|
|
||||||
class InterfaceConnectionsListView(ObjectListView):
|
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.interface'
|
||||||
queryset = Interface.objects.select_related(
|
queryset = Interface.objects.select_related(
|
||||||
'device', 'cable', '_connected_interface__device'
|
'device', 'cable', '_connected_interface__device'
|
||||||
).filter(
|
).filter(
|
||||||
@ -1894,7 +1919,8 @@ class InterfaceConnectionsListView(ObjectListView):
|
|||||||
# Inventory items
|
# Inventory items
|
||||||
#
|
#
|
||||||
|
|
||||||
class InventoryItemListView(ObjectListView):
|
class InventoryItemListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_inventoryitem'
|
||||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
||||||
filter = filters.InventoryItemFilter
|
filter = filters.InventoryItemFilter
|
||||||
filter_form = forms.InventoryItemFilterForm
|
filter_form = forms.InventoryItemFilterForm
|
||||||
@ -1949,7 +1975,8 @@ class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Virtual chassis
|
# Virtual chassis
|
||||||
#
|
#
|
||||||
|
|
||||||
class VirtualChassisListView(ObjectListView):
|
class VirtualChassisListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_virtualchassis'
|
||||||
queryset = VirtualChassis.objects.select_related('master').annotate(member_count=Count('members'))
|
queryset = VirtualChassis.objects.select_related('master').annotate(member_count=Count('members'))
|
||||||
table = tables.VirtualChassisTable
|
table = tables.VirtualChassisTable
|
||||||
filter = filters.VirtualChassisFilter
|
filter = filters.VirtualChassisFilter
|
||||||
@ -2184,7 +2211,8 @@ class VirtualChassisRemoveMemberView(PermissionRequiredMixin, GetReturnURLMixin,
|
|||||||
# Power panels
|
# Power panels
|
||||||
#
|
#
|
||||||
|
|
||||||
class PowerPanelListView(ObjectListView):
|
class PowerPanelListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_powerpanel'
|
||||||
queryset = PowerPanel.objects.select_related(
|
queryset = PowerPanel.objects.select_related(
|
||||||
'site', 'rack_group'
|
'site', 'rack_group'
|
||||||
).annotate(
|
).annotate(
|
||||||
@ -2196,7 +2224,8 @@ class PowerPanelListView(ObjectListView):
|
|||||||
template_name = 'dcim/powerpanel_list.html'
|
template_name = 'dcim/powerpanel_list.html'
|
||||||
|
|
||||||
|
|
||||||
class PowerPanelView(View):
|
class PowerPanelView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_powerpanel'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -2253,7 +2282,8 @@ class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Power feeds
|
# Power feeds
|
||||||
#
|
#
|
||||||
|
|
||||||
class PowerFeedListView(ObjectListView):
|
class PowerFeedListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'dcim.view_powerfeed'
|
||||||
queryset = PowerFeed.objects.select_related(
|
queryset = PowerFeed.objects.select_related(
|
||||||
'power_panel', 'rack'
|
'power_panel', 'rack'
|
||||||
)
|
)
|
||||||
@ -2263,7 +2293,8 @@ class PowerFeedListView(ObjectListView):
|
|||||||
template_name = 'dcim/powerfeed_list.html'
|
template_name = 'dcim/powerfeed_list.html'
|
||||||
|
|
||||||
|
|
||||||
class PowerFeedView(View):
|
class PowerFeedView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_powerfeed'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ from django.urls import reverse
|
|||||||
|
|
||||||
from dcim.models import Site
|
from dcim.models import Site
|
||||||
from extras.models import ConfigContext, ObjectChange, Tag
|
from extras.models import ConfigContext, ObjectChange, Tag
|
||||||
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
|
|
||||||
class TagTestCase(TestCase):
|
class TagTestCase(TestCase):
|
||||||
@ -35,8 +36,9 @@ class TagTestCase(TestCase):
|
|||||||
class ConfigContextTestCase(TestCase):
|
class ConfigContextTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['extras.view_configcontext'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -70,11 +72,9 @@ class ConfigContextTestCase(TestCase):
|
|||||||
class ObjectChangeTestCase(TestCase):
|
class ObjectChangeTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['extras.view_objectchange'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
user = User(username='testuser', email='testuser@example.com')
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
|
@ -96,7 +96,8 @@ class TagBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Config contexts
|
# Config contexts
|
||||||
#
|
#
|
||||||
|
|
||||||
class ConfigContextListView(ObjectListView):
|
class ConfigContextListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'extras.view_configcontext'
|
||||||
queryset = ConfigContext.objects.all()
|
queryset = ConfigContext.objects.all()
|
||||||
filter = filters.ConfigContextFilter
|
filter = filters.ConfigContextFilter
|
||||||
filter_form = ConfigContextFilterForm
|
filter_form = ConfigContextFilterForm
|
||||||
@ -104,7 +105,8 @@ class ConfigContextListView(ObjectListView):
|
|||||||
template_name = 'extras/configcontext_list.html'
|
template_name = 'extras/configcontext_list.html'
|
||||||
|
|
||||||
|
|
||||||
class ConfigContextView(View):
|
class ConfigContextView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'extras.view_configcontext'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -173,7 +175,8 @@ class ObjectConfigContextView(View):
|
|||||||
# Change logging
|
# Change logging
|
||||||
#
|
#
|
||||||
|
|
||||||
class ObjectChangeListView(ObjectListView):
|
class ObjectChangeListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'extras.view_objectchange'
|
||||||
queryset = ObjectChange.objects.select_related('user', 'changed_object_type')
|
queryset = ObjectChange.objects.select_related('user', 'changed_object_type')
|
||||||
filter = filters.ObjectChangeFilter
|
filter = filters.ObjectChangeFilter
|
||||||
filter_form = ObjectChangeFilterForm
|
filter_form = ObjectChangeFilterForm
|
||||||
@ -181,7 +184,8 @@ class ObjectChangeListView(ObjectListView):
|
|||||||
template_name = 'extras/objectchange_list.html'
|
template_name = 'extras/objectchange_list.html'
|
||||||
|
|
||||||
|
|
||||||
class ObjectChangeView(View):
|
class ObjectChangeView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'extras.view_objectchange'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -272,10 +276,11 @@ class ImageAttachmentDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
|||||||
# Reports
|
# Reports
|
||||||
#
|
#
|
||||||
|
|
||||||
class ReportListView(View):
|
class ReportListView(PermissionRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
Retrieve all of the available reports from disk and the recorded ReportResult (if any) for each.
|
Retrieve all of the available reports from disk and the recorded ReportResult (if any) for each.
|
||||||
"""
|
"""
|
||||||
|
permission_required = 'extras.view_reportresult'
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
|
||||||
@ -295,10 +300,11 @@ class ReportListView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class ReportView(View):
|
class ReportView(PermissionRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
Display a single Report and its associated ReportResult (if any).
|
Display a single Report and its associated ReportResult (if any).
|
||||||
"""
|
"""
|
||||||
|
permission_required = 'extras.view_reportresult'
|
||||||
|
|
||||||
def get(self, request, name):
|
def get(self, request, name):
|
||||||
|
|
||||||
|
@ -7,13 +7,15 @@ from django.urls import reverse
|
|||||||
from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site
|
from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site
|
||||||
from ipam.constants import IP_PROTOCOL_TCP
|
from ipam.constants import IP_PROTOCOL_TCP
|
||||||
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
|
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
|
||||||
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
|
|
||||||
class VRFTestCase(TestCase):
|
class VRFTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_vrf'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
VRF.objects.bulk_create([
|
VRF.objects.bulk_create([
|
||||||
VRF(name='VRF 1', rd='65000:1'),
|
VRF(name='VRF 1', rd='65000:1'),
|
||||||
@ -41,8 +43,9 @@ class VRFTestCase(TestCase):
|
|||||||
class RIRTestCase(TestCase):
|
class RIRTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_rir'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
RIR.objects.bulk_create([
|
RIR.objects.bulk_create([
|
||||||
RIR(name='RIR 1', slug='rir-1'),
|
RIR(name='RIR 1', slug='rir-1'),
|
||||||
@ -57,18 +60,13 @@ class RIRTestCase(TestCase):
|
|||||||
response = self.client.get(url)
|
response = self.client.get(url)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_rir(self):
|
|
||||||
|
|
||||||
rir = RIR.objects.first()
|
|
||||||
response = self.client.get(rir.get_absolute_url())
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
|
|
||||||
class AggregateTestCase(TestCase):
|
class AggregateTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_aggregate'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
rir = RIR(name='RIR 1', slug='rir-1')
|
rir = RIR(name='RIR 1', slug='rir-1')
|
||||||
rir.save()
|
rir.save()
|
||||||
@ -99,8 +97,9 @@ class AggregateTestCase(TestCase):
|
|||||||
class RoleTestCase(TestCase):
|
class RoleTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_role'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
Role.objects.bulk_create([
|
Role.objects.bulk_create([
|
||||||
Role(name='Role 1', slug='role-1'),
|
Role(name='Role 1', slug='role-1'),
|
||||||
@ -119,8 +118,9 @@ class RoleTestCase(TestCase):
|
|||||||
class PrefixTestCase(TestCase):
|
class PrefixTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_prefix'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -151,8 +151,9 @@ class PrefixTestCase(TestCase):
|
|||||||
class IPAddressTestCase(TestCase):
|
class IPAddressTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_ipaddress'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
vrf = VRF(name='VRF 1', rd='65000:1')
|
vrf = VRF(name='VRF 1', rd='65000:1')
|
||||||
vrf.save()
|
vrf.save()
|
||||||
@ -183,8 +184,9 @@ class IPAddressTestCase(TestCase):
|
|||||||
class VLANGroupTestCase(TestCase):
|
class VLANGroupTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_vlangroup'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -209,8 +211,9 @@ class VLANGroupTestCase(TestCase):
|
|||||||
class VLANTestCase(TestCase):
|
class VLANTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_vlan'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
vlangroup = VLANGroup(name='VLAN Group 1', slug='vlan-group-1')
|
vlangroup = VLANGroup(name='VLAN Group 1', slug='vlan-group-1')
|
||||||
vlangroup.save()
|
vlangroup.save()
|
||||||
@ -241,8 +244,9 @@ class VLANTestCase(TestCase):
|
|||||||
class ServiceTestCase(TestCase):
|
class ServiceTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['ipam.view_service'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
|
@ -113,7 +113,8 @@ def add_available_vlans(vlan_group, vlans):
|
|||||||
# VRFs
|
# VRFs
|
||||||
#
|
#
|
||||||
|
|
||||||
class VRFListView(ObjectListView):
|
class VRFListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_vrf'
|
||||||
queryset = VRF.objects.select_related('tenant')
|
queryset = VRF.objects.select_related('tenant')
|
||||||
filter = filters.VRFFilter
|
filter = filters.VRFFilter
|
||||||
filter_form = forms.VRFFilterForm
|
filter_form = forms.VRFFilterForm
|
||||||
@ -121,7 +122,8 @@ class VRFListView(ObjectListView):
|
|||||||
template_name = 'ipam/vrf_list.html'
|
template_name = 'ipam/vrf_list.html'
|
||||||
|
|
||||||
|
|
||||||
class VRFView(View):
|
class VRFView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_vrf'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -180,7 +182,8 @@ class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# RIRs
|
# RIRs
|
||||||
#
|
#
|
||||||
|
|
||||||
class RIRListView(ObjectListView):
|
class RIRListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_rir'
|
||||||
queryset = RIR.objects.annotate(aggregate_count=Count('aggregates'))
|
queryset = RIR.objects.annotate(aggregate_count=Count('aggregates'))
|
||||||
filter = filters.RIRFilter
|
filter = filters.RIRFilter
|
||||||
filter_form = forms.RIRFilterForm
|
filter_form = forms.RIRFilterForm
|
||||||
@ -286,7 +289,8 @@ class RIRBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Aggregates
|
# Aggregates
|
||||||
#
|
#
|
||||||
|
|
||||||
class AggregateListView(ObjectListView):
|
class AggregateListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_aggregate'
|
||||||
queryset = Aggregate.objects.select_related('rir').extra(select={
|
queryset = Aggregate.objects.select_related('rir').extra(select={
|
||||||
'child_count': 'SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix',
|
'child_count': 'SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix',
|
||||||
})
|
})
|
||||||
@ -312,7 +316,8 @@ class AggregateListView(ObjectListView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AggregateView(View):
|
class AggregateView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_aggregate'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -398,7 +403,8 @@ class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Prefix/VLAN roles
|
# Prefix/VLAN roles
|
||||||
#
|
#
|
||||||
|
|
||||||
class RoleListView(ObjectListView):
|
class RoleListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_role'
|
||||||
queryset = Role.objects.all()
|
queryset = Role.objects.all()
|
||||||
table = tables.RoleTable
|
table = tables.RoleTable
|
||||||
template_name = 'ipam/role_list.html'
|
template_name = 'ipam/role_list.html'
|
||||||
@ -433,7 +439,8 @@ class RoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Prefixes
|
# Prefixes
|
||||||
#
|
#
|
||||||
|
|
||||||
class PrefixListView(ObjectListView):
|
class PrefixListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_prefix'
|
||||||
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||||
filter = filters.PrefixFilter
|
filter = filters.PrefixFilter
|
||||||
filter_form = forms.PrefixFilterForm
|
filter_form = forms.PrefixFilterForm
|
||||||
@ -446,7 +453,8 @@ class PrefixListView(ObjectListView):
|
|||||||
return self.queryset.annotate_depth(limit=limit)
|
return self.queryset.annotate_depth(limit=limit)
|
||||||
|
|
||||||
|
|
||||||
class PrefixView(View):
|
class PrefixView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_prefix'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -489,7 +497,8 @@ class PrefixView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class PrefixPrefixesView(View):
|
class PrefixPrefixesView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_prefix'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -531,7 +540,8 @@ class PrefixPrefixesView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class PrefixIPAddressesView(View):
|
class PrefixIPAddressesView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_prefix'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -617,7 +627,8 @@ class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# IP addresses
|
# IP addresses
|
||||||
#
|
#
|
||||||
|
|
||||||
class IPAddressListView(ObjectListView):
|
class IPAddressListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_ipaddress'
|
||||||
queryset = IPAddress.objects.select_related(
|
queryset = IPAddress.objects.select_related(
|
||||||
'vrf__tenant', 'tenant', 'nat_inside'
|
'vrf__tenant', 'tenant', 'nat_inside'
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
@ -629,7 +640,8 @@ class IPAddressListView(ObjectListView):
|
|||||||
template_name = 'ipam/ipaddress_list.html'
|
template_name = 'ipam/ipaddress_list.html'
|
||||||
|
|
||||||
|
|
||||||
class IPAddressView(View):
|
class IPAddressView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_ipaddress'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -788,7 +800,8 @@ class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# VLAN groups
|
# VLAN groups
|
||||||
#
|
#
|
||||||
|
|
||||||
class VLANGroupListView(ObjectListView):
|
class VLANGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_vlangroup'
|
||||||
queryset = VLANGroup.objects.select_related('site').annotate(vlan_count=Count('vlans'))
|
queryset = VLANGroup.objects.select_related('site').annotate(vlan_count=Count('vlans'))
|
||||||
filter = filters.VLANGroupFilter
|
filter = filters.VLANGroupFilter
|
||||||
filter_form = forms.VLANGroupFilterForm
|
filter_form = forms.VLANGroupFilterForm
|
||||||
@ -822,7 +835,9 @@ class VLANGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
default_return_url = 'ipam:vlangroup_list'
|
default_return_url = 'ipam:vlangroup_list'
|
||||||
|
|
||||||
|
|
||||||
class VLANGroupVLANsView(View):
|
class VLANGroupVLANsView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_vlangroup'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
vlan_group = get_object_or_404(VLANGroup.objects.all(), pk=pk)
|
vlan_group = get_object_or_404(VLANGroup.objects.all(), pk=pk)
|
||||||
@ -861,7 +876,8 @@ class VLANGroupVLANsView(View):
|
|||||||
# VLANs
|
# VLANs
|
||||||
#
|
#
|
||||||
|
|
||||||
class VLANListView(ObjectListView):
|
class VLANListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_vlan'
|
||||||
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role').prefetch_related('prefixes')
|
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role').prefetch_related('prefixes')
|
||||||
filter = filters.VLANFilter
|
filter = filters.VLANFilter
|
||||||
filter_form = forms.VLANFilterForm
|
filter_form = forms.VLANFilterForm
|
||||||
@ -869,7 +885,8 @@ class VLANListView(ObjectListView):
|
|||||||
template_name = 'ipam/vlan_list.html'
|
template_name = 'ipam/vlan_list.html'
|
||||||
|
|
||||||
|
|
||||||
class VLANView(View):
|
class VLANView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_vlan'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -886,7 +903,8 @@ class VLANView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class VLANMembersView(View):
|
class VLANMembersView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_vlan'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -954,7 +972,8 @@ class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Services
|
# Services
|
||||||
#
|
#
|
||||||
|
|
||||||
class ServiceListView(ObjectListView):
|
class ServiceListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'ipam.view_service'
|
||||||
queryset = Service.objects.select_related('device', 'virtual_machine')
|
queryset = Service.objects.select_related('device', 'virtual_machine')
|
||||||
filter = filters.ServiceFilter
|
filter = filters.ServiceFilter
|
||||||
filter_form = forms.ServiceFilterForm
|
filter_form = forms.ServiceFilterForm
|
||||||
@ -962,7 +981,8 @@ class ServiceListView(ObjectListView):
|
|||||||
template_name = 'ipam/service_list.html'
|
template_name = 'ipam/service_list.html'
|
||||||
|
|
||||||
|
|
||||||
class ServiceView(View):
|
class ServiceView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'ipam.view_service'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
@ -1,25 +1,19 @@
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site
|
from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site
|
||||||
from secrets.models import Secret, SecretRole
|
from secrets.models import Secret, SecretRole
|
||||||
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
|
|
||||||
class SecretRoleTestCase(TestCase):
|
class SecretRoleTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['secrets.view_secretrole'])
|
||||||
TEST_USERNAME = 'testuser'
|
|
||||||
TEST_PASSWORD = 'testpassword'
|
|
||||||
|
|
||||||
User = get_user_model()
|
|
||||||
User.objects.create(username=TEST_USERNAME, email='testuser@example.com', password=TEST_PASSWORD)
|
|
||||||
|
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
self.client.login(username=TEST_USERNAME, password=TEST_PASSWORD)
|
self.client.force_login(user)
|
||||||
|
|
||||||
SecretRole.objects.bulk_create([
|
SecretRole.objects.bulk_create([
|
||||||
SecretRole(name='Secret Role 1', slug='secret-role-1'),
|
SecretRole(name='Secret Role 1', slug='secret-role-1'),
|
||||||
@ -29,7 +23,7 @@ class SecretRoleTestCase(TestCase):
|
|||||||
|
|
||||||
def test_secretrole_list(self):
|
def test_secretrole_list(self):
|
||||||
|
|
||||||
url = reverse('secrets:secret_list')
|
url = reverse('secrets:secretrole_list')
|
||||||
|
|
||||||
response = self.client.get(url, follow=True)
|
response = self.client.get(url, follow=True)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
@ -38,8 +32,9 @@ class SecretRoleTestCase(TestCase):
|
|||||||
class SecretTestCase(TestCase):
|
class SecretTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['secrets.view_secret'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
site = Site(name='Site 1', slug='site-1')
|
site = Site(name='Site 1', slug='site-1')
|
||||||
site.save()
|
site.save()
|
||||||
@ -75,7 +70,7 @@ class SecretTestCase(TestCase):
|
|||||||
response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)), follow=True)
|
response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)), follow=True)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_configcontext(self):
|
def test_secret(self):
|
||||||
|
|
||||||
secret = Secret.objects.first()
|
secret = Secret.objects.first()
|
||||||
response = self.client.get(secret.get_absolute_url(), follow=True)
|
response = self.client.get(secret.get_absolute_url(), follow=True)
|
||||||
|
@ -32,7 +32,8 @@ def get_session_key(request):
|
|||||||
# Secret roles
|
# Secret roles
|
||||||
#
|
#
|
||||||
|
|
||||||
class SecretRoleListView(ObjectListView):
|
class SecretRoleListView(PermissionRequiredMixin, 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
|
||||||
template_name = 'secrets/secretrole_list.html'
|
template_name = 'secrets/secretrole_list.html'
|
||||||
@ -67,8 +68,8 @@ class SecretRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Secrets
|
# Secrets
|
||||||
#
|
#
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
class SecretListView(PermissionRequiredMixin, ObjectListView):
|
||||||
class SecretListView(ObjectListView):
|
permission_required = 'secrets.view_secret'
|
||||||
queryset = Secret.objects.select_related('role', 'device')
|
queryset = Secret.objects.select_related('role', 'device')
|
||||||
filter = filters.SecretFilter
|
filter = filters.SecretFilter
|
||||||
filter_form = forms.SecretFilterForm
|
filter_form = forms.SecretFilterForm
|
||||||
@ -76,8 +77,8 @@ class SecretListView(ObjectListView):
|
|||||||
template_name = 'secrets/secret_list.html'
|
template_name = 'secrets/secret_list.html'
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
class SecretView(PermissionRequiredMixin, View):
|
||||||
class SecretView(View):
|
permission_required = 'secrets.view_secret'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ class SecretDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class SecretBulkImportView(BulkImportView):
|
class SecretBulkImportView(BulkImportView):
|
||||||
permission_required = 'ipam.add_vlan'
|
permission_required = 'secrets.add_secret'
|
||||||
model_form = forms.SecretCSVForm
|
model_form = forms.SecretCSVForm
|
||||||
table = tables.SecretTable
|
table = tables.SecretTable
|
||||||
template_name = 'secrets/secret_import.html'
|
template_name = 'secrets/secret_import.html'
|
||||||
|
@ -4,13 +4,15 @@ from django.test import Client, TestCase
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from tenancy.models import Tenant, TenantGroup
|
from tenancy.models import Tenant, TenantGroup
|
||||||
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
|
|
||||||
class TenantGroupTestCase(TestCase):
|
class TenantGroupTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['tenancy.view_tenantgroup'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
TenantGroup.objects.bulk_create([
|
TenantGroup.objects.bulk_create([
|
||||||
TenantGroup(name='Tenant Group 1', slug='tenant-group-1'),
|
TenantGroup(name='Tenant Group 1', slug='tenant-group-1'),
|
||||||
@ -29,8 +31,9 @@ class TenantGroupTestCase(TestCase):
|
|||||||
class TenantTestCase(TestCase):
|
class TenantTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['tenancy.view_tenant'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
tenantgroup = TenantGroup(name='Tenant Group 1', slug='tenant-group-1')
|
tenantgroup = TenantGroup(name='Tenant Group 1', slug='tenant-group-1')
|
||||||
tenantgroup.save()
|
tenantgroup.save()
|
||||||
|
@ -18,7 +18,8 @@ from .models import Tenant, TenantGroup
|
|||||||
# Tenant groups
|
# Tenant groups
|
||||||
#
|
#
|
||||||
|
|
||||||
class TenantGroupListView(ObjectListView):
|
class TenantGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'tenancy.view_tenantgroup'
|
||||||
queryset = TenantGroup.objects.annotate(tenant_count=Count('tenants'))
|
queryset = TenantGroup.objects.annotate(tenant_count=Count('tenants'))
|
||||||
table = tables.TenantGroupTable
|
table = tables.TenantGroupTable
|
||||||
template_name = 'tenancy/tenantgroup_list.html'
|
template_name = 'tenancy/tenantgroup_list.html'
|
||||||
@ -53,7 +54,8 @@ class TenantGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Tenants
|
# Tenants
|
||||||
#
|
#
|
||||||
|
|
||||||
class TenantListView(ObjectListView):
|
class TenantListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'tenancy.view_tenant'
|
||||||
queryset = Tenant.objects.select_related('group')
|
queryset = Tenant.objects.select_related('group')
|
||||||
filter = filters.TenantFilter
|
filter = filters.TenantFilter
|
||||||
filter_form = forms.TenantFilterForm
|
filter_form = forms.TenantFilterForm
|
||||||
@ -61,7 +63,8 @@ class TenantListView(ObjectListView):
|
|||||||
template_name = 'tenancy/tenant_list.html'
|
template_name = 'tenancy/tenant_list.html'
|
||||||
|
|
||||||
|
|
||||||
class TenantView(View):
|
class TenantView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'tenancy.view_tenant'
|
||||||
|
|
||||||
def get(self, request, slug):
|
def get(self, request, slug):
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import login as auth_login, logout as auth_logout, update_session_auth_hash
|
from django.contrib.auth import login as auth_login, logout as auth_logout, update_session_auth_hash
|
||||||
from django.contrib.auth.decorators import login_required
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||||
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
@ -74,8 +73,7 @@ class LogoutView(View):
|
|||||||
# User profiles
|
# User profiles
|
||||||
#
|
#
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
class ProfileView(LoginRequiredMixin, View):
|
||||||
class ProfileView(View):
|
|
||||||
template_name = 'users/profile.html'
|
template_name = 'users/profile.html'
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
@ -85,8 +83,7 @@ class ProfileView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
class ChangePasswordView(LoginRequiredMixin, View):
|
||||||
class ChangePasswordView(View):
|
|
||||||
template_name = 'users/change_password.html'
|
template_name = 'users/change_password.html'
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
@ -111,8 +108,7 @@ class ChangePasswordView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
class UserKeyView(LoginRequiredMixin, View):
|
||||||
class UserKeyView(View):
|
|
||||||
template_name = 'users/userkey.html'
|
template_name = 'users/userkey.html'
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
@ -127,10 +123,9 @@ class UserKeyView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class UserKeyEditView(View):
|
class UserKeyEditView(LoginRequiredMixin, View):
|
||||||
template_name = 'users/userkey_edit.html'
|
template_name = 'users/userkey_edit.html'
|
||||||
|
|
||||||
@method_decorator(login_required)
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
self.userkey = UserKey.objects.get(user=request.user)
|
self.userkey = UserKey.objects.get(user=request.user)
|
||||||
@ -164,7 +159,6 @@ class UserKeyEditView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
|
||||||
class SessionKeyDeleteView(LoginRequiredMixin, View):
|
class SessionKeyDeleteView(LoginRequiredMixin, View):
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import Permission, User
|
||||||
from rest_framework.test import APITestCase as _APITestCase
|
from rest_framework.test import APITestCase as _APITestCase
|
||||||
|
|
||||||
from users.models import Token
|
from users.models import Token
|
||||||
@ -22,3 +22,16 @@ class APITestCase(_APITestCase):
|
|||||||
self.assertEqual(response.status_code, expected_status, err_message.format(
|
self.assertEqual(response.status_code, expected_status, err_message.format(
|
||||||
expected_status, response.status_code, response.data
|
expected_status, response.status_code, response.data
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def create_test_user(username='testuser', permissions=list()):
|
||||||
|
"""
|
||||||
|
Create a User with the given permissions.
|
||||||
|
"""
|
||||||
|
user = User.objects.create_user(username=username)
|
||||||
|
for perm_name in permissions:
|
||||||
|
app, codename = perm_name.split('.')
|
||||||
|
perm = Permission.objects.get(content_type__app_label=app, codename=codename)
|
||||||
|
user.user_permissions.add(perm)
|
||||||
|
|
||||||
|
return user
|
||||||
|
@ -3,14 +3,16 @@ import urllib.parse
|
|||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from utilities.testing import create_test_user
|
||||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||||
|
|
||||||
|
|
||||||
class ClusterGroupTestCase(TestCase):
|
class ClusterGroupTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['virtualization.view_clustergroup'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
ClusterGroup.objects.bulk_create([
|
ClusterGroup.objects.bulk_create([
|
||||||
ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'),
|
ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'),
|
||||||
@ -29,8 +31,9 @@ class ClusterGroupTestCase(TestCase):
|
|||||||
class ClusterTypeTestCase(TestCase):
|
class ClusterTypeTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['virtualization.view_clustertype'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
ClusterType.objects.bulk_create([
|
ClusterType.objects.bulk_create([
|
||||||
ClusterType(name='Cluster Type 1', slug='cluster-type-1'),
|
ClusterType(name='Cluster Type 1', slug='cluster-type-1'),
|
||||||
@ -49,8 +52,9 @@ class ClusterTypeTestCase(TestCase):
|
|||||||
class ClusterTestCase(TestCase):
|
class ClusterTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['virtualization.view_cluster'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
clustergroup = ClusterGroup(name='Cluster Group 1', slug='cluster-group-1')
|
clustergroup = ClusterGroup(name='Cluster Group 1', slug='cluster-group-1')
|
||||||
clustergroup.save()
|
clustergroup.save()
|
||||||
@ -85,8 +89,9 @@ class ClusterTestCase(TestCase):
|
|||||||
class VirtualMachineTestCase(TestCase):
|
class VirtualMachineTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
user = create_test_user(permissions=['virtualization.view_virtualmachine'])
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
clustertype = ClusterType(name='Cluster Type 1', slug='cluster-type-1')
|
clustertype = ClusterType(name='Cluster Type 1', slug='cluster-type-1')
|
||||||
clustertype.save()
|
clustertype.save()
|
||||||
|
@ -22,7 +22,8 @@ from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
|||||||
# Cluster types
|
# Cluster types
|
||||||
#
|
#
|
||||||
|
|
||||||
class ClusterTypeListView(ObjectListView):
|
class ClusterTypeListView(PermissionRequiredMixin, 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
|
||||||
template_name = 'virtualization/clustertype_list.html'
|
template_name = 'virtualization/clustertype_list.html'
|
||||||
@ -57,7 +58,8 @@ class ClusterTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Cluster groups
|
# Cluster groups
|
||||||
#
|
#
|
||||||
|
|
||||||
class ClusterGroupListView(ObjectListView):
|
class ClusterGroupListView(PermissionRequiredMixin, 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
|
||||||
template_name = 'virtualization/clustergroup_list.html'
|
template_name = 'virtualization/clustergroup_list.html'
|
||||||
@ -92,7 +94,8 @@ class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
# Clusters
|
# Clusters
|
||||||
#
|
#
|
||||||
|
|
||||||
class ClusterListView(ObjectListView):
|
class ClusterListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'virtualization.view_cluster'
|
||||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
||||||
table = tables.ClusterTable
|
table = tables.ClusterTable
|
||||||
filter = filters.ClusterFilter
|
filter = filters.ClusterFilter
|
||||||
@ -100,7 +103,8 @@ class ClusterListView(ObjectListView):
|
|||||||
template_name = 'virtualization/cluster_list.html'
|
template_name = 'virtualization/cluster_list.html'
|
||||||
|
|
||||||
|
|
||||||
class ClusterView(View):
|
class ClusterView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'virtualization.view_cluster'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -247,7 +251,8 @@ class ClusterRemoveDevicesView(PermissionRequiredMixin, View):
|
|||||||
# Virtual machines
|
# Virtual machines
|
||||||
#
|
#
|
||||||
|
|
||||||
class VirtualMachineListView(ObjectListView):
|
class VirtualMachineListView(PermissionRequiredMixin, ObjectListView):
|
||||||
|
permission_required = 'virtualization.view_virtualmachine'
|
||||||
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role', 'primary_ip4', 'primary_ip6')
|
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role', 'primary_ip4', 'primary_ip6')
|
||||||
filter = filters.VirtualMachineFilter
|
filter = filters.VirtualMachineFilter
|
||||||
filter_form = forms.VirtualMachineFilterForm
|
filter_form = forms.VirtualMachineFilterForm
|
||||||
@ -255,7 +260,8 @@ class VirtualMachineListView(ObjectListView):
|
|||||||
template_name = 'virtualization/virtualmachine_list.html'
|
template_name = 'virtualization/virtualmachine_list.html'
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineView(View):
|
class VirtualMachineView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'virtualization.view_virtualmachine'
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
@ -270,7 +276,8 @@ class VirtualMachineView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineConfigContextView(ObjectConfigContextView):
|
class VirtualMachineConfigContextView(PermissionRequiredMixin, ObjectConfigContextView):
|
||||||
|
permission_required = 'virtualization.view_virtualmachine'
|
||||||
object_class = VirtualMachine
|
object_class = VirtualMachine
|
||||||
base_template = 'virtualization/virtualmachine.html'
|
base_template = 'virtualization/virtualmachine.html'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user