Skip to content

Commit

Permalink
Handle erroneous requests and add tests for this for bulk api
Browse files Browse the repository at this point in the history
Signed-off-by: Shivam Sandbhor <[email protected]>
  • Loading branch information
sbs2001 committed Jan 16, 2021
1 parent 41f5aee commit f9aef59
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 10 deletions.
29 changes: 21 additions & 8 deletions vulnerabilities/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,23 @@ class PackageViewSet(viewsets.ReadOnlyModelViewSet):
def bulk_search(self, request):
filter_list = Q()
response = {}
# TODO: Do some validation here of request body

for purl in request.POST.getlist("packages"):
filter_list |= Q(
**{k: v for k, v in PackageURL.from_string(purl).to_dict().items() if v}
if not isinstance(request.data.get("packages"), list):
return Response(
status=400,
data={
"Error": "Request needs to contain a key 'packages' which has the value of a list of package urls" # nopep8
},
)
for purl in request.data["packages"]:
try:
filter_list |= Q(
**{k: v for k, v in PackageURL.from_string(purl).to_dict().items() if v}
)
except ValueError as ve:
return Response(status=400, data={"Error": str(ve)})

# This handles the case when the said purl doesnt exist in db
response[purl] = {}

res = Package.objects.filter(filter_list)
for p in res:
response[p.package_url] = PackageSerializer(p, context={"request": request}).data
Expand All @@ -169,9 +176,15 @@ class VulnerabilityViewSet(viewsets.ReadOnlyModelViewSet):
def bulk_search(self, request):
filter_list = []
response = {}
# TODO: Do some validation here of request body
if not isinstance(request.data.get("vulnerabilities"), list):
return Response(
status=400,
data={
"Error": "Request needs to contain a key 'vulnerabilities' which has the value of a list of vulnerability ids" # nopep8
},
)

for cve_id in request.POST.getlist("vulnerabilities"):
for cve_id in request.data["vulnerabilities"]:
filter_list.append(cve_id)
# This handles the case when the said cve doesnt exist in db
response[cve_id] = {}
Expand Down
65 changes: 63 additions & 2 deletions vulnerabilities/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ def test_bulk_vulnerabilities_api(self):
},
"RANDOM-CVE": {},
}
response = self.client.post("/api/vulnerabilities/bulk_search/", request_body).data
response = self.client.post(
"/api/vulnerabilities/bulk_search/", data=request_body, content_type="application/json"
).data
assert response == expected_response

def test_bulk_packages_api(self):
Expand All @@ -249,7 +251,9 @@ def test_bulk_packages_api(self):
"pkg:deb/debian/[email protected]?distro=jessie",
]
}
response = self.client.post("/api/packages/bulk_search/", request_body).data
response = self.client.post(
"/api/packages/bulk_search/", data=request_body, content_type="application/json"
).data
expected_response = {
"pkg:deb/debian/[email protected]?distro=jessie": {
"url": "http://testserver/api/packages/1/",
Expand Down Expand Up @@ -298,3 +302,60 @@ def test_bulk_packages_api(self):
}

assert response == expected_response

def test_invalid_request_bulk_packages(self):
error_response = {
"Error": "Request needs to contain a key 'packages' which has the value of a list of package urls" # nopep8
}
invalid_key_request_data = {"pkg": []}
response = self.client.post(
"/api/packages/bulk_search/",
data=invalid_key_request_data,
content_type="application/json",
).data
assert response == error_response

valid_key_invalid_datatype_request_data = {"packages": {}}
response = self.client.post(
"/api/packages/bulk_search/",
data=valid_key_invalid_datatype_request_data,
content_type="application/json",
).data
assert response == error_response

invalid_purl_request_data = {
"packages": [
"pkg:deb/debian/[email protected]?distro=jessie",
"pg:deb/debian/[email protected]?distro=jessie",
]
}
response = self.client.post(
"/api/packages/bulk_search/",
data=invalid_purl_request_data,
content_type="application/json",
).data
purl_error_respones = {
"Error": "purl is missing the required \"pkg\" scheme component: 'pg:deb/debian/[email protected]?distro=jessie'." # nopep8
}
assert response == purl_error_respones

def test_invalid_request_bulk_vulnerabilities(self):
error_response = {
"Error": "Request needs to contain a key 'vulnerabilities' which has the value of a list of vulnerability ids" # nopep8
}

wrong_key_data = {"xyz": []}
response = self.client.post(
"/api/vulnerabilities/bulk_search/",
data=wrong_key_data,
content_type="application/json",
).data
assert response == error_response

wrong_type_data = {"vulnerabilities": {}}
response = self.client.post(
"/api/vulnerabilities/bulk_search/",
data=wrong_key_data,
content_type="application/json",
).data
assert response == error_response

0 comments on commit f9aef59

Please sign in to comment.