@@ -0,0 +1,16 @@ | |||
""" | |||
ASGI config for Contentserver project. | |||
It exposes the ASGI callable as a module-level variable named ``application``. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ | |||
""" | |||
import os | |||
from django.core.asgi import get_asgi_application | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Contentserver.settings') | |||
application = get_asgi_application() |
@@ -0,0 +1,138 @@ | |||
""" | |||
Django settings for Contentserver project. | |||
Generated by 'django-admin startproject' using Django 3.1.4. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/3.1/topics/settings/ | |||
For the full list of settings and their values, see | |||
https://docs.djangoproject.com/en/3.1/ref/settings/ | |||
""" | |||
from pathlib import Path | |||
import os | |||
# Build paths inside the project like this: BASE_DIR / 'subdir'. | |||
BASE_DIR = Path(__file__).resolve().parent.parent | |||
# Quick-start development settings - unsuitable for production | |||
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ | |||
# SECURITY WARNING: keep the secret key used in production secret! | |||
SECRET_KEY = '#^9h3-tg+(r__c)5m9@51#iq+f!e+ifr2&(q3y_3w=-9h2aizr' | |||
# SECURITY WARNING: don't run with debug turned on in production! | |||
DEBUG = True | |||
ALLOWED_HOSTS = ['192.168.192.75', '188.195.130.70', '0.0.0.0', 'localhost', '127.0.0.1'] | |||
CORS_ORIGIN_ALLOW_ALL=True | |||
# Application definition | |||
INSTALLED_APPS = [ | |||
'corsheaders', | |||
'django.contrib.admin', | |||
'django.contrib.auth', | |||
'django.contrib.contenttypes', | |||
'django.contrib.sessions', | |||
'django.contrib.messages', | |||
'django.contrib.staticfiles', | |||
'rest_framework', | |||
'health_view' | |||
] | |||
REST_FRAMEWORK = { | |||
# Use Django's standard `django.contrib.auth` permissions, | |||
# or allow read-only access for unauthenticated users. | |||
'DEFAULT_PERMISSION_CLASSES': [ | |||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' | |||
], | |||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', | |||
'PAGE_SIZE': 10 | |||
} | |||
MIDDLEWARE = [ | |||
'corsheaders.middleware.CorsMiddleware', | |||
'django.middleware.common.CommonMiddleware', | |||
'django.middleware.security.SecurityMiddleware', | |||
'django.contrib.sessions.middleware.SessionMiddleware', | |||
'django.middleware.common.CommonMiddleware', | |||
'django.middleware.csrf.CsrfViewMiddleware', | |||
'django.contrib.auth.middleware.AuthenticationMiddleware', | |||
'django.contrib.messages.middleware.MessageMiddleware', | |||
'django.middleware.clickjacking.XFrameOptionsMiddleware', | |||
] | |||
ROOT_URLCONF = 'Contentserver.urls' | |||
TEMPLATES = [ | |||
{ | |||
'BACKEND': 'django.template.backends.django.DjangoTemplates', | |||
'DIRS': [os.path.join(BASE_DIR, 'templates')], | |||
'APP_DIRS': True, | |||
'OPTIONS': { | |||
'context_processors': [ | |||
'django.template.context_processors.debug', | |||
'django.template.context_processors.request', | |||
'django.contrib.auth.context_processors.auth', | |||
'django.contrib.messages.context_processors.messages', | |||
], | |||
}, | |||
}, | |||
] | |||
WSGI_APPLICATION = 'Contentserver.wsgi.application' | |||
# Database | |||
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases | |||
DATABASES = { | |||
'default': { | |||
'ENGINE': 'django.db.backends.sqlite3', | |||
'NAME': BASE_DIR / 'db.sqlite3', | |||
} | |||
} | |||
# Password validation | |||
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators | |||
AUTH_PASSWORD_VALIDATORS = [ | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', | |||
}, | |||
] | |||
# Internationalization | |||
# https://docs.djangoproject.com/en/3.1/topics/i18n/ | |||
LANGUAGE_CODE = 'en-us' | |||
TIME_ZONE = 'Europe/Berlin' | |||
USE_I18N = True | |||
USE_L10N = True | |||
USE_TZ = True | |||
# Static files (CSS, JavaScript, Images) | |||
# https://docs.djangoproject.com/en/3.1/howto/static-files/ | |||
STATIC_URL = '/static/' | |||
LOGIN_REDIRECT_URL = '/' |
@@ -0,0 +1,18 @@ | |||
from django.urls import include, path | |||
from rest_framework import routers | |||
from health_view import views | |||
from django.contrib import admin | |||
router = routers.DefaultRouter() | |||
router.register(r'users', views.UserViewSet) | |||
router.register(r'groups', views.GroupViewSet) | |||
router.register(r'folderpartnames', views.GetFolderPartNames) | |||
# Wire up our API using automatic URL routing. | |||
# Additionally, we include login URLs for the browsable API. | |||
urlpatterns = [ | |||
path('admin/', admin.site.urls), | |||
path('', include(router.urls)), | |||
path('', include('health_view.urls')), | |||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) | |||
] |
@@ -0,0 +1,16 @@ | |||
""" | |||
WSGI config for Contentserver project. | |||
It exposes the WSGI callable as a module-level variable named ``application``. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/ | |||
""" | |||
import os | |||
from django.core.wsgi import get_wsgi_application | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Contentserver.settings') | |||
application = get_wsgi_application() |
@@ -0,0 +1,22 @@ | |||
from django.contrib import admin | |||
from .models import FolderInfo, FolderPart, JustifiedKey, FolderPart_Name | |||
admin.site.register(FolderInfo) | |||
admin.site.register(FolderPart) | |||
admin.site.register(FolderPart_Name) | |||
admin.site.register(JustifiedKey) | |||
#@admin.register(BookInstance) | |||
#class BookInstanceAdmin(admin.ModelAdmin): | |||
# list_display = ('book', 'status', 'borrower', 'due_back', 'id') | |||
# list_filter = ('status', 'due_back')# | |||
# | |||
# fieldsets = ( | |||
# (None, { | |||
# 'fields': ('book','imprint', 'id') | |||
# }), | |||
# ('Availability', { | |||
# 'fields': ('status', 'due_back','borrower') | |||
# }), | |||
# ) |
@@ -0,0 +1,5 @@ | |||
from django.apps import AppConfig | |||
class HealthViewConfig(AppConfig): | |||
name = 'health_view' |
@@ -0,0 +1,103 @@ | |||
import os | |||
import codecs | |||
from Crypto.PublicKey import RSA | |||
from Crypto.Cipher import PKCS1_OAEP, AES | |||
from Crypto.Hash import SHA256 | |||
from Crypto.Signature import PKCS1_v1_5 | |||
from Crypto import Random | |||
from base64 import b64decode, b64encode | |||
BS = 16 | |||
pub_key_contentserver = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYI/jGk6f0LAT2Z6AAQUR7izbi\na5O4Zzaz4WtK00jr3AqbZMVeVZAs+As5RS35PY2BlCuEEza/J5XX1tlbUhGk/Nzu\nyYqlID6ILEk9kUqh1A6EAuNVrcCL174BRLy620pU5m+E61za0tIr1lU+Jhy4ikVK\niGQ+na5a5g0kuzZTHwIDAQAB\n-----END PUBLIC KEY-----' | |||
private_key_contentserver = '-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDYI/jGk6f0LAT2Z6AAQUR7izbia5O4Zzaz4WtK00jr3AqbZMVe\nVZAs+As5RS35PY2BlCuEEza/J5XX1tlbUhGk/NzuyYqlID6ILEk9kUqh1A6EAuNV\nrcCL174BRLy620pU5m+E61za0tIr1lU+Jhy4ikVKiGQ+na5a5g0kuzZTHwIDAQAB\nAoGAFuf9CgKFBrYRkpGZ3d0M5nDzEJzpC1546ChoKAZrUH/B6gUMe7pirLle6yNf\nQ25YDFcJI5arsyd9VGITJ//zGZC1CC9MBL1v4Ey5Vm3OAwcn7aoiPYoZhtNUDGhE\nCKzIrKWlq5wQDfYCjL2zQnCIAq+nZWACI/X+k/bPd37FZpUCQQDdQNQ3Azaq0owx\nd2crResCW4OryvhTPipLNz8AaW2IMuDfxLUKEaTTkU3NOFRRhIddRRA9/vfcHbrw\nlgZ3Vo5NAkEA+hWX0tItz4lL4pSJTc38Tzjb9WyGQPuAINlntnDwOhtvvRYPfTLi\nLb/22btAfgQWSBICxFdO5Ze0A5Dx140VGwJARwVhWYtZh/nv8I0Ae/6EkowntwR/\nM9FXqC9CtPIiq76ROqMc7e999j/FNqPnRQeCoCjkLtJiY7DTahjuWG5bXQJBAIAD\nS5scAV0pz5FlLT+JgGzhEx729WYQF085WjB2cVGdN75Xq4gP4t0+VVKw2ltnJiyw\nI4BznKxD0l689D69Nh8CQQDLkom4Fhkl8CZQLB1cIX9PjNw+KCBkTV92dJmzdmR5\nGE+p7jO849HPS83W21AV6/eyL8VMqDyE6CBzHNr2ITJT\n-----END RSA PRIVATE KEY-----' | |||
pub_key_licenseserver= "-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG54kIgf8wi+WLrmg0OLXTsMF7BsYjJ8+mmx1/Ml1Hts2oVoisf8iKbfcC0jWBc1aEibi7EIZK9AWEmgpIHPZpf2Ezt36KX7pjA7CDgZBye/bw+G1CaDGxrN8a18db8c16hNxHMTMiqPm7WAgoyekOzlCT6/rqF+3w2oYuGx1tmQIDAQAB-----END PUBLIC KEY-----" | |||
def make_key_pair_rsa(username): | |||
random_generator = Random.new().read | |||
priv_key = RSA.generate(1024, random_generator) | |||
pub_key = priv_key.publickey() | |||
print("new key pair") | |||
print(priv_key.exportKey()) | |||
print(pub_key.exportKey()) | |||
user_smartcard_path = "/tmp/smartcards/" + str(username) + ".txt" | |||
file_object = open(user_smartcard_path, "w+") | |||
file_object.write(priv_key.exportKey().decode('utf-8')) | |||
file_object.write("\n") | |||
file_object.write(pub_key.exportKey().decode('utf-8')) | |||
file_object.close() | |||
return pub_key.exportKey().decode('utf-8') | |||
def make_rand_key_aes(): | |||
return os.urandom(32) | |||
def pad(s): | |||
return s + (BS - len(s) % BS) * chr(BS - len(s) % BS).encode() | |||
def unpad(s): | |||
return s[:-ord(s[len(s)-1:])] | |||
def encrypt_aes(message, key): | |||
message = message.encode() | |||
raw = pad(message) | |||
cipher = AES.new(key, AES.MODE_ECB) | |||
enc = cipher.encrypt(raw) | |||
return b64encode(enc).decode('utf-8') | |||
def decrypt_aes(enc, key): | |||
enc = b64decode(enc) | |||
cipher = AES.new(key, AES.MODE_ECB) | |||
dec = cipher.decrypt(enc) | |||
return dec.decode('utf-8') | |||
def make_encrypted_key_content_server(): | |||
random_key = make_rand_key_aes() | |||
key = RSA.importKey(pub_key_contentserver) | |||
pub_key = key.publickey() | |||
encrypted_key = encrypt(random_key, pub_key) | |||
return encrypted_key.hex() | |||
def decrypt(ciphertext): | |||
key = RSA.importKey(private_key_contentserver) | |||
cipher = PKCS1_OAEP.new(key) | |||
ciphertext = codecs.decode(ciphertext, 'hex') | |||
return cipher.decrypt(ciphertext) | |||
def encrypt(message): | |||
cipher = PKCS1_OAEP.new(pub_key_contentserver) | |||
return cipher.encrypt(message) | |||
def sign(message, priv_key): | |||
priv_key = RSA.importKey(priv_key) | |||
signer = PKCS1_v1_5.new(priv_key) | |||
hash_gen = SHA256.new() | |||
hash_gen.update(message.encode()) | |||
return b64encode(signer.sign(hash_gen)).decode('utf-8') | |||
def verify(message, signature, pub_key): | |||
pub_key = pub_key.replace("-----BEGIN PUBLIC KEY-----", "") | |||
pub_key = pub_key.replace("-----END PUBLIC KEY-----", "") | |||
pub_key = pub_key.replace(" ", "") | |||
pub_key = ('\n'.join(pub_key[i:i + 64] for i in range(0, len(pub_key), 64))) | |||
pub_key = "-----BEGIN PUBLIC KEY-----\n" + pub_key + "\n-----END PUBLIC KEY-----" | |||
signature = b64decode(signature) | |||
pub_key = RSA.importKey(pub_key) | |||
verifier = PKCS1_v1_5.new(pub_key) | |||
hash_gen = SHA256.new(message.encode()) | |||
return verifier.verify(hash_gen, signature) | |||
@@ -0,0 +1,54 @@ | |||
from django.db import models | |||
from django.contrib.auth.models import User | |||
from django.dispatch import receiver | |||
from django.db.models.signals import post_save | |||
class FolderInfo(models.Model): | |||
"""Adding attributes to default model user""" | |||
patient = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True, default="") | |||
pub_key = models.CharField(max_length=300, blank=True, default="") | |||
def __str__(self): | |||
"""String for representing the Model object.""" | |||
return str(self.id) | |||
@receiver(post_save, sender=User) | |||
def create_folderinfo(sender, instance, created, **kwargs): | |||
"""Creates Folderinfo for user when he is created""" | |||
if created: | |||
FolderInfo.objects.create(patient=instance) | |||
class FolderPart_Name(models.Model): | |||
shortcut = models.CharField(max_length=3, default="x") | |||
part_name = models.CharField(max_length=40, primary_key=True, default="x") | |||
def __str__(self): | |||
"""String for representing the Model object.""" | |||
return str(self.part_name) | |||
class FolderPart(models.Model): | |||
part_class = models.ForeignKey(FolderPart_Name, on_delete=models.CASCADE, default="") | |||
folder_id = models.ForeignKey(FolderInfo, on_delete=models.CASCADE, default="") | |||
part_context = models.CharField(max_length=500, default="nothing for you") | |||
class Meta: | |||
unique_together = ('part_class', 'folder_id') | |||
def __str__(self): | |||
"""String for representing the Model object.""" | |||
return self.part_class.part_name | |||
class JustifiedKey(models.Model): | |||
part = models.ForeignKey(FolderPart, on_delete=models.CASCADE, null=True, default="") | |||
justified_name = models.ForeignKey(User, on_delete=models.CASCADE, default="") | |||
key = models.CharField(max_length=260, default="") | |||
@@ -0,0 +1,64 @@ | |||
from abc import ABC | |||
from django.contrib.auth.models import User, Group | |||
from rest_framework import serializers | |||
from health_view.models import FolderPart, JustifiedKey, FolderPart_Name, FolderInfo | |||
class UserSerializer(serializers.HyperlinkedModelSerializer): | |||
class Meta: | |||
model = User | |||
fields = ['url', 'username', 'email', 'groups'] | |||
class GroupSerializer(serializers.HyperlinkedModelSerializer): | |||
class Meta: | |||
model = Group | |||
fields = ['url', 'name'] | |||
class KeySerializer(serializers.Serializer): | |||
part = serializers.CharField() | |||
justified_name = serializers.CharField(max_length=100) | |||
key = serializers.CharField(max_length=260) | |||
def create(self, validated_data): | |||
part = FolderPart.objects.get(pk=validated_data.get("part_class")) | |||
justified_name = FolderPart.objects.get(pk=validated_data.get("part_class")) | |||
key = validated_data.get("part_key") | |||
JustifiedKey(part=part, justified_name=justified_name, key=key) | |||
return True | |||
def update(self, instance, validated_data): | |||
instance.part = FolderPart.objects.get(pk=validated_data.get("part_class")) | |||
instance.justified_name = FolderPart.objects.get(pk=validated_data.get("part_class")) | |||
instance.key = instance.part_context = validated_data.get("part_key") | |||
instance.save() | |||
return True | |||
class ContentSerializer(serializers.Serializer): | |||
part_class = serializers.CharField() | |||
folder_id = serializers.CharField() | |||
part_context = serializers.CharField() | |||
def update(self, instance, validated_data): | |||
instance.part_class = FolderPart_Name.objects.get(pk=validated_data.get("part_class")) | |||
instance.folder_id = FolderInfo.objects.get(pk=validated_data.get("folder_id")) | |||
instance.part_context = validated_data.get("part_context") | |||
instance.save() | |||
return instance | |||
class FolderPartSerializer(serializers.Serializer): | |||
part = serializers.CharField() | |||
justified_name = serializers.CharField() | |||
key = serializers.CharField() | |||
class FolderPartNameSerializer(serializers.HyperlinkedModelSerializer): | |||
class Meta: | |||
model = FolderPart_Name() | |||
fields = ['part_name'] | |||
@@ -0,0 +1,3 @@ | |||
from django.test import TestCase | |||
# Create your tests here. |
@@ -0,0 +1,12 @@ | |||
from django.urls import path | |||
from . import views | |||
urlpatterns = [ | |||
path('key/<name>/<justified>', views.get_key), | |||
path('content/<name>/', views.get_content), | |||
path('folder/create/', views.create_new_folder), | |||
path('create/key/', views.create_key), | |||
path('folder/read/', views.read_folder), | |||
path('folder/write/', views.write_folder), | |||
path('manage/delete/', views.delete_justified_key), | |||
] |
@@ -0,0 +1,270 @@ | |||
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 |
@@ -1,26 +1,9 @@ | |||
from django.contrib import admin | |||
from .models import Author, Genre, Book, BookInstance, FolderInfo, Permission, License, FolderPart | |||
from .models import FolderInfo, Permission, License, FolderPart | |||
#admin.site.register(Book) | |||
#admin.site.register(Author) | |||
#admin.site.register(Genre) | |||
admin.site.register(FolderInfo) | |||
admin.site.register(License) | |||
admin.site.register(FolderPart) | |||
admin.site.register(Permission) | |||
#@admin.register(BookInstance) | |||
#class BookInstanceAdmin(admin.ModelAdmin): | |||
# list_display = ('book', 'status', 'borrower', 'due_back', 'id') | |||
# list_filter = ('status', 'due_back')# | |||
# | |||
# fieldsets = ( | |||
# (None, { | |||
# 'fields': ('book','imprint', 'id') | |||
# }), | |||
# ('Availability', { | |||
# 'fields': ('status', 'due_back','borrower') | |||
# }), | |||
# ) |
@@ -6,8 +6,9 @@ import requests | |||
import json | |||
loginname_restapi = 'gabi' | |||
passwort_restapi = 'Lolo7138' | |||
#needs logindata from admin account form Contentserver | |||
loginname_restapi = '' | |||
passwort_restapi = '' | |||
def check_exp_date(): |