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

Enforce object-level permissions for circuit termination swap view

Jeremy Stretch пре 5 година
родитељ
комит
71d4b5c5df
2 измењених фајлова са 46 додато и 28 уклоњено
  1. 1 2
      netbox/circuits/urls.py
  2. 45 26
      netbox/circuits/views.py

+ 1 - 2
netbox/circuits/urls.py

@@ -37,10 +37,9 @@ urlpatterns = [
     path('circuits/<int:pk>/edit/', views.CircuitEditView.as_view(), name='circuit_edit'),
     path('circuits/<int:pk>/edit/', views.CircuitEditView.as_view(), name='circuit_edit'),
     path('circuits/<int:pk>/delete/', views.CircuitDeleteView.as_view(), name='circuit_delete'),
     path('circuits/<int:pk>/delete/', views.CircuitDeleteView.as_view(), name='circuit_delete'),
     path('circuits/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='circuit_changelog', kwargs={'model': Circuit}),
     path('circuits/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='circuit_changelog', kwargs={'model': Circuit}),
-    path('circuits/<int:pk>/terminations/swap/', views.circuit_terminations_swap, name='circuit_terminations_swap'),
+    path('circuits/<int:pk>/terminations/swap/', views.CircuitSwapTerminations.as_view(), name='circuit_terminations_swap'),
 
 
     # Circuit terminations
     # Circuit terminations
-
     path('circuits/<int:circuit>/terminations/add/', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'),
     path('circuits/<int:circuit>/terminations/add/', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'),
     path('circuit-terminations/<int:pk>/edit/', views.CircuitTerminationEditView.as_view(), name='circuittermination_edit'),
     path('circuit-terminations/<int:pk>/edit/', views.CircuitTerminationEditView.as_view(), name='circuittermination_edit'),
     path('circuit-terminations/<int:pk>/delete/', views.CircuitTerminationDeleteView.as_view(), name='circuittermination_delete'),
     path('circuit-terminations/<int:pk>/delete/', views.CircuitTerminationDeleteView.as_view(), name='circuittermination_delete'),

+ 45 - 26
netbox/circuits/views.py

@@ -1,6 +1,5 @@
 from django.conf import settings
 from django.conf import settings
 from django.contrib import messages
 from django.contrib import messages
-from django.contrib.auth.decorators import permission_required
 from django.db import transaction
 from django.db import transaction
 from django.db.models import Count, OuterRef
 from django.db.models import Count, OuterRef
 from django.shortcuts import get_object_or_404, redirect, render
 from django.shortcuts import get_object_or_404, redirect, render
@@ -191,25 +190,47 @@ class CircuitBulkDeleteView(BulkDeleteView):
     default_return_url = 'circuits:circuit_list'
     default_return_url = 'circuits:circuit_list'
 
 
 
 
-@permission_required('circuits.change_circuittermination')
-def circuit_terminations_swap(request, pk):
+class CircuitSwapTerminations(ObjectEditView):
+    """
+    Swap the A and Z terminations of a circuit.
+    """
+    queryset = Circuit.objects.all()
+
+    def get(self, request, pk):
+        circuit = get_object_or_404(self.queryset, pk=pk)
+        form = ConfirmationForm()
 
 
-    circuit = get_object_or_404(Circuit, pk=pk)
-    termination_a = CircuitTermination.objects.filter(
-        circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
-    ).first()
-    termination_z = CircuitTermination.objects.filter(
-        circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_Z
-    ).first()
-    if not termination_a and not termination_z:
-        messages.error(request, "No terminations have been defined for circuit {}.".format(circuit))
-        return redirect('circuits:circuit', pk=circuit.pk)
+        # Circuit must have at least one termination to swap
+        if not circuit.termination_a and not circuit.termination_z:
+            messages.error(request, "No terminations have been defined for circuit {}.".format(circuit))
+            return redirect('circuits:circuit', pk=circuit.pk)
+
+        return render(request, 'circuits/circuit_terminations_swap.html', {
+            'circuit': circuit,
+            'termination_a': circuit.termination_a,
+            'termination_z': circuit.termination_z,
+            'form': form,
+            'panel_class': 'default',
+            'button_class': 'primary',
+            'return_url': circuit.get_absolute_url(),
+        })
 
 
-    if request.method == 'POST':
+    def post(self, request, pk):
+        circuit = get_object_or_404(self.queryset, pk=pk)
         form = ConfirmationForm(request.POST)
         form = ConfirmationForm(request.POST)
+
         if form.is_valid():
         if form.is_valid():
+
+            termination_a = CircuitTermination.objects.filter(
+                circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
+            ).first()
+            termination_z = CircuitTermination.objects.filter(
+                circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_Z
+            ).first()
+
             if termination_a and termination_z:
             if termination_a and termination_z:
                 # Use a placeholder to avoid an IntegrityError on the (circuit, term_side) unique constraint
                 # Use a placeholder to avoid an IntegrityError on the (circuit, term_side) unique constraint
+                print('swapping')
                 with transaction.atomic():
                 with transaction.atomic():
                     termination_a.term_side = '_'
                     termination_a.term_side = '_'
                     termination_a.save()
                     termination_a.save()
@@ -223,21 +244,19 @@ def circuit_terminations_swap(request, pk):
             else:
             else:
                 termination_z.term_side = 'A'
                 termination_z.term_side = 'A'
                 termination_z.save()
                 termination_z.save()
+
             messages.success(request, "Swapped terminations for circuit {}.".format(circuit))
             messages.success(request, "Swapped terminations for circuit {}.".format(circuit))
             return redirect('circuits:circuit', pk=circuit.pk)
             return redirect('circuits:circuit', pk=circuit.pk)
 
 
-    else:
-        form = ConfirmationForm()
-
-    return render(request, 'circuits/circuit_terminations_swap.html', {
-        'circuit': circuit,
-        'termination_a': termination_a,
-        'termination_z': termination_z,
-        'form': form,
-        'panel_class': 'default',
-        'button_class': 'primary',
-        'return_url': circuit.get_absolute_url(),
-    })
+        return render(request, 'circuits/circuit_terminations_swap.html', {
+            'circuit': circuit,
+            'termination_a': circuit.termination_a,
+            'termination_z': circuit.termination_z,
+            'form': form,
+            'panel_class': 'default',
+            'button_class': 'primary',
+            'return_url': circuit.get_absolute_url(),
+        })
 
 
 
 
 #
 #