Skip to content

Commit

Permalink
Update the Package list to use the new Vulnerability model #138
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <tdruez@nexb.com>
  • Loading branch information
tdruez committed Aug 5, 2024
1 parent 724998a commit a352e00
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 13 deletions.
9 changes: 9 additions & 0 deletions component_catalog/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,15 @@ class PackageFilterSet(DataspacedFilterSet):
empty_label="Last modified (default)",
widget=SortDropDownWidget,
)
is_vulnerable = HasRelationFilter(
label=_("Is Vulnerable"),
field_name="affected_by_vulnerabilities",
choices=(
("yes", _("Affected by vulnerabilities")),
("no", _("No vulnerabilities found")),
),
widget=DropDownRightWidget,
)

class Meta:
model = Package
Expand Down
10 changes: 7 additions & 3 deletions component_catalog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1627,11 +1627,15 @@ def has_package_url(self):
"""Return objects with Package URL defined."""
return self.filter(~models.Q(type="") & ~models.Q(name=""))

def with_vulnerability_count(self):
"""Annotate the QuerySet with the vulnerability_count."""
return self.annotate(
vulnerability_count=models.Count("affected_by_vulnerabilities", distinct=True)
)

def with_vulnerabilties(self):
"""Return vulnerable Packages."""
return self.annotate(
vulnerability_count=models.Count("affected_by_vulnerabilities")
).filter(vulnerability_count__gt=0)
return self.with_vulnerability_count().filter(vulnerability_count__gt=0)

def annotate_sortable_identifier(self):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
<a href="{% inject_preserved_filters object.details_url %}#activity" class="r-link"><span class="badge text-bg-request">R</span></a>
</li>
{% endif %}
{% if object.is_vulnerable %}
{% if object.vulnerability_count %}
<li class="list-inline-item">
{% include 'component_catalog/includes/vulnerability_icon_link.html' %}
{% include 'component_catalog/includes/vulnerability_icon_link.html' with count=object.vulnerability_count %}
</li>
{% endif %}
</ul>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<a href="{{ object.get_absolute_url }}#vulnerabilities" target="_blank" data-bs-toggle="tooltip" title="Vulnerabilities">
<i class="fas fa-bug vulnerability"></i>
<a href="{{ object.get_absolute_url }}#vulnerabilities" target="_blank" class="vulnerability" data-bs-toggle="tooltip" title="Vulnerabilities">
<i class="fas fa-bug"></i>{% if count %}{{ count }}{% endif %}
</a>
8 changes: 7 additions & 1 deletion component_catalog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,12 @@ class PackageListView(
include_reference_dataspace = True
put_results_in_session = True
table_headers = (
Header("sortable_identifier", _("Identifier"), Package.identifier_help()),
Header(
"sortable_identifier",
_("Identifier"),
Package.identifier_help(),
filter="is_vulnerable",
),
Header("usage_policy", _("Policy"), filter="usage_policy", condition=include_policy),
Header("license_expression", _("Concluded license"), filter="licenses"),
Header("primary_language", _("Language"), filter="primary_language"),
Expand Down Expand Up @@ -1081,6 +1086,7 @@ def get_queryset(self):
"dataspace",
)
.annotate_sortable_identifier()
.with_vulnerability_count()
.select_related(
"usage_policy",
)
Expand Down
13 changes: 8 additions & 5 deletions dje/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,16 +844,19 @@ class HasRelationFilter(django_filters.ChoiceFilter):
def __init__(self, *args, **kwargs):
kwargs["lookup_expr"] = "isnull"
kwargs["empty_label"] = "Any"
kwargs["choices"] = (
("with", _("With")),
("without", _("Without")),
kwargs.setdefault(
"choices",
(
("with", _("With")),
("without", _("Without")),
),
)
super().__init__(*args, **kwargs)

def filter(self, qs, value):
if value == "with":
if value in ["with", "yes"]:
return qs.filter(**{f"{self.field_name}__{self.lookup_expr}": False}).distinct()
elif value == "without":
elif value in ["without", "no"]:
return qs.filter(**{f"{self.field_name}__{self.lookup_expr}": True}).distinct()
return qs

Expand Down

0 comments on commit a352e00

Please sign in to comment.