Skip to content

Commit e5f2160

Browse files
Return invalid IP error in network explorer search
1 parent 1bef8d1 commit e5f2160

4 files changed

Lines changed: 50 additions & 5 deletions

File tree

changelog.d/3534.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Show errors on invalid IP in network explorer search

python/nav/web/networkexplorer/forms.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from django import forms
22

3+
from nav.util import is_valid_ip
4+
35

46
# TODO: Borrowed from newer radius. Need to be removed
57
# TODO: and imported from elsewhere
@@ -81,3 +83,12 @@ class NetworkSearchForm(forms.Form):
8183
hide_ports = forms.BooleanField(
8284
label='Hide ports with no description', required=False
8385
)
86+
87+
def clean(self):
88+
cleaned_data = super().clean()
89+
if cleaned_data.get("query"):
90+
query, query_type = cleaned_data["query"]
91+
if query_type == "ip" and cleaned_data["exact_results"]:
92+
if not is_valid_ip(query):
93+
self._errors['address'] = self.error_class(["Invalid IP address"])
94+
return cleaned_data

python/nav/web/networkexplorer/views.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,19 @@ def render_to_response(self, context):
9494

9595
class SearchView(JSONResponseMixin, View):
9696
def form_invalid(self, form):
97-
return {'error': form.errors}
97+
return {'errors': form.errors}
9898

9999
def form_valid(self, form):
100100
return search(form.cleaned_data)
101101

102102
def get(self, request, *_args, **_kwargs):
103103
form = NetworkSearchForm(request.GET)
104+
status = 200
104105

105106
if form.is_valid():
106107
context = self.form_valid(form)
107108
else:
108109
context = self.form_invalid(form)
110+
status = 400
109111

110-
return self.render_json_response(context)
112+
return self.render_json_response(context, status=status)

tests/integration/networkexplorer_test.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,47 @@ def test_search_view_with_invalid_query(self):
110110
response = SearchView.as_view()(request)
111111
content = response.content.decode('utf-8')
112112

113-
self.assertEqual(response.status_code, 200)
113+
self.assertEqual(response.status_code, 400)
114114
self.assertFalse('routers' in content)
115115
self.assertFalse('gwports' in content)
116116
self.assertFalse('swports' in content)
117117

118+
def test_search_view_will_return_status_400_on_invalid_exact_ip_search(self):
119+
request = self.factory.get(
120+
self.url_root + 'search/',
121+
{
122+
'query_0': 'invalid',
123+
'query_1': 'ip',
124+
'exact_results': 'on',
125+
},
126+
)
127+
response = SearchView.as_view()(request)
128+
content = response.content.decode('utf-8')
129+
130+
assert response.status_code == 400
131+
assert "Invalid IP address" in content
132+
118133

119134
class FormsTest(TestDataMixin, TestCase):
120-
def test_search_form(self):
135+
def test_search_form_with_valid_data_is_valid(self):
121136
valid_form = NetworkSearchForm(self.valid_data)
122-
invalid_form = NetworkSearchForm(self.invalid_data)
123137

124138
self.assertTrue(valid_form.is_valid(), msg='Valid form failed validaion')
139+
140+
def test_search_form_with_missing_argument_is_invalid(self):
141+
invalid_form = NetworkSearchForm(self.invalid_data)
142+
125143
self.assertFalse(invalid_form.is_valid(), msg='Invalid form passed validation')
144+
145+
def test_search_form_with_invalid_ip_for_exact_search_is_invalid(self):
146+
invalid_ip_form = NetworkSearchForm(
147+
{
148+
"query_0": "invalid_ip",
149+
"query_1": "ip",
150+
"exact_results": True,
151+
}
152+
)
153+
154+
self.assertFalse(
155+
invalid_ip_form.is_valid(), msg="Invalid IP form passed validation"
156+
)

0 commit comments

Comments
 (0)