Skip to content

Commit 364f8f8

Browse files
committed
progress on the triage tab
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent 293a6b4 commit 364f8f8

2 files changed

Lines changed: 109 additions & 31 deletions

File tree

product_portfolio/templates/product_portfolio/tabs/tab_triage.html

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,85 @@
1010
</div>
1111

1212
{% if page_obj.object_list %}
13-
<table class="table table-bordered table-md text-break">
14-
<thead>
13+
<table class="table table-hover">
14+
<thead class="table-light">
1515
<tr>
16-
<th>{% trans "Package" %}</th>
17-
<th>{% trans "Recommended action" %}</th>
18-
<th>{% trans "Ruleset" %}</th>
19-
<th>{% trans "Rules triggered" %}</th>
20-
<th>{% trans "Detected" %}</th>
16+
<th style="width: 38%">{% trans "Package" %}</th>
17+
<th style="width: 22%">{% trans "Recommended action" %}</th>
18+
<th>{% trans "Vulnerability exposure" %}</th>
19+
<th style="width: 10%" class="text-nowrap">{% trans "Detected" %}</th>
2120
</tr>
2221
</thead>
2322
<tbody>
2423
{% for record in page_obj.object_list %}
25-
<tr>
26-
<td>
27-
<strong>
28-
<a href="{{ record.product_package.package.get_absolute_url }}#vulnerabilities" target="_blank">
29-
{{ record.product_package.package }}
30-
</a>
31-
</strong>
24+
<tr class="align-top">
25+
<td class="py-3">
26+
<a class="fw-semibold text-decoration-none"
27+
href="{{ record.product_package.package.get_absolute_url }}#vulnerabilities"
28+
target="_blank">
29+
{{ record.product_package.package }}
30+
</a>
31+
<div class="d-flex flex-wrap gap-2 mt-2">
32+
{% with score=record.product_package.weighted_risk_score %}
33+
{% if score %}
34+
<span class="badge {% if score >= 8.0 %}bg-danger-subtle text-danger-emphasis{% elif score >= 6.0 %}bg-warning-subtle text-warning-emphasis{% elif score >= 3.0 %}bg-info-subtle text-info-emphasis{% else %}bg-secondary-subtle text-secondary-emphasis{% endif %}">
35+
{% trans "Risk" %} {{ score }}
36+
</span>
37+
{% endif %}
38+
{% endwith %}
39+
{% if record.product_package.is_deployed %}
40+
<span class="badge bg-body-tertiary text-body-secondary border">
41+
{% trans "Deployed" %}
42+
</span>
43+
{% endif %}
44+
{% if record.product_package.purpose %}
45+
<span class="badge bg-body-tertiary text-body-secondary border">
46+
{{ record.product_package.purpose.label }}
47+
</span>
48+
{% endif %}
49+
</div>
3250
</td>
33-
<td>
34-
<span class="badge bg-warning-subtle text-warning-emphasis">
35-
{{ record.action_label }}
36-
</span>
51+
<td class="py-3">
52+
<div>
53+
<span class="badge {{ record.action_badge_class }} px-2 py-1">
54+
<i class="fas {{ record.action_icon }} me-1"></i>{{ record.action_label }}
55+
</span>
56+
</div>
57+
<div class="small text-body-secondary mt-2">
58+
<i class="fas fa-layer-group fa-xs me-1"></i>{{ record.ruleset.name }}
59+
</div>
3760
</td>
38-
<td class="text-nowrap">{{ record.ruleset.name }}</td>
39-
<td>
40-
{% for label in record.rule_labels %}
41-
<div class="small">{{ label }}</div>
42-
{% endfor %}
61+
<td class="py-3">
62+
<div class="d-flex flex-wrap align-items-center gap-1">
63+
{% if record.critical_count %}
64+
<span class="badge bg-danger-subtle text-danger-emphasis">
65+
{{ record.critical_count }} {% trans "critical" %}
66+
</span>
67+
{% endif %}
68+
{% if record.high_count %}
69+
<span class="badge bg-warning-subtle text-warning-emphasis">
70+
{{ record.high_count }} {% trans "high" %}
71+
</span>
72+
{% endif %}
73+
{% if record.vulnerability_count and not record.critical_count and not record.high_count %}
74+
<span class="badge bg-warning-subtle text-warning-emphasis">
75+
{{ record.vulnerability_count }} {% trans "vulnerabilities" %}
76+
</span>
77+
{% endif %}
78+
</div>
79+
{% if record.vulnerability_count %}
80+
<div class="mt-2">
81+
<a href="{{ record.product_package.package.get_absolute_url }}#vulnerabilities"
82+
target="_blank"
83+
class="small text-body-secondary text-decoration-none">
84+
{{ record.vulnerability_count }} {% trans "total" %} &rarr;
85+
</a>
86+
</div>
87+
{% endif %}
88+
</td>
89+
<td class="py-3 small text-body-secondary text-nowrap">
90+
{{ record.detected_date|date:"N j, Y" }}
4391
</td>
44-
<td class="text-nowrap small text-body-secondary">{{ record.detected_date|date:"Y-m-d" }}</td>
4592
</tr>
4693
{% endfor %}
4794
</tbody>
@@ -53,6 +100,8 @@
53100
<div class="text-center py-5">
54101
<i class="fa-solid fa-circle-check text-success fs-2"></i>
55102
<div class="mt-2 fw-semibold">{% trans "No pending triage actions" %}</div>
56-
<div class="text-body-secondary small mt-1">{% trans "All packages are within acceptable risk parameters." %}</div>
103+
<div class="text-body-secondary small mt-1">
104+
{% trans "All packages are within acceptable risk parameters." %}
105+
</div>
57106
</div>
58107
{% endif %}

