From 830a82fa7e9590ef25c0a3f121d0992145bc423a Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 25 Oct 2022 14:30:43 -0700 Subject: [PATCH] 10719 check ip permission on fhrpgroup form save --- netbox/ipam/forms/models.py | 20 -------------------- netbox/ipam/views.py | 15 +++++++++++++++ netbox/netbox/views/generic/object_views.py | 12 ++++++++++++ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/netbox/ipam/forms/models.py b/netbox/ipam/forms/models.py index f66b7efba..dae71032d 100644 --- a/netbox/ipam/forms/models.py +++ b/netbox/ipam/forms/models.py @@ -550,26 +550,6 @@ class FHRPGroupForm(NetBoxModelForm): 'protocol', 'group_id', 'auth_type', 'auth_key', 'description', 'ip_vrf', 'ip_address', 'ip_status', 'tags', ) - def save(self, *args, **kwargs): - instance = super().save(*args, **kwargs) - - # Check if we need to create a new IPAddress for the group - if self.cleaned_data.get('ip_address'): - ipaddress = IPAddress( - vrf=self.cleaned_data['ip_vrf'], - address=self.cleaned_data['ip_address'], - status=self.cleaned_data['ip_status'], - role=FHRP_PROTOCOL_ROLE_MAPPINGS.get(self.cleaned_data['protocol'], IPAddressRoleChoices.ROLE_VIP), - assigned_object=instance - ) - ipaddress.save() - - # Check that the new IPAddress conforms with any assigned object-level permissions - if not IPAddress.objects.filter(pk=ipaddress.pk).first(): - raise PermissionsViolation() - - return instance - def clean(self): super().clean() diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 04d07e356..a4ccd25fe 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -11,6 +11,7 @@ from dcim.models import Interface, Site, Device from dcim.tables import SiteTable from netbox.views import generic from utilities.utils import count_related +from utilities.exceptions import PermissionsViolation from virtualization.filtersets import VMInterfaceFilterSet from virtualization.models import VMInterface, VirtualMachine from . import filtersets, forms, tables @@ -930,6 +931,20 @@ class FHRPGroupEditView(generic.ObjectEditView): return return_url + def save_related_data(self, request, form, obj): + ipaddress = IPAddress( + vrf=form.cleaned_data['ip_vrf'], + address=form.cleaned_data['ip_address'], + status=form.cleaned_data['ip_status'], + role=FHRP_PROTOCOL_ROLE_MAPPINGS.get(form.cleaned_data['protocol'], IPAddressRoleChoices.ROLE_VIP), + assigned_object=obj + ) + ipaddress.save() + + # Check that the new IPAddress conforms with any assigned object-level permissions + if not IPAddress.objects.restrict(request.user, 'add').filter(pk=ipaddress.pk).first(): + raise PermissionsViolation() + class FHRPGroupDeleteView(generic.ObjectDeleteView): queryset = FHRPGroup.objects.all() diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index 3b0c77251..2ad16aaf5 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -362,6 +362,13 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): **self.get_extra_context(request, obj), }) + def save_related_data(self, request, form, objd): + """ + Optionally override to save model specific related data after the form is saved. + Raise exception (PermissionsViolation) or such if error. + """ + return + def post(self, request, *args, **kwargs): """ POST request handler. @@ -371,6 +378,7 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): """ logger = logging.getLogger('netbox.views.ObjectEditView') obj = self.get_object(**kwargs) + object_created = False # Take a snapshot for change logging (if editing an existing object) if obj.pk and hasattr(obj, 'snapshot'): @@ -389,6 +397,8 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): object_created = form.instance.pk is None obj = form.save() + self.save_related_data(request, form, obj) + # Check that the new object conforms with any assigned object-level permissions if not self.queryset.filter(pk=obj.pk).exists(): raise PermissionsViolation() @@ -425,6 +435,8 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): logger.debug(e.message) form.add_error(None, e.message) clear_webhooks.send(sender=self) + if object_created and obj: + obj.pk = None else: logger.debug("Form validation failed")