Skip to content

Commit f32fcef

Browse files
authored
Move the vulnerabilities related code to its own module #95 (#177)
Signed-off-by: tdruez <[email protected]>
1 parent 29c7d32 commit f32fcef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1315
-852
lines changed

component_catalog/filters.py

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
from django import forms
1010
from django.contrib.admin.options import IncorrectLookupParameters
11-
from django.db.models import F
1211
from django.utils.functional import cached_property
1312
from django.utils.translation import gettext_lazy as _
1413

@@ -17,14 +16,12 @@
1716
from component_catalog.models import Component
1817
from component_catalog.models import ComponentKeyword
1918
from component_catalog.models import Package
20-
from component_catalog.models import Vulnerability
2119
from component_catalog.programming_languages import PROGRAMMING_LANGUAGES
2220
from dje.filters import DataspacedFilterSet
2321
from dje.filters import DefaultOrderingFilter
2422
from dje.filters import HasRelationFilter
2523
from dje.filters import MatchOrderedSearchFilter
2624
from dje.filters import RelatedLookupListFilter
27-
from dje.filters import SearchFilter
2825
from dje.widgets import BootstrapSelectMultipleWidget
2926
from dje.widgets import DropDownRightWidget
3027
from dje.widgets import SortDropDownWidget
@@ -283,82 +280,3 @@ def show_created_date(self):
283280
@cached_property
284281
def show_last_modified_date(self):
285282
return not self.sort_value or self.has_sort_by("last_modified_date")
286-
287-
288-
class NullsLastOrderingFilter(django_filters.OrderingFilter):
289-
"""
290-
A custom ordering filter that ensures null values are sorted last.
291-
292-
When sorting by fields with potential null values, this filter modifies the
293-
ordering to use Django's `nulls_last` clause for better handling of null values,
294-
whether in ascending or descending order.
295-
"""
296-
297-
def filter(self, qs, value):
298-
if not value:
299-
return qs
300-
301-
ordering = []
302-
for field in value:
303-
if field.startswith("-"):
304-
field_name = field[1:]
305-
ordering.append(F(field_name).desc(nulls_last=True))
306-
else:
307-
ordering.append(F(field).asc(nulls_last=True))
308-
309-
return qs.order_by(*ordering)
310-
311-
312-
vulnerability_score_ranges = {
313-
"low": (0.1, 3),
314-
"medium": (4.0, 6.9),
315-
"high": (7.0, 8.9),
316-
"critical": (9.0, 10.0),
317-
}
318-
319-
SCORE_CHOICES = [
320-
(key, f"{key.capitalize()} ({value[0]} - {value[1]})")
321-
for key, value in vulnerability_score_ranges.items()
322-
]
323-
324-
325-
class VulnerabilityFilterSet(DataspacedFilterSet):
326-
q = SearchFilter(
327-
label=_("Search"),
328-
search_fields=["vulnerability_id", "aliases"],
329-
)
330-
sort = NullsLastOrderingFilter(
331-
label=_("Sort"),
332-
fields=[
333-
"max_score",
334-
"min_score",
335-
"affected_products_count",
336-
"affected_packages_count",
337-
"fixed_packages_count",
338-
"created_date",
339-
"last_modified_date",
340-
],
341-
widget=SortDropDownWidget,
342-
)
343-
max_score = django_filters.ChoiceFilter(
344-
choices=SCORE_CHOICES,
345-
method="filter_by_score_range",
346-
label="Score Range",
347-
help_text="Select a score range to filter.",
348-
)
349-
350-
class Meta:
351-
model = Vulnerability
352-
fields = [
353-
"q",
354-
]
355-
356-
def __init__(self, *args, **kwargs):
357-
super().__init__(*args, **kwargs)
358-
self.filters["max_score"].extra["widget"] = DropDownRightWidget(anchor=self.anchor)
359-
360-
def filter_by_score_range(self, queryset, name, value):
361-
if value in vulnerability_score_ranges:
362-
low, high = vulnerability_score_ranges[value]
363-
return queryset.filter(max_score__gte=low, max_score__lte=high)
364-
return queryset

component_catalog/importers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
from component_catalog.models import Package
3131
from component_catalog.models import Subcomponent
3232
from component_catalog.programming_languages import PROGRAMMING_LANGUAGES
33-
from component_catalog.vulnerabilities import fetch_for_queryset
3433
from dje.fields import SmartFileField
3534
from dje.forms import JSONListField
3635
from dje.importers import BaseImporter
@@ -42,6 +41,7 @@
4241
from policy.models import UsagePolicy
4342
from product_portfolio.models import ProductComponent
4443
from product_portfolio.models import ProductPackage
44+
from vulnerabilities.fetch import fetch_for_queryset
4545

4646
keywords_help = (
4747
get_help_text(Component, "keywords")
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 5.0.6 on 2024-09-04 08:17
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('component_catalog', '0007_vulnerability_fixed_packages_count_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='package',
15+
name='affected_by_vulnerabilities',
16+
),
17+
migrations.RemoveField(
18+
model_name='component',
19+
name='affected_by_vulnerabilities',
20+
),
21+
migrations.DeleteModel(
22+
name='Vulnerability',
23+
),
24+
]
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Generated by Django 5.0.6 on 2024-09-04 09:22
2+
3+
import django.db.models.deletion
4+
import uuid
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('component_catalog', '0008_remove_package_affected_by_vulnerabilities_and_more'),
12+
('dje', '0004_dataspace_vulnerabilities_updated_at'),
13+
('vulnerabilities', '0001_initial'),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name='ComponentAffectedByVulnerability',
19+
fields=[
20+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21+
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='UUID')),
22+
('component', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='component_catalog.component')),
23+
('dataspace', models.ForeignKey(editable=False, help_text='A Dataspace is an independent, exclusive set of DejaCode data, which can be either nexB master reference data or installation-specific data.', on_delete=django.db.models.deletion.PROTECT, to='dje.dataspace')),
24+
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.vulnerability')),
25+
],
26+
options={
27+
'unique_together': {('component', 'vulnerability'), ('dataspace', 'uuid')},
28+
},
29+
),
30+
migrations.AddField(
31+
model_name='component',
32+
name='affected_by_vulnerabilities',
33+
field=models.ManyToManyField(help_text='Vulnerabilities affecting this object.', related_name='affected_%(class)ss', through='component_catalog.ComponentAffectedByVulnerability', to='vulnerabilities.vulnerability'),
34+
),
35+
migrations.CreateModel(
36+
name='PackageAffectedByVulnerability',
37+
fields=[
38+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
39+
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='UUID')),
40+
('dataspace', models.ForeignKey(editable=False, help_text='A Dataspace is an independent, exclusive set of DejaCode data, which can be either nexB master reference data or installation-specific data.', on_delete=django.db.models.deletion.PROTECT, to='dje.dataspace')),
41+
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='component_catalog.package')),
42+
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.vulnerability')),
43+
],
44+
options={
45+
'unique_together': {('dataspace', 'uuid'), ('package', 'vulnerability')},
46+
},
47+
),
48+
migrations.AddField(
49+
model_name='package',
50+
name='affected_by_vulnerabilities',
51+
field=models.ManyToManyField(help_text='Vulnerabilities affecting this object.', related_name='affected_%(class)ss', through='component_catalog.PackageAffectedByVulnerability', to='vulnerabilities.vulnerability'),
52+
),
53+
]

0 commit comments

Comments
 (0)