Skip to content

Commit

Permalink
Add severity score in the list #95
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <tdruez@nexb.com>
  • Loading branch information
tdruez committed Aug 23, 2024
1 parent e64fbf9 commit f23efb7
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 19 deletions.
48 changes: 44 additions & 4 deletions component_catalog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand Down Expand Up @@ -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)
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
{% load urlize_target_blank from dje_tags %}
{% load naturaltime_short from dje_tags %}

<table id="object-list-table" class="table table-bordered table-striped table-md table-fixed-layout text-break vulnerabilities-table">
<table id="object-list-table" class="table table-bordered table-striped table-md text-break vulnerabilities-table">
{% include 'includes/object_list_table_header.html' %}
<tbody>
{% for vulnerability in object_list %}
<tr>
<td>
<strong>
{# TODO #}
<a href="{{ values.vulnerablecode_url }}vulnerabilities/{{ vulnerability.vulnerability_id }}" target="_blank">
<a href="{{ vulnerablecode_url }}vulnerabilities/{{ vulnerability.vulnerability_id }}" target="_blank">
{{ vulnerability.vulnerability_id }}
<i class="fa-solid fa-up-right-from-square mini"></i>
</a>
Expand All @@ -20,6 +19,22 @@
<td>
{% include 'component_catalog/includes/vulnerability_aliases.html' with aliases=vulnerability.aliases only %}
</td>
<td>
<strong>{{ vulnerability.get_highest_score }}</strong>
<div>Range: {{ vulnerability.get_severity_range }}</div>
</td>
<td>
{% if vulnerability.summary %}
{% if vulnerability.summary|length > 120 %}
<details>
<summary>{{ vulnerability.summary|slice:":120" }}...</summary>
{{ vulnerability.summary|slice:"120:" }}
</details>
{% else %}
{{ vulnerability.summary }}
{% endif %}
{% endif %}
</td>
<td>
{{ vulnerability.affected_packages_count }}
</td>
Expand Down
32 changes: 20 additions & 12 deletions component_catalog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2491,29 +2491,37 @@ 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"),
)

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"),
)
.order_by(
"-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
9 changes: 9 additions & 0 deletions dejacode/static/css/dejacode_bootstrap.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit f23efb7

Please sign in to comment.