Skip to content

Commit

Permalink
Automate VEX creation
Browse files Browse the repository at this point in the history
Signed-off-by: ziadhany <ziadhany2016@gmail.com>
  • Loading branch information
ziadhany committed Apr 17, 2024
1 parent ee63a45 commit e6f7725
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 185 deletions.
10 changes: 5 additions & 5 deletions component_catalog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
from dejacode_toolkit.scancodeio import ScanCodeIO
from dejacode_toolkit.scancodeio import get_package_download_url
from dejacode_toolkit.scancodeio import get_scan_results_as_file_url
from dejacode_toolkit.vex import create_auto_vex
from dejacode_toolkit.vulnerablecode import VulnerableCode
from dje import tasks
from dje.client_data import add_client_data
Expand Down Expand Up @@ -860,7 +861,6 @@ def get_vulnerabilities_tab_fields(self, vulnerabilities):
vulnerability_fields = self.get_vulnerability_fields(vulnerability, dataspace)
fields.extend(vulnerability_fields)
vulnerabilities_count += 1

return fields, vulnerabilities_count

def get_context_data(self, **kwargs):
Expand Down Expand Up @@ -1455,6 +1455,8 @@ def get_vulnerabilities_tab_fields(self, vulnerabilities):
fields = []
vulnerabilities_count = 0

create_auto_vex(self.object, vulnerabilities)

for entry in vulnerabilities:
unresolved = entry.get("affected_by_vulnerabilities", [])
for vulnerability in unresolved:
Expand Down Expand Up @@ -2566,10 +2568,8 @@ def get_object(self):
print(self.kwargs.get("uuid"))
print(self.kwargs.get("dataspace")) # TODO check
print(self.kwargs.get("vulnerability_id"))
dataspace = "nexB/pypi/flask@1.1.0/"
self.kwargs["uuid"] = "6f3beb98-8187-420f-88b5-877427b6b190"
self.kwargs["vulnerability_id"] = "VCID-2w9q-sann-aaak"
return self.model.objects.get(
return get_object_or_404(
self.model,
productpackage__uuid=self.kwargs.get("uuid"),
vulnerability_id=self.kwargs.get("vulnerability_id"),
)
Expand Down
92 changes: 92 additions & 0 deletions dejacode_toolkit/tests/test_vex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#
# Copyright (c) nexB Inc. and others. All rights reserved.
# DejaCode is a trademark of nexB Inc.
# SPDX-License-Identifier: AGPL-3.0-only
# See https://github.com/nexB/dejacode for support or download.
# See https://aboutcode.org for more information about AboutCode FOSS projects.
#


from unittest import mock

from django.contrib.auth import get_user_model
from django.test import TestCase

from component_catalog.models import Package
from dejacode_toolkit import vex
from dje.models import Dataspace
from dje.tests import create_superuser
from dje.tests import create_user
from product_portfolio.models import Product
from product_portfolio.models import ProductPackage
from product_portfolio.models import ProductPackageVEX

User = get_user_model()


class VEXTestCase(TestCase):
def setUp(self):
self.nexb_dataspace = Dataspace.objects.create(name="nexB")
self.nexb_user = User.objects.create_superuser(
"nexb_user", "test@test.com", "t3st", self.nexb_dataspace
)
self.basic_user = create_user("basic_user", self.nexb_dataspace)
self.product1 = Product.objects.create(
name="Product1 With Space", version="1.0", dataspace=self.nexb_dataspace
)
self.package1 = Package.objects.create(filename="package1", dataspace=self.nexb_dataspace)

self.productpacakge1 = ProductPackage.objects.create(
product=self.product1, package=self.package1, dataspace=self.nexb_dataspace
)

def test_create_auto_vex1(self):
vulnerabilities = [
{
"affected_by_vulnerabilities": [
{
"url": "http://public.vulnerablecode.io/api/vulnerabilities/121332",
"vulnerability_id": "VCID-111c-u9bh-aaac",
}
]
},
{
"affected_by_vulnerabilities": [
{
"url": "https://public.vulnerablecode.io/api/vulnerabilities/121331",
"vulnerability_id": "VCID-uxf9-7c97-aaaj",
}
]
},
]
assert ProductPackageVEX.objects.count() == 0
vex.create_auto_vex(self.package1, vulnerabilities)
assert ProductPackageVEX.objects.count() == 2

# run create_auto_vex agian and make sure that the databse ignore errors
vex.create_auto_vex(self.package1, vulnerabilities)
assert ProductPackageVEX.objects.count() == 2

def test_create_auto_vex2(self):
# duplicated vulnerability
vulnerabilities = [
{
"affected_by_vulnerabilities": [
{
"url": "http://public.vulnerablecode.io/api/vulnerabilities/121332",
"vulnerability_id": "VCID-111c-u9bh-aaac",
}
]
},
{
"affected_by_vulnerabilities": [
{
"url": "http://public.vulnerablecode.io/api/vulnerabilities/121332",
"vulnerability_id": "VCID-111c-u9bh-aaac",
}
]
},
]
assert ProductPackageVEX.objects.count() == 0
vex.create_auto_vex(self.package1, vulnerabilities)
assert ProductPackageVEX.objects.count() == 1
177 changes: 0 additions & 177 deletions dejacode_toolkit/tests/vulnerablecode.py

This file was deleted.

32 changes: 31 additions & 1 deletion dejacode_toolkit/vex.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,36 @@
from cyclonedx.model.bom import Bom
from cyclonedx.model.vulnerability import Vulnerability

from product_portfolio.models import ProductPackage
from product_portfolio.models import ProductPackageVEX


def create_auto_vex(package, vulnerabilities):
"""
automatically create a VEX for each product package that has a vulnerability
"""
vex_objects = []
vulnerability_ids = []
for entry in vulnerabilities:
unresolved = entry.get("affected_by_vulnerabilities", [])
for vulnerability in unresolved:
vulnerability_id = vulnerability.get("vulnerability_id")
if vulnerability_id:
vulnerability_ids.append(vulnerability_id)

productpackages = ProductPackage.objects.filter(package=package)
for productpackage in productpackages:
for vulnerability_id in vulnerability_ids:
vex_objects.append(
ProductPackageVEX(
productpackage=productpackage,
vulnerability_id=vulnerability_id,
)
)

ProductPackageVEX.objects.bulk_create(vex_objects, ignore_conflicts=True)


vex = {
"bomFormat": "CycloneDX",
"specVersion": "1.4",
Expand Down Expand Up @@ -34,7 +64,7 @@
}


@dataclasses.dataclass
# @dataclasses.dataclass
class VEXCycloneDX:
"""https://github.com/CycloneDX/bom-examples/tree/master/VEX"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
<td{% if vex.productpackage %} data-purl="{{ vex.productpackage.package.aboutcode_data.package_url }}"{% endif %}>
{% include 'product_portfolio/includes/productrelation_element.html' with relation=vex.productpackage %}
</td>
<td><a href="http://public.vulnerablecode.io/vulnerabilities/{{ vex.vulnerability_id }}">{{ vex.vulnerability_id }}</a></td>
<td>{{ vex.status }}</td>
<td><a href="TODO/vulnerabilities/{{ vex.vulnerability_id }}">{{ vex.vulnerability_id }}</a></td>
<td>{{ vex.get_status_display }}</td>
<td class="text-center">{{ vex.action }}</td>
<td class="text-center">{{ vex.impact }}</td>
<td class="text-center">{{ vex.notes }}</td>
Expand Down

0 comments on commit e6f7725

Please sign in to comment.