Skip to content

Commit 3859939

Browse files
committed
Get related advisory using impacted pkg in v2 pkg details view
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent f647d96 commit 3859939

File tree

4 files changed

+68
-89
lines changed

4 files changed

+68
-89
lines changed

vulnerabilities/models.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3112,23 +3112,6 @@ def calculate_version_rank(self):
31123112
PackageV2.objects.bulk_update(sorted_packages, fields=["version_rank"])
31133113
return self.version_rank
31143114

3115-
@property
3116-
def fixed_package_details(self):
3117-
"""
3118-
Return a mapping of vulnerabilities that affect this package and the next and
3119-
latest non-vulnerable versions.
3120-
"""
3121-
package_details = {}
3122-
package_details["purl"] = PackageURL.from_string(self.purl)
3123-
3124-
next_non_vulnerable, latest_non_vulnerable = self.get_non_vulnerable_versions()
3125-
package_details["next_non_vulnerable"] = next_non_vulnerable
3126-
package_details["latest_non_vulnerable"] = latest_non_vulnerable
3127-
3128-
package_details["advisories"] = self.get_affecting_vulnerabilities()
3129-
3130-
return package_details
3131-
31323115
def get_non_vulnerable_versions(self):
31333116
"""
31343117
Return a tuple of the next and latest non-vulnerable versions as Package instance.

vulnerabilities/templates/package_details_v2.html

Lines changed: 24 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{% load widget_tweaks %}
44
{% load static %}
55
{% load url_filters %}
6+
{% load utils %}
67

78
{% block title %}
89
VulnerableCode Package Details - {{ package.purl }}
@@ -60,7 +61,7 @@
6061
</span>
6162
</td>
6263
<td class="two-col-right">
63-
{{ fixed_package_details.purl.to_string }}
64+
{{ package.purl }}
6465
</td>
6566
</tr>
6667
{% if package.is_ghost %}
@@ -91,9 +92,9 @@
9192
Next non-vulnerable version
9293
</td>
9394
<td class="two-col-right">
94-
{% if fixed_package_details.next_non_vulnerable.version %}
95-
<a href="/packages/v2/{{ fixed_package_details.next_non_vulnerable|url_quote }}?search={{ fixed_package_details.next_non_vulnerable }}"
96-
target="_self">{{ fixed_package_details.next_non_vulnerable.version }}</a>
95+
{% if next_non_vulnerable.version %}
96+
<a href="/packages/v2/{{ next_non_vulnerable|url_quote }}?search={{ next_non_vulnerable }}"
97+
target="_self">{{ next_non_vulnerable.version }}</a>
9798
{% else %}
9899
<span class="emphasis-vulnerable">None.</span>
99100
{% endif %}
@@ -104,9 +105,9 @@
104105
Latest non-vulnerable version
105106
</td>
106107
<td class="two-col-right">
107-
{% if fixed_package_details.latest_non_vulnerable.version %}
108-
<a href="/packages/v2/{{ fixed_package_details.latest_non_vulnerable|url_quote }}?search={{ fixed_package_details.latest_non_vulnerable }}"
109-
target="_self">{{ fixed_package_details.latest_non_vulnerable.version }}</a>
108+
{% if latest_non_vulnerable.version %}
109+
<a href="/packages/v2/{{ latest_non_vulnerable|url_quote }}?search={{ latest_non_vulnerable }}"
110+
target="_self">{{ latest_non_vulnerable.version }}</a>
110111
{% else %}
111112
<span class="emphasis-vulnerable">None.</span>
112113
{% endif %}
@@ -175,66 +176,22 @@
175176
{{ advisory.summary }}
176177
</td>
177178
<td style="word-wrap: break-word; word-break: break-all;">
178-
{% if package.purl == fixed_package_details.purl.to_string %}
179-
{% for key, value in fixed_package_details.items %}
180-
{% if key == "advisories" %}
181-
{% for vuln in value %}
182-
{% if vuln.advisory.advisory_id == advisory.advisory_id %}
183-
{% if vuln.fixed_by_package_details is None %}
184-
<span class="emphasis-vulnerable">There are no reported fixed by versions.</span>
185-
{% else %}
186-
{% for fixed_pkg in vuln.fixed_by_package_details %}
187-
<section>
188-
{% if fixed_pkg.fixed_by_purl_advisories|length == 0 %}
189-
<a href="/packages/v2/{{ fixed_pkg.fixed_by_purl|url_quote }}?search={{ fixed_pkg.fixed_by_purl }}"
190-
target="_self">{{ fixed_pkg.fixed_by_purl.version }}</a>
191-
<br />
192-
<span class="emphasis-not-vulnerable">Subject of 0 other advisories.</span>
193-
{% else %}
194-
<a href="/packages/v2/{{ fixed_pkg.fixed_by_purl|url_quote }}?search={{ fixed_pkg.fixed_by_purl }}"
195-
target="_self">{{ fixed_pkg.fixed_by_purl.version }}</a>
196-
{% if fixed_pkg.fixed_by_purl_advisories|length != 1 %}
197-
<br />
198-
<span class="emphasis-vulnerable">Subject of {{ fixed_pkg.fixed_by_purl_advisories|length }} other
199-
advisory.</span>
200-
{% else %}
201-
<br />
202-
<span class="emphasis-vulnerable">Subject of {{ fixed_pkg.fixed_by_purl_advisories|length }} other
203-
advisory.</span>
204-
{% endif %}
205-
206-
<div class="dropdown is-hoverable has-text-weight-normal is-right">
207-
<div class="dropdown-trigger">
208-
<i
209-
class="fa fa-question-circle ml-0 fa-sm has-background-white has-text-link"></i>
210-
</div>
211-
<div class="dropdown-menu dropdown-vuln-list-width" id="dropdown-menu4"
212-
role="menu">
213-
<div class="dropdown-content dropdown-instructions-box-shadow">
214-
<div class="dropdown-item">
215-
<div style="max-height: 200px; overflow-y: auto;">
216-
This version is subject of other advisories:
217-
<div style="padding-top: 5px;">
218-
{% for fixed_by_vuln in fixed_pkg.fixed_by_purl_advisories %}
219-
<div>
220-
{{fixed_by_vuln.advisory_id }}
221-
</div>
222-
{% endfor %}
223-
</div>
224-
</div>
225-
</div>
226-
</div>
227-
</div>
228-
</div>
229-
{% endif %}
230-
</section>
231-
{% endfor %}
232-
{% endif %}
233-
{% endif %}
234-
{% endfor %}
235-
{% endif %}
236-
{% endfor %}
237-
{% endif %}
179+
{% with fixed=fixed_package_details|get_item:advisory.id %}
180+
{% if fixed %}
181+
{% for item in fixed %}
182+
<section>
183+
<a href="/packages/v2/{{ item.pkg.purl|url_quote }}?search={{ item.pkg.purl }}"
184+
target="_self">{{ item.pkg.version }}</a>
185+
<br/>
186+
<span class="{{ item.affected_count|yesno:'emphasis-vulnerable,emphasis-not-vulnerable' }}">
187+
Subject of {{ item.affected_count }} other advisories.
188+
</span>
189+
</section>
190+
{% endfor %}
191+
{% else %}
192+
<span class="emphasis-vulnerable">There are no reported fixed by versions.</span>
193+
{% endif %}
194+
{% endwith %}
238195
</td>
239196
</tr>
240197
{% empty %}

vulnerabilities/templatetags/utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,8 @@ def active_item(context, url_name):
3434
if request.resolver_match.url_name == url_name:
3535
return "is-active"
3636
return ""
37+
38+
39+
@register.filter
40+
def get_item(dictionary, key):
41+
return dictionary.get(key)

vulnerabilities/views.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from vulnerabilities.forms import PackageSearchForm
3535
from vulnerabilities.forms import PipelineSchedulePackageForm
3636
from vulnerabilities.forms import VulnerabilitySearchForm
37+
from vulnerabilities.models import ImpactedPackage
3738
from vulnerabilities.models import PipelineRun
3839
from vulnerabilities.models import PipelineSchedule
3940
from vulnerabilities.severity_systems import EPSS
@@ -186,18 +187,51 @@ class PackageV2Details(DetailView):
186187
def get_context_data(self, **kwargs):
187188
context = super().get_context_data(**kwargs)
188189
package = self.object
190+
next_non_vulnerable, latest_non_vulnerable = package.get_non_vulnerable_versions()
191+
fixed_pkg_details = {}
192+
for impact in package.affected_in_impacts.all():
193+
if impact.advisory.id not in fixed_pkg_details:
194+
fixed_pkg_details[impact.advisory.id] = []
195+
fixed_pkg_details[impact.advisory.id].extend(
196+
[
197+
{"pkg": pkg, "affected_count": pkg.affected_in_impacts.count()}
198+
for pkg in impact.fixed_by_packages.all()
199+
]
200+
)
189201
context["package"] = package
190-
context["affected_by_advisories"] = package.affected_by_advisories.order_by("advisory_id")
202+
context["next_non_vulnerable"] = next_non_vulnerable
203+
context["latest_non_vulnerable"] = latest_non_vulnerable
204+
context["affected_by_advisories"] = {
205+
impact.advisory for impact in package.affected_in_impacts.all()
206+
}
191207
# Ghost package should not fix any vulnerability.
192-
context["fixing_advisories"] = (
193-
None if package.is_ghost else package.fixing_advisories.order_by("advisory_id")
194-
)
208+
if not package.is_ghost:
209+
context["fixing_advisories"] = {
210+
impact.advisory for impact in package.fixed_in_impacts.all()
211+
}
212+
195213
context["package_search_form"] = PackageSearchForm(self.request.GET)
196-
context["fixed_package_details"] = package.fixed_package_details
214+
context["fixed_package_details"] = fixed_pkg_details
197215

198216
# context["history"] = list(package.history)
199217
return context
200218

219+
def get_queryset(self):
220+
return (
221+
super()
222+
.get_queryset()
223+
.prefetch_related(
224+
Prefetch(
225+
"affected_in_impacts",
226+
queryset=ImpactedPackage.objects.select_related("advisory"),
227+
),
228+
Prefetch(
229+
"fixed_in_impacts",
230+
queryset=ImpactedPackage.objects.select_related("advisory"),
231+
),
232+
)
233+
)
234+
201235
def get_object(self, queryset=None):
202236
if queryset is None:
203237
queryset = self.get_queryset()

0 commit comments

Comments
 (0)