Skip to content
Merged
49 changes: 49 additions & 0 deletions embark/embark/wsgi_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# pylint: disable=simplifiable-if-statement, unused-argument, wrong-import-order, wrong-import-position, ungrouped-imports
import os

os.environ["DJANGO_SETTINGS_MODULE"] = "embark.settings.deploy"

import django
django.setup()

from django.core.handlers.wsgi import WSGIHandler

application = WSGIHandler()

from users.models import User
from django import db


def check_password(environ, user, password):
db.reset_queries()

kwargs = {'username': user, 'is_active': True}

try:
try:
user = User.objects.get(**kwargs)
except User.DoesNotExist:
return None

if user.check_password(password):
return True
else:
return False
finally:
db.connection.close()


def groups_for_user(environ, user):
db.reset_queries()

kwargs = {'username': user, 'is_active': True}

try:
user = User.objects.get(**kwargs)
except User.DoesNotExist:
return None

group_list = user.groups.values_list('name', flat=True)
print(group_list)
db.connection.close()
return group_list
20 changes: 20 additions & 0 deletions embark/templates/uploader/download.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% load static %}
{% block style %}<link rel="stylesheet" type="text/css" href="{% static 'content/css/uploader.css' %}"/>{% endblock style %}

<div class="row DownloadRow">
<div class="box">
<p class="mainText">Select and download a firmware file</p>
<form action="{% url 'embark-uploader-download' %}" method="post" id="download-form">
<!-- onsubmit="window.confirmDelete(event)" -->
{% csrf_token %}
<div class="innerBlock">
<div id="firmwareToDownload" class="form-group downloadFirmware" >
{{ download_form }}
</div>
</div>
<div class="buttonRow">
<button type="submit" class="btn buttonRowElem">Download</button>
</div>
</form>
</div>
</div>
1 change: 1 addition & 0 deletions embark/templates/uploader/manage.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
{% block maincontent %}
{% block upload %}{% include "uploader/upload.html" %}{% endblock upload %}
{% block delete %}{% include "uploader/delete.html" %}{% endblock delete %}
{% block download %}{% include "uploader/download.html" %}{% endblock download %}
{% endblock maincontent %}
4 changes: 4 additions & 0 deletions embark/uploader/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,7 @@ def clean_scan_modules(self):

class DeleteFirmwareForm(forms.Form):
firmware = forms.ModelChoiceField(queryset=models.FirmwareFile.objects, empty_label='Select firmware-file to delete')


class DownloadFirmwareForm(forms.Form):
firmware = forms.ModelChoiceField(queryset=models.FirmwareFile.objects, empty_label='Select firmware-file to download')
1 change: 1 addition & 0 deletions embark/uploader/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
path('uploader/manage/', views.manage_file, name='embark-uploader-manage-file'),
path('uploader/save/', views.save_file, name='embark-uploader-save'),
path('uploader/delete/', views.delete_fw_file, name='embark-uploader-delete'),
path('uploader/download/', views.download_firmware, name='embark-uploader-download'),

path('uploader/start/', views.start_analysis, name='embark-uploader-start-analysis'),

Expand Down
63 changes: 53 additions & 10 deletions embark/uploader/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
__license__ = 'MIT'

import logging
import mimetypes
import os
from wsgiref.util import FileWrapper

from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseServerError, QueryDict
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError, QueryDict, StreamingHttpResponse
from django.contrib.auth.decorators import login_required, permission_required
from django.views.decorators.http import require_http_methods
from django.contrib import messages
Expand All @@ -19,7 +21,7 @@

from embark.helper import disk_space_check, user_is_auth
from uploader.boundedexecutor import BoundedExecutor
from uploader.forms import DeviceForm, FirmwareAnalysisForm, DeleteFirmwareForm, LabelForm, VendorForm
from uploader.forms import DeviceForm, DownloadFirmwareForm, FirmwareAnalysisForm, DeleteFirmwareForm, LabelForm, VendorForm
from uploader.models import FirmwareFile
from uploader.serializers import FirmwareAnalysisSerializer
from users.decorators import require_api_key
Expand Down Expand Up @@ -283,10 +285,12 @@ def start_analysis(request):
def manage_file(request):
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})
delete_form = DeleteFirmwareForm(initial={'firmware': FirmwareFile.objects.filter(user=request.user).latest('upload_date').id})
download_form = DownloadFirmwareForm(initial={'firmware': FirmwareFile.objects.filter(user=request.user).latest('upload_date').id})
else:
delete_form = DeleteFirmwareForm()
download_form = DownloadFirmwareForm()
return render(request, 'uploader/manage.html', {'delete_form': delete_form, 'download_form': download_form})


@permission_required("users.uploader_permission_advanced", login_url='/')
Expand All @@ -308,16 +312,17 @@ def delete_fw_file(request):

