digitaleagenturnc/digitaleagentur/views.py

178 lines
4.9 KiB
Python

from django.shortcuts import render
from django.contrib.auth.mixins import AccessMixin
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView, TemplateView
import requests
import magic
from django.conf import settings
from django.core.validators import URLValidator, ValidationError
from django.http import Http404, HttpResponse
from django.views.generic import View
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import os, six
from recoverdir.models import RecoverDirSetting
from datetime import datetime
from django.contrib import messages
from django.shortcuts import render, redirect, reverse
def _get_setting(name):
setting_name = "DEFF_{}".format(name)
return os.getenv(setting_name, getattr(settings, setting_name, None))
def get_bytes(v):
if isinstance(v, six.string_types):
return bytes(v.encode("utf-8"))
if isinstance(v, bytes):
return v
raise TypeError(
"SALT & PASSWORD must be specified as strings that convert nicely to "
"bytes."
)
SALT = get_bytes(_get_setting("SALT"))
PASSWORD = get_bytes(_get_setting("PASSWORD"))
FETCH_URL_NAME = _get_setting("FETCH_URL_NAME")
class Cryptographer(object):
_fernet = Fernet(base64.urlsafe_b64encode(PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=SALT,
iterations=100000,
backend=default_backend()
).derive(PASSWORD)))
@classmethod
def encrypted(cls, content):
return cls._fernet.encrypt(content)
@classmethod
def decrypted(cls, content):
return cls._fernet.decrypt(content)
def registerdone(request):
return render (request, 'users/registercomplete.html')
# TASK: Hier den Abruf von Dokumenten bei eingeloggtem Recover-Datum weniger als 10 Minuten implementieren
class GetCryptFileRecover(TemplateView):
def get(self, request, *args, **kwargs):
try:
settings = RecoverDirSetting.objects.filter(agency_id=kwargs['agpk'])[0]
except IndexError:
messages.warning(self.request, f'Diese Agentur hat keine Notfallhilfe.')
return redirect('load-rd-external')
if settings.lastlogg == None:
messages.warning(self.request, f'Bitte loggen Sie sich erneut ein!')
return redirect('load-rd-external')
else:
now = datetime.now()
time_delta = (now-settings.lastlogg)
total_seconds = time_delta.total_seconds()
minutes = total_seconds/60
if(settings.lastlogg != None and minutes < 10):
# LOGIN OK AND LOGIN EARLIER THAN 10 MINUTES
path = kwargs.get("path")
# No path? You're boned. Move along.
if not path:
raise Http404
if self._is_url(path):
content = requests.get(path, stream=True).raw.read()
else:
# Normalise the path to strip out naughty attempts
#path = os.path.normpath(path).replace(settings.MEDIA_URL, settings.MEDIA_ROOT, 1)
path = "media/" + path
# Evil path request!
#if not path.startswith(settings.MEDIA_ROOT):
# print("404 startswith")
# raise Http404
# The file requested doesn't exist locally. A legit 404
if not os.path.exists(path):
raise Http404
with open(path, "rb") as f:
content = f.read()
content = Cryptographer.decrypted(content)
return HttpResponse(content, content_type=magic.Magic(mime=True).from_buffer(content))
else:
# LOGIN TO OLD - SET LASTLOGG TO NONE AND SEND MESSAGE
settings.lastlogg = None
settings.save()
messages.warning(self.request, f'Bitte loggen Sie sich erneut ein!')
return redirect('load-rd-external')
@staticmethod
def _is_url(path):
try:
URLValidator()(path)
return True
except ValidationError:
return False
class GetCryptFile(DetailView):
def get(self, request, *args, **kwargs):
if(self.request.user.has_perm("users.recoverdirmanager")):
path = kwargs.get("path")
# No path? You're boned. Move along.
if not path:
raise Http404
if self._is_url(path):
content = requests.get(path, stream=True).raw.read()
else:
# Normalise the path to strip out naughty attempts
path = os.path.normpath(path).replace(settings.MEDIA_URL, settings.MEDIA_ROOT, 1)
path = "media/" + path
# Evil path request!
#if not path.startswith(settings.MEDIA_ROOT):
# print("404 startswith")
# raise Http404
# The file requested doesn't exist locally. A legit 404
if not os.path.exists(path):
raise Http404
with open(path, "rb") as f:
content = f.read()
content = Cryptographer.decrypted(content)
return HttpResponse(content, content_type=magic.Magic(mime=True).from_buffer(content))
else:
return render(request, 'cloud/noentrie.html')
@staticmethod
def _is_url(path):
try:
URLValidator()(path)
return True
except ValidationError:
return False