|
40 | 40 | from vulnerabilities.improver import Improver |
41 | 41 | from vulnerabilities.improver import Inference |
42 | 42 | from vulnerabilities.models import Advisory |
| 43 | +from vulnerabilities.models import Package |
| 44 | +from vulnerabilities.models import PackageV2 |
43 | 45 | from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipeline |
44 | 46 | from vulnerabilities.pipelines.github_importer import GitHubAPIImporterPipeline |
45 | 47 | from vulnerabilities.pipelines.gitlab_importer import GitLabImporterPipeline |
@@ -73,15 +75,45 @@ def get_package_versions( |
73 | 75 | """ |
74 | 76 | Return a list of versions published before `until` for the `package_url` |
75 | 77 | """ |
76 | | - versions = package_versions.versions(str(package_url)) |
| 78 | + versions = list(package_versions.versions(str(package_url)) or []) |
| 79 | + self.store_package_release_dates(package_url=package_url, versions=versions) |
77 | 80 | versions_before_until = [] |
78 | | - for version in versions or []: |
| 81 | + for version in versions: |
79 | 82 | if until and version.release_date and version.release_date > until: |
80 | 83 | continue |
81 | 84 | versions_before_until.append(version.value) |
82 | 85 |
|
83 | 86 | return versions_before_until |
84 | 87 |
|
| 88 | + def store_package_release_dates(self, package_url: PackageURL, versions: List) -> None: |
| 89 | + """ |
| 90 | + Persist release dates for known package versions in both Package and PackageV2. |
| 91 | + """ |
| 92 | + releases_by_version = { |
| 93 | + version.value: version.release_date |
| 94 | + for version in versions |
| 95 | + if getattr(version, "value", None) and getattr(version, "release_date", None) |
| 96 | + } |
| 97 | + if not releases_by_version: |
| 98 | + return |
| 99 | + |
| 100 | + filters = { |
| 101 | + "type": package_url.type, |
| 102 | + "namespace": package_url.namespace, |
| 103 | + "name": package_url.name, |
| 104 | + "version__in": list(releases_by_version), |
| 105 | + } |
| 106 | + |
| 107 | + for model in (Package, PackageV2): |
| 108 | + packages_to_update = [] |
| 109 | + for package in model.objects.filter(**filters).only("id", "version", "release_date"): |
| 110 | + release_date = releases_by_version.get(package.version) |
| 111 | + if release_date and package.release_date != release_date: |
| 112 | + package.release_date = release_date |
| 113 | + packages_to_update.append(package) |
| 114 | + if packages_to_update: |
| 115 | + model.objects.bulk_update(packages_to_update, fields=["release_date"]) |
| 116 | + |
85 | 117 | def get_inferences(self, advisory_data: AdvisoryData) -> Iterable[Inference]: |
86 | 118 | """ |
87 | 119 | Yield Inferences for the given advisory data |
|
0 commit comments