Skip to content

Commit a248c9c

Browse files
Improve license detection and summary related views
Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
1 parent 225c216 commit a248c9c

File tree

8 files changed

+230
-52
lines changed

8 files changed

+230
-52
lines changed

scanpipe/filters.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ class ResourceFilterSet(FilterSetUtilsMixin, django_filters.FilterSet):
492492
dropdown_widget_fields = [
493493
"status",
494494
"type",
495+
"programming_language",
495496
"tag",
496497
"compliance_alert",
497498
"in_package",
@@ -521,6 +522,7 @@ class ResourceFilterSet(FilterSetUtilsMixin, django_filters.FilterSet):
521522
"related_from__from_resource__path",
522523
],
523524
)
525+
programming_language = django_filters.AllValuesFilter()
524526
compliance_alert = django_filters.ChoiceFilter(
525527
choices=[(EMPTY_VAR, "None")] + CodebaseResource.Compliance.choices,
526528
)
@@ -577,8 +579,8 @@ class Meta:
577579

578580
def __init__(self, *args, **kwargs):
579581
super().__init__(*args, **kwargs)
580-
license_expression_filer = self.filters["detected_license_expression"]
581-
license_expression_filer.extra["widget"] = HasValueDropdownWidget()
582+
license_expression_filter = self.filters["detected_license_expression"]
583+
license_expression_filter.extra["widget"] = HasValueDropdownWidget()
582584

583585
@classmethod
584586
def filter_for_lookup(cls, field, lookup_type):

scanpipe/models.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,13 @@ def resource_count(self):
13171317
"""Return the number of resources related to this project."""
13181318
return self.codebaseresources.count()
13191319

1320+
@cached_property
1321+
def resource_compliance_alert_count(self):
1322+
"""Return the number of resources related to this project which have
1323+
a license compliance error alert.
1324+
"""
1325+
return self.codebaseresources.has_compliance_alert().count()
1326+
13201327
@cached_property
13211328
def file_count(self):
13221329
"""Return the number of **file** resources related to this project."""
@@ -1365,14 +1372,28 @@ def license_detections_count(self):
13651372

13661373
@cached_property
13671374
def package_compliance_alert_count(self):
1368-
"""Return the number of packages related to this project which have."""
1375+
"""
1376+
Return the number of packages related to this project which have
1377+
a license compliance error alert.
1378+
"""
13691379
return self.discoveredpackages.has_compliance_alert().count()
13701380

13711381
@cached_property
13721382
def license_compliance_alert_count(self):
1373-
"""Return the number of packages related to this project which have."""
1383+
"""
1384+
Return the number of license detections related to this project
1385+
which have a license compliance error alert.
1386+
"""
13741387
return self.discoveredlicenses.has_compliance_alert().count()
13751388

1389+
@cached_property
1390+
def resource_compliance_alert_count(self):
1391+
"""
1392+
Return the number of codebase resources related to this project which have
1393+
a license compliance error alert.
1394+
"""
1395+
return self.codebaseresources.has_compliance_alert().count()
1396+
13761397
@cached_property
13771398
def message_count(self):
13781399
"""Return the number of messages related to this project."""
@@ -2042,7 +2063,15 @@ def convert_glob_to_django_regex(glob_pattern):
20422063
return escaped_pattern
20432064

20442065

