From c8d468a4ac9eb842fefe886f0c86e7eef43e9da6 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 08:29:07 +0000 Subject: [PATCH 01/16] add filter username in stopform --- embark/dashboard/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embark/dashboard/views.py b/embark/dashboard/views.py index 5f947a84..b91afa87 100644 --- a/embark/dashboard/views.py +++ b/embark/dashboard/views.py @@ -78,7 +78,7 @@ def service_dashboard(request): :return httpresp: html servicedashboard """ form = StopAnalysisForm() - form.fields['analysis'].queryset = FirmwareAnalysis.objects.filter(finished=False) + form.fields['analysis'].queryset = FirmwareAnalysis.objects.filter(user=request.user).filter(finished=False) return render(request, 'dashboard/serviceDashboard.html', {'username': request.user.username, 'form': form, 'success_message': False}) From 1c21378ed22258402f06ec0b5bccfe3d51de97aa Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 08:53:35 +0000 Subject: [PATCH 02/16] seperate further --- embark/dashboard/views.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/embark/dashboard/views.py b/embark/dashboard/views.py index b91afa87..5444bdad 100644 --- a/embark/dashboard/views.py +++ b/embark/dashboard/views.py @@ -27,7 +27,7 @@ @login_required(login_url='/' + settings.LOGIN_URL) def main_dashboard(request): if request.user.is_authenticated: - if FirmwareAnalysis.objects.filter(finished=True, failed=False).count() > 0 and Result.objects.all().count() > 0: + if FirmwareAnalysis.objects.filter(finished=True, failed=False).count() > 0 and Result.objects.filter(restricted=False).count() > 0: return render(request, 'dashboard/mainDashboard.html', {'nav_switch': True, 'username': request.user.username}) messages.info(request, "Redirected - There are no Results to display yet") return redirect('embark-uploader-home') @@ -50,18 +50,21 @@ def stop_analysis(request): logger.debug("Posted Form is valid") # get id analysis = form.cleaned_data['analysis'] - logger.info("Stopping analysis with id %s", analysis.id) - pid = FirmwareAnalysis.objects.get(id=analysis.id).pid + analysis_object_ = FirmwareAnalysis.objects.get(id=analysis.id) + # check if user auth + if request.user != analysis_object_.user: + return HttpResponseForbidden("You are not authorized!") + logger.info("Stopping analysis with id %s", analysis_object_.id) + pid = analysis_object_.pid logger.debug("PID is %s", pid) try: BoundedExecutor.submit_kill(analysis.id) os.killpg(os.getpgid(pid), signal.SIGTERM) # kill proc group too form = StopAnalysisForm() - form.fields['analysis'].queryset = FirmwareAnalysis.objects.filter(finished=False) + form.fields['analysis'].queryset = FirmwareAnalysis.objects.filter(user=request.user).filter(finished=False) return render(request, 'dashboard/serviceDashboard.html', {'username': request.user.username, 'form': form, 'success_message': True, 'message': "Stopped successfully"}) except builtins.Exception as error: logger.error("Error %s", error) - analysis_object_ = FirmwareAnalysis.objects.get(id=analysis.id) analysis_object_.failed = True analysis_object_.save(update_fields=["failed"]) return HttpResponseServerError("Failed to stop process, but set its status to failed. Please handle EMBA process manually: PID=" + str(pid)) @@ -92,7 +95,7 @@ def report_dashboard(request): :return: rendered ReportDashboard """ - firmwares = FirmwareAnalysis.objects.all() + firmwares = FirmwareAnalysis.objects.filter(hidden=False) return render(request, 'dashboard/reportDashboard.html', {'firmwares': firmwares, 'username': request.user.username}) @@ -122,6 +125,9 @@ def show_log(request, analysis_id): """ logger.info("showing log for analyze_id: %s", analysis_id) firmware = FirmwareAnalysis.objects.get(id=analysis_id) + # check if user auth + if request.user != firmware.user: + return HttpResponseForbidden("You are not authorized!") # get the file path log_file_path_ = f"{Path(firmware.path_to_logs).parent}/emba_run.log" logger.debug("Taking file at %s and render it", log_file_path_) @@ -145,6 +151,9 @@ def show_logviewer(request, analysis_id): logger.info("showing log viewer for analyze_id: %s", analysis_id) firmware = FirmwareAnalysis.objects.get(id=analysis_id) + # check if user auth + if request.user != firmware.user: + return HttpResponseForbidden("You are not authorized!") # get the file path log_file_path_ = f"{Path(firmware.path_to_logs).parent}/emba_run.log" logger.debug("Taking file at %s and render it", log_file_path_) @@ -200,6 +209,9 @@ def archive_analysis(request, analysis_id): """ logger.info("Archiving Analysis with id: %s", analysis_id) analysis = FirmwareAnalysis.objects.get(id=analysis_id) + # check if user auth + if request.user != analysis.user and not request.user.is_superuser: + return HttpResponseForbidden("You are not authorized!") if analysis.zip_file is None: # make archive for uuid _ = make_zip(request, analysis_id) From ed510dc9d978c84eba5a0914a7d450bc84bb7bd2 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 09:34:04 +0000 Subject: [PATCH 03/16] add hide button and seperate further --- embark/dashboard/urls.py | 1 + embark/dashboard/views.py | 20 ++++++++++++- .../templates/dashboard/reportDashboard.html | 29 ++++++++++++++++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/embark/dashboard/urls.py b/embark/dashboard/urls.py index 2cbe1417..4613d8dc 100644 --- a/embark/dashboard/urls.py +++ b/embark/dashboard/urls.py @@ -10,6 +10,7 @@ path('dashboard/report/', views.report_dashboard, name='embark-ReportDashboard'), path('dashboard/report/deleteAnalysis/', views.delete_analysis, name='embark-dashboard-delete-analysis'), path('dashboard/report/archive/', views.archive_analysis, name='embark-dashboard-archive'), + path('dashboard/report/hide/', views.hide_analysis, name='embark-dashboard-hide'), path('dashboard/individualReport/', views.individual_report_dashboard, name='embark-IndividualReportDashboard'), path('dashboard/stop/', views.stop_analysis, name='embark-stop-analysis'), path('dashboard/log/', views.show_log, name='embark-show-log'), diff --git a/embark/dashboard/views.py b/embark/dashboard/views.py index 5444bdad..1a11ef17 100644 --- a/embark/dashboard/views.py +++ b/embark/dashboard/views.py @@ -95,7 +95,8 @@ def report_dashboard(request): :return: rendered ReportDashboard """ - firmwares = FirmwareAnalysis.objects.filter(hidden=False) + # show all not hidden by others and ALL of your own + firmwares = (FirmwareAnalysis.objects.filter(hidden=False) | FirmwareAnalysis.objects.filter(user=request.user)).distinct() return render(request, 'dashboard/reportDashboard.html', {'firmwares': firmwares, 'username': request.user.username}) @@ -219,3 +220,20 @@ def archive_analysis(request, analysis_id): analysis.archived = True analysis.save(update_fields=["archived"]) return redirect('..') + + +@login_required(login_url='/' + settings.LOGIN_URL) +@require_http_methods(["GET"]) +def hide_analysis(request, analysis_id): + """ + hides the analysis + checks user + """ + logger.info("Hiding Analysis with id: %s", analysis_id) + analysis = FirmwareAnalysis.objects.get(id=analysis_id) + # check if user auth + if request.user != analysis.user and not request.user.is_superuser: + return HttpResponseForbidden("You are not authorized!") + analysis.hidden = True + analysis.save(update_fields=["hidden"]) + return redirect('..') diff --git a/embark/templates/dashboard/reportDashboard.html b/embark/templates/dashboard/reportDashboard.html index 32011cea..fe3aa6c6 100644 --- a/embark/templates/dashboard/reportDashboard.html +++ b/embark/templates/dashboard/reportDashboard.html @@ -62,6 +62,11 @@
+ {% if firmware.hidden is False %} + + {% endif %} {% if firmware.finished is False %} {% if firmware.failed is True %} -
+
@@ -145,6 +150,28 @@
+ From 646a295711686949ad41959c38bdc7f1340a2985 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 10:27:54 +0000 Subject: [PATCH 04/16] add user seperation to uploader views --- embark/uploader/views.py | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/embark/uploader/views.py b/embark/uploader/views.py index a28acd3a..aa5a291f 100644 --- a/embark/uploader/views.py +++ b/embark/uploader/views.py @@ -1,10 +1,9 @@ -# pylint: disable=W0613,C0206 import logging import os from django.conf import settings from django.shortcuts import render -from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError +from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseServerError from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.contrib import messages @@ -23,8 +22,9 @@ @login_required(login_url='/' + settings.LOGIN_URL) @require_http_methods(["GET"]) def uploader_home(request): - if FirmwareFile.objects.all().count() > 0: - analysis_form = FirmwareAnalysisForm(initial={'firmware': FirmwareFile.objects.latest('upload_date')}) + req_logger.info("User %s called uploader_home", request.user.username) + if FirmwareFile.objects.filter(user=request.user).count() > 0: + analysis_form = FirmwareAnalysisForm(initial={'firmware': FirmwareFile.objects.filter(user=request.user).latest('upload_date')}) device_form = DeviceForm() label_form = LabelForm() vendor_form = VendorForm() @@ -47,6 +47,7 @@ def save_file(request): :return: HttpResponse including the status """ + req_logger.info("User %s called save_file", request.user.username) logger.info("User %s tryied to upload %s", request.user.username, request.FILES.getlist('file')) for file in request.FILES.getlist('file'): # FIXME determin usecase for multi-file-upload in one request firmware_file = FirmwareFile.objects.create(file=file) @@ -59,6 +60,7 @@ def save_file(request): @require_http_methods(["POST"]) @login_required(login_url='/' + settings.LOGIN_URL) def device_setup(request): + req_logger.info("User %s called device_setup", request.user.username) # TODO redirect is static ? change to 200 form = DeviceForm(request.POST) if form.is_valid(): @@ -80,6 +82,7 @@ def device_setup(request): @require_http_methods(["POST"]) @login_required(login_url='/' + settings.LOGIN_URL) def vendor(request): + req_logger.info("User %s called vendor", request.user.username) form = VendorForm(request.POST) if form.is_valid(): logger.info("User %s tryied to create vendor %s", request.user.username, request.POST['vendor_name']) @@ -98,6 +101,7 @@ def vendor(request): @require_http_methods(["POST"]) @login_required(login_url='/' + settings.LOGIN_URL) def label(request): + req_logger.info("User %s called label", request.user.username) form = LabelForm(request.POST) if form.is_valid(): logger.info("User %s tryied to create label %s", request.user.username, request.POST['label_name']) @@ -128,24 +132,22 @@ def start_analysis(request): Returns: redirect """ + req_logger.info("User %s called start_analysis", request.user.username) if request.method == 'POST': form = FirmwareAnalysisForm(request.POST) - logger.debug("Form: %s", form.is_valid()) logger.debug("Form: %s", form.errors) if form.is_valid(): - logger.debug("Posted Form is valid") logger.info("Starting analysis with %s", form.Meta.model.id) - new_analysis = form.save(commit=False) - new_analysis.user = request.user + # get the id of the firmware-file to submit + new_firmware_file = FirmwareFile.objects.get(id=new_analysis.firmware.id) + logger.debug("Firmware file: %s", new_firmware_file) + if request.user != new_firmware_file.user and not request.user.is_superuser: + return HttpResponseForbidden("You are not authorized!") + new_analysis.user = new_firmware_file.user logger.debug(" FILE_NAME is %s", new_analysis.firmware.file.name) new_analysis.firmware_name = os.path.basename(new_analysis.firmware.file.name) new_analysis = form.save() - - # get the id of the firmware-file to submit - new_firmware_file = FirmwareFile.objects.get(id=new_analysis.firmware.id) - logger.info("Firmware file: %s", new_firmware_file) - # inject into bounded Executor if BoundedExecutor.submit_firmware(firmware_flags=new_analysis, firmware_file=new_firmware_file): return redirect('embark-dashboard-service') @@ -153,8 +155,8 @@ def start_analysis(request): return HttpResponseServerError("Queue full") logger.error("Form invalid %s", request.POST) return HttpResponseBadRequest("Bad Request") - if FirmwareFile.objects.all().count() > 0: - analysis_form = FirmwareAnalysisForm(initial={'firmware': FirmwareFile.objects.latest('upload_date')}) + if FirmwareFile.objects.filter(user=request.user).count() > 0: + analysis_form = FirmwareAnalysisForm(initial={'firmware': FirmwareFile.objects.filter(user=request.user).latest('upload_date')}) return render(request, 'uploader/index.html', {'analysis_form': analysis_form}) analysis_form = FirmwareAnalysisForm() device_form = DeviceForm() @@ -166,8 +168,9 @@ def start_analysis(request): @require_http_methods(["GET"]) @login_required(login_url='/' + settings.LOGIN_URL) def manage_file(request): - if FirmwareFile.objects.all().count() > 0: - form = DeleteFirmwareForm(initial={'firmware': FirmwareFile.objects.latest('upload_date').id}) + req_logger.info("User %s called manage_file", request.user.username) + if FirmwareFile.objects.filter(user=request.user).count() > 0: + form = DeleteFirmwareForm(initial={'firmware': FirmwareFile.objects.filter(user=request.user).latest('upload_date').id}) return render(request, 'uploader/manage.html', {'delete_form': form}) form = DeleteFirmwareForm() return render(request, 'uploader/manage.html', {'delete_form': form}) @@ -184,6 +187,7 @@ def delete_fw_file(request): :return: HttpResponse including the status """ + req_logger.info("User %s called delete_fw_file", request.user.username) form = DeleteFirmwareForm(request.POST) if form.is_valid(): @@ -191,7 +195,8 @@ def delete_fw_file(request): # get relevant data firmware_file = form.cleaned_data['firmware'] - # if firmware_file.user is request.user: + if request.user != firmware_file.user and not request.user.is_superuser: + return HttpResponseForbidden("You are not authorized!") firmware_file.delete() messages.info(request, 'delete successful.') return redirect('..') From fb700bb5e08b2c2d72bf27e9928efdcfe5aa8b19 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 11:28:24 +0000 Subject: [PATCH 05/16] add label column --- embark/templates/dashboard/reportDashboard.html | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/embark/templates/dashboard/reportDashboard.html b/embark/templates/dashboard/reportDashboard.html index fe3aa6c6..2c9a7e57 100644 --- a/embark/templates/dashboard/reportDashboard.html +++ b/embark/templates/dashboard/reportDashboard.html @@ -28,6 +28,7 @@ Version Start Date End Date + Labels Actions @@ -46,11 +47,10 @@ {% endfor %} {{ firmware.version }} - - {{ firmware.start_date}} + {{ firmware.start_date }} {% if firmware.end_date is not None %} - {{ firmware.end_date}} + {{ firmware.end_date }} {% else %}
+ {% endif %} + +
From 149bb2b6c22d051d8a0558e1a36b8db9e68ab6db Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 12:57:51 +0000 Subject: [PATCH 06/16] fix issue of not using instance for http response --- embark/porter/views.py | 2 +- embark/reporter/views.py | 4 ++-- embark/tracker/views.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embark/porter/views.py b/embark/porter/views.py index ac9cbd79..b176400f 100644 --- a/embark/porter/views.py +++ b/embark/porter/views.py @@ -88,7 +88,7 @@ def import_read(request): messages.error(request, 'import failed') return redirect('..') messages.error(request, 'form invalid') - return HttpResponseBadRequest + return HttpResponseBadRequest("invalid form") @login_required(login_url='/' + settings.LOGIN_URL) diff --git a/embark/reporter/views.py b/embark/reporter/views.py index d59dc7f8..98fbcc13 100644 --- a/embark/reporter/views.py +++ b/embark/reporter/views.py @@ -46,7 +46,7 @@ def html_report(request, analysis_id, html_file): logger.debug("html_report - analysis_id: %s html_file: %s", analysis_id, html_file) return HttpResponse(html_body.render({'embarkBackUrl': reverse('embark-ReportDashboard')})) logger.error("could not get template - %s", request) - return HttpResponseBadRequest + return HttpResponseBadRequest("Bad Request") @require_http_methods(["GET"]) @@ -60,7 +60,7 @@ def html_report_path(request, analysis_id, html_path, html_file): logger.debug("html_report - analysis_id: %s path: %s html_file: %s", analysis_id, html_path, html_file) return HttpResponse(html_body.render({'embarkBackUrl': reverse('embark-ReportDashboard')})) logger.error("could not get path - %s", request) - return HttpResponseBadRequest + return HttpResponseBadRequest("Bad Request") @require_http_methods(["GET"]) diff --git a/embark/tracker/views.py b/embark/tracker/views.py index 5226d023..aa218fd8 100644 --- a/embark/tracker/views.py +++ b/embark/tracker/views.py @@ -118,7 +118,7 @@ def get_report_for_device(request, device_id): 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}) logger.error("device id nonexistent: %s", device_id) logger.error("could not get template - %s", request) - return HttpResponseBadRequest + return HttpResponseBadRequest("Bad Request") @require_http_methods(["GET"]) @@ -133,7 +133,7 @@ def tracker_time(request, time): data.append(Device.objects.filter(device_vendor=_vendor).count()) device_table = SimpleDeviceTable(data=Device.objects.all(), template_name="django_tables2/bootstrap-responsive.html") return render(request=request, template_name='tracker/index.html', context={'username': request.user.username, 'table': device_table, 'labels': label_list, 'data': data}) - return HttpResponseBadRequest + return HttpResponseBadRequest("Bad Request") @require_http_methods(["POST"]) From d1b5e298d601b1b64e7fd690f49e4e02b0745718 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 13:05:38 +0000 Subject: [PATCH 07/16] don't render that! --- embark/templates/dashboard/reportDashboard.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embark/templates/dashboard/reportDashboard.html b/embark/templates/dashboard/reportDashboard.html index 2c9a7e57..ee9215d3 100644 --- a/embark/templates/dashboard/reportDashboard.html +++ b/embark/templates/dashboard/reportDashboard.html @@ -65,7 +65,7 @@ Archived {% endif %} - + From fce73819acdc8fee98e227f9b5cca9c4cec50594 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Fri, 24 Nov 2023 13:29:03 +0000 Subject: [PATCH 08/16] move hide button into dropdown --- embark/templates/dashboard/reportDashboard.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/embark/templates/dashboard/reportDashboard.html b/embark/templates/dashboard/reportDashboard.html index ee9215d3..b1caf437 100644 --- a/embark/templates/dashboard/reportDashboard.html +++ b/embark/templates/dashboard/reportDashboard.html @@ -70,11 +70,6 @@
- {% if firmware.hidden is False %} - - {% endif %} {% if firmware.finished is False %} {% if firmware.failed is True %} + {% if firmware.hidden is False %} + + {% endif %} From 6fbf31a1dcd8245e7eaa76390febba6572ba8ae3 Mon Sep 17 00:00:00 2001 From: Benedikt Kuehne Date: Mon, 27 Nov 2023 09:12:53 +0000 Subject: [PATCH 09/16] rework buttons and add some messages --- embark/dashboard/views.py | 2 + .../templates/dashboard/reportDashboard.html | 204 +++++++++--------- 2 files changed, 105 insertions(+), 101 deletions(-) diff --git a/embark/dashboard/views.py b/embark/dashboard/views.py index 1a11ef17..876e4fe5 100644 --- a/embark/dashboard/views.py +++ b/embark/dashboard/views.py @@ -219,6 +219,7 @@ def archive_analysis(request, analysis_id): analysis.do_archive() analysis.archived = True analysis.save(update_fields=["archived"]) + messages.success(request, 'Analysis: ' + str(analysis_id) + ' successfully archived') return redirect('..') @@ -236,4 +237,5 @@ def hide_analysis(request, analysis_id): return HttpResponseForbidden("You are not authorized!") analysis.hidden = True analysis.save(update_fields=["hidden"]) + messages.success(request, 'Analysis: ' + str(analysis_id) + ' successfully hidden') return redirect('..') diff --git a/embark/templates/dashboard/reportDashboard.html b/embark/templates/dashboard/reportDashboard.html index b1caf437..a67d6e9e 100644 --- a/embark/templates/dashboard/reportDashboard.html +++ b/embark/templates/dashboard/reportDashboard.html @@ -60,127 +60,129 @@ {% endif %} - {% if firmware.archived is True %} - - {% endif %} - +
+ {% if firmware.archived is True %} + + {% elif firmware.failed is True %} + + {% endif %} + +
- -
+ +
{% if firmware.finished is False %} {% if firmware.failed is True %} - - {% endif %} - {% else %} - {% if firmware.failed is True %} - - {% endif %} -
- - + + + + +