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