Skip to content

Commit

Permalink
Merge pull request #164 from BenediktMKuehne/Dev
Browse files Browse the repository at this point in the history
Report-Dashboard-changes
  • Loading branch information
m-1-k-3 authored Nov 21, 2023
2 parents f9d6530 + 625245b commit 82c9f95
Show file tree
Hide file tree
Showing 20 changed files with 276 additions and 65 deletions.
2 changes: 1 addition & 1 deletion dev-tools/debug-server-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

# http-server options
PORT="8000"
IP="127.0.0.1"
IP="0.0.0.0"

export RED='\033[0;31m'
export GREEN='\033[0;32m'
Expand Down
2 changes: 2 additions & 0 deletions embark/dashboard/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
path('dashboard/main/', views.main_dashboard, name='embark-MainDashboard'),
path('dashboard/service/', views.service_dashboard, name='embark-dashboard-service'),
path('dashboard/report/', views.report_dashboard, name='embark-ReportDashboard'),
path('dashboard/report/deleteAnalysis/<uuid:analysis_id>', views.delete_analysis, name='embark-dashboard-delete-analysis'),
path('dashboard/report/archive/<uuid:analysis_id>', views.archive_analysis, name='embark-dashboard-archive'),
path('dashboard/individualReport/<uuid:analysis_id>', views.individual_report_dashboard, name='embark-IndividualReportDashboard'),
path('dashboard/stop/', views.stop_analysis, name='embark-stop-analysis'),
path('dashboard/log/<uuid:analysis_id>', views.show_log, name='embark-show-log'),
Expand Down
60 changes: 59 additions & 1 deletion embark/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseRedirect, HttpResponseServerError
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.contrib import messages
from django.shortcuts import redirect
from tracker.forms import AssociateForm
from uploader.boundedexecutor import BoundedExecutor

from uploader.models import FirmwareAnalysis
from dashboard.models import Result
from dashboard.forms import StopAnalysisForm
from porter.views import make_zip


logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -50,7 +54,7 @@ def stop_analysis(request):
logger.debug("PID is %s", pid)
try:
BoundedExecutor.submit_kill(analysis.id)
os.killpg(os.getpgid(pid), signal.SIGTERM)
os.killpg(os.getpgid(pid), signal.SIGTERM) # kill proc group too
form = StopAnalysisForm()
form.fields['analysis'].queryset = FirmwareAnalysis.objects.filter(finished=False)
return render(request, 'dashboard/serviceDashboard.html', {'username': request.user.username, 'form': form, 'success_message': True, 'message': "Stopped successfully"})
Expand Down Expand Up @@ -145,3 +149,57 @@ def show_logviewer(request, analysis_id):

except FileNotFoundError:
return HttpResponseServerError(content="File is not yet available")


@require_http_methods(["GET"])
@login_required(login_url='/' + settings.LOGIN_URL)
def delete_analysis(request, analysis_id):
"""
:params request: HTTP request
:params analysis_id: uuid of analysis the user wants to stop
:return: redirect
"""
logger.info("Deleting analyze_id: %s", analysis_id)
analysis = FirmwareAnalysis.objects.get(id=analysis_id)
# check that the user is authorized
if request.user == analysis.user or request.user.is_superuser:
if analysis.finished is False:
try:
BoundedExecutor.submit_kill(analysis.id)
os.killpg(os.getpgid(analysis.pid), signal.SIGTERM) # kill proc group too
except builtins.Exception as error:
logger.error("Error %s when stopping", error)
messages.error(request, 'Error when stopping Analysis')
# check if finished
if analysis.finished is True:
# delete
try:
analysis.delete(keep_parents=True)
messages.success(request, 'Analysis: ' + str(analysis_id) + ' successfully deleted')
except builtins.Exception as error:
logger.error("Error %s", error)
messages.error(request, 'Error when deleting Analysis')
else:
messages.error(request, 'Analysis is still running')
return redirect('..')
messages.error(request, "You are not authorized to delete another users Analysis")
return redirect('..')


@login_required(login_url='/' + settings.LOGIN_URL)
@require_http_methods(["GET"])
def archive_analysis(request, analysis_id):
"""
archives analysis, safes zip instead of normal log directory
and sets analysis into archived state
"""
logger.info("Archiving Analysis with id: %s", analysis_id)
analysis = FirmwareAnalysis.objects.get(id=analysis_id)
if analysis.zip_file is None:
# make archive for uuid
_ = make_zip(request, analysis_id)
analysis.do_archive()
analysis.archived = True
analysis.save(update_fields=["archived"])
return redirect('..')
18 changes: 18 additions & 0 deletions embark/embark/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ def zip_check(content_list):
return all(value_ in content_list for value_ in check_list)


def cleanup_charfield(charfield):
# 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())
3 changes: 3 additions & 0 deletions embark/embark/settings/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""
from pathlib import Path
import os
import pytz

from dotenv import load_dotenv

Expand Down Expand Up @@ -231,6 +232,8 @@

USE_TZ = False

TIMEZONES = tuple(zip(pytz.all_timezones, pytz.all_timezones))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
Expand Down
5 changes: 4 additions & 1 deletion embark/embark/settings/dev.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pathlib import Path
import os
import pytz

from dotenv import load_dotenv

Expand Down Expand Up @@ -195,7 +196,9 @@

USE_L10N = True

USE_TZ = False
USE_TZ = True

TIMEZONES = tuple(zip(pytz.all_timezones, pytz.all_timezones))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
Expand Down
7 changes: 2 additions & 5 deletions embark/reporter/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.urls import reverse
from embark.helper import cleanup_charfield
from uploader.boundedexecutor import BoundedExecutor