# get relevant data
firmware_file = form.cleaned_data['firmware']
if request.user != firmware_file.user and not request.user.is_superuser:
return HttpResponseForbidden("You are not authorized!")
if not user_is_auth(request.user, firmware_file.user):
messages.error(request, 'You are not authorized to delete this firmware file.')
return redirect('embark-uploader-manage-file')
firmware_file.delete()
messages.info(request, 'delete successful.')
return redirect('..')
return redirect('embark-uploader-manage-file')

logger.error("Form %s is invalid", form)
logger.error("Form error: %s", form.errors)
messages.error(request, 'error in form')
return redirect('..')
return redirect('embark-uploader-manage-file')


@permission_required("users.uploader_permission_minimal", login_url='/')
Expand All @@ -332,3 +337,41 @@ def uploader_home_minimal(request):
analysis_form = FirmwareAnalysisForm()
analysis_form.fields.pop('device')
return render(request, 'uploader/minimal.html', {'analysis_form': analysis_form})


@permission_required("users.uploader_permission_advanced", login_url='/')
@login_required(login_url='/' + settings.LOGIN_URL)
@require_http_methods(["POST"])
def download_firmware(request):
"""
Download the firmware file
"""
req_logger.info("User %s called download_firmware", request.user.username)
form = DownloadFirmwareForm(request.POST)

if form.is_valid():
logger.debug("Form %s is valid", form)

# get relevant data
firmware_file = form.cleaned_data['firmware']
if not user_is_auth(request.user, firmware_file.user):
messages.error(request, 'You are not authorized to download this firmware file.')
return redirect('embark-uploader-manage-file')
file = firmware_file.file.path
filename = os.path.basename(file)
chunk_size = 8192
response = StreamingHttpResponse(
FileWrapper(
open(file, "rb"), # pylint: disable=consider-using-with
chunk_size,
),
content_type=mimetypes.guess_type(file)[0],
)
response["Content-Length"] = os.path.getsize(file)
response["Content-Disposition"] = f"attachment; filename={filename}"
return response

logger.error("Form %s is invalid", form)
logger.error("Form error: %s", form.errors)
messages.error(request, 'error in form')
return redirect('embark-uploader-manage-file')
48 changes: 44 additions & 4 deletions run-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,54 @@ if ! [[ -d /var/www/conf ]]; then
mkdir /var/www/conf
fi
{
echo -e "LoadModule auth_basic_module \${MOD_WSGI_MODULES_DIRECTORY}/mod_auth_basic.so"
echo -e "LoadModule authz_user_module \${MOD_WSGI_MODULES_DIRECTORY}/mod_authz_user.so"
echo -e "WSGIPythonHome /var/www/.venv"
echo -e "WSGIPythonPath /var/www/embark/embark"
echo -e ""
echo -e "WSGIProcessGroup %{GLOBAL}"
echo -e "WSGIApplicationGroup %{GLOBAL}"
echo -e ""
echo -e "<Location /admin>"
echo -e "Order deny,allow"
echo -e "Deny from all"
echo -e "Allow from 127.0.0.1"
echo -e " Order deny,allow"
echo -e " Deny from all"
echo -e " Allow from 127.0.0.1"
if [[ ${#ADMIN_HOST_RANGE[@]} -ne 0 ]]; then
echo -e "Allow from ${ADMIN_HOST_RANGE[*]}"
echo -e " Allow from ${ADMIN_HOST_RANGE[*]}"
fi
echo -e "</Location>"
echo -e ""
echo -e "Alias '/media' '/var/www/media'"
echo -e "<Directory '/var/www/media'>"
echo -e " AllowOverride None"
echo -e "<IfVersion < 2.4>"
echo -e " Order allow,deny"
echo -e " Allow from all"
echo -e "</IfVersion>"
echo -e "<IfVersion >= 2.4>"
echo -e " Require all granted"
echo -e "</IfVersion>"
echo -e "</Directory>"
echo -e "<Location /media>"
echo -e " Order deny,allow"
echo -e " Deny from all"
echo -e " Allow from 127.0.0.1"
if [[ ${#ADMIN_HOST_RANGE[@]} -ne 0 ]]; then
echo -e " Allow from ${ADMIN_HOST_RANGE[*]}"
fi
echo -e " AuthType Basic"
echo -e " AuthName Admin"
echo -e " AuthBasicProvider wsgi"
echo -e " WSGIAuthUserScript /var/www/embark/embark/wsgi_auth.py"
echo -e " WSGIAuthGroupScript /var/www/embark/embark/wsgi_auth.py"
# echo -e " Require valid-user"
echo -e " Require wsgi-group Administration_Group"
echo -e "</Location>"
# echo -e "<Directory /var/www/embark/embark>"
# echo -e " <Files wsgi_auth.py>"
# echo -e " Require all granted"
# echo -e " </Files>"
# echo -e "</Directory>"
} > /var/www/conf/embark.conf

# certs
Expand Down
Loading