Skip to content

Commit 8df1bf2

Browse files
committed
Handle erroneous requests and add tests for this for bulk api
Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
1 parent 434d65e commit 8df1bf2

2 files changed

Lines changed: 84 additions & 10 deletions

File tree

vulnerabilities/api.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,23 @@ class PackageViewSet(viewsets.ReadOnlyModelViewSet):
133133
def bulk_search(self, request):
134134
filter_list = Q()
135135
response = {}
136-
# TODO: Do some validation here of request body
137-
138-
for purl in request.POST.getlist("packages"):
139-
filter_list |= Q(
140-
**{k: v for k, v in PackageURL.from_string(purl).to_dict().items() if v}
136+
if not isinstance(request.data.get("packages"), list):
137+
return Response(
138+
status=400,
139+
data={
140+
"Error": "Request needs to contain a key 'packages' which has the value of a list of package urls" # nopep8
141+
},
141142
)
143+
for purl in request.data["packages"]:
144+
try:
145+
filter_list |= Q(
146+
**{k: v for k, v in PackageURL.from_string(purl).to_dict().items() if v}
147+
)
148+
except ValueError as ve:
149+
return Response(status=400, data={"Error": str(ve)})
142150

143151
# This handles the case when the said purl doesnt exist in db
144152
response[purl] = {}
145-
146153
res = Package.objects.filter(filter_list)
147154
for p in res:
148155
response[p.package_url] = PackageSerializer(p, context={"request": request}).data
@@ -169,9 +176,15 @@ class VulnerabilityViewSet(viewsets.ReadOnlyModelViewSet):
169176
def bulk_search(self, request):
170177
filter_list = []
171178
response = {}
172-
# TODO: Do some validation here of request body
179+
if not isinstance(request.data.get("vulnerabilities"), list):
180+
return Response(
181+
status=400,
182+
data={
183+
"Error": "Request needs to contain a key 'vulnerabilities' which has the value of a list of vulnerability ids" # nopep8
184+
},
185+
)
173186

174-
for cve_id in request.POST.getlist("vulnerabilities"):
187+
for cve_id in request.data["vulnerabilities"]:
175188
filter_list.append(cve_id)
176189
# This handles the case when the said cve doesnt exist in db
177190
response[cve_id] = {}

vulnerabilities/tests/test_api.py

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,9 @@ def test_bulk_vulnerabilities_api(self):
239239
},
240240
"RANDOM-CVE": {},
241241
}
242-
response = self.client.post("/api/vulnerabilities/bulk_search/", request_body).data
242+
response = self.client.post(
243+
"/api/vulnerabilities/bulk_search/", data=request_body, content_type="application/json"
244+
).data
243245
assert response == expected_response
244246

245247
def test_bulk_packages_api(self):
@@ -249,7 +251,9 @@ def test_bulk_packages_api(self):
249251
"pkg:deb/debian/mimetex@1.50-1.1?distro=jessie",
250252
]
251253
}
252-
response = self.client.post("/api/packages/bulk_search/", request_body).data
254+
response = self.client.post(
255+
"/api/packages/bulk_search/", data=request_body, content_type="application/json"
256+
).data
253257
expected_response = {
254258
"pkg:deb/debian/librsync@0.9.7-10?distro=jessie": {
255259
"url": "http://testserver/api/packages/1/",
@@ -298,3 +302,60 @@ def test_bulk_packages_api(self):
298302
}
299303

300304
assert response == expected_response
305+
306+
def test_invalid_request_bulk_packages(self):
307+
error_response = {
308+
"Error": "Request needs to contain a key 'packages' which has the value of a list of package urls" # nopep8
309+
}
310+
invalid_key_request_data = {"pkg": []}
311+
response = self.client.post(
312+
"/api/packages/bulk_search/",
313+
data=invalid_key_request_data,
314+
content_type="application/json",
315+
).data
316+
assert response == error_response
317+
318+
valid_key_invalid_datatype_request_data = {"packages": {}}
319+
response = self.client.post(
320+
"/api/packages/bulk_search/",
321+
data=valid_key_invalid_datatype_request_data,
322+
content_type="application/json",
323+
).data
324+
assert response == error_response
325+
326+
invalid_purl_request_data = {
327+
"packages": [
328+
"pkg:deb/debian/librsync@0.9.7-10?distro=jessie",
329+
"pg:deb/debian/mimetex@1.50-1.1?distro=jessie",
330+
]
331+
}
332+
response = self.client.post(
333+
"/api/packages/bulk_search/",
334+
data=invalid_purl_request_data,
335+
content_type="application/json",
336+
).data
337+
purl_error_respones = {
338+
"Error": "purl is missing the required \"pkg\" scheme component: 'pg:deb/debian/mimetex@1.50-1.1?distro=jessie'." # nopep8
339+
}
340+
assert response == purl_error_respones
341+
342+
def test_invalid_request_bulk_vulnerabilities(self):
343+
error_response = {
344+
"Error": "Request needs to contain a key 'vulnerabilities' which has the value of a list of vulnerability ids" # nopep8
345+
}
346+
347+
wrong_key_data = {"xyz": []}
348+
response = self.client.post(
349+
"/api/vulnerabilities/bulk_search/",
350+
data=wrong_key_data,
351+
content_type="application/json",
352+
).data
353+
assert response == error_response
354+
355+
wrong_type_data = {"vulnerabilities": {}}
356+
response = self.client.post(
357+
"/api/vulnerabilities/bulk_search/",
358+
data=wrong_key_data,
359+
content_type="application/json",
360+
).data
361+
assert response == error_response

0 commit comments

Comments
 (0)