from uploader.models import FirmwareAnalysis, ResourceTimestamp
Expand Down Expand Up @@ -188,11 +189,7 @@ def get_accumulated_reports(request):
system_bin_dict[key] += int(system_bin[key])

for charfield in charfields:
# 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
charfield = cleanup_charfield(charfield)

if charfield not in data:
data[charfield] = {}
Expand Down
1 change: 0 additions & 1 deletion embark/static/content/css/navigation.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#navigation .logo-content {
height: 60px;
margin-bottom: 20px;
}

#navigation .logo-content .logo {
Expand Down
4 changes: 2 additions & 2 deletions embark/static/scripts/accumulatedReports.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ function makeCharts(returnData) {
plugins: {
title: {
display: true,
text: 'Binaries with weak functions',
text: 'Binaries using legacy C-function strcpy',
position: 'top',
color: 666,
padding: {
Expand Down Expand Up @@ -574,7 +574,7 @@ function makeCharts(returnData) {
plugins: {
title: {
display: true,
text: 'System Binaries',
text: 'Binaries using C-function system',
position: 'top',
color: 666,
padding: {
Expand Down
2 changes: 1 addition & 1 deletion embark/templates/dashboard/logViewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</pre>
<div class="buttonRow">
<form action={% url 'embark-show-log' analysis_id %} method='get'>
<button type="submit" class="btn buttonRowElem">Download Logs</button>
<button type="submit" class="btn buttonRowElem">Raw EMBA log file</button>
</form>
</div>
</div>
Expand Down
113 changes: 83 additions & 30 deletions embark/templates/dashboard/reportDashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
</thead>

<tbody>
{% load tz %}
{% timezone request.session.django_timezone %}
{% for firmware in firmwares %}
<tr>
<td>{{ firmware.id }}</td>
Expand All @@ -44,49 +46,100 @@
{% endfor %}
</td>
<td>{{ firmware.version }}</td>
<td>{{ firmware.start_date }}</td>
<td>{{ firmware.end_date }}</td>

<td>{{ firmware.start_date}}</td>
<td>
{% 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>
{% endif %}
</td>
<td>
<!--ButtonRow with menue-->
<div class="buttonRow">
<!-- If firmware is being worked on-->
{% if firmware.finished is False %}
<button class="btn btn-primary" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Loading...
</button>
<button class="btn btn-primary" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Loading...
</button>
{% else %}
{% if firmware.failed is True %}
<button class="btn btn-primary" type="button" disabled>
<span class="badge badge-danger">Analysis Failed</span>
</button>
{% else %}
{% if firmware.zip_file is not None %}
<form action={% url 'embark-download' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Download Logs</button>
</form>
{% else %}
<form action={% url 'embark-make-zip' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Make Zip Logs</button>
</form>
{% endif %}
<form action={% url 'embark-html-report' firmware.id 'index.html' %} method='get'>
<button type="submit" class="btn buttonRowElem" >Open Report</button>
</form>
<form action={% url 'embark-IndividualReportDashboard' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Detail View</button>
</form>
<form action={% url 'embark-uploader-home' %} method='get'>
<button type="submit" class="btn buttonRowElem" >Rescan/delete</button>
</form>
{% endif %}
<div class="btn-group dropup">
<button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action-Menue
</button>
<div class="dropdown-menu">
{% if firmware.failed is False %}
{% if firmware.zip_file is not None %}
<form action={% url 'embark-download' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Download Logs</button>
</form>
{% elif firmware.archived is False %}
<form action={% url 'embark-make-zip' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Make Zip Logs</button>
</form>
{% endif %}
<form action={% url 'embark-html-report' firmware.id 'index.html' %} method='get'>
<button type="submit" class="btn buttonRowElem" >Open Report</button>
</form>
<form action={% url 'embark-IndividualReportDashboard' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Detail View</button>
</form>
<form action={% url 'embark-uploader-home' %} method='get'>
<button type="submit" class="btn buttonRowElem" >Rescan/delete</button>
</form>
{% if firmware.archived is False %}
<form action={% url 'embark-dashboard-archive' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >Archive</button>
</form>
{% endif %}
{% endif %}
<form action={% url 'embark-show-logviewer' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >View Log</button>
</form>
<button type="button" class="btn buttonRowElem btn-danger" data-bs-toggle="modal" data-bs-target="#DeleteModal-{{ firmware.id }}">
Delete Analysis
</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>
</div>
</div>
</div>
{% endif %}
<form action={% url 'embark-show-logviewer' firmware.id %} method='get'>
<button type="submit" class="btn buttonRowElem" >View Log</button>
</form>
</div>
</div>
</td>
</tr>
{% endfor %}
{% endtimezone %}
</tbody>
</table>
</div>
Expand Down
4 changes: 2 additions & 2 deletions embark/templates/navigation.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@
<span class="nav-link" >My Account</span>
</a>
<ul class="dropdown-content">
<a href="{% url 'embark-user-menu' %}">
<span class="nav-link">User Menu(unavailable)</span>
<a href="{% url 'embark-user-main' %}">
<span class="nav-link">User Menu</span>
</a>
<a href="{% url 'embark-password-change' %}">
<span class="nav-link">Change password</span>
Expand Down
12 changes: 12 additions & 0 deletions embark/templates/user/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "base.html" %}
{% load static %}
{% block style %}<link rel="stylesheet" type="text/css" href="{% static 'content/css/menu.css' %}"/>{% endblock style %}
{% block title %}EMBArk User-menue{% endblock title %}

{% block navigation %}{% include "navigation.html" %}{% endblock navigation %}
{% block maincontent %}
<div class="container-fluid">
{% block timezone %}{% include "user/timezone.html" %}{% endblock timezone %}
</div>
{% endblock maincontent %}

Loading

0 comments on commit 82c9f95

Please sign in to comment.