Skip to content

Commit feab9fd

Browse files
authored
Merge pull request #1612 from aboutcode-org/new-models
Segregate PackageRelatedVulnerability model to new models
2 parents 9910bef + 5081691 commit feab9fd

19 files changed

+420
-252
lines changed

vulnerabilities/admin.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
from vulnerabilities.models import ApiUser
1515
from vulnerabilities.models import Package
16-
from vulnerabilities.models import PackageRelatedVulnerability
1716
from vulnerabilities.models import Vulnerability
1817
from vulnerabilities.models import VulnerabilityReference
1918
from vulnerabilities.models import VulnerabilitySeverity
@@ -35,12 +34,6 @@ class PackageAdmin(admin.ModelAdmin):
3534
search_fields = ["name"]
3635

3736

38-
@admin.register(PackageRelatedVulnerability)
39-
class PackageRelatedVulnerabilityAdmin(admin.ModelAdmin):
40-
list_filter = ("package__type", "package__namespace")
41-
search_fields = ["vulnerability__vulnerability_id", "package__name"]
42-
43-
4437
@admin.register(VulnerabilitySeverity)
4538
class VulnerabilitySeverityAdmin(admin.ModelAdmin):
4639
pass

vulnerabilities/api.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def get_fixed_packages(self, package):
287287
type=package.type,
288288
qualifiers=package.qualifiers,
289289
subpath=package.subpath,
290-
packagerelatedvulnerability__fix=True,
290+
fixingpackagerelatedvulnerability__isnull=False,
291291
)
292292
.with_is_vulnerable()
293293
.distinct()
@@ -300,10 +300,13 @@ def get_vulnerabilities_for_a_package(self, package, fix) -> dict:
300300
otherwise return vulnerabilities fixed by the `package`.
301301
"""
302302
fixed_packages = self.get_fixed_packages(package=package)
303-
qs = package.vulnerabilities.filter(packagerelatedvulnerability__fix=fix)
303+
if fix:
304+
qs = package.affected_by_vulnerabilities.all()
305+
else:
306+
qs = package.fixing_vulnerabilities.all()
304307
qs = qs.prefetch_related(
305308
Prefetch(
306-
"packages",
309+
"fixed_by_packages",
307310
queryset=fixed_packages,
308311
to_attr="filtered_fixed_packages",
309312
)
@@ -372,7 +375,6 @@ class Meta:
372375
"qualifiers",
373376
"subpath",
374377
"purl",
375-
"packagerelatedvulnerability__fix",
376378
]
377379

378380
def filter_purl(self, queryset, name, value):
@@ -590,7 +592,11 @@ def get_fixed_packages_qs(self):
590592
Filter the packages that fixes a vulnerability
591593
on fields like name, namespace and type.
592594
"""
593-
return self.get_packages_qs().filter(packagerelatedvulnerability__fix=True)
595+
return (
596+
self.get_packages_qs()
597+
.filter(fixingpackagerelatedvulnerability__isnull=False)
598+
.with_is_vulnerable()
599+
)
594600

