diff --git a/vulnerabilities/models.py b/vulnerabilities/models.py index 16c93002f..161a26ae8 100644 --- a/vulnerabilities/models.py +++ b/vulnerabilities/models.py @@ -356,28 +356,32 @@ class Meta: ordering = ["vulnerability", "reference"] -def purl_to_dict(purl: PackageURL): +def purl_to_dict(purl: PackageURL, without_version=False): """ Return a dict of purl components suitable for use in a queryset. We need to have specific empty values for using in querysets because of our peculiar model structure. For example:: >>> purl_to_dict(PackageURL.from_string("pkg:generic/postgres")) - {'type': 'generic', 'namespace': '', 'name': 'postgres', 'version': '', 'qualifiers': {}, 'subpath': ''} + {'type': 'generic', 'namespace': '', 'name': 'postgres', 'qualifiers': {}, 'subpath': '', 'version': ''} >>> purl_to_dict(PackageURL.from_string("pkg:generic/postgres/postgres@1.2?foo=bar#baz")) - {'type': 'generic', 'namespace': 'postgres', 'name': 'postgres', 'version': '1.2', 'qualifiers': {'foo': 'bar'}, 'subpath': 'baz'} + {'type': 'generic', 'namespace': 'postgres', 'name': 'postgres', 'qualifiers': {'foo': 'bar'}, 'subpath': 'baz', 'version': '1.2'} + >>> purl_to_dict(purl = PackageURL.from_string("pkg:generic/postgres/postgres@1.2?foo=bar#baz"), without_version=True) + {'type': 'generic', 'namespace': 'postgres', 'name': 'postgres', 'qualifiers': {'foo': 'bar'}, 'subpath': 'baz'} """ if isinstance(purl, str): purl = PackageURL.from_string(purl) - return dict( + lookup = dict( type=purl.type, namespace=purl.namespace or "", name=purl.name, - version=purl.version or "", qualifiers=purl.qualifiers or {}, subpath=purl.subpath or "", ) + if not without_version: + lookup["version"] = purl.version or "" + return lookup class PackageQuerySet(BaseQuerySet, PackageURLQuerySet): @@ -431,17 +435,6 @@ def with_vulnerability_counts(self): ), ) - def fixing_packages(self, package, with_qualifiers_and_subpath=True): - """ - Return a queryset of packages that are fixing the vulnerability of - ``package``. - """ - - return self.match_purl( - purl=package.purl, - with_qualifiers_and_subpath=with_qualifiers_and_subpath, - ).fixing() - def search(self, query=None): """ Return a Package queryset searching for the ``query``. @@ -496,6 +489,15 @@ def for_cve(self, cve): """ return self.filter(vulnerabilities__vulnerabilityreference__reference_id__exact=cve) + def matching_packages(self, purl): + if not purl: + return self + if not isinstance(purl, PackageURL): + purl = str(purl) + purl = PackageURL.from_string(purl) + lookups = purl_to_dict(purl=purl, without_version=True) + return self.filter(**lookups) + def get_purl_query_lookups(purl): """ @@ -599,13 +601,6 @@ def fixing(self): # legacy aliases resolved_to = fixing - @property - def fixed_packages(self): - """ - Return a queryset of packages that are fixed. - """ - return Package.objects.fixing_packages(package=self).distinct() - @property def is_vulnerable(self) -> bool: """ diff --git a/vulnerabilities/templates/package_details.html b/vulnerabilities/templates/package_details.html index 6a391d3d3..7fc639b53 100644 --- a/vulnerabilities/templates/package_details.html +++ b/vulnerabilities/templates/package_details.html @@ -58,7 +58,7 @@ {% for vulnerability in affected_by_vulnerabilities %}