digitaleagenturnc/digitaleagentur/views.py

107 lines
2.8 KiB
Python

from django.shortcuts import render
from django.contrib.auth.mixins import AccessMixin
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView
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
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')
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