2045-
class CodebaseResourceQuerySet(ProjectRelatedQuerySet):
2066+
class ComplianceAlertQuerySetMixin:
2067+
def has_compliance_alert(self):
2068+
return self.filter(Q(compliance_alert__exact=CodebaseResource.Compliance.ERROR))
2069+
2070+
2071+
class CodebaseResourceQuerySet(
2072+
ComplianceAlertQuerySetMixin,
2073+
ProjectRelatedQuerySet,
2074+
):
20462075
def prefetch_for_serializer(self):
20472076
"""
20482077
Optimized prefetching for a QuerySet to be consumed by the
@@ -2945,11 +2974,6 @@ def vulnerable(self):
29452974
return self.filter(~Q(affected_by_vulnerabilities__in=EMPTY_VALUES))
29462975

29472976

2948-
class ComplianceAlertQuerySetMixin:
2949-
def has_compliance_alert(self):
2950-
return self.filter(Q(compliance_alert__exact=CodebaseResource.Compliance.ERROR))
2951-
2952-
29532977
class DiscoveredPackageQuerySet(
29542978
VulnerabilityQuerySetMixin,
29552979
ComplianceAlertQuerySetMixin,

scanpipe/templates/scanpipe/includes/project_summary_level.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,17 @@
4949
<div class="level-item has-text-centered">
5050
<div>
5151
<p class="heading">Resources</p>
52-
<p class="{{ title_class }}">
52+
<p class="{{ title_class }} is-flex is-align-items-center is-justify-content-center">
5353
{% if project.resource_count %}
5454
<a href="{{ project_resources_url }}">
5555
{{ project.resource_count|intcomma }}
5656
</a>
57+
{% if project.resource_compliance_alert_count %}
58+
<a href="{% url 'project_resources' project.slug %}?compliance_alert=error" class="has-text-danger is-size-5 ml-2">
59+
{{ project.resource_compliance_alert_count|intcomma }}
60+
<i class="fa-solid fa-scale-balanced is-size-6"></i>
61+
</a>
62+
{% endif %}
5763
{% else %}
5864
<span>0</span>
5965
{% endif %}

scanpipe/templates/scanpipe/license_detection_list.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<a href="{% url 'license_detail' project.slug license_detection.identifier %}">{{ license_detection.identifier }}</a>
2727
{% if license_detection.has_compliance_alert %}
2828
<a href="{% url 'license_detail' project.slug license_detection.identifier %}#detection">
29-
<i class="fa-solid fa-scale-balanced fa-sm has-text-danger" title="License Compliance Error"></i>
29+
<i class="fa-solid fa-scale-balanced fa-sm has-text-danger" title="License Compliance Alerts"></i>
3030
</a>
3131
{% endif %}
3232
</td>

scanpipe/templates/scanpipe/panels/license_detections_summary.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,29 @@
33
<div class="column is-half">
44
<nav class="panel is-info">
55
<p class="panel-heading py-2 is-size-6">
6-
Top 10 Unique License detections
6+
Unique License detections
77
</p>
88
{% for license_expression, count in license_detection_summary.items %}
9-
<a class="panel-block is-align-items-flex-start break-word" href="{{ project_licenses_url }}?license_expression={{ license_expression|default:'_EMPTY_' }}" target="_blank">
9+
<a class="panel-block is-align-items-flex-start break-word is-flex is-align-items-center" href="{{ project_licenses_url }}?license_expression={{ license_expression|default:'_EMPTY_' }}" target="_blank">
1010
{{ license_expression|default:'<i>No licenses</i>' }}
1111
<span class="tag is-rounded ml-1">{{ count|intcomma }}</span>
1212
{% if license_expression in expressions_with_compliance_alert %}
13-
&nbsp; <span class="fa-solid fa-scale-balanced has-text-danger" title="License Compliance Error"></span>
13+
&nbsp; <span class="fa-solid fa-scale-balanced has-text-danger" title="License Compliance Alerts"></span>
1414
{% endif %}
1515
</a>
1616
{% endfor %}
17+
{% if total_counts.all %}
18+
<a class="panel-block is-align-items-flex-start break-word is-flex is-align-items-center" href="{{ project_licenses_url }}" target="_blank">
19+
See all License Detections
20+
<span class="tag is-rounded ml-1">{{ total_counts.all|intcomma }}</span>
21+
{% if total_counts.with_compliance_error %}
22+
<span class="has-text-danger is-size-6 ml-2">
23+
<i class="fa-solid fa-scale-balanced fa-sm"></i>
24+
{{ total_counts.with_compliance_error|intcomma }}
25+
</span>
26+
{% endif %}
27+
</a>
28+
{% endif %}
1729
</nav>
1830
</div>
1931
{% endif %}

scanpipe/templates/scanpipe/panels/scan_summary_panel.html

Lines changed: 147 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,80 @@
66
</div>
77
<div class="panel-block p-0">
88
<table class="table is-fullwidth border-bottom-radius">
9-
{% for field_label, values in scan_summary.items %}
10-
<tr>
11-
<th class="is-narrow">
12-
{{ field_label }}
13-
</th>
14-
<td>
15-
<ul>
16-
{% for entry in values %}
17-
{% if entry.value %}
9+
<tr>
10+
<th class="is-narrow">
11+
Declared license
12+
</th>
13+
<td>
14+
<ul>
15+
{% for entry in scan_summary.declared_license_expression %}
16+
{% if entry.value %}
17+
<li>
18+
{{ entry.value }}
19+
{% if entry.count %}
20+
<span class="tag is-rounded">
21+
{{ entry.count|intcomma }}
22+
</span>
23+
{% endif %}
24+
</li>
25+
{% endif %}
26+
{% endfor %}
27+
</ul>
28+
</td>
29+
</tr>
30+
<tr>
31+
<th class="is-narrow">
32+
Declared holder
33+
</th>
34+
<td>
35+
<ul>
36+
{% for entry in scan_summary.declared_holder %}
37+
{% if entry.value %}
38+
<li>
39+
{{ entry.value }}
40+
{% if entry.count %}
41+
<span class="tag is-rounded">
42+
{{ entry.count|intcomma }}
43+
</span>
44+
{% endif %}
45+
</li>
46+
{% endif %}
47+
{% endfor %}
48+
</ul>
49+
</td>
50+
</tr>
51+
<tr>
52+
<th class="is-narrow">
53+
Primary language
54+
</th>
55+
<td>
56+
<ul>
57+
{% for entry in scan_summary.primary_language %}
58+
{% if entry.value %}
59+
<li>
60+
<a href="{% url 'project_resources' project.slug %}?programming_language={{ entry.value }}" target="_blank">
61+
{{ entry.value }}
62+
{% if entry.count %}
63+
<span class="tag is-rounded">
64+
{{ entry.count|intcomma }}
65+
</span>
66+
{% endif %}
67+
</a>
68+
</li>
69+
{% endif %}
70+
{% endfor %}
71+
</ul>
72+
</td>
73+
</tr>
74+
<tr>
75+
<th class="is-narrow">
76+
Other licenses
77+
</th>
78+
<td>
79+
<ul>
80+
{% for entry in scan_summary.other_license_expressions %}
81+
{% if entry.value %}
82+
<a href="{% url 'project_licenses' project.slug %}?license_expression={{ entry.value }}" target="_blank">
1883
<li>
1984
{{ entry.value }}
2085
{% if entry.count %}
@@ -23,12 +88,79 @@
2388
</span>
2489
{% endif %}
2590
</li>
26-
{% endif %}
27-
{% endfor %}
28-
</ul>
29-
</td>
30-
</tr>
31-
{% endfor %}
91+
</a>
92+
{% endif %}
93+
{% endfor %}
94+
</ul>
95+
</td>
96+
</tr>
97+
<tr>
98+
<th class="is-narrow">
99+
Other holders
100+
</th>
101+
<td>
102+
<ul>
103+
{% for entry in scan_summary.other_holders %}
104+
{% if entry.value %}
105+
<li>
106+
{{ entry.value }}
107+
{% if entry.count %}
108+
<span class="tag is-rounded">
109+
{{ entry.count|intcomma }}
110+
</span>
111+
{% endif %}
112+
</li>
113+
{% endif %}
114+
{% endfor %}
115+
</ul>
116+
</td>
117+
</tr>
118+
<tr>
119+
<th class="is-narrow">
120+
Other languages
121+
</th>
122+
<td>
123+
<ul>
124+
{% for entry in scan_summary.other_languages %}
125+
{% if entry.value %}
126+
<a href="{% url 'project_resources' project.slug %}?programming_language={{ entry.value }}" target="_blank">
127+
<li>
128+
{{ entry.value }}
129+
{% if entry.count %}
130+
<span class="tag is-rounded">
131+
{{ entry.count|intcomma }}
132+
</span>
133+
{% endif %}
134+
</li>
135+
</a>
136+
{% endif %}
137+
{% endfor %}
138+
</ul>
139+
</td>
140+
</tr>
141+
<tr>
142+
<th class="is-narrow">
143+
Key Files
144+
</th>
145+
<td>
146+
<ul>
147+
{% for path, license in scan_summary.key_file_licenses.items %}
148+
{% if path %}
149+
<a href="{% url 'resource_detail' project.slug path %}#detection" target="_blank">
150+
<li>
151+
{{ path }}
152+
{% if license %}
153+
<span class="tag is-rounded">
154+
{{ license }}
155+
</span>
156+
{% endif %}
157+
</li>
158+
</a>
159+
{% endif %}
160+
{% endfor %}
161+
</ul>
162+
</td>
163+
</tr>
32164
</table>
33165
</div>
34166
</article>

scanpipe/templates/scanpipe/tabset/tab_license_detections.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
{{ match.license_expression }}
2020
</td>
2121
<td class="break-all">
22-
{{ match.from_file }}
22+
<a href="{% url 'resource_detail' project.slug match.from_file %}#detection">{{ match.from_file }}</a>
2323
</td>
2424
<td class="break-all">
2525
{{ match.rule_url }}
@@ -73,7 +73,7 @@
7373
{% for file_region in tab_data.fields.file_regions.value %}
7474
<tr>
7575
<td class="break-all">
76-
{{ file_region.path }}
76+
<a href="{% url 'resource_detail' project.slug file_region.path %}#detection">{{ file_region.path }}</a>
7777
</td>
7878
<td class="break-all">
7979
{{ file_region.start_line }}

0 commit comments

Comments
 (0)