diff --git a/embark/dashboard/models.py b/embark/dashboard/models.py index be3052c6..bf3af3fb 100644 --- a/embark/dashboard/models.py +++ b/embark/dashboard/models.py @@ -19,7 +19,7 @@ class Vulnerability(models.Model): class SoftwareInfo(models.Model): """ - Many-to-many object for SBOM entries + Many-to-one object for SBOM entries """ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) type = models.CharField(verbose_name="type of blob", blank=False, editable=True, default="NA", max_length=256) @@ -34,6 +34,15 @@ class SoftwareInfo(models.Model): properties = models.JSONField(null=True, editable=True) +class SoftwareBillOfMaterial(models.Model): + """ + 1-to-1 object for result + """ + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) + meta = models.CharField(verbose_name="meta data sbom", blank=False, editable=True, default="NA", max_length=1024) + component = models.ManyToManyField(SoftwareInfo, help_text='Software Bill of Material', related_query_name='sbom', editable=True, blank=True) + + class Result(models.Model): """ 1-to-1 Result object for related FirmwareAnalysis @@ -89,4 +98,4 @@ class Result(models.Model): system_bin = models.TextField(default='{}') vulnerability = models.ManyToManyField(Vulnerability, help_text='CVE/Vulnerability', related_query_name='CVE', editable=True, blank=True) - sbom = models.ManyToManyField(SoftwareInfo, help_text='Software Bill of Material', related_query_name='sbom', editable=True, blank=True) + sbom = models.OneToOneField(SoftwareBillOfMaterial, help_text='Software Bill of Material', related_query_name='sbom', editable=True, blank=True, on_delete=models.CASCADE, null=True) diff --git a/embark/porter/importer.py b/embark/porter/importer.py index c4753f59..108ad5a0 100644 --- a/embark/porter/importer.py +++ b/embark/porter/importer.py @@ -14,7 +14,7 @@ from django.conf import settings -from dashboard.models import SoftwareInfo, Vulnerability, Result +from dashboard.models import SoftwareBillOfMaterial, SoftwareInfo, Vulnerability, Result from uploader.models import FirmwareAnalysis logger = logging.getLogger(__name__) @@ -212,32 +212,44 @@ def f15_json(_file_path, _analysis_id): SBOM json """ logger.debug("starting f15 json import") - res, _ = Result.objects.get_or_create( - firmware_analysis=FirmwareAnalysis.objects.get(id=_analysis_id) - ) with open(_file_path, 'r', encoding='utf-8') as f15_json_file: f15_data = json.load(f15_json_file) - for component_ in f15_data['components']: - logger.debug("Component is %s", component_) - try: - new_sbom, add_ = SoftwareInfo.objects.update_or_create( - id=component_['bom-ref'], - name=component_['name'], - type=component_['type'], - group=component_['group'] or 'NA', - version=component_['version'] or 'NA', - hashes=component_['hashes'], - cpe=component_['cpe'] or 'NA', - purl=component_['purl'] or 'NA', - description=component_['description'] or 'NA', - properties=component_['properties'] or 'NA' - ) - logger.debug("Was new? %s", add_) - logger.debug("Adding SBOM item: %s to res %s", new_sbom, res) - if add_: - res.sbom.add(new_sbom) - except builtins.Exception as error_: - logger.error("Error in f15 readin: %s", error_) + sbom_obj, add_sbom = SoftwareBillOfMaterial.objects.get_or_create( + id=f15_data['serialNumber'] #TODO grep uuid from this: "urn:uuid:f601dc24-7ba9-4821-b398-a30c59f7775e" + ) + if add_sbom: + res, _ = Result.objects.get_or_create( + firmware_analysis=FirmwareAnalysis.objects.get(id=_analysis_id), + sbom=add_sbom + ) + else: + for component_ in f15_data['components']: + logger.debug("Component is %s", component_) + try: + new_sitem, add_sitem = SoftwareInfo.objects.update_or_create( + id=component_['bom-ref'], + name=component_['name'], + type=component_['type'], + group=component_['group'] or 'NA', + version=component_['version'] or 'NA', + hashes=component_['hashes'], + cpe=component_['cpe'] or 'NA', + purl=component_['purl'] or 'NA', + description=component_['description'] or 'NA', + properties=component_['properties'] or 'NA' + ) + logger.debug("Was new? %s", add_sitem) + logger.debug("Adding SBOM item: %s to sbom %s", new_sitem, sbom_obj) + if add_sitem: + sbom_obj.add(add_sitem) + else: + sbom_obj.add(new_sitem) + except builtins.Exception as error_: + logger.error("Error in f15 readin: %s", error_) + res, _ = Result.objects.get_or_create( + firmware_analysis=FirmwareAnalysis.objects.get(id=_analysis_id), + sbom=sbom_obj + ) logger.debug("read f15 json done") return res diff --git a/embark/templates/tracker/device.html b/embark/templates/tracker/device.html index 54330970..fd40556a 100644 --- a/embark/templates/tracker/device.html +++ b/embark/templates/tracker/device.html @@ -34,7 +34,7 @@ {% endfor %} - +{% block sbom %}{% include "tracker/results.html" %}{% endblock sbom%}

Device tracker

diff --git a/embark/templates/tracker/sbom.html b/embark/templates/tracker/results.html similarity index 79% rename from embark/templates/tracker/sbom.html rename to embark/templates/tracker/results.html index c3aa4791..e62751a1 100644 --- a/embark/templates/tracker/sbom.html +++ b/embark/templates/tracker/results.html @@ -2,8 +2,8 @@ This renders a interactive SBOM table for the device -->
-

SBOM - PUT VERSION of device here

+

Results

{% load django_tables2 %} - {% render_table table %} + {% render_table result_table %}
\ No newline at end of file diff --git a/embark/tracker/tables.py b/embark/tracker/tables.py index f19fe02c..25dd6bbd 100644 --- a/embark/tracker/tables.py +++ b/embark/tracker/tables.py @@ -7,7 +7,7 @@ from django.utils.html import format_html from django.urls import reverse -from dashboard.models import SoftwareInfo +from dashboard.models import Result, SoftwareInfo from uploader.models import Device @@ -29,3 +29,10 @@ class Meta: # def render_id(self, value): # return format_html(f"{value}") + + +class SimpleResultTable(tables.Table): + + class Meta: + model = Result + orderable = True diff --git a/embark/tracker/urls.py b/embark/tracker/urls.py index 6e27a079..7bbeb799 100644 --- a/embark/tracker/urls.py +++ b/embark/tracker/urls.py @@ -12,6 +12,7 @@ path('tracker/', views.tracker, name='embark-tracker'), # path('tracker//', views.tracker, name='embark-tracker-time'), path('tracker/device//', views.get_report_for_device, name='embark-tracker-device'), + path('tracker/device//sbom/', views.get_sbom_for_device, name='embark-tracker-sbom'), path('tracker/device//toggle', views.toggle_device_visible, name='embark-tracker-device-visible'), # path('tracker/vendor//', views.get_report_for_vendor, name='embark-tracker-vendor'), path('tracker/associate/', views.set_associate_device_to, name='embark-tracker-ass') diff --git a/embark/tracker/views.py b/embark/tracker/views.py index c238373d..3dec4c58 100644 --- a/embark/tracker/views.py +++ b/embark/tracker/views.py @@ -18,7 +18,7 @@ from dashboard.models import Result from embark.helper import rnd_rgb_color, rnd_rgb_full from uploader.models import FirmwareAnalysis, Device, Vendor -from tracker.tables import SimpleDeviceTable, SimpleSBOMTable +from tracker.tables import SimpleDeviceTable, SimpleResultTable, SimpleSBOMTable from tracker.forms import AssociateForm, TimeForm logger = logging.getLogger(__name__) @@ -73,12 +73,12 @@ def tracker(request): return redirect('embark-uploader-home') -@require_http_methods(["GET"]) +@require_http_methods(["GET", "POST"]) @login_required(login_url='/' + settings.LOGIN_URL) def get_report_for_device(request, device_id): if Device.objects.filter(id=device_id).exists(): device = Device.objects.get(id=device_id) - analysis_queryset = FirmwareAnalysis.objects.filter(device=device) # TODO uhm Q working? and add user check + analysis_queryset = FirmwareAnalysis.objects.filter(device=device, failed=False) # TODO uhm Q working? and add user check label_list = [ 'strcpy', 'cve_high', @@ -118,16 +118,24 @@ def get_report_for_device(request, device_id): dataset['pointHoverBackgroundColor'] = '#fff' dataset['pointHoverBorderColor'] = rnd_rgb_color() data.append(dataset) - # sbom table - sbom_table = SimpleSBOMTable(data=result_queryset.sbom, template_name="django_tables2/bootstrap-responsive.html") - RequestConfig(request).configure(sbom_table) + + result_queryset = Result.objects.filter(firmware_analysis__in=analysis_queryset) + if result_queryset: + result_table = SimpleResultTable(data=analysis_queryset.all(), template_name="django_tables2/bootstrap-responsive.html") + RequestConfig(request).configure(result_table) logger.debug("tracker/device data: %s", str(data)) - return render(request=request, template_name='tracker/device.html', context={'username': request.user.username, 'device_id': device_id, 'device': device, 'labels': label_list, 'data': data}) + return render(request=request, template_name='tracker/device.html', context={'username': request.user.username, 'device_id': device_id, 'device': device, 'labels': label_list, 'data': data, 'result_table': result_table}) logger.error("device id nonexistent: %s", device_id) logger.error("could not get template - %s", request) return HttpResponseBadRequest("Bad Request") +@require_http_methods(["GET"]) +@login_required(login_url='/' + settings.LOGIN_URL) +def get_sbom_for_device(request, device_id, result_id): + pass # TODO + + @require_http_methods(["GET"]) @login_required(login_url='/' + settings.LOGIN_URL) def tracker_time(request, time):