mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Enforce object-level permissions for circuit termination swap view
This commit is contained in:
parent
7e64d3e653
commit
71d4b5c5df
@ -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'),
|
||||||
|
@ -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')
|
class CircuitSwapTerminations(ObjectEditView):
|
||||||
def circuit_terminations_swap(request, pk):
|
"""
|
||||||
|
Swap the A and Z terminations of a circuit.
|
||||||
|
"""
|
||||||
|
queryset = Circuit.objects.all()
|
||||||
|
|
||||||
circuit = get_object_or_404(Circuit, pk=pk)
|
def get(self, request, pk):
|
||||||
termination_a = CircuitTermination.objects.filter(
|
circuit = get_object_or_404(self.queryset, pk=pk)
|
||||||
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
|
form = ConfirmationForm()
|
||||||
).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)
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
# 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(),
|
||||||
|
})
|
||||||
|
|
||||||
|
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:
|
return render(request, 'circuits/circuit_terminations_swap.html', {
|
||||||
form = ConfirmationForm()
|
'circuit': circuit,
|
||||||
|
'termination_a': circuit.termination_a,
|
||||||
return render(request, 'circuits/circuit_terminations_swap.html', {
|
'termination_z': circuit.termination_z,
|
||||||
'circuit': circuit,
|
'form': form,
|
||||||
'termination_a': termination_a,
|
'panel_class': 'default',
|
||||||
'termination_z': termination_z,
|
'button_class': 'primary',
|
||||||
'form': form,
|
'return_url': circuit.get_absolute_url(),
|
||||||
'panel_class': 'default',
|
})
|
||||||
'button_class': 'primary',
|
|
||||||
'return_url': circuit.get_absolute_url(),
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user