Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buttonsandbugs #166

Merged
merged 17 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
uses: actions/checkout@v3
- name: Install dependencies for linting
run: |
sudo apt-get update -y
sudo apt-get install -y python3-dev npm pycodestyle python3-pylint-django bandit
sudo npm install -g jshint
- name: Install Python, pipenv and Pipfile packages
Expand Down
10 changes: 7 additions & 3 deletions embark/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from django.conf import settings
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseRedirect, 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
Expand All @@ -29,7 +29,8 @@ 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:
return render(request, 'dashboard/mainDashboard.html', {'nav_switch': True, 'username': request.user.username})
return HttpResponseRedirect('../../uploader/')
messages.info(request, "Redirected - There are no Results to display yet")
return redirect('embark-uploader-home')
return HttpResponseForbidden


Expand Down Expand Up @@ -60,7 +61,10 @@ def stop_analysis(request):
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)
return HttpResponseServerError("Failed to stop process, please handle manually: PID=" + str(pid))
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))
return HttpResponseBadRequest("invalid form")


Expand Down
15 changes: 3 additions & 12 deletions embark/embark/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,15 @@ def zip_check(content_list):
return all(value_ in content_list for value_ in check_list)


def cleanup_charfield(charfield):
def cleanup_charfield(charfield) -> str:
# clean-up for linux extensive os-descriptions
if charfield.startswith("Linux"):
charfield = charfield.split("/", 2)[:2]
charfield = f"{charfield[0]}{charfield[1]}"
charfield = (charfield[:16] + '..') if len(charfield) > 18 else charfield
# clean-up for architecture descriptions
elif isinstance(charfield, dict):
for key_, value_ in charfield.items():
if value_.lower() == 'el':
charfield = f"{key_} - Little Endian"
elif value_.lower() == 'eb':
charfield = f"{key_} - Big Endian"
else:
charfield = key_
return charfield


if __name__ == '__main__':
print(rnd_rgb_color())
print(rnd_rgb_full())
TEST_STRING = 'Linux / v2.6.33.2'
print(cleanup_charfield(TEST_STRING))
4 changes: 2 additions & 2 deletions embark/embark/logreader.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# pylint: disable=W0602
# ignores no-assignment error since there is one!
import builtins
import datetime
import difflib
import pathlib
import re
Expand All @@ -15,6 +14,7 @@

from channels.layers import get_channel_layer
from django.conf import settings
from django.utils import timezone

from uploader.models import FirmwareAnalysis

Expand Down Expand Up @@ -75,7 +75,7 @@ def save_status(self):
logger.debug("Appending status with message: %s", self.status_msg)
# append message to the json-field structure of the analysis
self.analysis.status["percentage"] = self.status_msg["percentage"]
self.analysis.status["last_update"] = str(datetime.datetime.now())
self.analysis.status["last_update"] = str(timezone.now())
# append modules and phase list
if self.status_msg["module"] != self.analysis.status["last_module"]:
self.analysis.status["last_module"] = self.status_msg["module"]
Expand Down
2 changes: 1 addition & 1 deletion embark/embark/settings/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
TIME_ZONE = os.environ.get('TIME_ZONE', 'UTC')

USE_I18N = True

Expand Down
2 changes: 1 addition & 1 deletion embark/embark/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
TIME_ZONE = os.environ.get('TIME_ZONE', 'UTC')

USE_I18N = True

Expand Down
4 changes: 2 additions & 2 deletions embark/porter/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.conf import settings
from django.db.models.signals import pre_delete
from django.dispatch import receiver
from django.utils.datetime_safe import datetime
from django.utils import timezone
from django.db import models

from users.models import User as Userclass
Expand All @@ -20,7 +20,7 @@ class LogZipFile
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)

upload_date = models.DateTimeField(default=datetime.now, blank=True)
upload_date = models.DateTimeField(default=timezone.now, blank=True)
user = models.ForeignKey(Userclass, on_delete=models.SET_NULL, related_name='Import_zip_Upload_User', null=True, blank=True)

def get_storage_path(self, filename):
Expand Down
33 changes: 26 additions & 7 deletions embark/reporter/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def get_individual_report(request, analysis_id):

logger.debug("getting individual report for %s", result)

return_dict = dict(model_to_dict(instance=result, exclude=['vulnerability']))
return_dict = model_to_dict(instance=result, exclude=['vulnerability'])

