mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-25 18:08:38 -06:00
* Fixes #11470: Validation and user friendly message on invalid address query param * Update invalid input handling to return empty set instead of raising exception
This commit is contained in:
parent
189668fbfb
commit
6640fc9eb7
@ -16,6 +16,7 @@ from virtualization.models import VirtualMachine, VMInterface
|
|||||||
from .choices import *
|
from .choices import *
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AggregateFilterSet',
|
'AggregateFilterSet',
|
||||||
@ -599,7 +600,33 @@ class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
|
|||||||
return queryset.none()
|
return queryset.none()
|
||||||
return queryset.filter(q)
|
return queryset.filter(q)
|
||||||
|
|
||||||
|
def parse_inet_addresses(self, value):
|
||||||
|
'''
|
||||||
|
Parse networks or IP addresses and cast to a format
|
||||||
|
acceptable by the Postgres inet type.
|
||||||
|
|
||||||
|
Skips invalid values.
|
||||||
|
'''
|
||||||
|
parsed = []
|
||||||
|
for addr in value:
|
||||||
|
if netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr):
|
||||||
|
parsed.append(addr)
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
network = netaddr.IPNetwork(addr)
|
||||||
|
parsed.append(str(network))
|
||||||
|
except (AddrFormatError, ValueError):
|
||||||
|
continue
|
||||||
|
return parsed
|
||||||
|
|
||||||
def filter_address(self, queryset, name, value):
|
def filter_address(self, queryset, name, value):
|
||||||
|
# Let's first parse the addresses passed
|
||||||
|
# as argument. If they are all invalid,
|
||||||
|
# we return an empty queryset
|
||||||
|
value = self.parse_inet_addresses(value)
|
||||||
|
if (len(value) == 0):
|
||||||
|
return queryset.none()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return queryset.filter(address__net_in=value)
|
return queryset.filter(address__net_in=value)
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
|
@ -10,6 +10,7 @@ from ipam.models import *
|
|||||||
from utilities.testing import ChangeLoggedFilterSetTests, create_test_device, create_test_virtualmachine
|
from utilities.testing import ChangeLoggedFilterSetTests, create_test_device, create_test_virtualmachine
|
||||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||||
from tenancy.models import Tenant, TenantGroup
|
from tenancy.models import Tenant, TenantGroup
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
class ASNTestCase(TestCase, ChangeLoggedFilterSetTests):
|
class ASNTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||||
@ -851,6 +852,26 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
params = {'address': ['2001:db8::1/64', '2001:db8::1/65']}
|
params = {'address': ['2001:db8::1/64', '2001:db8::1/65']}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
# Check for valid edge cases. Note that Postgres inet type
|
||||||
|
# only accepts netmasks in the int form, so the filterset
|
||||||
|
# casts netmasks in the xxx.xxx.xxx.xxx format.
|
||||||
|
params = {'address': ['24']}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
|
||||||
|
params = {'address': ['10.0.0.1/255.255.255.0']}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||||
|
params = {'address': ['10.0.0.1/255.255.255.0', '10.0.0.1/25']}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
# Check for invalid input.
|
||||||
|
params = {'address': ['/24']}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
|
||||||
|
params = {'address': ['10.0.0.1/255.255.999.0']} # Invalid netmask
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
|
||||||
|
|
||||||
|
# Check for partially invalid input.
|
||||||
|
params = {'address': ['10.0.0.1', '/24', '10.0.0.10/24']}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
def test_mask_length(self):
|
def test_mask_length(self):
|
||||||
params = {'mask_length': '24'}
|
params = {'mask_length': '24'}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5)
|
||||||
|
Loading…
Reference in New Issue
Block a user