Digital Rights Management für elektronische Patientenakten
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. from rest_framework import viewsets, permissions
  2. from django.http import HttpResponse, JsonResponse
  3. from django.views.decorators.csrf import csrf_exempt
  4. from rest_framework.parsers import JSONParser
  5. from health_view.serializers import *
  6. from health_view.crypto_functions import *
  7. from datetime import datetime
  8. from rest_framework.decorators import api_view, permission_classes
  9. from rest_framework.permissions import IsAdminUser
  10. from rest_framework.response import Response
  11. import json
  12. @csrf_exempt
  13. def get_key(request, name, part_name="", justified=""):
  14. user_obj = User.objects.get(username=name)
  15. justified_obj = User.objects.get(username=justified)
  16. folderinfo = user_obj.folderinfo
  17. folderpart_obj = FolderPart.objects.get(part_class=part_name, folder_id=folderinfo)
  18. key = JustifiedKey.objects.filter(justified_name=justified_obj, part=folderpart_obj).first()
  19. if request.method == 'GET':
  20. serializer = KeySerializer(key)
  21. return JsonResponse(serializer.data)
  22. elif request.method == 'POST':
  23. data = JSONParser().parse(request)
  24. serializer = KeySerializer(key, data=data)
  25. if serializer.is_valid():
  26. serializer.save()
  27. return JsonResponse(serializer.data, status=201)
  28. return JsonResponse(serializer.errors, status=400)
  29. @csrf_exempt
  30. def get_content(request, name, part_name=""):
  31. user_obj = User.objects.get(username=name)
  32. folderinfo = user_obj.folderinfo
  33. folderpart_obj = FolderPart.objects.get(part_class=part_name, folder_id=folderinfo)
  34. if request.method == 'GET':
  35. serializer = ContentSerializer(folderpart_obj)
  36. return JsonResponse(serializer.data)
  37. elif request.method == 'POST':
  38. data = json.loads(request.body)
  39. serializer = ContentSerializer(folderpart_obj, data=data)
  40. if serializer.is_valid():
  41. serializer.save()
  42. return JsonResponse(serializer.data, status=201)
  43. return JsonResponse(serializer.errors, status=400)
  44. def create_signature_string(license):
  45. signature_string = license["patient"] + "&" + license["justified"] + "&" + license["creator"] + "&" + license["expdate"].replace(" ", ",") + "&" + license["permissions"] + "&" + license["folderparts"]
  46. signature_string = signature_string.replace(" ", "")
  47. return signature_string
  48. def create_signature_string_certificate(license):
  49. signature_string = license["patient"] + "&" + license["justified"] + "&" + license["creator"] + "&" + license["expdate"].replace(" ", ",") + "&" + license["permissions"] + "&" + license["folderparts"] + "&" + license["signature"] + "&" + license['content_key']
  50. signature_string = signature_string.replace(" ", "")
  51. return signature_string
  52. def get_creator(license):
  53. creator = User.objects.get(username=license["creator"])
  54. return creator
  55. def get_pubkey(user):
  56. pubkey = user.folderinfo.pub_key
  57. return pubkey
  58. def check_expiration_date(license):
  59. exp_date = license["expdate"]
  60. print(exp_date)
  61. for fmt in ('%d-%m-%Y %H:%M', '%d/%m/%Y %H:%M', '%d/%m/%Y', '%d-%m-%Y'):
  62. try:
  63. datetime_object = datetime.strptime(exp_date, fmt)
  64. break
  65. except ValueError:
  66. pass
  67. try:
  68. return datetime.now() < datetime_object
  69. except Exception:
  70. return False
  71. def check_permissions(license, part, permission):
  72. if part == "":
  73. return True
  74. if permission not in license["permissions"]:
  75. return False
  76. if part not in license["folderparts"]:
  77. return False
  78. return True
  79. def check_change_siganture(pubkey, user_sign, datetime_given, content):
  80. message = datetime_given + "|" + content
  81. if verify(message, user_sign, pubkey):
  82. return True
  83. return False
  84. def check_license(license, folderpart="", permission=""):
  85. creator = get_creator(license)
  86. if not verify(create_signature_string(license), license['signature'], get_pubkey(creator)):
  87. return False
  88. if not verify(create_signature_string_certificate(license), license['serversign'], pub_key_licenseserver):
  89. return False
  90. if not check_expiration_date(license):
  91. return False
  92. if not check_permissions(license, folderpart, permission):
  93. return False
  94. return True
  95. @csrf_exempt
  96. def read_folder(request):
  97. if request.method == 'POST':
  98. data = json.loads(request.body)
  99. license = data[0]
  100. folderpart = data[1]
  101. if not check_license(license, folderpart, "Read"):
  102. return HttpResponse(status=404)
  103. content_key = license['content_key']
  104. content_key_decrypted = decrypt(content_key)
  105. patient = User.objects.get(username=license["patient"])
  106. part_class = FolderPart_Name.objects.get(part_name=folderpart)
  107. part = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=part_class)
  108. justified = User.objects.get(username=license["justified"])
  109. pubkey_justified = justified.folderinfo.pub_key
  110. if len(data) == 3:
  111. justified = User.objects.get(username=license["creator"])
  112. key_obj = JustifiedKey.objects.get(part=part, justified_name=justified)
  113. content = part.part_context
  114. decrypt_content = decrypt_aes(content, content_key_decrypted)
  115. response_obj = {'content': decrypt_content,
  116. 'key': key_obj.key,
  117. 'pubkey': pubkey_justified}
  118. return JsonResponse(response_obj, status=201)
  119. @csrf_exempt
  120. def write_folder(request):
  121. if request.method == 'POST':
  122. data = json.loads(request.body)
  123. license = data[0]
  124. folderpart = data[1]
  125. content = data[2]
  126. datetime_given = data[3]
  127. user_sign = data[4]
  128. if not check_license(license, folderpart, "Write"):
  129. return HttpResponse(status=404)
  130. content_key = license['content_key']
  131. datetime_given_formatted = datetime.strptime(datetime_given, '%Y-%m-%d|%H:%M:%S')
  132. date_difference = datetime.now() - datetime_given_formatted
  133. content_key_decrypt = decrypt(content_key)
  134. patient = User.objects.get(username=license["patient"])
  135. part_class = FolderPart_Name.objects.get(part_name=folderpart)
  136. part = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=part_class)
  137. justified = User.objects.get(username=license["justified"])
  138. if date_difference.seconds//60.0 > 4.0 or not check_change_siganture(get_pubkey(justified), user_sign, datetime_given, content):
  139. return HttpResponse(status=404)
  140. content = folderpart + content
  141. part.part_context = encrypt_aes(content, content_key_decrypt)
  142. if JustifiedKey.objects.filter(part=part, justified_name=justified).exists():
  143. part.save()
  144. json_obj = {'works': 'fined'}
  145. return JsonResponse(json_obj, status=201)
  146. @csrf_exempt
  147. def create_new_folder(request):
  148. if request.method == 'POST':
  149. data = json.loads(request.body)
  150. print(data)
  151. license = data[0]
  152. if not check_license(license):
  153. return HttpResponse(status=404)
  154. content_key = license['content_key']
  155. content_key_decrypt = decrypt(content_key)
  156. patient = User.objects.get(username=license["patient"])
  157. for c in range(1, len(data)):
  158. part_class = data[c]["part_class"]
  159. content = data[c]["content"]
  160. content = part_class + content
  161. encrypted_key = data[c]["encrypted_key"]
  162. encrypted_content = encrypt_aes(content, content_key_decrypt)
  163. part_class = FolderPart_Name.objects.get(part_name=part_class)
  164. part = FolderPart(folder_id=patient.folderinfo, part_class=part_class, part_context=encrypted_content)
  165. part.save()
  166. justified = User.objects.get(username=license["justified"])
  167. justified_key = JustifiedKey(part=part, justified_name=justified, key=encrypted_key)
  168. justified_key.save()
  169. json_obj = {'works': 'fined'}
  170. return JsonResponse(json_obj, status=201)
  171. @csrf_exempt
  172. def create_key(request):
  173. if request.method == 'POST':
  174. data = json.loads(request.body)
  175. license = data[0]
  176. part_class = data[1]
  177. key = data[2]
  178. if not check_license(license):
  179. return HttpResponse(status=404)
  180. patient = User.objects.get(username=license["patient"])
  181. part_class = FolderPart_Name.objects.get(part_name=part_class)
  182. justified = User.objects.get(username=license["justified"])
  183. part = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=part_class)
  184. if not JustifiedKey.objects.filter(part=part, justified_name=justified, key=key).exists():
  185. justified_key = JustifiedKey(part=part, justified_name=justified, key=key)
  186. justified_key.save()
  187. content_response = {"done": 1}
  188. return JsonResponse(content_response, status=201)
  189. @api_view(['POST'])
  190. @csrf_exempt
  191. @permission_classes([IsAdminUser])
  192. def delete_justified_key(request):
  193. post_content = json.loads(request.body)
  194. print(post_content)
  195. patient = post_content['patient']
  196. justified = post_content['justified']
  197. folder_parts_delete_key = post_content['folder_parts']
  198. old_total_key = post_content['old_total_key']
  199. new_total_key = post_content['new_total_key']
  200. old_total_key_decrypt = decrypt(old_total_key)
  201. new_total_key_decrypt = decrypt(new_total_key)
  202. patient = User.objects.get(username=patient)
  203. justified = User.objects.get(username=justified)
  204. all_folder_parts = FolderPart_Name.objects.all().values_list()
  205. for part in all_folder_parts:
  206. folder_part_name_object = FolderPart_Name.objects.get(part_name=part[1])
  207. folder_part_object = FolderPart.objects.get(part_class=folder_part_name_object,folder_id=patient.folderinfo)
  208. decrypted_content = decrypt_aes(folder_part_object.part_context, old_total_key_decrypt)
  209. encrypted_content = encrypt_aes(decrypted_content, new_total_key_decrypt)
  210. folder_part_object.part_context = encrypted_content
  211. folder_part_object.save()
  212. for part in folder_parts_delete_key:
  213. folder_part_name_object = FolderPart_Name.objects.get(part_name=part)
  214. folder_part_object = FolderPart.objects.get(folder_id=patient.folderinfo, part_class=folder_part_name_object)
  215. key = JustifiedKey.objects.filter(part=folder_part_object, justified_name=justified)
  216. key.delete()
  217. return Response(status=201)
  218. class UserViewSet(viewsets.ModelViewSet):
  219. """
  220. API endpoint that allows users to be viewed or edited.
  221. """
  222. queryset = User.objects.all().order_by('-date_joined')
  223. serializer_class = UserSerializer
  224. permission_classes = [permissions.IsAuthenticated]
  225. class GroupViewSet(viewsets.ModelViewSet):
  226. """
  227. API endpoint that allows groups to be viewed or edited.
  228. """
  229. queryset = Group.objects.all()
  230. serializer_class = GroupSerializer
  231. permission_classes = [permissions.IsAuthenticated]
  232. class GetFolderPartNames(viewsets.ModelViewSet):
  233. queryset = FolderPart_Name.objects.all()
  234. serializer_class = FolderPartNameSerializer