diff --git a/docker/web/.env.dev.web-example b/docker/web/.env.dev.web-example index 36fa363..afa3627 100644 --- a/docker/web/.env.dev.web-example +++ b/docker/web/.env.dev.web-example @@ -1,6 +1,6 @@ DEBUG=1 SECRET_KEY= -ALLOWED_HOSTS=host.docker.internal,localhost,127.0.0.1,[::1] +ALLOWED_HOSTS=host.docker.internal,localhost,127.0.0.1,[::1],testserver # Default account, obviously change for any real use. DJANGO_SUPERUSER_USERNAME=admin diff --git a/src/management/app/tests.py b/src/management/app/tests.py index 7ce503c..b00cfba 100644 --- a/src/management/app/tests.py +++ b/src/management/app/tests.py @@ -1,3 +1,60 @@ +import json from django.test import TestCase +from django.test import Client +from app.models import Package, Metric +client = Client() -# Create your tests here. +class ViewApiGetPackageTests(TestCase): + + registered_package_url = "pkg:github/rails/rails" + registered_url = "https://github.com/rails/rails" + metric_key = "openssf.security-review" + metric_value = "test" + metric_properties = "test" + + def setUp(self): + package = Package.objects.create(package_url=self.registered_package_url) + metric = Metric.objects.create( + package=package, key=self.metric_key, value=self.metric_value, properties=self.metric_properties + ) + + def test_valid_package_url(self): + response = client.get(f"/api/1/get-project?package_url={self.registered_package_url}") + self.assertEqual(response.status_code, 200) + self.assertEqual( + json.loads(response.content), + { + "package_url": self.registered_package_url, + "metrics": [ + { + "key": self.metric_key, + "value": self.metric_value, + "properties": self.metric_properties + } + ] + } + ) + + def test_valid_url(self): + response = client.get(f"/api/1/get-project?url={self.registered_url}") + self.assertEqual(response.status_code, 200) + + def test_not_found(self): + response = client.get("/api/1/get-project?package_url=pkg:github/not_found/not_found") + self.assertEqual(response.status_code, 404) + self.assertEqual(json.loads(response.content)["message"], "Not Found.") + + def test_no_parameters(self): + response = client.get("/api/1/get-project") + self.assertEqual(response.status_code, 400) + self.assertEqual(json.loads(response.content)["message"], "Required, package_url or url.") + + def test_invalid_package_url(self): + response = client.get("/api/1/get-project?package_url=invalid") + self.assertEqual(response.status_code, 400) + self.assertEqual(json.loads(response.content)["message"], "Invalid Package URL.") + + def test_invalid_url(self): + response = client.get("/api/1/get-project?url=invalid") + self.assertEqual(response.status_code, 400) + self.assertEqual(json.loads(response.content)["message"], "Invalid URL.") diff --git a/src/management/app/views.py b/src/management/app/views.py index 3537871..2de7c0f 100644 --- a/src/management/app/views.py +++ b/src/management/app/views.py @@ -8,8 +8,9 @@ from django.core.management import call_command, find_commands, get_commands from django.core.paginator import Paginator from django.forms.models import model_to_dict -from django.http import HttpRequest, HttpResponse, JsonResponse +from django.http import HttpRequest, HttpResponse, HttpResponseNotFound, JsonResponse from django.http.response import HttpResponseBadRequest +from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import HttpResponseRedirect, get_object_or_404, render from packageurl import PackageURL from packageurl.contrib.url2purl import url2purl @@ -79,20 +80,27 @@ def api_get_package(request: HttpRequest) -> HttpResponse: """ purl = None package_url = request.GET.get("package_url") + url = request.GET.get("url") + if not (package_url or url): + return __get_bad_request_with_json("Required, package_url or url.") + if package_url: - purl = PackageURL.from_string(package_url) + try: + purl = PackageURL.from_string(package_url) + except ValueError: + return __get_bad_request_with_json("Invalid Package URL.") + elif url: + purl = url2purl(url) if not purl: - return HttpResponseBadRequest("Invalid Package URL.") - else: - url = request.GET.get("url") - if url: - purl = url2purl(url) - if not purl: - return HttpResponseBadRequest("Invalid URL.") - if not purl: - return HttpResponseBadRequest("Required, package_url or url.") - - package = get_object_or_404(Package, package_url=str(purl)) + return __get_bad_request_with_json("Invalid URL.") + try: + package = Package.objects.get(package_url=str(purl)) + except ObjectDoesNotExist: + return HttpResponseNotFound( + __to_serialized_error_json("Not Found."), + content_type="application/json" + ) + data = {"package_url": package.package_url} metrics = [] @@ -123,3 +131,15 @@ def search_package(request: HttpRequest) -> HttpResponse: def general_about(request: HttpRequest) -> HttpResponse: return render(request, "app/about.html", {}) + +def __get_bad_request_with_json(message: str) -> HttpResponseBadRequest: + return HttpResponseBadRequest( + __to_serialized_error_json(message), + content_type="application/json" + ) + +def __to_serialized_error_json(message: str) -> str: + error_json = { + "message": message + } + return json.dumps(error_json, indent=2) diff --git a/src/requirements.txt b/src/requirements.txt index 5cf166c..3f354a5 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -37,3 +37,4 @@ typing-extensions==3.7.4.3 urllib3==1.26.5 websockets==9.1 yarl==1.6.3 +django-redis==5.0.0 \ No newline at end of file