595601
def get_packages_qs(self):
596602
"""
@@ -613,13 +619,9 @@ def get_queryset(self):
613619
super()
614620
.get_queryset()
615621
.prefetch_related(
616-
Prefetch(
617-
"packages",
618-
queryset=self.get_packages_qs(),
619-
),
620622
"weaknesses",
621623
Prefetch(
622-
"packages",
624+
"fixed_by_packages",
623625
queryset=self.get_fixed_packages_qs(),
624626
to_attr="filtered_fixed_packages",
625627
),

vulnerabilities/api_extension.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,6 @@ class Meta:
238238
"qualifiers",
239239
"subpath",
240240
"purl",
241-
# this hurts
242-
"packagerelatedvulnerability__fix",
243241
]
244242

245243
def filter_purl(self, queryset, name, value):

vulnerabilities/import_runner.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
from vulnerabilities.improver import Inference
2222
from vulnerabilities.improvers.default import DefaultImporter
2323
from vulnerabilities.models import Advisory
24+
from vulnerabilities.models import AffectedByPackageRelatedVulnerability
2425
from vulnerabilities.models import Alias
26+
from vulnerabilities.models import FixingPackageRelatedVulnerability
2527
from vulnerabilities.models import Package
26-
from vulnerabilities.models import PackageRelatedVulnerability
2728
from vulnerabilities.models import Vulnerability
2829
from vulnerabilities.models import VulnerabilityChangeLog
2930
from vulnerabilities.models import VulnerabilityReference
@@ -211,22 +212,20 @@ def process_inferences(inferences: List[Inference], advisory: Advisory, improver
211212

212213
for affected_purl in inference.affected_purls or []:
213214
vulnerable_package, _ = Package.objects.get_or_create_from_purl(purl=affected_purl)
214-
PackageRelatedVulnerability(
215+
AffectedByPackageRelatedVulnerability(
215216
vulnerability=vulnerability,
216217
package=vulnerable_package,
217218
created_by=improver_name,
218219
confidence=inference.confidence,
219-
fix=False,
220220
).update_or_create(advisory=advisory)
221221

222222
if inference.fixed_purl:
223223
fixed_package, _ = Package.objects.get_or_create_from_purl(purl=inference.fixed_purl)
224-
PackageRelatedVulnerability(
224+
FixingPackageRelatedVulnerability(
225225
vulnerability=vulnerability,
226226
package=fixed_package,
227227
created_by=improver_name,
228228
confidence=inference.confidence,
229-
fix=True,
230229
).update_or_create(advisory=advisory)
231230

232231
if inference.weaknesses and vulnerability:

vulnerabilities/improve_runner.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
from vulnerabilities.importers import IMPORTERS_REGISTRY
1818
from vulnerabilities.improver import Inference
1919
from vulnerabilities.models import Advisory
20+
from vulnerabilities.models import AffectedByPackageRelatedVulnerability
2021
from vulnerabilities.models import Alias
22+
from vulnerabilities.models import FixingPackageRelatedVulnerability
2123
from vulnerabilities.models import Package
22-
from vulnerabilities.models import PackageRelatedVulnerability
2324
from vulnerabilities.models import Vulnerability
2425
from vulnerabilities.models import VulnerabilityChangeLog
2526
from vulnerabilities.models import VulnerabilityReference
@@ -135,12 +136,11 @@ def process_inferences(
135136
vulnerable_package, created = Package.objects.get_or_create_from_purl(
136137
purl=affected_purl
137138
)
138-
PackageRelatedVulnerability(
139+
AffectedByPackageRelatedVulnerability(
139140
vulnerability=vulnerability,
140141
package=vulnerable_package,
141142
created_by=improver_name,
142143
confidence=inference.confidence,
143-
fix=False,
144144
).update_or_create(
145145
advisory=advisory,
146146
)
@@ -149,12 +149,11 @@ def process_inferences(
149149
fixed_package, created = Package.objects.get_or_create_from_purl(
150150
purl=inference.fixed_purl
151151
)
152-
PackageRelatedVulnerability(
152+
FixingPackageRelatedVulnerability(
153153
vulnerability=vulnerability,
154154
package=fixed_package,
155155
created_by=improver_name,
156156
confidence=inference.confidence,
157-
fix=True,
158157
).update_or_create(
159158
advisory=advisory,
160159
)

vulnerabilities/management/commands/export.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def export_data(self, base_path: Path):
116116
}
117117
package_vulnerabilities.append(package_data)
118118

119-
for vuln in pkg_version.vulnerabilities.all():
119+
for vuln in pkg_version.vulnerabilities:
120120
vcid = vuln.vulnerability_id
121121
# do not write twice the same file
122122
if vcid in seen_vcid:
@@ -158,10 +158,14 @@ def packages_by_type_ns_name():
158158
qs = (
159159
Package.objects.order_by("type", "namespace", "name", "version")
160160
.prefetch_related(
161-
"vulnerabilities",
162-
"vulnerabilities__references",
163-
"vulnerabilities__weaknesses",
164-
"vulnerabilities__references__vulnerabilityseverity_set",
161+
"affected_by_vulnerabilities",
162+
"affected_by_vulnerabilities__references",
163+
"affected_by_vulnerabilities__weaknesses",
164+
"affected_by_vulnerabilities__references__vulnerabilityseverity_set",
165+
"fixing_vulnerabilities",
166+
"fixing_vulnerabilities__references",
167+
"fixing_vulnerabilities__weaknesses",
168+
"fixing_vulnerabilities__references__vulnerabilityseverity_set",
165169
)
166170
.paginated()
167171
)

vulnerabilities/migrations/0070_alter_advisory_created_by_and_more.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ class Migration(migrations.Migration):
3636
max_length=100,
3737
),
3838
),
39-
]
39+
]
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
from django.db import migrations, models
2+
import django.db.models.deletion
3+
from django.core.validators import MaxValueValidator, MinValueValidator
4+
from vulnerabilities.improver import MAX_CONFIDENCE
5+
6+
def split_packagerelatedvulnerability(apps, schema_editor):
7+
PackageRelatedVulnerability = apps.get_model('vulnerabilities', 'PackageRelatedVulnerability')
8+
FixingPackageRelatedVulnerability = apps.get_model('vulnerabilities', 'FixingPackageRelatedVulnerability')
9+
AffectedByPackageRelatedVulnerability = apps.get_model('vulnerabilities', 'AffectedByPackageRelatedVulnerability')
10+
11+
for prv in PackageRelatedVulnerability.objects.all():
12+
if prv.fix:
13+
FixingPackageRelatedVulnerability.objects.create(
14+
package=prv.package,
15+
vulnerability=prv.vulnerability,
16+
created_by=prv.created_by,
17+
confidence=prv.confidence,
18+
)
19+
else:
20+
AffectedByPackageRelatedVulnerability.objects.create(
21+
package=prv.package,
22+
vulnerability=prv.vulnerability,
23+
created_by=prv.created_by,
24+
confidence=prv.confidence,
25+
)
26+
27+
def reverse_migration(apps, schema_editor):
28+
FixingPackageRelatedVulnerability = apps.get_model('vulnerabilities', 'FixingPackageRelatedVulnerability')
29+
AffectedByPackageRelatedVulnerability = apps.get_model('vulnerabilities', 'AffectedByPackageRelatedVulnerability')
30+
PackageRelatedVulnerability = apps.get_model('vulnerabilities', 'PackageRelatedVulnerability')
31+
32+
for fpv in FixingPackageRelatedVulnerability.objects.all():
33+
PackageRelatedVulnerability.objects.create(
34+
package=fpv.package,
35+
vulnerability=fpv.vulnerability,
36+
created_by=fpv.created_by,
37+
confidence=fpv.confidence,
38+
fix=True,
39+
)
40+
41+
for apv in AffectedByPackageRelatedVulnerability.objects.all():
42+
PackageRelatedVulnerability.objects.create(
43+
package=apv.package,
44+
vulnerability=apv.vulnerability,
45+
created_by=apv.created_by,
46+
confidence=apv.confidence,
47+
fix=False,
48+
)
49+
50+
class Migration(migrations.Migration):
51+
52+
dependencies = [
53+
("vulnerabilities", "0070_alter_advisory_created_by_and_more"),
54+
]
55+
56+
operations = [
57+
migrations.AlterField(
58+
model_name="advisory",
59+
name="created_by",
60+
field=models.CharField(
61+
help_text="Fully qualified name of the importer prefixed with themodule name importing the advisory. Eg:vulnerabilities.pipeline.nginx_importer.NginxImporterPipeline",
62+
max_length=100,
63+
),
64+
),
65+
migrations.CreateModel(
66+
name="FixingPackageRelatedVulnerability",
67+
fields=[
68+
(
69+
"id",
70+
models.AutoField(
71+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
72+
),
73+
),
74+
(
75+
"created_by",
76+
models.CharField(
77+
blank=True,
78+
help_text="Fully qualified name of the improver prefixed with the module name responsible for creating this relation. Eg: vulnerabilities.importers.nginx.NginxBasicImprover",
79+
max_length=100,
80+
),
81+
),
82+
(
83+
"confidence",
84+
models.PositiveIntegerField(
85+
default=100,
86+
help_text="Confidence score for this relation",
87+
validators=[
88+
django.core.validators.MinValueValidator(0),
89+
django.core.validators.MaxValueValidator(100),
90+
],
91+
),
92+
),
93+
(
94+
"package",
95+
models.ForeignKey(
96+
on_delete=django.db.models.deletion.CASCADE, to="vulnerabilities.package"
97+
),
98+
),
99+
(
100+
"vulnerability",
101+
models.ForeignKey(
102+
on_delete=django.db.models.deletion.CASCADE,
103+
to="vulnerabilities.vulnerability",
104+
),
105+
),
106+
],
107+
options={
108+
"verbose_name_plural": "Fixing Package Related Vulnerabilities",
109+
"ordering": ["package", "vulnerability"],
110+
"abstract": False,
111+
"unique_together": {("package", "vulnerability")},
112+
},
113+
),
114+
migrations.CreateModel(
115+
name="AffectedByPackageRelatedVulnerability",
116+
fields=[
117+
(
118+
"id",
119+
models.AutoField(
120+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
121+
),
122+
),
123+
(
124+
"created_by",
125+
models.CharField(
126+
blank=True,
127+
help_text="Fully qualified name of the improver prefixed with the module name responsible for creating this relation. Eg: vulnerabilities.importers.nginx.NginxBasicImprover",
128+
max_length=100,
129+
),
130+
),
131+
(
132+
"confidence",
133+
models.PositiveIntegerField(
134+
default=100,
135+
help_text="Confidence score for this relation",
136+
validators=[
137+
django.core.validators.MinValueValidator(0),
138+
django.core.validators.MaxValueValidator(100),
139+
],
140+
),
141+
),
142+
(
143+
"package",
144+
models.ForeignKey(
145+
on_delete=django.db.models.deletion.CASCADE, to="vulnerabilities.package"
146+
),
147+
),
148+
(
149+
"vulnerability",
150+
models.ForeignKey(
151+
on_delete=django.db.models.deletion.CASCADE,
152+
to="vulnerabilities.vulnerability",
153+
),
154+
),
155+
],
156+
options={
157+
"verbose_name_plural": "Affected By Package Related Vulnerabilities",
158+
"ordering": ["package", "vulnerability"],
159+
"abstract": False,
160+
"unique_together": {("package", "vulnerability")},
161+
},
162+
),
163+
migrations.RunPython(split_packagerelatedvulnerability, reverse_migration),
164+
]

0 commit comments

Comments
 (0)