diff --git a/component_catalog/models.py b/component_catalog/models.py index 30f3cf1a..a4fa55ac 100644 --- a/component_catalog/models.py +++ b/component_catalog/models.py @@ -2604,10 +2604,7 @@ class Vulnerability(HistoryDateFieldsMixin, DataspacedModel): help_text=_("A list of packages that are not affected by this vulnerability."), ) fixed_packages_length = models.GeneratedField( - expression=models.Func( - models.F('fixed_packages'), - function='jsonb_array_length' - ), + expression=models.Func(models.F("fixed_packages"), function="jsonb_array_length"), output_field=models.IntegerField(), db_persist=True, ) @@ -2656,3 +2653,46 @@ def create_from_data(cls, dataspace, data, validate=False, affecting=None): instance.add_affected(affecting) return instance + + def get_severities(self): + return [score for reference in self.references for score in reference.get("scores", [])] + + # Duplicated from + # https://github.com/aboutcode-org/vulnerablecode/blob/main/vulnerabilities/utils.py + # Until made available in the API https://github.com/aboutcode-org/vulnerablecode/issues/1565 + def get_severity_range(self): + severities = self.get_severities() + if len(severities) < 1: + return + + scores = self.get_severity_scores(severities) + if scores: + return f"{min(scores)} - {max(scores)}" + + @staticmethod + def get_severity_scores(severities): + score_map = { + "low": [0.1, 3], + "moderate": [4.0, 6.9], + "medium": [4.0, 6.9], + "high": [7.0, 8.9], + "important": [7.0, 8.9], + "critical": [9.0, 10.0], + } + + consolidated_scores = [] + for severity in severities: + score = severity.get("value") + try: + consolidated_scores.append(float(score)) + except ValueError: + if score_range := score_map.get(score.lower(), None): + consolidated_scores.extend(score_range) + + return consolidated_scores + + def get_highest_score(self): + severities = self.get_severities() + scores = self.get_severity_scores(severities) + if scores: + return max(scores) diff --git a/component_catalog/templates/component_catalog/includes/vulnerability_list_table.html b/component_catalog/templates/component_catalog/includes/vulnerability_list_table.html index 0d6bf5d2..2a6e5392 100644 --- a/component_catalog/templates/component_catalog/includes/vulnerability_list_table.html +++ b/component_catalog/templates/component_catalog/includes/vulnerability_list_table.html @@ -3,15 +3,14 @@ {% load urlize_target_blank from dje_tags %} {% load naturaltime_short from dje_tags %} -
- {# TODO #}
-
+
{{ vulnerability.vulnerability_id }}
@@ -20,6 +19,22 @@
{% include 'component_catalog/includes/vulnerability_aliases.html' with aliases=vulnerability.aliases only %}
|
+
+ {{ vulnerability.get_highest_score }}
+ |
+ Range: {{ vulnerability.get_severity_range }}
+
+ {% if vulnerability.summary %}
+ {% if vulnerability.summary|length > 120 %}
+ |
+
+ {% else %}
+ {{ vulnerability.summary }}
+ {% endif %}
+ {% endif %}
+ {{ vulnerability.summary|slice:":120" }}...+ {{ vulnerability.summary|slice:"120:" }} +
{{ vulnerability.affected_packages_count }}
|
diff --git a/component_catalog/views.py b/component_catalog/views.py
index fd2285a6..422ed3a7 100644
--- a/component_catalog/views.py
+++ b/component_catalog/views.py
@@ -2491,9 +2491,10 @@ class VulnerabilityListView(
table_headers = (
Header("vulnerability_id", _("Vulnerability")),
Header("aliases", _("Aliases")),
- # Header("score"),
- Header("affected_packages_count", "Affected packages", help_text=" "),
- Header("fixed_packages_length", "Fixed by packages", help_text=" "),
+ Header("score", _("Severity score"), help_text="TODO"),
+ Header("summary", _("Summary")),
+ Header("affected_packages_count", "Affected packages", help_text="TODO"),
+ Header("fixed_packages_length", "Fixed by packages", help_text="TODO"),
# Header("affected_product_count", "Affected products"),
)
@@ -2501,15 +2502,16 @@ def get_queryset(self):
return (
super()
.get_queryset()
- .only(
- "uuid",
- "vulnerability_id",
- "aliases",
- "fixed_packages_length",
- "created_date",
- "last_modified_date",
- "dataspace",
- )
+ # .only(
+ # "uuid",
+ # "vulnerability_id",
+ # "aliases",
+ # "summary",
+ # "fixed_packages_length",
+ # "created_date",
+ # "last_modified_date",
+ # "dataspace",
+ # )
.annotate(
affected_packages_count=Count("affected_packages"),
)
@@ -2517,3 +2519,9 @@ def get_queryset(self):
"-last_modified_date",
)
)
+
+ def get_context_data(self, **kwargs):
+ context_data = super().get_context_data(**kwargs)
+ vulnerablecode = VulnerableCode(self.dataspace)
+ context_data["vulnerablecode_url"] = vulnerablecode.service_url
+ return context_data
diff --git a/dejacode/static/css/dejacode_bootstrap.css b/dejacode/static/css/dejacode_bootstrap.css
index 26bf7b52..1fdd2907 100644
--- a/dejacode/static/css/dejacode_bootstrap.css
+++ b/dejacode/static/css/dejacode_bootstrap.css
@@ -358,6 +358,15 @@ table.packages-table .column-primary_language {
margin-right: 0.3rem;
}
+/* -- Vulnerability List -- */
+table.vulnerabilities-table .column-vulnerability_id {
+ width: 220px;
+}
+table.vulnerabilities-table .column-summary {
+ width: 300px;
+ max-width: 300px;
+}
+
/* -- Package Details -- */
textarea.licenseexpressionwidget {
height: 62px;
|