Update invalid input handling to return empty set instead of raising exception

This commit is contained in:
rmanyari 2023-03-01 10:31:43 -07:00
parent 1e2a33337f
commit fe14cdf07c
2 changed files with 28 additions and 24 deletions

View File

@ -601,23 +601,33 @@ class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
return queryset.filter(q) return queryset.filter(q)
def parse_inet_addresses(self, value): def parse_inet_addresses(self, value):
try: '''
Parse networks or IP addresses and cast to a format
acceptable by the Postgres inet type.
Skips invalid values.
'''
parsed = [] parsed = []
for addr in value: for addr in value:
if netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr): if netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr):
parsed.append(addr) parsed.append(addr)
continue continue
try:
network = netaddr.IPNetwork(addr) network = netaddr.IPNetwork(addr)
parsed.append(str(network)) parsed.append(str(network))
return parsed
except (AddrFormatError, ValueError): except (AddrFormatError, ValueError):
raise serializers.ValidationError({ continue
'address': f'Invalid address {addr}. It must be a valid IPv4 or IPv6 address or network' return parsed
})
def filter_address(self, queryset, name, value): def filter_address(self, queryset, name, value):
try: # 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) value = self.parse_inet_addresses(value)
if (len(value) == 0):
return queryset.none()
try:
return queryset.filter(address__net_in=value) return queryset.filter(address__net_in=value)
except ValidationError: except ValidationError:
return queryset.none() return queryset.none()

View File

@ -864,19 +864,13 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests):
# Check for invalid input. # Check for invalid input.
params = {'address': ['/24']} params = {'address': ['/24']}
with self.assertRaises(serializers.ValidationError) as cm: self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
self.filterset(params, self.queryset).qs.count() params = {'address': ['10.0.0.1/255.255.999.0']} # Invalid netmask
self.assertRegex(cm.exception.detail['address'], r'^Invalid address.*') self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
params = {'address': ['10.0.0.1/255.255.555.0']} # Check for partially invalid input.
with self.assertRaises(serializers.ValidationError) as cm: params = {'address': ['10.0.0.1', '/24', '10.0.0.10/24']}
self.filterset(params, self.queryset).qs.count() self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
self.assertRegex(cm.exception.detail['address'], r'^Invalid address.*')
params = {'address': ['10.0.0.1', '/24']}
with self.assertRaises(serializers.ValidationError) as cm:
self.filterset(params, self.queryset).qs.count()
self.assertRegex(cm.exception.detail['address'], r'^Invalid address.*')
def test_mask_length(self): def test_mask_length(self):
params = {'mask_length': '24'} params = {'mask_length': '24'}