Skip to content

Commit

Permalink
Refine the generated schema for PurlValidateViewSet
Browse files Browse the repository at this point in the history
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
  • Loading branch information
keshav-space committed Dec 12, 2023
1 parent 8206a62 commit 66100a0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 28 deletions.
64 changes: 37 additions & 27 deletions packagedb/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
PackageAPISerializer,
PackageSetAPISerializer, PartySerializer,
ResourceAPISerializer)
from packagedb.serializers import PurlValidateResponseSerializer
from packagedb.serializers import PurlValidateSerializer
from drf_spectacular.utils import extend_schema
from drf_spectacular.utils import OpenApiParameter
from packagedb.serializers import IndexPackagesSerializer
Expand Down Expand Up @@ -639,7 +641,7 @@ def _reindex_package(package, reindexed_packages):
serializer = self.serializer_class(data=request.data)

if not serializer.is_valid():
return Response({'errors': serializer.errors}, status=400)
return Response({'errors': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

validated_data = serializer.validated_data
packages = validated_data.get('packages', [])
Expand Down Expand Up @@ -702,7 +704,6 @@ def _reindex_package(package, reindexed_packages):
serializer = IndexPackagesResponseSerializer(response_data, context={'request': request})
return Response(serializer.data)


class PurlValidateViewSet(viewsets.ViewSet):
"""
Take a `purl` and check whether it's valid PackageURL or not.
Expand All @@ -711,7 +712,7 @@ class PurlValidateViewSet(viewsets.ViewSet):
**Note:** As of now `check_existence` only supports `apache`, `composer`, `deb`, `gem`,
`github`, `golang`, `maven`, `npm`, `nuget`and `pypi` ecosystems.
**Input example:**
**Request example:**
{
"purl": "pkg:npm/foobar@12.3.1",
Expand All @@ -725,12 +726,27 @@ class PurlValidateViewSet(viewsets.ViewSet):
- exists
- True, if input PURL exists in real world and `check_existence` flag is enabled.
"""
serializer_class = PurlValidateSerializer

def get_view_name(self):
return 'Validate PURL'


@extend_schema(
parameters=[
OpenApiParameter('purl', str, 'query', description='PackageURL'),
OpenApiParameter('check_existence', bool, 'query', description='Check existence', default=False),
],
responses={200: PurlValidateResponseSerializer()},
)
def list(self, request):
purl = request.query_params.get("purl")
check_existence = request.query_params.get("check_existence") or False
serializer = self.serializer_class(data=request.query_params)

if not serializer.is_valid():
return Response({'errors': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

validated_data = serializer.validated_data
purl = validated_data.get('purl')
check_existence = validated_data.get('check_existence', False)

message_valid = "The provided PackageURL is valid."
message_not_valid = "The provided PackageURL is not valid."
Expand All @@ -743,6 +759,9 @@ def list(self, request):
message_error_no_purl = (
"PackageURL (purl) is required. Please provide a PackageURL in the request."
)
response = {}
response['exists'] = None
response['purl'] = purl

if not purl:
return Response(
Expand All @@ -757,22 +776,19 @@ def list(self, request):
try:
package_url = PackageURL.from_string(purl)
except ValueError:
return Response(
{
"valid": False,
"message": message_not_valid,
"purl": purl,
}
)
response['valid'] = False
response['message'] = message_not_valid
serializer = PurlValidateResponseSerializer(response, context={'request': request})
return Response(serializer.data)

exists = None
message = message_valid
response['valid'] = True
response['message'] = message_valid
if check_existence:
exists = False
response['exists'] = False
lookups = purl_to_lookups(purl)
packages = Package.objects.filter(**lookups)
if packages.exists():
exists = True
response['exists'] = True
else:
versionless_purl = PackageURL(
type=package_url.type,
Expand All @@ -785,17 +801,11 @@ def list(self, request):
):
# True, if requested purl has no version and any version of package exists upstream.
# True, if requested purl.version exists upstream.
exists = True
message = message_valid_and_exists if exists else message_valid_but_does_not_exist
response['exists'] = True
response['message'] = message_valid_and_exists if response['exists'] else message_valid_but_does_not_exist

return Response(
{
"valid": True,
"exists": exists,
"message": message,
"purl": purl,
}
)
serializer = PurlValidateResponseSerializer(response, context={'request': request})
return Response(serializer.data)


def get_resolved_purls(packages, supported_ecosystems):
Expand Down
12 changes: 11 additions & 1 deletion packagedb/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,4 +370,14 @@ class IndexPackagesResponseSerializer(Serializer):
unsupported_vers = ListField(
child=CharField(),
help_text="List of vers range that are not supported by the univers or package_manager."
)
)

class PurlValidateResponseSerializer(Serializer):
valid = BooleanField()
exists = BooleanField(required=False)
message = CharField()
purl = CharField()

class PurlValidateSerializer(Serializer):
purl = CharField()
check_existence = BooleanField(required=False, default=False)

0 comments on commit 66100a0

Please sign in to comment.