From 469c52be28a9dc83a64e3413095469046e0a8a22 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Jun 2017 16:41:57 -0400 Subject: [PATCH] Fixes #1263: Differentiate add and edit permissions for objects --- netbox/circuits/urls.py | 8 ++-- netbox/circuits/views.py | 32 +++++++++++---- netbox/dcim/urls.py | 24 +++++------ netbox/dcim/views.py | 89 +++++++++++++++++++++++++++++----------- netbox/ipam/urls.py | 16 ++++---- netbox/ipam/views.py | 72 ++++++++++++++++++++++++-------- netbox/secrets/urls.py | 2 +- netbox/secrets/views.py | 8 +++- netbox/tenancy/urls.py | 4 +- netbox/tenancy/views.py | 16 ++++++-- 10 files changed, 189 insertions(+), 82 deletions(-) diff --git a/netbox/circuits/urls.py b/netbox/circuits/urls.py index 12a7dc298..7dd72ad9d 100644 --- a/netbox/circuits/urls.py +++ b/netbox/circuits/urls.py @@ -10,7 +10,7 @@ urlpatterns = [ # Providers url(r'^providers/$', views.ProviderListView.as_view(), name='provider_list'), - url(r'^providers/add/$', views.ProviderEditView.as_view(), name='provider_add'), + url(r'^providers/add/$', views.ProviderCreateView.as_view(), name='provider_add'), url(r'^providers/import/$', views.ProviderBulkImportView.as_view(), name='provider_import'), url(r'^providers/edit/$', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'), url(r'^providers/delete/$', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'), @@ -20,13 +20,13 @@ urlpatterns = [ # Circuit types url(r'^circuit-types/$', views.CircuitTypeListView.as_view(), name='circuittype_list'), - url(r'^circuit-types/add/$', views.CircuitTypeEditView.as_view(), name='circuittype_add'), + url(r'^circuit-types/add/$', views.CircuitTypeCreateView.as_view(), name='circuittype_add'), url(r'^circuit-types/delete/$', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'), url(r'^circuit-types/(?P[\w-]+)/edit/$', views.CircuitTypeEditView.as_view(), name='circuittype_edit'), # Circuits url(r'^circuits/$', views.CircuitListView.as_view(), name='circuit_list'), - url(r'^circuits/add/$', views.CircuitEditView.as_view(), name='circuit_add'), + url(r'^circuits/add/$', views.CircuitCreateView.as_view(), name='circuit_add'), url(r'^circuits/import/$', views.CircuitBulkImportView.as_view(), name='circuit_import'), url(r'^circuits/edit/$', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'), url(r'^circuits/delete/$', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'), @@ -36,7 +36,7 @@ urlpatterns = [ url(r'^circuits/(?P\d+)/terminations/swap/$', views.circuit_terminations_swap, name='circuit_terminations_swap'), # Circuit terminations - url(r'^circuits/(?P\d+)/terminations/add/$', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'), + url(r'^circuits/(?P\d+)/terminations/add/$', views.CircuitTerminationCreateView.as_view(), name='circuittermination_add'), url(r'^circuit-terminations/(?P\d+)/edit/$', views.CircuitTerminationEditView.as_view(), name='circuittermination_edit'), url(r'^circuit-terminations/(?P\d+)/delete/$', views.CircuitTerminationDeleteView.as_view(), name='circuittermination_delete'), diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 35e37f4c5..eda37340d 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -49,14 +49,18 @@ class ProviderView(View): }) -class ProviderEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'circuits.change_provider' +class ProviderCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'circuits.add_provider' model = Provider form_class = forms.ProviderForm template_name = 'circuits/provider_edit.html' default_return_url = 'circuits:provider_list' +class ProviderEditView(ProviderCreateView): + permission_required = 'circuits.change_provider' + + class ProviderDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'circuits.delete_provider' model = Provider @@ -96,8 +100,8 @@ class CircuitTypeListView(ObjectListView): template_name = 'circuits/circuittype_list.html' -class CircuitTypeEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'circuits.change_circuittype' +class CircuitTypeCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'circuits.add_circuittype' model = CircuitType form_class = forms.CircuitTypeForm @@ -105,6 +109,10 @@ class CircuitTypeEditView(PermissionRequiredMixin, ObjectEditView): return reverse('circuits:circuittype_list') +class CircuitTypeEditView(CircuitTypeCreateView): + permission_required = 'circuits.change_circuittype' + + class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'circuits.delete_circuittype' cls = CircuitType @@ -146,14 +154,18 @@ class CircuitView(View): }) -class CircuitEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'circuits.change_circuit' +class CircuitCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'circuits.add_circuit' model = Circuit form_class = forms.CircuitForm template_name = 'circuits/circuit_edit.html' default_return_url = 'circuits:circuit_list' +class CircuitEditView(CircuitCreateView): + permission_required = 'circuits.change_circuit' + + class CircuitDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'circuits.delete_circuit' model = Circuit @@ -232,8 +244,8 @@ def circuit_terminations_swap(request, pk): # Circuit terminations # -class CircuitTerminationEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'circuits.change_circuittermination' +class CircuitTerminationCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'circuits.add_circuittermination' model = CircuitTermination form_class = forms.CircuitTerminationForm template_name = 'circuits/circuittermination_edit.html' @@ -247,6 +259,10 @@ class CircuitTerminationEditView(PermissionRequiredMixin, ObjectEditView): return obj.circuit.get_absolute_url() +class CircuitTerminationEditView(CircuitTerminationCreateView): + permission_required = 'circuits.change_circuittermination' + + class CircuitTerminationDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'circuits.delete_circuittermination' model = CircuitTermination diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 775daeabf..3a72a758b 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from django.conf.urls import url from extras.views import ImageAttachmentEditView -from ipam.views import ServiceEditView +from ipam.views import ServiceCreateView from secrets.views import secret_add from .models import Device, Rack, Site from . import views @@ -14,13 +14,13 @@ urlpatterns = [ # Regions url(r'^regions/$', views.RegionListView.as_view(), name='region_list'), - url(r'^regions/add/$', views.RegionEditView.as_view(), name='region_add'), + url(r'^regions/add/$', views.RegionCreateView.as_view(), name='region_add'), url(r'^regions/delete/$', views.RegionBulkDeleteView.as_view(), name='region_bulk_delete'), url(r'^regions/(?P\d+)/edit/$', views.RegionEditView.as_view(), name='region_edit'), # Sites url(r'^sites/$', views.SiteListView.as_view(), name='site_list'), - url(r'^sites/add/$', views.SiteEditView.as_view(), name='site_add'), + url(r'^sites/add/$', views.SiteCreateView.as_view(), name='site_add'), url(r'^sites/import/$', views.SiteBulkImportView.as_view(), name='site_import'), url(r'^sites/edit/$', views.SiteBulkEditView.as_view(), name='site_bulk_edit'), url(r'^sites/(?P[\w-]+)/$', views.SiteView.as_view(), name='site'), @@ -30,13 +30,13 @@ urlpatterns = [ # Rack groups url(r'^rack-groups/$', views.RackGroupListView.as_view(), name='rackgroup_list'), - url(r'^rack-groups/add/$', views.RackGroupEditView.as_view(), name='rackgroup_add'), + url(r'^rack-groups/add/$', views.RackGroupCreateView.as_view(), name='rackgroup_add'), url(r'^rack-groups/delete/$', views.RackGroupBulkDeleteView.as_view(), name='rackgroup_bulk_delete'), url(r'^rack-groups/(?P\d+)/edit/$', views.RackGroupEditView.as_view(), name='rackgroup_edit'), # Rack roles url(r'^rack-roles/$', views.RackRoleListView.as_view(), name='rackrole_list'), - url(r'^rack-roles/add/$', views.RackRoleEditView.as_view(), name='rackrole_add'), + url(r'^rack-roles/add/$', views.RackRoleCreateView.as_view(), name='rackrole_add'), url(r'^rack-roles/delete/$', views.RackRoleBulkDeleteView.as_view(), name='rackrole_bulk_delete'), url(r'^rack-roles/(?P\d+)/edit/$', views.RackRoleEditView.as_view(), name='rackrole_edit'), @@ -56,18 +56,18 @@ urlpatterns = [ url(r'^racks/(?P\d+)/$', views.RackView.as_view(), name='rack'), url(r'^racks/(?P\d+)/edit/$', views.RackEditView.as_view(), name='rack_edit'), url(r'^racks/(?P\d+)/delete/$', views.RackDeleteView.as_view(), name='rack_delete'), - url(r'^racks/(?P\d+)/reservations/add/$', views.RackReservationEditView.as_view(), name='rack_add_reservation'), + url(r'^racks/(?P\d+)/reservations/add/$', views.RackReservationCreateView.as_view(), name='rack_add_reservation'), url(r'^racks/(?P\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='rack_add_image', kwargs={'model': Rack}), # Manufacturers url(r'^manufacturers/$', views.ManufacturerListView.as_view(), name='manufacturer_list'), - url(r'^manufacturers/add/$', views.ManufacturerEditView.as_view(), name='manufacturer_add'), + url(r'^manufacturers/add/$', views.ManufacturerCreateView.as_view(), name='manufacturer_add'), url(r'^manufacturers/delete/$', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'), url(r'^manufacturers/(?P[\w-]+)/edit/$', views.ManufacturerEditView.as_view(), name='manufacturer_edit'), # Device types url(r'^device-types/$', views.DeviceTypeListView.as_view(), name='devicetype_list'), - url(r'^device-types/add/$', views.DeviceTypeEditView.as_view(), name='devicetype_add'), + url(r'^device-types/add/$', views.DeviceTypeCreateView.as_view(), name='devicetype_add'), url(r'^device-types/edit/$', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'), url(r'^device-types/delete/$', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'), url(r'^device-types/(?P\d+)/$', views.DeviceTypeView.as_view(), name='devicetype'), @@ -101,19 +101,19 @@ urlpatterns = [ # Device roles url(r'^device-roles/$', views.DeviceRoleListView.as_view(), name='devicerole_list'), - url(r'^device-roles/add/$', views.DeviceRoleEditView.as_view(), name='devicerole_add'), + url(r'^device-roles/add/$', views.DeviceRoleCreateView.as_view(), name='devicerole_add'), url(r'^device-roles/delete/$', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'), url(r'^device-roles/(?P[\w-]+)/edit/$', views.DeviceRoleEditView.as_view(), name='devicerole_edit'), # Platforms url(r'^platforms/$', views.PlatformListView.as_view(), name='platform_list'), - url(r'^platforms/add/$', views.PlatformEditView.as_view(), name='platform_add'), + url(r'^platforms/add/$', views.PlatformCreateView.as_view(), name='platform_add'), url(r'^platforms/delete/$', views.PlatformBulkDeleteView.as_view(), name='platform_bulk_delete'), url(r'^platforms/(?P[\w-]+)/edit/$', views.PlatformEditView.as_view(), name='platform_edit'), # Devices url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'), - url(r'^devices/add/$', views.DeviceEditView.as_view(), name='device_add'), + url(r'^devices/add/$', views.DeviceCreateView.as_view(), name='device_add'), url(r'^devices/import/$', views.DeviceBulkImportView.as_view(), name='device_import'), url(r'^devices/import/child-devices/$', views.ChildDeviceBulkImportView.as_view(), name='device_import_child'), url(r'^devices/edit/$', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'), @@ -124,7 +124,7 @@ urlpatterns = [ url(r'^devices/(?P\d+)/inventory/$', views.DeviceInventoryView.as_view(), name='device_inventory'), url(r'^devices/(?P\d+)/lldp-neighbors/$', views.DeviceLLDPNeighborsView.as_view(), name='device_lldp_neighbors'), url(r'^devices/(?P\d+)/add-secret/$', secret_add, name='device_addsecret'), - url(r'^devices/(?P\d+)/services/assign/$', ServiceEditView.as_view(), name='service_assign'), + url(r'^devices/(?P\d+)/services/assign/$', ServiceCreateView.as_view(), name='service_assign'), url(r'^devices/(?P\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='device_add_image', kwargs={'model': Device}), # Console ports diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 40b18e33a..db4da8c4d 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals from copy import deepcopy -from difflib import SequenceMatcher import re from natsort import natsorted from operator import attrgetter @@ -152,8 +151,8 @@ class RegionListView(ObjectListView): template_name = 'dcim/region_list.html' -class RegionEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_region' +class RegionCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_region' model = Region form_class = forms.RegionForm @@ -161,6 +160,10 @@ class RegionEditView(PermissionRequiredMixin, ObjectEditView): return reverse('dcim:region_list') +class RegionEditView(RegionCreateView): + permission_required = 'dcim.change_region' + + class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_region' cls = Region @@ -204,14 +207,18 @@ class SiteView(View): }) -class SiteEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_site' +class SiteCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_site' model = Site form_class = forms.SiteForm template_name = 'dcim/site_edit.html' default_return_url = 'dcim:site_list' +class SiteEditView(SiteCreateView): + permission_required = 'dcim.change_site' + + class SiteDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'dcim.delete_site' model = Site @@ -246,8 +253,8 @@ class RackGroupListView(ObjectListView): template_name = 'dcim/rackgroup_list.html' -class RackGroupEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_rackgroup' +class RackGroupCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_rackgroup' model = RackGroup form_class = forms.RackGroupForm @@ -255,6 +262,10 @@ class RackGroupEditView(PermissionRequiredMixin, ObjectEditView): return reverse('dcim:rackgroup_list') +class RackGroupEditView(RackGroupCreateView): + permission_required = 'dcim.change_rackgroup' + + class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_rackgroup' cls = RackGroup @@ -272,8 +283,8 @@ class RackRoleListView(ObjectListView): template_name = 'dcim/rackrole_list.html' -class RackRoleEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_rackrole' +class RackRoleCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_rackrole' model = RackRole form_class = forms.RackRoleForm @@ -281,6 +292,10 @@ class RackRoleEditView(PermissionRequiredMixin, ObjectEditView): return reverse('dcim:rackrole_list') +class RackRoleEditView(RackRoleCreateView): + permission_required = 'dcim.change_rackrole' + + class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_rackrole' cls = RackRole @@ -374,14 +389,18 @@ class RackView(View): }) -class RackEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_rack' +class RackCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_rack' model = Rack form_class = forms.RackForm template_name = 'dcim/rack_edit.html' default_return_url = 'dcim:rack_list' +class RackEditView(RackCreateView): + permission_required = 'dcim.change_rack' + + class RackDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'dcim.delete_rack' model = Rack @@ -423,8 +442,8 @@ class RackReservationListView(ObjectListView): template_name = 'dcim/rackreservation_list.html' -class RackReservationEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_rackreservation' +class RackReservationCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_rackreservation' model = RackReservation form_class = forms.RackReservationForm @@ -438,6 +457,10 @@ class RackReservationEditView(PermissionRequiredMixin, ObjectEditView): return obj.rack.get_absolute_url() +class RackReservationEditView(RackReservationCreateView): + permission_required = 'dcim.change_rackreservation' + + class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'dcim.delete_rackreservation' model = RackReservation @@ -462,8 +485,8 @@ class ManufacturerListView(ObjectListView): template_name = 'dcim/manufacturer_list.html' -class ManufacturerEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_manufacturer' +class ManufacturerCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_manufacturer' model = Manufacturer form_class = forms.ManufacturerForm @@ -471,6 +494,10 @@ class ManufacturerEditView(PermissionRequiredMixin, ObjectEditView): return reverse('dcim:manufacturer_list') +class ManufacturerEditView(ManufacturerCreateView): + permission_required = 'dcim.change_manufacturer' + + class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_manufacturer' cls = Manufacturer @@ -542,14 +569,18 @@ class DeviceTypeView(View): }) -class DeviceTypeEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_devicetype' +class DeviceTypeCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_devicetype' model = DeviceType form_class = forms.DeviceTypeForm template_name = 'dcim/devicetype_edit.html' default_return_url = 'dcim:devicetype_list' +class DeviceTypeEditView(DeviceTypeCreateView): + permission_required = 'dcim.change_devicetype' + + class DeviceTypeDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'dcim.delete_devicetype' model = DeviceType @@ -686,8 +717,8 @@ class DeviceRoleListView(ObjectListView): template_name = 'dcim/devicerole_list.html' -class DeviceRoleEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_devicerole' +class DeviceRoleCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_devicerole' model = DeviceRole form_class = forms.DeviceRoleForm @@ -695,6 +726,10 @@ class DeviceRoleEditView(PermissionRequiredMixin, ObjectEditView): return reverse('dcim:devicerole_list') +class DeviceRoleEditView(DeviceRoleCreateView): + permission_required = 'dcim.change_devicerole' + + class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_devicerole' cls = DeviceRole @@ -711,8 +746,8 @@ class PlatformListView(ObjectListView): template_name = 'dcim/platform_list.html' -class PlatformEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_platform' +class PlatformCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_platform' model = Platform form_class = forms.PlatformForm @@ -720,6 +755,10 @@ class PlatformEditView(PermissionRequiredMixin, ObjectEditView): return reverse('dcim:platform_list') +class PlatformEditView(PlatformCreateView): + permission_required = 'dcim.change_platform' + + class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_platform' cls = Platform @@ -843,14 +882,18 @@ class DeviceLLDPNeighborsView(View): }) -class DeviceEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'dcim.change_device' +class DeviceCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'dcim.add_device' model = Device form_class = forms.DeviceForm template_name = 'dcim/device_edit.html' default_return_url = 'dcim:device_list' +class DeviceEditView(DeviceCreateView): + permission_required = 'dcim.change_device' + + class DeviceDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'dcim.delete_device' model = Device diff --git a/netbox/ipam/urls.py b/netbox/ipam/urls.py index d28bf8a13..6c647c3dc 100644 --- a/netbox/ipam/urls.py +++ b/netbox/ipam/urls.py @@ -10,7 +10,7 @@ urlpatterns = [ # VRFs url(r'^vrfs/$', views.VRFListView.as_view(), name='vrf_list'), - url(r'^vrfs/add/$', views.VRFEditView.as_view(), name='vrf_add'), + url(r'^vrfs/add/$', views.VRFCreateView.as_view(), name='vrf_add'), url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'), url(r'^vrfs/edit/$', views.VRFBulkEditView.as_view(), name='vrf_bulk_edit'), url(r'^vrfs/delete/$', views.VRFBulkDeleteView.as_view(), name='vrf_bulk_delete'), @@ -20,13 +20,13 @@ urlpatterns = [ # RIRs url(r'^rirs/$', views.RIRListView.as_view(), name='rir_list'), - url(r'^rirs/add/$', views.RIREditView.as_view(), name='rir_add'), + url(r'^rirs/add/$', views.RIRCreateView.as_view(), name='rir_add'), url(r'^rirs/delete/$', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'), url(r'^rirs/(?P[\w-]+)/edit/$', views.RIREditView.as_view(), name='rir_edit'), # Aggregates url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'), - url(r'^aggregates/add/$', views.AggregateEditView.as_view(), name='aggregate_add'), + url(r'^aggregates/add/$', views.AggregateCreateView.as_view(), name='aggregate_add'), url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'), url(r'^aggregates/edit/$', views.AggregateBulkEditView.as_view(), name='aggregate_bulk_edit'), url(r'^aggregates/delete/$', views.AggregateBulkDeleteView.as_view(), name='aggregate_bulk_delete'), @@ -36,13 +36,13 @@ urlpatterns = [ # Roles url(r'^roles/$', views.RoleListView.as_view(), name='role_list'), - url(r'^roles/add/$', views.RoleEditView.as_view(), name='role_add'), + url(r'^roles/add/$', views.RoleCreateView.as_view(), name='role_add'), url(r'^roles/delete/$', views.RoleBulkDeleteView.as_view(), name='role_bulk_delete'), url(r'^roles/(?P[\w-]+)/edit/$', views.RoleEditView.as_view(), name='role_edit'), # Prefixes url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'), - url(r'^prefixes/add/$', views.PrefixEditView.as_view(), name='prefix_add'), + url(r'^prefixes/add/$', views.PrefixCreateView.as_view(), name='prefix_add'), url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'), url(r'^prefixes/edit/$', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'), url(r'^prefixes/delete/$', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'), @@ -53,7 +53,7 @@ urlpatterns = [ # IP addresses url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'), - url(r'^ip-addresses/add/$', views.IPAddressEditView.as_view(), name='ipaddress_add'), + url(r'^ip-addresses/add/$', views.IPAddressCreateView.as_view(), name='ipaddress_add'), url(r'^ip-addresses/bulk-add/$', views.IPAddressBulkAddView.as_view(), name='ipaddress_bulk_add'), url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'), url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'), @@ -64,13 +64,13 @@ urlpatterns = [ # VLAN groups url(r'^vlan-groups/$', views.VLANGroupListView.as_view(), name='vlangroup_list'), - url(r'^vlan-groups/add/$', views.VLANGroupEditView.as_view(), name='vlangroup_add'), + url(r'^vlan-groups/add/$', views.VLANGroupCreateView.as_view(), name='vlangroup_add'), url(r'^vlan-groups/delete/$', views.VLANGroupBulkDeleteView.as_view(), name='vlangroup_bulk_delete'), url(r'^vlan-groups/(?P\d+)/edit/$', views.VLANGroupEditView.as_view(), name='vlangroup_edit'), # VLANs url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'), - url(r'^vlans/add/$', views.VLANEditView.as_view(), name='vlan_add'), + url(r'^vlans/add/$', views.VLANCreateView.as_view(), name='vlan_add'), url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'), url(r'^vlans/edit/$', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'), url(r'^vlans/delete/$', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'), diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index f8fe0535a..20aa083b1 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -114,14 +114,18 @@ class VRFView(View): }) -class VRFEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_vrf' +class VRFCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_vrf' model = VRF form_class = forms.VRFForm template_name = 'ipam/vrf_edit.html' default_return_url = 'ipam:vrf_list' +class VRFEditView(VRFCreateView): + permission_required = 'ipam.change_vrf' + + class VRFDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'ipam.delete_vrf' model = VRF @@ -239,8 +243,8 @@ class RIRListView(ObjectListView): } -class RIREditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_rir' +class RIRCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_rir' model = RIR form_class = forms.RIRForm @@ -248,6 +252,10 @@ class RIREditView(PermissionRequiredMixin, ObjectEditView): return reverse('ipam:rir_list') +class RIREditView(RIRCreateView): + permission_required = 'ipam.change_rir' + + class RIRBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'ipam.delete_rir' cls = RIR @@ -324,14 +332,18 @@ class AggregateView(View): }) -class AggregateEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_aggregate' +class AggregateCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_aggregate' model = Aggregate form_class = forms.AggregateForm template_name = 'ipam/aggregate_edit.html' default_return_url = 'ipam:aggregate_list' +class AggregateEditView(AggregateCreateView): + permission_required = 'ipam.change_aggregate' + + class AggregateDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'ipam.delete_aggregate' model = Aggregate @@ -371,8 +383,8 @@ class RoleListView(ObjectListView): template_name = 'ipam/role_list.html' -class RoleEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_role' +class RoleCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_role' model = Role form_class = forms.RoleForm @@ -380,6 +392,10 @@ class RoleEditView(PermissionRequiredMixin, ObjectEditView): return reverse('ipam:role_list') +class RoleEditView(RoleCreateView): + permission_required = 'ipam.change_role' + + class RoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'ipam.delete_role' cls = Role @@ -519,14 +535,18 @@ class PrefixIPAddressesView(View): }) -class PrefixEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_prefix' +class PrefixCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_prefix' model = Prefix form_class = forms.PrefixForm template_name = 'ipam/prefix_edit.html' default_return_url = 'ipam:prefix_list' +class PrefixEditView(PrefixCreateView): + permission_required = 'ipam.change_prefix' + + class PrefixDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'ipam.delete_prefix' model = Prefix @@ -612,14 +632,18 @@ class IPAddressView(View): }) -class IPAddressEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_ipaddress' +class IPAddressCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_ipaddress' model = IPAddress form_class = forms.IPAddressForm template_name = 'ipam/ipaddress_edit.html' default_return_url = 'ipam:ipaddress_list' +class IPAddressEditView(IPAddressCreateView): + permission_required = 'ipam.change_ipaddress' + + class IPAddressDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'ipam.delete_ipaddress' model = IPAddress @@ -683,8 +707,8 @@ class VLANGroupListView(ObjectListView): template_name = 'ipam/vlangroup_list.html' -class VLANGroupEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_vlangroup' +class VLANGroupCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_vlangroup' model = VLANGroup form_class = forms.VLANGroupForm @@ -692,6 +716,10 @@ class VLANGroupEditView(PermissionRequiredMixin, ObjectEditView): return reverse('ipam:vlangroup_list') +class VLANGroupEditView(VLANGroupCreateView): + permission_required = 'ipam.change_vlangroup' + + class VLANGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'ipam.delete_vlangroup' cls = VLANGroup @@ -728,14 +756,18 @@ class VLANView(View): }) -class VLANEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_vlan' +class VLANCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_vlan' model = VLAN form_class = forms.VLANForm template_name = 'ipam/vlan_edit.html' default_return_url = 'ipam:vlan_list' +class VLANEditView(VLANCreateView): + permission_required = 'ipam.change_vlan' + + class VLANDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'ipam.delete_vlan' model = VLAN @@ -769,8 +801,8 @@ class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): # Services # -class ServiceEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'ipam.change_service' +class ServiceCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'ipam.add_service' model = Service form_class = forms.ServiceForm template_name = 'ipam/service_edit.html' @@ -784,6 +816,10 @@ class ServiceEditView(PermissionRequiredMixin, ObjectEditView): return obj.device.get_absolute_url() +class ServiceEditView(ServiceCreateView): + permission_required = 'ipam.change_service' + + class ServiceDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'ipam.delete_service' model = Service diff --git a/netbox/secrets/urls.py b/netbox/secrets/urls.py index b28198a2f..961e0f0ed 100644 --- a/netbox/secrets/urls.py +++ b/netbox/secrets/urls.py @@ -10,7 +10,7 @@ urlpatterns = [ # Secret roles url(r'^secret-roles/$', views.SecretRoleListView.as_view(), name='secretrole_list'), - url(r'^secret-roles/add/$', views.SecretRoleEditView.as_view(), name='secretrole_add'), + url(r'^secret-roles/add/$', views.SecretRoleCreateView.as_view(), name='secretrole_add'), url(r'^secret-roles/delete/$', views.SecretRoleBulkDeleteView.as_view(), name='secretrole_bulk_delete'), url(r'^secret-roles/(?P[\w-]+)/edit/$', views.SecretRoleEditView.as_view(), name='secretrole_edit'), diff --git a/netbox/secrets/views.py b/netbox/secrets/views.py index e046f1dbc..ac4226358 100644 --- a/netbox/secrets/views.py +++ b/netbox/secrets/views.py @@ -40,8 +40,8 @@ class SecretRoleListView(ObjectListView): template_name = 'secrets/secretrole_list.html' -class SecretRoleEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'secrets.change_secretrole' +class SecretRoleCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'secrets.add_secretrole' model = SecretRole form_class = forms.SecretRoleForm @@ -49,6 +49,10 @@ class SecretRoleEditView(PermissionRequiredMixin, ObjectEditView): return reverse('secrets:secretrole_list') +class SecretRoleEditView(SecretRoleCreateView): + permission_required = 'secrets.change_secretrole' + + class SecretRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'secrets.delete_secretrole' cls = SecretRole diff --git a/netbox/tenancy/urls.py b/netbox/tenancy/urls.py index cb04cffb9..76d800344 100644 --- a/netbox/tenancy/urls.py +++ b/netbox/tenancy/urls.py @@ -10,13 +10,13 @@ urlpatterns = [ # Tenant groups url(r'^tenant-groups/$', views.TenantGroupListView.as_view(), name='tenantgroup_list'), - url(r'^tenant-groups/add/$', views.TenantGroupEditView.as_view(), name='tenantgroup_add'), + url(r'^tenant-groups/add/$', views.TenantGroupCreateView.as_view(), name='tenantgroup_add'), url(r'^tenant-groups/delete/$', views.TenantGroupBulkDeleteView.as_view(), name='tenantgroup_bulk_delete'), url(r'^tenant-groups/(?P[\w-]+)/edit/$', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'), # Tenants url(r'^tenants/$', views.TenantListView.as_view(), name='tenant_list'), - url(r'^tenants/add/$', views.TenantEditView.as_view(), name='tenant_add'), + url(r'^tenants/add/$', views.TenantCreateView.as_view(), name='tenant_add'), url(r'^tenants/import/$', views.TenantBulkImportView.as_view(), name='tenant_import'), url(r'^tenants/edit/$', views.TenantBulkEditView.as_view(), name='tenant_bulk_edit'), url(r'^tenants/delete/$', views.TenantBulkDeleteView.as_view(), name='tenant_bulk_delete'), diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index 5a820b8f6..d151ff5ca 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -26,8 +26,8 @@ class TenantGroupListView(ObjectListView): template_name = 'tenancy/tenantgroup_list.html' -class TenantGroupEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'tenancy.change_tenantgroup' +class TenantGroupCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'tenancy.add_tenantgroup' model = TenantGroup form_class = forms.TenantGroupForm @@ -35,6 +35,10 @@ class TenantGroupEditView(PermissionRequiredMixin, ObjectEditView): return reverse('tenancy:tenantgroup_list') +class TenantGroupEditView(TenantGroupCreateView): + permission_required = 'tenancy.change_tenantgroup' + + class TenantGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'tenancy.delete_tenantgroup' cls = TenantGroup @@ -81,14 +85,18 @@ class TenantView(View): }) -class TenantEditView(PermissionRequiredMixin, ObjectEditView): - permission_required = 'tenancy.change_tenant' +class TenantCreateView(PermissionRequiredMixin, ObjectEditView): + permission_required = 'tenancy.add_tenant' model = Tenant form_class = forms.TenantForm template_name = 'tenancy/tenant_edit.html' default_return_url = 'tenancy:tenant_list' +class TenantEditView(TenantCreateView): + permission_required = 'tenancy.change_tenant' + + class TenantDeleteView(PermissionRequiredMixin, ObjectDeleteView): permission_required = 'tenancy.delete_tenant' model = Tenant