2021-02-11 20:38:39 +01:00

271 lines
11 KiB
Python

from rest_framework import viewsets, permissions
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from health_view.serializers import *
from health_view.crypto_functions import *
from datetime import datetime
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
import json
@csrf_exempt
def get_key(request, name, part_name="", justified=""):
user_obj = User.objects.get(username=name)
justified_obj = User.objects.get(username=justified)
folderinfo = user_obj.folderinfo
folderpart_obj = FolderPart.objects.get(part_class=part_name, folder_id=folderinfo)
key = JustifiedKey.objects.filter(justified_name=justified_obj, part=folderpart_obj).first()
if request.method == 'GET':
serializer = KeySerializer(key)
return JsonResponse(serializer.data)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = KeySerializer(key, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@csrf_exempt
def get_content(request, name, part_name=""):
user_obj = User.objects.get(username=name)
folderinfo = user_obj.folderinfo
folderpart_obj = FolderPart.objects.get(part_class=part_name, folder_id=folderinfo)
if request.method == 'GET':
serializer = ContentSerializer(folderpart_obj)
return JsonResponse(serializer.data)
elif request.method == 'POST':
data = json.loads(request.body)
serializer = ContentSerializer(folderpart_obj, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
def create_signature_string(license):
signature_string = license["patient"] + "&" + license["justified"] + "&" + license["creator"] + "&" + license["expdate"].replace(" ", ",") + "&" + license["permissions"] + "&" + license["folderparts"]
signature_string = signature_string.replace(" ", "")
return signature_string
def create_signature_string_certificate(license):
signature_string = license["patient"] + "&" + license["justified"] + "&" + license["creator"] + "&" + license["expdate"].replace(" ", ",") + "&" + license["permissions"] + "&" + license["folderparts"] + "&" + license["signature"] + "&" + license['content_key']
signature_string = signature_string.replace(" ", "")
return signature_string
def get_creator(license):
creator = User.objects.get(username=license["creator"])
return creator
def get_pubkey(user):
pubkey = user.folderinfo.pub_key
return pubkey
def check_expiration_date(license):
exp_date = license["expdate"]
print(exp_date)
for fmt in ('%d-%m-%Y %H:%M', '%d/%m/%Y %H:%M', '%d/%m/%Y', '%d-%m-%Y'):
try:
datetime_object = datetime.strptime(exp_date, fmt)
break
except ValueError:
pass
try:
return datetime.now() < datetime_object
except Exception:
return False
def check_permissions(license, part, permission):
if part == "":
return True
if permission not in license["permissions"]:
return False
if part not in license["folderparts"]:
return False
return True
def check_change_siganture(pubkey, user_sign, datetime_given, content):
message = datetime_given + "|" + content
if verify(message, user_sign, pubkey):
return True
return False
def check_license(license, folderpart="", permission=""):
creator = get_creator(license)
if not verify(create_signature_string(license), license['signature'], get_pubkey(creator)):
return False
if not verify(create_signature_string_certificate(license), license['serversign'], pub_key_licenseserver):
return False
if not check_expiration_date(license):
return False
if not check_permissions(license, folderpart, permission):
return False
return True
@csrf_exempt
def read_folder(request):
if request.method == 'POST':
data = json.loads(request.body)
license = data[0]
folderpart = data[1]
if not check_license(license, folderpart, "Read"):
return HttpResponse(status=404)
content_key = license['content_key']
content_key_decrypted = decrypt(content_key)
patient = User.objects.get(username=license["patient"])
part_class = FolderPart_Name.objects.get(part_name=folderpart)
part = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=part_class)
justified = User.objects.get(username=license["justified"])
pubkey_justified = justified.folderinfo.pub_key
if len(data) == 3:
justified = User.objects.get(username=license["creator"])
key_obj = JustifiedKey.objects.get(part=part, justified_name=justified)
content = part.part_context
decrypt_content = decrypt_aes(content, content_key_decrypted)
response_obj = {'content': decrypt_content,
'key': key_obj.key,
'pubkey': pubkey_justified}
return JsonResponse(response_obj, status=201)
@csrf_exempt
def write_folder(request):
if request.method == 'POST':
data = json.loads(request.body)
license = data[0]
folderpart = data[1]
content = data[2]
datetime_given = data[3]
user_sign = data[4]
if not check_license(license, folderpart, "Write"):
return HttpResponse(status=404)
content_key = license['content_key']
datetime_given_formatted = datetime.strptime(datetime_given, '%Y-%m-%d|%H:%M:%S')
date_difference = datetime.now() - datetime_given_formatted
content_key_decrypt = decrypt(content_key)
patient = User.objects.get(username=license["patient"])
part_class = FolderPart_Name.objects.get(part_name=folderpart)
part = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=part_class)
justified = User.objects.get(username=license["justified"])
if date_difference.seconds//60.0 > 4.0 or not check_change_siganture(get_pubkey(justified), user_sign, datetime_given, content):
return HttpResponse(status=404)
content = folderpart + content
part.part_context = encrypt_aes(content, content_key_decrypt)
if JustifiedKey.objects.filter(part=part, justified_name=justified).exists():
part.save()
json_obj = {'works': 'fined'}
return JsonResponse(json_obj, status=201)
@csrf_exempt
def create_new_folder(request):
if request.method == 'POST':
data = json.loads(request.body)
print(data)
license = data[0]
if not check_license(license):
return HttpResponse(status=404)
content_key = license['content_key']
content_key_decrypt = decrypt(content_key)
patient = User.objects.get(username=license["patient"])
for c in range(1, len(data)):
part_class = data[c]["part_class"]
content = data[c]["content"]
content = part_class + content
encrypted_key = data[c]["encrypted_key"]
encrypted_content = encrypt_aes(content, content_key_decrypt)
part_class = FolderPart_Name.objects.get(part_name=part_class)
part = FolderPart(folder_id=patient.folderinfo, part_class=part_class, part_context=encrypted_content)
part.save()
justified = User.objects.get(username=license["justified"])
justified_key = JustifiedKey(part=part, justified_name=justified, key=encrypted_key)
justified_key.save()
json_obj = {'works': 'fined'}
return JsonResponse(json_obj, status=201)
@csrf_exempt
def create_key(request):
if request.method == 'POST':
data = json.loads(request.body)
license = data[0]
part_class = data[1]
key = data[2]
if not check_license(license):
return HttpResponse(status=404)
patient = User.objects.get(username=license["patient"])
part_class = FolderPart_Name.objects.get(part_name=part_class)
justified = User.objects.get(username=license["justified"])
part = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=part_class)
if not JustifiedKey.objects.filter(part=part, justified_name=justified, key=key).exists():
justified_key = JustifiedKey(part=part, justified_name=justified, key=key)
justified_key.save()
content_response = {"done": 1}
return JsonResponse(content_response, status=201)
@api_view(['POST'])
@csrf_exempt
@permission_classes([IsAdminUser])
def delete_justified_key(request):
post_content = json.loads(request.body)
print(post_content)
patient = post_content['patient']
justified = post_content['justified']
folder_parts_delete_key = post_content['folder_parts']
old_total_key = post_content['old_total_key']
new_total_key = post_content['new_total_key']
old_total_key_decrypt = decrypt(old_total_key)
new_total_key_decrypt = decrypt(new_total_key)
patient = User.objects.get(username=patient)
justified = User.objects.get(username=justified)
all_folder_parts = FolderPart_Name.objects.all().values_list()
for part in all_folder_parts:
folder_part_name_object = FolderPart_Name.objects.get(part_name=part[1])
folder_part_object = FolderPart.objects.get(part_class=folder_part_name_object,folder_id=patient.folderinfo)
decrypted_content = decrypt_aes(folder_part_object.part_context, old_total_key_decrypt)
encrypted_content = encrypt_aes(decrypted_content, new_total_key_decrypt)
folder_part_object.part_context = encrypted_content
folder_part_object.save()
for part in folder_parts_delete_key:
folder_part_name_object = FolderPart_Name.objects.get(part_name=part)
folder_part_object = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=folder_part_name_object)
key = JustifiedKey.objects.filter(part=folder_part_object, justified_name=justified)
key.delete()
return Response(status=201)
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [permissions.IsAuthenticated]
class GetFolderPartNames(viewsets.ModelViewSet):
queryset = FolderPart_Name.objects.all()
serializer_class = FolderPartNameSerializer