return_dict['firmware_name'] = analysis_object.firmware_name
if analysis_object.firmware:
Expand All @@ -143,6 +143,13 @@ def get_individual_report(request, analysis_id):
return_dict['version'] = analysis_object.version
return_dict['path_to_logs'] = analysis_object.path_to_logs
return_dict['strcpy_bin'] = json.loads(return_dict['strcpy_bin'])
# architecture
if isinstance(return_dict['architecture_verified'], dict):
arch_ = json.loads(return_dict['architecture_verified'])
for key_, value_ in arch_.items():
return_dict['architecture_verified'] += f"{key_}-{value_} "
else:
return_dict['architecture_verified'] = str(return_dict['architecture_verified'])

return JsonResponse(data=return_dict, status=HTTPStatus.OK)
except Result.DoesNotExist:
Expand All @@ -165,17 +172,31 @@ def get_accumulated_reports(request):
}
"""
results = Result.objects.all()
charfields = ['architecture_verified', 'os_verified']
charfields = ['os_verified', 'architecture_verified']
data = {}
strcpy_bins = {}
system_bin_dict = {}
for result in results:
result = model_to_dict(result)
# Pop firmware object_id
# Pop all unnecessary data
result.pop('vulnerability', None) # FIXME this is disabled for now
result.pop('firmware', None)
result.pop('emba_command', None)

# architecture FIXME
# architecture = result.pop('architecture_verified', '{}')
# if isinstance(architecture, dict):
# # clean-up for architecture descriptions
# for key_, value_ in architecture.items():
# if value_.lower() == 'el':
# data['architecture_verified'] += f"{key_}-Little Endian "
# elif value_.lower() == 'eb':
# data['architecture_verified'] += f"{key_}-Big Endian "
# else:
# data['architecture_verified'] += f"{key_}-{value_} "
# else:
# data['architecture_verified'] = str(architecture)

# Get counts for all strcpy_bin and system_bin values
system_bin = json.loads(result.pop('system_bin', '{}'))
strcpy_bin = json.loads(result.pop('strcpy_bin', '{}'))
Expand All @@ -188,18 +209,16 @@ def get_accumulated_reports(request):
system_bin_dict[key] = 0
system_bin_dict[key] += int(system_bin[key])

# os_verified
for charfield in charfields:
charfield = cleanup_charfield(charfield)

if charfield not in data:
data[charfield] = {}

value = result.pop(charfield)

if value not in data[charfield]:
data[charfield][value] = 0

data[charfield][value] += 1

for field in result:
if field not in data:
data[field] = {'sum': 0, 'count': 0}
Expand Down
3 changes: 3 additions & 0 deletions embark/templates/dashboard/logViewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<pre id="logArea" style="font-family: monospace;">
</pre>
<div class="buttonRow">
<form action={% url 'embark-dashboard-service' %} method='get'>
<button type="submit" class="btn buttonRowElem">Back</button>
</form>
<form action={% url 'embark-show-log' analysis_id %} method='get'>
<button type="submit" class="btn buttonRowElem">Raw EMBA log file</button>
</form>
Expand Down
62 changes: 36 additions & 26 deletions embark/templates/dashboard/reportDashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,25 @@
{% if firmware.end_date is not None %}
{{ firmware.end_date}}
{% else %}
<button class="btn btn-primary" type="button" disabled>
<span class="badge badge-danger">Results are on their way</span>
</button>
<form action={% url 'embark-show-logviewer' firmware.id %} method='get'>
<button type="submit" class="btn btn-primary">
<span class="badge badge-danger">Results are on their way</span>
</button>
</form>
{% endif %}
</td>
<td>
<!--ButtonRow with menue-->
<div class="buttonRow">
{% if firmware.finished is False %}
{% if firmware.failed is True %}
<button class="btn btn-primary" type="button" disabled>
<span class="badge badge-danger">Failed/Error</span>
</button>
<button type="button" class="btn buttonRowElem btn-danger" data-bs-toggle="modal" data-bs-target="#DeleteModal-{{ firmware.id }}">
Delete Analysis
</button>
{% endif %}
<button class="btn btn-primary" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Loading...
Expand Down Expand Up @@ -109,32 +119,32 @@
</button>
</div>
</div>
<!-- Modals -->
<div class="modal fade" id="DeleteModal-{{ firmware.id }}" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="DeleteModal-{{ firmware.id }}-Label">Delete Analysis {{ firmware.id }}</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">Close</span>
</button>
</div>
<div class="modal-body">
Are you sure you want to delete this analysis of {{ firmware.firmware_name }}?
-- if the analysis is archived already, this will delete it from the archives,too!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">NO</button>

<form action="{% url 'embark-dashboard-delete-analysis' firmware.id %}" method="get" id="delete-form-{{ firmware.id }}">
<button type="submit" class="btn btn-primary">YES</button>
</form>

</div>
{% endif %}
<!-- Modals -->
<div class="modal fade" id="DeleteModal-{{ firmware.id }}" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="DeleteModal-{{ firmware.id }}-Label">Delete Analysis {{ firmware.id }}</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">Close</span>
</button>
</div>
<div class="modal-body">
Are you sure you want to delete this analysis of {{ firmware.firmware_name }}?
-- if the analysis is archived already, this will delete it from the archives,too!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">NO</button>

<form action="{% url 'embark-dashboard-delete-analysis' firmware.id %}" method="get" id="delete-form-{{ firmware.id }}">
<button type="submit" class="btn btn-primary">YES</button>
</form>

</div>
</div>
</div>
{% endif %}
</div>
</div>
</td>
</tr>
Expand Down
6 changes: 3 additions & 3 deletions embark/templates/user/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
<img src="{% static 'content/images/embark_logo.svg' %}" alt="EMBArk logo graphic" height="auto" width="auto"/>
</div>
<div class="d-flex justify-content-center">
<h3><span class="badge bg-secondary">New</span>Device-based Tracking</h3>
</div>
<h3><span class="badge bg-secondary">New</span>Per-user timezone settings in the user menu</h3>
</div>
<div class="d-flex justify-content-center">
<h3><span class="badge bg-secondary">New</span>Import functionality</h3>
<h3><span class="badge bg-secondary">New</span>New Buttons everywhere</h3>
</div>
<div class="login">
<form action="{% url 'embark-login' %}" class="login-form" method="post">
Expand Down
4 changes: 2 additions & 2 deletions embark/tracker/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from datetime import datetime, timedelta
import logging

from django.conf import settings
Expand All @@ -8,6 +7,7 @@
from django.views.decorators.http import require_http_methods
from django.shortcuts import redirect
from django.contrib import messages
from django.utils import timezone

from django_tables2 import RequestConfig

Expand Down Expand Up @@ -44,7 +44,7 @@ def tracker(request):
return redirect('embark-uploader-home')
logger.error("invalid date form")
return redirect('..')
date = datetime.today() - timedelta(days=7)
date = timezone.localdate() - timezone.timedelta(days=7)
vendor_list = Vendor.objects.all()
if vendor_list.count() != 0:
label_list = []
Expand Down
6 changes: 3 additions & 3 deletions embark/uploader/boundedexecutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from threading import BoundedSemaphore

from django.dispatch import receiver
from django.utils.datetime_safe import datetime
from django.utils import timezone
from django.conf import settings

from uploader import finish_execution
Expand Down Expand Up @@ -116,8 +116,8 @@ def run_emba_cmd(cls, cmd, analysis_id=None, active_analyzer_dir=None):

# finalize db entry
if analysis:
analysis.end_date = datetime.now()
analysis.scan_time = datetime.now() - analysis.start_date
analysis.end_date = timezone.now()
analysis.scan_time = timezone.now() - analysis.start_date
analysis.duration = str(analysis.scan_time)
analysis.finished = True
analysis.failed = exit_fail
Expand Down
5 changes: 2 additions & 3 deletions embark/uploader/management/commands/runapscheduler.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import datetime as dtime
import logging
import psutil

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils.datetime_safe import datetime
from django.utils import timezone
from django_apscheduler.jobstores import DjangoJobStore
from django_apscheduler.models import DjangoJobExecution
from django_apscheduler import util
Expand Down Expand Up @@ -54,7 +53,7 @@ def delete_old_job_executions(max_age=1_209_600):
DjangoJobExecution.objects.delete_old_job_executions(max_age)

# delete entries in db older than 2 weeks
time_delta = datetime.now() - dtime.timedelta(seconds=max_age)
time_delta = timezone.now() - timezone.timedelta(seconds=max_age)
ResourceTimestamp.objects.all().filter(timestamp__lt=time_delta).delete()


Expand Down
Loading
Loading