1010from collections import defaultdict
1111from urllib .parse import urlencode
1212
13+ from django .db .models import Exists
1314from django .db .models import Max
15+ from django .db .models import OuterRef
1416from django .db .models import Prefetch
17+ from django .db .models import Q
1518from django_filters import rest_framework as filters
1619from drf_spectacular .utils import extend_schema
1720from packageurl import PackageURL
3033from vulnerabilities .models import AdvisoryWeakness
3134from vulnerabilities .models import GroupedAdvisory
3235from vulnerabilities .models import ImpactedPackageAffecting
36+ from vulnerabilities .models import ImpactedPackageFixedBy
3337from vulnerabilities .models import PackageV2
3438from vulnerabilities .throttling import PermissionBasedUserRateThrottle
3539from vulnerabilities .utils import TYPES_WITH_MULTIPLE_IMPORTERS
@@ -467,7 +471,20 @@ def create(self, request, *args, **kwargs):
467471 for p in map (PackageURL .from_string , purls )
468472 ]
469473
474+ affecting_exists = ImpactedPackageAffecting .objects .filter (
475+ package_id = OuterRef ("pk" ),
476+ impacted_package__advisory___all_impacts_unfurled = True ,
477+ impacted_package__advisory__is_latest = True ,
478+ )
479+
480+ fixed_by_exists = ImpactedPackageFixedBy .objects .filter (
481+ package_id = OuterRef ("pk" ),
482+ impacted_package__advisory___all_impacts_unfurled = True ,
483+ impacted_package__advisory__is_latest = True ,
484+ )
485+
470486 if not details :
487+ # Return back vulnerable PURLs only
471488 if ignore_qualifiers_subpath :
472489 query = (
473490 PackageV2 .objects .filter_plain_purls (plain_purls )
@@ -481,6 +498,10 @@ def create(self, request, *args, **kwargs):
481498 .values_list ("package_url" , flat = True )
482499 )
483500
501+ query = query .annotate (
502+ is_vulnerable = Exists (affecting_exists ),
503+ ).filter (is_vulnerable = True )
504+
484505 page = self .paginate_queryset (query )
485506 return self .get_paginated_response (page )
486507
@@ -489,6 +510,11 @@ def create(self, request, *args, **kwargs):
489510 else :
490511 query = PackageV2 .objects .filter_purls (purls ).order_by ("package_url" )
491512
513+ # Return all vulnerable and non vulnerable purls with details
514+ query = query .annotate (
515+ is_vulnerable = Exists (affecting_exists ),
516+ is_fixing = Exists (fixed_by_exists ),
517+ ).filter (Q (is_vulnerable = True ) | Q (is_fixing = True ))
492518 page = self .paginate_queryset (query )
493519 affected_advisory_map = get_affected_advisories_bulk (page )
494520 fixing_advisory_map = get_fixing_advisories_bulk (page )
0 commit comments