product_portfolio/views.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@
152152
from vulnerabilities.models import get_risk_level
153153
from vulnerabilities.triage.models import TriageAction
154154
from vulnerabilities.triage.models import TriageRecord
155-
from vulnerabilities.triage.rules import RULE_REGISTRY as TRIAGE_RULE_REGISTRY
156155

157156

158157
class BaseProductViewMixin:
@@ -1375,17 +1374,47 @@ def get_context_data(self, **kwargs):
13751374
product = self.object
13761375

13771376
action_labels = dict(TriageAction.choices)
1378-
rule_labels = {
1379-
rule_type: handler.label for rule_type, handler in TRIAGE_RULE_REGISTRY.items()
1377+
action_styles = {
1378+
"upgrade": ("bg-danger-subtle text-danger-emphasis", "fa-arrow-circle-up"),
1379+
"apply_patch": ("bg-danger-subtle text-danger-emphasis", "fa-wrench"),
1380+
"replace_package": ("bg-warning-subtle text-warning-emphasis", "fa-exchange-alt"),
1381+
"forensic_analysis": ("bg-warning-subtle text-warning-emphasis", "fa-search"),
1382+
"reachability_analysis": ("bg-warning-subtle text-warning-emphasis", "fa-sitemap"),
1383+
"change_config": ("bg-info-subtle text-info-emphasis", "fa-cog"),
1384+
"notify": ("bg-primary-subtle text-primary-emphasis", "fa-bell"),
1385+
"create_request": ("bg-secondary-subtle text-secondary-emphasis", "fa-file-alt"),
13801386
}
1387+
default_style = ("bg-secondary-subtle text-secondary-emphasis", "fa-exclamation-circle")
13811388

13821389
triage_qs = (
13831390
TriageRecord.objects.filter(product_package__product=product)
13841391
.primary_actions()
13851392
.select_related(
13861393
"product_package__package",
1394+
"product_package",
13871395
"ruleset",
13881396
)
1397+
.annotate(
1398+
vulnerability_count=Count(
1399+
"product_package__package__affected_by_vulnerabilities",
1400+
distinct=True,
1401+
),
1402+
critical_count=Count(
1403+
"product_package__package__affected_by_vulnerabilities",
1404+
filter=Q(
1405+
product_package__package__affected_by_vulnerabilities__risk_level="critical"
1406+
),
1407+
distinct=True,
1408+
),
1409+
high_count=Count(
1410+
"product_package__package__affected_by_vulnerabilities",
1411+
filter=Q(
1412+
product_package__package__affected_by_vulnerabilities__risk_level="high"
1413+
),
1414+
distinct=True,
1415+
),
1416+
)
1417+
.order_by("-product_package__weighted_risk_score")
13891418
)
13901419
total_count = triage_qs.count()
13911420

@@ -1395,9 +1424,9 @@ def get_context_data(self, **kwargs):
13951424

13961425
for record in page_obj.object_list:
13971426
record.action_label = action_labels.get(record.action, record.action)
1398-
record.rule_labels = [
1399-
rule_labels.get(rule_type, rule_type) for rule_type in record.matched_rules
1400-
]
1427+
badge_class, icon = action_styles.get(record.action, default_style)
1428+
record.action_badge_class = badge_class
1429+
record.action_icon = icon
14011430

14021431
context_data = super().get_context_data(**kwargs)
14031432
context_data.update(

0 commit comments

Comments
 (0)