Skip to content

Commit

Permalink
Remove the user requirement on the Vulnerability model #138
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <[email protected]>
  • Loading branch information
tdruez committed Aug 5, 2024
1 parent 1fbc989 commit 525d8d3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 20 deletions.
18 changes: 4 additions & 14 deletions component_catalog/management/commands/fetchvulnerabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
# See https://aboutcode.org for more information about AboutCode FOSS projects.
#


from django.core.management.base import CommandError

from component_catalog.models import Component
from component_catalog.models import Package
from component_catalog.models import Vulnerability
from dejacode_toolkit.vulnerablecode import VulnerableCode
from dje.management.commands import DataspacedCommand
from dje.models import DejacodeUser
from dje.utils import chunked


Expand All @@ -23,11 +21,8 @@ class Command(DataspacedCommand):

def handle(self, *args, **options):
super().handle(*args, **options)
# chunk_size=10 -> make this configurable and see figure out best default
# TODO: chunk_size=10 -> make this configurable and see figure out best default

# TODO: Consider making the user optional on the Vulnerability model as its
# automatically collected
user = DejacodeUser.objects.scope(self.dataspace).all()[0]
vulnerablecode = VulnerableCode(self.dataspace)

if not self.dataspace.enable_vulnerablecodedb_access:
Expand Down Expand Up @@ -63,17 +58,12 @@ def handle(self, *args, **options):
if not affected_packages:
raise CommandError("Could not find package!")

# django.db.utils.IntegrityError: duplicate key value violates unique
# constraint "component_catalog_vulnerability_vulnerability_id_key"
# DETAIL: Key (vulnerability_id)=(VCID-311z-mwbu-aaac) already exists.

for vulnerability in affected_by_vulnerabilities:
if vulnerability_qs.filter(
vulnerability_id=vulnerability["vulnerability_id"]
).exists():
vulnerability_id = vulnerability["vulnerability_id"]
if vulnerability_qs.filter(vulnerability_id=vulnerability_id).exists():
continue # -> TODO: Update from data in that case?
Vulnerability.create_from_data(
user=user,
dataspace=self.dataspace,
data=vulnerability,
affected_packages=affected_packages,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 5.0.6 on 2024-08-05 13:56

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('component_catalog', '0007_vulnerability_affected_components_and_more'),
]

operations = [
migrations.RemoveField(
model_name='vulnerability',
name='created_by',
),
migrations.RemoveField(
model_name='vulnerability',
name='last_modified_by',
),
]
29 changes: 23 additions & 6 deletions component_catalog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from dje.models import DataspacedQuerySet
from dje.models import ExternalReferenceMixin
from dje.models import History
from dje.models import HistoryDateFieldsMixin
from dje.models import HistoryFieldsMixin
from dje.models import ParentChildModelMixin
from dje.models import ParentChildRelationshipModel
Expand Down Expand Up @@ -2514,12 +2515,16 @@ def __str__(self):
return f"<{self.component}>: {self.package}"


class Vulnerability(HistoryFieldsMixin, DataspacedModel):
class Vulnerability(HistoryDateFieldsMixin, DataspacedModel):
"""
A software vulnerability with a unique identifier and alternate aliases.
Adapted from the VulnerabeCode models at
https://github.com/nexB/vulnerablecode/blob/main/vulnerabilities/models.py#L164
Note that this model implements the HistoryDateFieldsMixin but not the
HistoryUserFieldsMixin as the Vulnerability records are usually created
automatically on object addition or during schedule tasks.
"""

vulnerability_id = models.CharField(
Expand Down Expand Up @@ -2584,14 +2589,26 @@ def add_affected_components(self, components):

@classmethod
def create_from_data(
cls, user, data, validate=False, affected_packages=None, affected_components=None
cls, dataspace, data, validate=False, affected_packages=None, affected_components=None
):
vulnerability = super().create_from_data(user, data, validate=validate)
# TODO: Remove duplication with super()
model_fields = cls.model_fields()
cleaned_data = {
field_name: value
for field_name, value in data.items()
if field_name in model_fields and value not in EMPTY_VALUES
}

instance = cls(dataspace=dataspace, **cleaned_data)

if validate:
instance.full_clean()
instance.save()

if affected_packages:
vulnerability.add_affected_packages(affected_packages)
instance.add_affected_packages(affected_packages)

if affected_components:
vulnerability.add_affected_component(affected_components)
instance.add_affected_component(affected_components)

return vulnerability
return instance

0 comments on commit 525d8d3

Please sign in to comment.