Skip to content

Commit

Permalink
Add vulnerabilities_risk_threshold to the Product model #97
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <tdruez@nexb.com>
  • Loading branch information
tdruez committed Dec 13, 2024
1 parent 2ea7f70 commit 61a47e3
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 8 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Release notes
new `data` dict.
https://github.com/aboutcode-org/dejacode/issues/202

- Add `vulnerabilities_risk_threshold` field to the DataspaceConfiguration model.
- Add the `vulnerabilities_risk_threshold` field to the Product and
DataspaceConfiguration models.
This threshold helps prioritize and control the level of attention to vulnerabilities.
https://github.com/aboutcode-org/dejacode/issues/97

Expand Down
1 change: 1 addition & 0 deletions product_portfolio/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ class ProductAdmin(
"is_active",
"configuration_status",
"contact",
"vulnerabilities_risk_threshold",
"get_feature_datalist",
)
},
Expand Down
1 change: 1 addition & 0 deletions product_portfolio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class Meta:
"primary_language",
"admin_notes",
"notice_text",
"vulnerabilities_risk_threshold",
"created_date",
"last_modified_date",
)
Expand Down
3 changes: 3 additions & 0 deletions product_portfolio/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class Meta:
"configuration_status",
"contact",
"keywords",
"vulnerabilities_risk_threshold",
]
field_classes = {
"owner": OwnerChoiceField,
Expand Down Expand Up @@ -170,6 +171,8 @@ def helper(self):
HTML("<hr>"),
Group("is_active", "configuration_status", "release_date"),
HTML("<hr>"),
Group("vulnerabilities_risk_threshold", "", ""),
HTML("<hr>"),
Submit("submit", self.submit_label, css_class="btn-success"),
self.save_as_new_submit,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.9 on 2024-12-13 13:01

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('product_portfolio', '0008_productdependency_is_resolved_to_is_pinned'),
]

operations = [
migrations.AddField(
model_name='product',
name='vulnerabilities_risk_threshold',
field=models.DecimalField(blank=True, decimal_places=1, help_text='Enter a risk value between 0.0 and 10.0. This threshold helps prioritize and control the level of attention to vulnerabilities.', max_digits=3, null=True),
),
]
21 changes: 21 additions & 0 deletions product_portfolio/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,17 @@ class Product(BaseProductMixin, FieldChangesMixin, KeywordsMixin, DataspacedMode
),
)

vulnerabilities_risk_threshold = models.DecimalField(
null=True,
blank=True,
max_digits=3,
decimal_places=1,
help_text=_(
"Enter a risk value between 0.0 and 10.0. This threshold helps prioritize "
"and control the level of attention to vulnerabilities."
),
)

licenses = models.ManyToManyField(
to="license_library.License",
through="ProductAssignedLicense",
Expand Down Expand Up @@ -338,6 +349,16 @@ def all_packages(self):
def vulnerability_count(self):
return self.get_vulnerability_qs().count()

def get_vulnerabilities_risk_threshold(self):
"""
Return the local vulnerabilities_risk_threshold value when defined on the
Product or look into the Dataspace configuration.
"""
risk_threshold = self.vulnerabilities_risk_threshold
if not risk_threshold:
risk_threshold = self.dataspace.get_configuration("vulnerabilities_risk_threshold")
return risk_threshold

def get_merged_descendant_ids(self):
"""
Return a list of Component ids collected on the Product descendants:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
</td>
<td class="text-center">
{% if package.vulnerability_analysis.is_reachable %}
<i class="fa-solid fa-circle-radiation text-danger fs-5" data-bs-toggle="tooltip" title="Vulnerability is reachable"></i>
<i class="fa-solid fa-circle-radiation text-danger fs-6" data-bs-toggle="tooltip" title="Vulnerability is reachable"></i>
{% elif package.vulnerability_analysis.is_reachable is False %}
<i class="fa-solid fa-bug-slash" data-bs-toggle="tooltip" title="Vulnerability is NOT reachable"></i>
{% endif %}
Expand Down
13 changes: 7 additions & 6 deletions product_portfolio/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,16 +531,18 @@ def tab_dependencies(self):
}

def tab_vulnerabilities(self):
dataspace = self.object.dataspace
vulnerablecode = VulnerableCode(self.object.dataspace)
product = self.object
dataspace = product.dataspace
vulnerablecode = VulnerableCode(dataspace)
display_tab_contions = [
dataspace.enable_vulnerablecodedb_access,
vulnerablecode.is_configured(),
]
if not all(display_tab_contions):
return

vulnerability_count = self.object.vulnerability_count
risk_threshold = product.get_vulnerabilities_risk_threshold()
vulnerability_count = product.get_vulnerability_qs(risk_threshold=risk_threshold).count()
if not vulnerability_count:
label = 'Vulnerabilities <span class="badge bg-secondary">0</span>'
return {
Expand All @@ -555,7 +557,7 @@ def tab_vulnerabilities(self):
)

# Pass the current request query context to the async request
tab_view_url = self.object.get_url("tab_vulnerabilities")
tab_view_url = product.get_url("tab_vulnerabilities")
if full_query_string := self.request.META["QUERY_STRING"]:
tab_view_url += f"?{full_query_string}"

Expand Down Expand Up @@ -1151,8 +1153,7 @@ class ProductTabVulnerabilitiesView(

def get_context_data(self, **kwargs):
product = self.object
dataspace = self.object.dataspace
risk_threshold = dataspace.get_configuration("vulnerabilities_risk_threshold")
risk_threshold = product.get_vulnerabilities_risk_threshold()

total_count = product.get_vulnerability_qs(risk_threshold=risk_threshold).count()
vulnerability_qs = (
Expand Down

0 comments on commit 61a47e3

Please sign in to comment.