""" | |||||
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() |
""" | |||||
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 = '/' |
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')) | |||||
] |
""" | |||||
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() |
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') | |||||
# }), | |||||
# ) |
from django.apps import AppConfig | |||||
class HealthViewConfig(AppConfig): | |||||
name = 'health_view' |
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) | |||||
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="") | |||||
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'] | |||||
from django.test import TestCase | |||||
# Create your tests here. |
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), | |||||
] |
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 |
from django.contrib import admin | 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(FolderInfo) | ||||
admin.site.register(License) | admin.site.register(License) | ||||
admin.site.register(FolderPart) | admin.site.register(FolderPart) | ||||
admin.site.register(Permission) | 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') | |||||
# }), | |||||
# ) |
import json | import json | ||||
loginname_restapi = 'gabi' | |||||
passwort_restapi = 'Lolo7138' | |||||
#needs logindata from admin account form Contentserver | |||||
loginname_restapi = '' | |||||
passwort_restapi = '' | |||||
def check_exp_date(): | def check_exp_date(): |