Licenseserver
This commit is contained in:
commit
b9553d64d8
0
Licenseserver/drm_server/__init__.py
Normal file
0
Licenseserver/drm_server/__init__.py
Normal file
16
Licenseserver/drm_server/asgi.py
Normal file
16
Licenseserver/drm_server/asgi.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
ASGI config for Licenseserver 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', 'Licenseserver.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
127
Licenseserver/drm_server/settings.py
Normal file
127
Licenseserver/drm_server/settings.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
"""
|
||||||
|
Django settings for Licenseserver 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.69', '188.195.130.70', '0.0.0.0', 'localhost', '127.0.0.1']
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'django_crontab',
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'health_view'
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'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 = 'Licenseserver.urls'
|
||||||
|
|
||||||
|
CRONJOBS = [
|
||||||
|
('*/1 * * * *', 'health_view.cron.check_exp_date', '>> /home/gabi/test.log')
|
||||||
|
]
|
||||||
|
|
||||||
|
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 = 'Licenseserver.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 = '/'
|
27
Licenseserver/drm_server/urls.py
Normal file
27
Licenseserver/drm_server/urls.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
"""Licenseserver URL Configuration
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/3.1/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
from django.views.generic import RedirectView
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
path('health_view/', include('health_view.urls')),
|
||||||
|
path('', RedirectView.as_view(url='health_view/')),
|
||||||
|
path('accounts/', include('django.contrib.auth.urls'))
|
||||||
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
16
Licenseserver/drm_server/wsgi.py
Normal file
16
Licenseserver/drm_server/wsgi.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
WSGI config for Licenseserver 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', 'Licenseserver.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
5
Licenseserver/health_view/.babelrc
Normal file
5
Licenseserver/health_view/.babelrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-env", "@babel/preset-react"
|
||||||
|
]
|
||||||
|
}
|
0
Licenseserver/health_view/__init__.py
Normal file
0
Licenseserver/health_view/__init__.py
Normal file
26
Licenseserver/health_view/admin.py
Normal file
26
Licenseserver/health_view/admin.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Author, Genre, Book, BookInstance, 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')
|
||||||
|
# }),
|
||||||
|
# )
|
5
Licenseserver/health_view/apps.py
Normal file
5
Licenseserver/health_view/apps.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class HealthViewConfig(AppConfig):
|
||||||
|
name = 'health_view'
|
50
Licenseserver/health_view/cron.py
Normal file
50
Licenseserver/health_view/cron.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from health_view.models import *
|
||||||
|
from health_view.views import check_expiration_date
|
||||||
|
from datetime import datetime
|
||||||
|
from health_view.crypto_functions import *
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
loginname_restapi = 'gabi'
|
||||||
|
passwort_restapi = 'Lolo7138'
|
||||||
|
|
||||||
|
|
||||||
|
def check_exp_date():
|
||||||
|
licenses = License.objects.all()
|
||||||
|
date_now = datetime.now()
|
||||||
|
for lic in licenses:
|
||||||
|
if check_expiration_date(lic):
|
||||||
|
continue
|
||||||
|
licenses_same_owner = License.objects.filter(justified=lic.justified, patient=lic.patient).exclude(id=lic.id)
|
||||||
|
folderparts = lic.folder_parts.all().values_list()
|
||||||
|
parts_to_delete = list()
|
||||||
|
for part in folderparts:
|
||||||
|
delete = True
|
||||||
|
for license in licenses_same_owner:
|
||||||
|
if not check_expiration_date(license):
|
||||||
|
continue
|
||||||
|
for check_part in license.folder_parts.all().values_list():
|
||||||
|
if check_part == part:
|
||||||
|
delete = False
|
||||||
|
if delete is True:
|
||||||
|
parts_to_delete.append(part[2])
|
||||||
|
if not parts_to_delete:
|
||||||
|
lic.delete()
|
||||||
|
continue
|
||||||
|
new_total_key = make_encrypted_key_content_server()
|
||||||
|
post_content = {
|
||||||
|
'patient': lic.patient.username,
|
||||||
|
'justified': lic.justified.username,
|
||||||
|
'new_total_key': new_total_key,
|
||||||
|
'old_total_key': lic.patient.folderinfo.content_key,
|
||||||
|
'folder_parts': parts_to_delete,
|
||||||
|
}
|
||||||
|
lic.patient.folderinfo.content_key = new_total_key
|
||||||
|
lic.patient.folderinfo.save()
|
||||||
|
lic.delete()
|
||||||
|
request = requests.post('http://192.168.192.75:8000/manage/delete/', json=post_content, auth=(loginname_restapi, passwort_restapi))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
84
Licenseserver/health_view/crypto_functions.py
Normal file
84
Licenseserver/health_view/crypto_functions.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import os
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
from Crypto import Random
|
||||||
|
from Crypto.Cipher import PKCS1_OAEP
|
||||||
|
from Crypto.Hash import SHA256
|
||||||
|
from Crypto.Signature import PKCS1_v1_5
|
||||||
|
from base64 import b64decode, b64encode
|
||||||
|
|
||||||
|
|
||||||
|
pub_key_contentserver = b'-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYI/jGk6f0LAT2Z6AAQUR7izbi\na5O4Zzaz4WtK00jr3AqbZMVeVZAs+As5RS35PY2BlCuEEza/J5XX1tlbUhGk/Nzu\nyYqlID6ILEk9kUqh1A6EAuNVrcCL174BRLy620pU5m+E61za0tIr1lU+Jhy4ikVK\niGQ+na5a5g0kuzZTHwIDAQAB\n-----END PUBLIC KEY-----'
|
||||||
|
pub_key_own= "-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG54kIgf8wi+WLrmg0OLXTsMF7BsYjJ8+mmx1/Ml1Hts2oVoisf8iKbfcC0jWBc1aEibi7EIZK9AWEmgpIHPZpf2Ezt36KX7pjA7CDgZBye/bw+G1CaDGxrN8a18db8c16hNxHMTMiqPm7WAgoyekOzlCT6/rqF+3w2oYuGx1tmQIDAQAB-----END PUBLIC KEY-----"
|
||||||
|
priv_key_own = b"""-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICWwIBAAKBgQCG54kIgf8wi+WLrmg0OLXTsMF7BsYjJ8+mmx1/Ml1Hts2oVois
|
||||||
|
f8iKbfcC0jWBc1aEibi7EIZK9AWEmgpIHPZpf2Ezt36KX7pjA7CDgZBye/bw+G1C
|
||||||
|
aDGxrN8a18db8c16hNxHMTMiqPm7WAgoyekOzlCT6/rqF+3w2oYuGx1tmQIDAQAB
|
||||||
|
AoGAXPatHenHW0LseidDs8jos+p4SjlOzOcgV2VJHGAum77DVh/bq1ObdJl2wMDv
|
||||||
|
EjfTBR6K6I3onTovm0MzlqIuw2BR2HoVkY9dkmv8v6j17jEImHvXqAXr4GyhLdcl
|
||||||
|
NAG6lZ+5BAoZskDULVPSeHY04rVMvIHWAqoE4jGIbQbZOOkCQQC2XHV1KbM9VWIf
|
||||||
|
H1PkrApsBiKMDa9AXSsbolawOUmsqlG38GuFv/5E0/9dVL2kSA2hDp8WfiaIsvvM
|
||||||
|
Rhe0l+obAkEAvWE/kaUBjU6aVG8EtD+pm20biO4sA6eMydhXOiREriX2mUFRRef0
|
||||||
|
y696P2Ge6GEGYSCdjwlZy/nwROQYoGsCWwJARyoHsEQorUuvseOA0qEMpCE0xCDm
|
||||||
|
/iAdnXgZikWg6Z/Bqh1JaHWHHYb5hYt3Qi/YGbzh+l4aXYgzWQEVaSVLdwJAcjj9
|
||||||
|
hnLnhLssClELnUvomH4uZWCB25JrMDL0KXVGl2L+YWEsC+XjmBa2vRO8LJyYpGxv
|
||||||
|
m54gMw8FBAgvclIYkQJAdV52mWKano6+ikCAw1WCEp/HB5Eiz6HU6/RLOsVxN9em
|
||||||
|
cz1snA0u3qV17TrZ920gzD/2od/bzU3Hul3yDhDRgQ==
|
||||||
|
-----END RSA PRIVATE KEY-----"""
|
||||||
|
|
||||||
|
|
||||||
|
def make_key_pair_public(username):
|
||||||
|
random_generator = Random.new().read
|
||||||
|
priv_key = RSA.generate(1024, random_generator)
|
||||||
|
pub_key = priv_key.publickey()
|
||||||
|
usercardpath = "/tmp/smartcards/" + str(username) + ".txt"
|
||||||
|
file_object = open(usercardpath, "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_key_aes():
|
||||||
|
return os.urandom(32)
|
||||||
|
|
||||||
|
|
||||||
|
def make_encrypted_key_content_server():
|
||||||
|
random_key = make_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, priv_key):
|
||||||
|
cipher = PKCS1_OAEP.new(priv_key)
|
||||||
|
return cipher.decrypt(ciphertext)
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt(message, pub_key):
|
||||||
|
cipher = PKCS1_OAEP.new(pub_key)
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
38
Licenseserver/health_view/forms.py
Normal file
38
Licenseserver/health_view/forms.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
from django import forms
|
||||||
|
from .models import License
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from health_view.models import Permission
|
||||||
|
|
||||||
|
class CreateLicenseForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = License
|
||||||
|
fields = ('patient', 'justified', 'exp_date', 'folder_parts', 'permissions', 'signature',)
|
||||||
|
|
||||||
|
def __init__(self, current_user, *args, **kwargs):
|
||||||
|
super(CreateLicenseForm, self).__init__(*args, **kwargs)
|
||||||
|
license = License.objects.filter(justified=current_user).order_by('patient')
|
||||||
|
conditions = Q(id='0')
|
||||||
|
for li in license:
|
||||||
|
print(li.patient_id)
|
||||||
|
conditions |= Q(id=li.patient_id)
|
||||||
|
self.fields['permissions'] = forms.ModelMultipleChoiceField(queryset=Permission.objects.all())
|
||||||
|
if License.objects.filter(justified=current_user).exists() and License.objects.filter(license_creator=current_user).exists():
|
||||||
|
self.fields['patient'].queryset = User.objects.filter(conditions).distinct()
|
||||||
|
elif License.objects.filter(justified=current_user).exists():
|
||||||
|
conditions |= Q(username=current_user.username)
|
||||||
|
self.fields['patient'].queryset = User.objects.filter(conditions).distinct()
|
||||||
|
elif License.objects.filter(license_creator=current_user).exists():
|
||||||
|
self.fields['patient'].queryset = User.objects.filter(username="-")
|
||||||
|
else:
|
||||||
|
self.fields['patient'].queryset = User.objects.filter(username=current_user.username)
|
||||||
|
|
||||||
|
|
||||||
|
class CreateLicenseForm_filled(forms.Form):
|
||||||
|
patient = forms.CharField()
|
||||||
|
justified = forms.CharField()
|
||||||
|
license_creator = forms.CharField()
|
||||||
|
exp_date = forms.CharField()
|
||||||
|
folder_parts = forms.CharField()
|
||||||
|
permissions = forms.CharField()
|
||||||
|
signature = forms.CharField()
|
60
Licenseserver/health_view/models.py
Normal file
60
Licenseserver/health_view/models.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
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
|
||||||
|
from health_view.crypto_functions import *
|
||||||
|
|
||||||
|
|
||||||
|
class FolderInfo(models.Model):
|
||||||
|
"""Adding attributes to default model user"""
|
||||||
|
patient = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
pub_key = models.CharField(max_length=300, blank=True)
|
||||||
|
content_key = models.CharField(max_length=300, blank=True, default="no_key")
|
||||||
|
|
||||||
|
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 when user gets created"""
|
||||||
|
if created:
|
||||||
|
folderinfo = FolderInfo.objects.create(patient=instance)
|
||||||
|
folderinfo.pub_key = make_key_pair_public(folderinfo.patient)
|
||||||
|
folderinfo.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Permission(models.Model):
|
||||||
|
shortcut = models.CharField(max_length=5)
|
||||||
|
permissions = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""String for representing the Model object."""
|
||||||
|
return self.permissions
|
||||||
|
|
||||||
|
|
||||||
|
class FolderPart(models.Model):
|
||||||
|
shortcut = models.CharField(max_length=3)
|
||||||
|
part_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""String for representing the Model object."""
|
||||||
|
return self.part_name
|
||||||
|
|
||||||
|
|
||||||
|
class License(models.Model):
|
||||||
|
"""License model which defines rights"""
|
||||||
|
patient = models.ForeignKey(User, on_delete=models.CASCADE, related_name='patient_id')
|
||||||
|
justified = models.ForeignKey(User, default=None, on_delete=models.CASCADE, related_name='justified_id')
|
||||||
|
license_creator = models.ForeignKey(User, default=None, null=True, blank=True, on_delete=models.CASCADE, related_name='license_creators')
|
||||||
|
exp_date = models.CharField(max_length=200, null=True, blank=True)
|
||||||
|
permissions = models.ManyToManyField(Permission)
|
||||||
|
folder_parts = models.ManyToManyField(FolderPart)
|
||||||
|
signature = models.CharField(max_length=200, null=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""String for representing the Model object."""
|
||||||
|
return self.justified.get_username() + " " + ''.join(p.shortcut for p in self.permissions.all())
|
||||||
|
|
||||||
|
|
4173
Licenseserver/health_view/package-lock.json
generated
Normal file
4173
Licenseserver/health_view/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
43
Licenseserver/health_view/package.json
Normal file
43
Licenseserver/health_view/package.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"dev": "webpack --mode development ./src/index.js --output-path ./static/frontend/",
|
||||||
|
"build": "webpack --mode production ./src/index.js --output-path ./static/frontend/"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.10",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.12.10",
|
||||||
|
"@babel/preset-env": "^7.12.11",
|
||||||
|
"@babel/preset-react": "^7.12.10",
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"babel-loader": "^8.2.2",
|
||||||
|
"babelify": "^10.0.0",
|
||||||
|
"react": "^17.0.1",
|
||||||
|
"react-dom": "^17.0.1",
|
||||||
|
"webpack": "^5.11.0",
|
||||||
|
"webpack-cli": "^4.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"assert": "^2.0.0",
|
||||||
|
"browserify": "^17.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"buffer-browserify": "^0.2.5",
|
||||||
|
"core-js": "^3.8.2",
|
||||||
|
"create-react-class": "^15.7.0",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
|
"crypto-browserify": "^3.12.0",
|
||||||
|
"crypto-js": "^4.0.0",
|
||||||
|
"cryptojs": "^2.5.3",
|
||||||
|
"jquery": "^3.5.1",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"regenerator-runtime": "^0.13.7",
|
||||||
|
"stream-browserify": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
406
Licenseserver/health_view/src/components/App.js
Normal file
406
Licenseserver/health_view/src/components/App.js
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
import "core-js/stable";
|
||||||
|
import "regenerator-runtime/runtime";
|
||||||
|
import * as cryptojs from 'crypto-js';
|
||||||
|
import $ from 'jquery';
|
||||||
|
var Buffer = require('buffer').Buffer;
|
||||||
|
|
||||||
|
var folderparts = 0;
|
||||||
|
var permissions = "0";
|
||||||
|
var patient = 0;
|
||||||
|
var justified = "0";
|
||||||
|
|
||||||
|
class Generate_Sign_Butn extends React.Component {
|
||||||
|
RSASign(string_sign) {
|
||||||
|
console.log(string_sign)
|
||||||
|
var signerObject = crypto.createSign("RSA-SHA256");
|
||||||
|
var PrivateKey = sessionStorage.getItem('privkey')
|
||||||
|
signerObject.update(string_sign);
|
||||||
|
var signature = signerObject.sign(PrivateKey, false);
|
||||||
|
console.log(signature);
|
||||||
|
var b64encoded = btoa(String.fromCharCode.apply(null, signature))
|
||||||
|
return(b64encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
get_license_signed(){
|
||||||
|
var patient_id = document.getElementById('id_patient').value;
|
||||||
|
var user = document.getElementById('username').innerHTML;
|
||||||
|
var justified_id = document.getElementById('id_justified').value;
|
||||||
|
var expdate_id = document.getElementById('id_exp_date').value;
|
||||||
|
var permissions_object = document.getElementById('id_permissions')
|
||||||
|
var folder_parts_object = document.getElementById('id_folder_parts')
|
||||||
|
var patient_object = document.getElementById('id_patient')
|
||||||
|
var justified_object = document.getElementById('id_justified')
|
||||||
|
var buttsn = new Generate_Sign_Butn();
|
||||||
|
patient_id = buttsn.return_string_fromObject(patient, patient_object)
|
||||||
|
justified_id = buttsn.return_string_fromObject(justified, justified_object)
|
||||||
|
permissions = buttsn.return_string_fromObject(permissions, permissions_object)
|
||||||
|
folderparts = buttsn.return_string_fromObject(folderparts, folder_parts_object)
|
||||||
|
var signature_string = patient_id + "&" + justified_id + "&" + user + "&" + expdate_id.replace(" ", ",") + "&" + permissions + "&" + folderparts
|
||||||
|
var signatured = buttsn.RSASign(signature_string)
|
||||||
|
document.getElementById('id_signature').value = signatured
|
||||||
|
return signatured;
|
||||||
|
}
|
||||||
|
return_string_fromObject(ids, element){
|
||||||
|
var object_string = "";
|
||||||
|
for (var i = 0; i < ids.length; i++){
|
||||||
|
object_string += element.options[ids[i]].text
|
||||||
|
object_string += ","
|
||||||
|
}
|
||||||
|
object_string = object_string.substring(0, object_string.length-1)
|
||||||
|
return object_string
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button onClick={this.get_license_signed}>Generate Signature</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_Params(){
|
||||||
|
var patient_id = document.getElementById('id_patient').textContent;
|
||||||
|
var justified_id = document.getElementById('id_justified').textContent;
|
||||||
|
var expdate_id = document.getElementById('id_exp_date').textContent;
|
||||||
|
var permissions = document.getElementById('id_permission').textContent
|
||||||
|
var folderparts = document.getElementById('id_folder_parts').textContent
|
||||||
|
var creator = document.getElementById('id_license_creator').textContent
|
||||||
|
var signature = document.getElementById('id_signature').textContent
|
||||||
|
signature = signature.replaceAll("\n", "")
|
||||||
|
signature = signature.replaceAll(" ", "")
|
||||||
|
var content_key = document.getElementById('id_content_key').textContent
|
||||||
|
content_key = content_key.replaceAll("\n", "")
|
||||||
|
content_key = content_key.replaceAll(" ", "")
|
||||||
|
var serversign = document.getElementById('licenseserver_sign').textContent
|
||||||
|
if (serversign){
|
||||||
|
serversign = serversign.replaceAll("\n", "")
|
||||||
|
serversign = serversign.replaceAll(" ", "")
|
||||||
|
var sig_array = [patient_id, creator, justified_id, expdate_id, permissions, folderparts, signature, content_key, serversign]}
|
||||||
|
else {
|
||||||
|
var sig_array = [patient_id, creator, justified_id, expdate_id, permissions, folderparts, signature, content_key]
|
||||||
|
}
|
||||||
|
return sig_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPrivKey(){
|
||||||
|
var privkey = document.getElementById('privkey').value;
|
||||||
|
var pubkey = document.getElementById('pubkey').value;
|
||||||
|
sessionStorage.setItem("privkey", privkey);
|
||||||
|
sessionStorage.setItem("pubkey", pubkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
var submitLogin = document.getElementById('submit_login');
|
||||||
|
if(submitLogin){
|
||||||
|
if (submitLogin.attachEvent) { submitLogin.attachEvent("submit", getPrivKey)} else {
|
||||||
|
submitLogin.addEventListener("submit", getPrivKey)}}
|
||||||
|
|
||||||
|
var check_submit = document.getElementById('submit_button_license');
|
||||||
|
if(check_submit){
|
||||||
|
document.getElementById("id_patient").onclick = function() {
|
||||||
|
patient = Array.from(this.selectedOptions).map(option => option.index)
|
||||||
|
}
|
||||||
|
document.getElementById("id_justified").onclick = function() {
|
||||||
|
justified = Array.from(this.selectedOptions).map(option => option.index)
|
||||||
|
}
|
||||||
|
document.getElementById("id_folder_parts").onclick = function() {
|
||||||
|
folderparts = Array.from(this.selectedOptions).map(option => option.index)
|
||||||
|
}
|
||||||
|
document.getElementById("id_permissions").onclick = function() {
|
||||||
|
permissions = Array.from(this.selectedOptions).map(option => option.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function display_folderpart(id){
|
||||||
|
var jsonArr = []
|
||||||
|
var params = get_Params()
|
||||||
|
var license = new License(params)
|
||||||
|
license.serversign = params[8]
|
||||||
|
jsonArr.push(license)
|
||||||
|
jsonArr.push(id)
|
||||||
|
var response_create = await fetch('http://192.168.192.75:8000/folder/read/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(jsonArr), // string or object
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var myJason = await response_create.json()
|
||||||
|
console.log(response_create)
|
||||||
|
console.log(myJason.key)
|
||||||
|
console.log(base64ToArrayBuffer(myJason.key))
|
||||||
|
var key = decrypt_key(base64ToArrayBuffer(myJason.key))
|
||||||
|
var enc_content = myJason.content.replace(id, "")
|
||||||
|
var content = aes_decrypt(key, enc_content)
|
||||||
|
console.log(content)
|
||||||
|
if (license.permissions.includes("Write")) {
|
||||||
|
ReactDOM.render(<div><div>{id}</div>
|
||||||
|
<textarea id="check_in_data" cols="40" rows="5"></textarea>
|
||||||
|
<div><button onClick={() => check_in_data(id, key, jsonArr)}>Check In</button></div></div>, document.getElementById('content_parts'))
|
||||||
|
} else {
|
||||||
|
ReactDOM.render(<div>{content}</div>, document.getElementById('license_cfaesontent'))
|
||||||
|
}
|
||||||
|
document.getElementById("check_in_data").value = content
|
||||||
|
}
|
||||||
|
|
||||||
|
async function check_in_data(id, key, jsonArr){
|
||||||
|
var content = document.getElementById("check_in_data").value
|
||||||
|
console.log(content)
|
||||||
|
var butin = new Generate_Sign_Butn()
|
||||||
|
var privkey = get_priv_key()
|
||||||
|
var encrypted_content = aes_encrypt(key, content)
|
||||||
|
var today = new Date()
|
||||||
|
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate()
|
||||||
|
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds()
|
||||||
|
var date_time = date + "|" + time
|
||||||
|
var change_signature = butin.RSASign(date_time + "|" + encrypted_content)
|
||||||
|
console.log(encrypted_content)
|
||||||
|
jsonArr.push(encrypted_content)
|
||||||
|
jsonArr.push(date_time)
|
||||||
|
jsonArr.push(change_signature)
|
||||||
|
var response_create = await fetch('http://192.168.192.75:8000/folder/write/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(jsonArr), // string or object
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var myJason = await response_create.json()
|
||||||
|
console.log("jo")
|
||||||
|
}
|
||||||
|
|
||||||
|
class Buaton_API extends React.Component {
|
||||||
|
async call_api (){
|
||||||
|
var jsonArr = []
|
||||||
|
var license = new License(get_Params())
|
||||||
|
folderparts = license.folderparts
|
||||||
|
folderparts = folderparts.split(", ")
|
||||||
|
document.getElementById("license_content").style.visibility = "visible"
|
||||||
|
var i = folderparts.map((part) => {
|
||||||
|
return <button id={part} onClick={() => display_folderpart(part)}>{part}</button>})
|
||||||
|
ReactDOM.render(i, document.getElementById('part_buttons'))
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button onClick={this.call_api}>Use License</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var readAPI = document.getElementById('use_license');
|
||||||
|
|
||||||
|
if (readAPI) {
|
||||||
|
ReactDOM.render(<Buaton_API />, document.getElementById('use_license'))
|
||||||
|
}
|
||||||
|
|
||||||
|
var check_if_creating = document.getElementById('create_available');
|
||||||
|
if (check_if_creating) {
|
||||||
|
ReactDOM.render(<Generate_Sign_Butn />, document.getElementById('create_available'))
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_pub_key(){
|
||||||
|
var pubkey = sessionStorage.getItem('pubkey')
|
||||||
|
return pubkey
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_priv_key(){
|
||||||
|
var privkey = sessionStorage.getItem('privkey')
|
||||||
|
return privkey
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_random_key(){
|
||||||
|
var key = crypto.randomBytes(32)
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
function encrypt_key(key){
|
||||||
|
var pubkey = get_pub_key()
|
||||||
|
var encryptkey = btoa(String.fromCharCode.apply(null, crypto.publicEncrypt(pubkey, key)))
|
||||||
|
return encryptkey
|
||||||
|
}
|
||||||
|
|
||||||
|
function encrypt_key_public(key, pubkey){
|
||||||
|
var encryptkey = btoa(String.fromCharCode.apply(null, crypto.publicEncrypt(pubkey, key)))
|
||||||
|
return encryptkey
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrypt_key(key){
|
||||||
|
var priv_key = get_priv_key()
|
||||||
|
var decrypted_key = btoa(String.fromCharCode.apply(null, crypto.privateDecrypt(priv_key, key)))
|
||||||
|
return decrypted_key
|
||||||
|
}
|
||||||
|
|
||||||
|
var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
|
||||||
|
|
||||||
|
function aes_encrypt(key, message){
|
||||||
|
let cfg = {
|
||||||
|
mode: cryptojs.mode.ECB
|
||||||
|
};
|
||||||
|
if(!base64Matcher.test(key)){
|
||||||
|
key = btoa(String.fromCharCode.apply(null, key))}
|
||||||
|
var encrypted = cryptojs.AES.encrypt(message, key, cfg).toString()
|
||||||
|
console.log(encrypted)
|
||||||
|
return encrypted
|
||||||
|
}
|
||||||
|
|
||||||
|
function base64ToArrayBuffer(base64) {
|
||||||
|
var binary_string = atob(base64);
|
||||||
|
var len = binary_string.length;
|
||||||
|
var bytes = new Uint8Array(len);
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
bytes[i] = binary_string.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
function aes_decrypt(key, message){
|
||||||
|
let cfg = {
|
||||||
|
mode: cryptojs.mode.ECB
|
||||||
|
};
|
||||||
|
var decryptedkey = cryptojs.AES.decrypt(message, key, cfg).toString(cryptojs.enc.Utf8)
|
||||||
|
return decryptedkey
|
||||||
|
}
|
||||||
|
class newFolder_part {
|
||||||
|
constructor(part_class, encrypt_key, content){
|
||||||
|
this.part_class = part_class
|
||||||
|
this.encrypted_key = encrypt_key
|
||||||
|
this.content = content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class License{
|
||||||
|
constructor(licensearr){
|
||||||
|
this.patient = licensearr[0]
|
||||||
|
this.creator = licensearr[1]
|
||||||
|
this.justified = licensearr[2]
|
||||||
|
this.expdate = licensearr[3]
|
||||||
|
this.permissions = licensearr[4]
|
||||||
|
this.folderparts = licensearr[5]
|
||||||
|
this.signature = licensearr[6]
|
||||||
|
this.content_key = licensearr[7]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreatePatientFolderButton extends React.Component {
|
||||||
|
async call_api (){
|
||||||
|
const response = await fetch('http://192.168.192.75:8000/folderpartnames/')
|
||||||
|
const myJason = await response.json()
|
||||||
|
var data = {
|
||||||
|
"part_class": "Röntgenbilder",
|
||||||
|
"folder_id": "1",
|
||||||
|
"part_context": "descht"
|
||||||
|
}
|
||||||
|
console.log(myJason)
|
||||||
|
var jsonArr = []
|
||||||
|
var testkeys = []
|
||||||
|
console.log(myJason.part_name)
|
||||||
|
var params = get_Params()
|
||||||
|
var license = new License(params)
|
||||||
|
license.serversign = params[8]
|
||||||
|
jsonArr.push(license)
|
||||||
|
for (var i = 0; i < myJason.results.length; i++){
|
||||||
|
var key = get_random_key()
|
||||||
|
var content = aes_encrypt(key, myJason.results[i].part_name)
|
||||||
|
var part = new newFolder_part(myJason.results[i].part_name, encrypt_key(key), content)
|
||||||
|
jsonArr.push(part)
|
||||||
|
testkeys.push(part)
|
||||||
|
}
|
||||||
|
var response_create = await fetch('http://192.168.192.75:8000/folder/create/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(jsonArr), // string or object
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button onClick={this.call_api}>CreateFolder</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_creating_folder = document.getElementById('create_patientfolder');
|
||||||
|
if (is_creating_folder) {
|
||||||
|
ReactDOM.render(<CreatePatientFolderButton />, document.getElementById('create_patientfolder'))
|
||||||
|
}
|
||||||
|
|
||||||
|
class UseLicenseButton extends React.Component {
|
||||||
|
async call_api (){
|
||||||
|
var jsonArr = []
|
||||||
|
var testkeys = []
|
||||||
|
var license = new License(get_Params())
|
||||||
|
folderparts = license.folderparts
|
||||||
|
folderparts = folderparts.split(", ")
|
||||||
|
print(folderparts)
|
||||||
|
render_info = folderparts.map((part) => {
|
||||||
|
return <button>{part}</button>})
|
||||||
|
ReactDOM.render(render_info, document.getElementById('call_api'))
|
||||||
|
jsonArr.push(license)
|
||||||
|
var response_create = await fetch('http://192.168.192.75:8000/folder/create/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(jsonArr), // string or object
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button onClick={this.call_api}>UseLicense</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var needs_call_api = document.getElementById('call_api');
|
||||||
|
if (needs_call_api) {
|
||||||
|
ReactDOM.render(<UseLicenseButton />, document.getElementById('call_api'))
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateLicenseButton extends React.Component {
|
||||||
|
async call_api (){
|
||||||
|
var jsonArr = []
|
||||||
|
var params = get_Params()
|
||||||
|
var license = new License(params)
|
||||||
|
license.serversign = params[8]
|
||||||
|
jsonArr.push(license)
|
||||||
|
console.log(license.folderparts)
|
||||||
|
var folderparts = license.folderparts.split(",")
|
||||||
|
for (var i = 0; i < folderparts.length; i++){
|
||||||
|
var part = folderparts[i]
|
||||||
|
jsonArr[1] = part
|
||||||
|
jsonArr[2] = "get"
|
||||||
|
var response_create = await fetch('http://192.168.192.75:8000/folder/read/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(jsonArr), // string or object
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var myJason = await response_create.json()
|
||||||
|
var key = decrypt_key(base64ToArrayBuffer(myJason.key))
|
||||||
|
var pubkey = myJason.pubkey
|
||||||
|
pubkey = pubkey.replace("-----BEGIN PUBLIC KEY-----", "-----BEGINPUBLICKEY-----")
|
||||||
|
pubkey = pubkey.replace("-----END PUBLIC KEY-----", "-----ENDPUBLICKEY-----")
|
||||||
|
pubkey = pubkey.replaceAll(" ", "\n")
|
||||||
|
pubkey = pubkey.replace("-----BEGINPUBLICKEY-----", "-----BEGIN PUBLIC KEY-----")
|
||||||
|
pubkey = pubkey.replace("-----ENDPUBLICKEY-----", "-----END PUBLIC KEY-----")
|
||||||
|
jsonArr[2] = encrypt_key_public(base64ToArrayBuffer(key), pubkey)
|
||||||
|
var response_create = await fetch('http://192.168.192.75:8000/create/key/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(jsonArr), // string or object
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button onClick={this.call_api}>Create License</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var want_create_license = document.getElementById('call_api_button');
|
||||||
|
if (want_create_license) {
|
||||||
|
ReactDOM.render(<CreateLicenseButton />, document.getElementById('call_api_button'))
|
||||||
|
}
|
4
Licenseserver/health_view/src/index.js
Normal file
4
Licenseserver/health_view/src/index.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
var buffer = require('buffer');
|
||||||
|
var Buffer = require('buffer');
|
||||||
|
import App from "./components/App";
|
||||||
|
|
83
Licenseserver/health_view/static/css/styles.css
Normal file
83
Licenseserver/health_view/static/css/styles.css
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
@import url(https://fonts.googleapis.com/css?family=Lato);
|
||||||
|
|
||||||
|
.topic {
|
||||||
|
font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 6pt;
|
||||||
|
margin-left: 0pt;
|
||||||
|
margin-top: 6pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
margin-bottom: 6pt;
|
||||||
|
margin-left: 25px;
|
||||||
|
margin-top: 6pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
button {
|
||||||
|
|
||||||
|
background-color: rgba(54, 94, 239, 0.3);
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 10px 20px rgba(0, 0, 0, .7);
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
list-style: none;
|
||||||
|
flex-direction: column;
|
||||||
|
list-style-type: none;
|
||||||
|
background-color: rgba(54, 94, 239, 0.3);
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 10px 20px rgba(0, 0, 0, .7);
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
}
|
||||||
|
.sidebar-nav li
|
||||||
|
{
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
.sidebar-nav a {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
padding: 10px 0;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
color: #000000;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav a:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: #222222;
|
||||||
|
transform: scaleX(0);
|
||||||
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav a:hover, li:hover, button:hover{
|
||||||
|
color: #95a5a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav a:hover::after {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
Licenseserver/health_view/static/favicon.png
Normal file
BIN
Licenseserver/health_view/static/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
BIN
Licenseserver/health_view/static/images/wall.jpg
Normal file
BIN
Licenseserver/health_view/static/images/wall.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 313 KiB |
64
Licenseserver/health_view/templates/base_generic.html
Normal file
64
Licenseserver/health_view/templates/base_generic.html
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
{% block title %}<title>Gabriel's DRM</title>{% endblock %}
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
|
||||||
|
{% load static %}
|
||||||
|
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
|
||||||
|
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.png' %}"/>
|
||||||
|
<style>
|
||||||
|
{% load static %}
|
||||||
|
body {
|
||||||
|
background-image: url('{% static "images/wall.jpg" %}');
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.col-sm-5{
|
||||||
|
margin-top: 20px;
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 10px 20px rgba(0, 0, 0, .7);
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
{% block sidebar %}
|
||||||
|
<ul class="sidebar-nav">
|
||||||
|
<li><a href="{% url 'index' %}">Home</a></li>
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<li> Username: </li>
|
||||||
|
<li id="username">{{ user.get_username }}</li>
|
||||||
|
<li> Folder ID: {{ user.folderinfo }}</li>
|
||||||
|
<li><a href="{% url 'create-license' user.folderinfo.id %}">Create License</a></li>
|
||||||
|
<li><a href="{% url 'given-licenses' %}">Given Licenses</a></li>
|
||||||
|
<li><a href="{% url 'my-licenses' %}">My Licenses</a></li>
|
||||||
|
<li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-5">{% block content %}{% endblock %}</div>
|
||||||
|
{% if "license/show" in request.path %}
|
||||||
|
<div class="col-sm-5" style="visibility: hidden" id="license_content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div id="part_buttons"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div id="content_parts"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="{% static 'frontend/main.js' %}"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,13 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Creating Process...</h1>
|
||||||
|
<form id="application" action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
{{ form.as_p }}
|
||||||
|
</table>
|
||||||
|
<input type="submit" style="margin: 10px" value="Submit" id="submit_button_license"/>
|
||||||
|
</form>
|
||||||
|
<div id="create_available"/>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,76 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if "create" in request.path %}
|
||||||
|
{% if serversign %}
|
||||||
|
<h1>Licensezertificate now:</h1>
|
||||||
|
{% else %}
|
||||||
|
<h1>License now:</h1>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if serversign %}
|
||||||
|
<h1>Licensezertificate:</h1>
|
||||||
|
{% else %}
|
||||||
|
<h1>License:</h1>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<div class="topic" > Patient: </div>
|
||||||
|
<div class="content" id="id_patient">{{patient}}</div>
|
||||||
|
<div class="topic"> Justified: </div>
|
||||||
|
<div class="content" id="id_justified">{{justified}}</div>
|
||||||
|
<div class="topic"> License Creator: </div>
|
||||||
|
<div class="content" id="id_license_creator">{{license_creator}}</div>
|
||||||
|
<div class="topic"> Expiration date: </div>
|
||||||
|
<div class="content" id="id_exp_date">{{exp_date}}</div>
|
||||||
|
<div class="topic"> Permission: </div>
|
||||||
|
<div class="content" id="id_permission">{{permission}}</div>
|
||||||
|
<div class="topic"> Folder Parts: </div>
|
||||||
|
<div class="content" id="id_folder_parts">{{folderparts}}</div>
|
||||||
|
<div class="topic"> Signature: </div>
|
||||||
|
<div class="content" id="id_signature">
|
||||||
|
{{signature.0}}
|
||||||
|
{{signature.1}}
|
||||||
|
{{signature.2}}
|
||||||
|
{{signature.3}}
|
||||||
|
</div>
|
||||||
|
<div class="topic">
|
||||||
|
{% if new_folder %}
|
||||||
|
New Content Key:
|
||||||
|
{% else %}
|
||||||
|
Content Key:
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="content" id="id_content_key">
|
||||||
|
{{key_split.0}}
|
||||||
|
{{key_split.1}}
|
||||||
|
{{key_split.2}}
|
||||||
|
{{key_split.3}}
|
||||||
|
</div>
|
||||||
|
{% if serversign %}
|
||||||
|
<div class="topic">
|
||||||
|
Licenseserver signature:
|
||||||
|
</div>
|
||||||
|
<div class="content" id="licenseserver_sign">
|
||||||
|
{{serversign.0}}
|
||||||
|
{{serversign.1}}
|
||||||
|
{{serversign.2}}
|
||||||
|
{{serversign.3}}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if "given" in request.path %}
|
||||||
|
<a href="{% url 'delete_license' %}"><button type="button" id="delete">Delete it</button></a>
|
||||||
|
{% elif "own" in request.path %}
|
||||||
|
<div id="use_license"></div>
|
||||||
|
{% else %}
|
||||||
|
{% if new_folder == True %}
|
||||||
|
|
||||||
|
<div id="create_patientfolder"></div>
|
||||||
|
{% else %}
|
||||||
|
<div id="call_api_button"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if "show" in request.path %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Licenses</h1>
|
||||||
|
{% if license_list %}
|
||||||
|
<ul>
|
||||||
|
{% for license in license_list %}
|
||||||
|
<li>
|
||||||
|
{% if "givenlicenses" in request.path %}
|
||||||
|
<a href="{% url 'license-detail-given' license.pk %}">{{ license.patient }}</a> ({{license.justified}})
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'license-detail-own' license.pk %}">{{ license.patient }}</a> ({{license.justified}})
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>There are no Licenses.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
14
Licenseserver/health_view/templates/index.html
Normal file
14
Licenseserver/health_view/templates/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
{% block title %}
|
||||||
|
<title>Gabriel's DRM</title>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>Local Health View</h1>
|
||||||
|
<p>Welcome to <em>Gabriel Kaufmann's </em>DRM System!</p>
|
||||||
|
<h2>Dynamic content</h2>
|
||||||
|
<p>The System has the following record counts:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>User: </strong> {{ num_user }}</li>
|
||||||
|
<li><strong>Licenses:</strong> {{ num_licenses }}</li>
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
3
Licenseserver/health_view/tests.py
Normal file
3
Licenseserver/health_view/tests.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
12
Licenseserver/health_view/urls.py
Normal file
12
Licenseserver/health_view/urls.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.index, name='index'),
|
||||||
|
path('mylicenses/', views.LicenseViewOwn.as_view(), name='my-licenses'),
|
||||||
|
path('givenlicenses/', views.LicenseViewGiven.as_view(), name='given-licenses'),
|
||||||
|
path('license/<int:fid>/create/', views.create_license, name='create-license'),
|
||||||
|
path('license/show/<int:pk>/own/', views.get_license_details, name='license-detail-own'),
|
||||||
|
path('license/show/<int:pk>/given/', views.get_license_details, name='license-detail-given'),
|
||||||
|
path('delete_license', views.delete_license, name='delete_license')
|
||||||
|
]
|
184
Licenseserver/health_view/views.py
Normal file
184
Licenseserver/health_view/views.py
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
from django.http import HttpResponseRedirect, HttpResponse
|
||||||
|
from django.shortcuts import render, get_object_or_404
|
||||||
|
from health_view.models import License, FolderInfo, Permission, FolderPart
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.views import generic
|
||||||
|
from datetime import datetime
|
||||||
|
from health_view.crypto_functions import *
|
||||||
|
from health_view.forms import CreateLicenseForm
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
"""View function for home page of site."""
|
||||||
|
num_licenses = License.objects.all().count()
|
||||||
|
num_user = User.objects.all().count()
|
||||||
|
context = {
|
||||||
|
'num_licenses': num_licenses,
|
||||||
|
'num_user': num_user,
|
||||||
|
}
|
||||||
|
return render(request, 'index.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
class FolderInfoID(generic.ListView):
|
||||||
|
model = FolderInfo
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return FolderInfo.objects.get(patient=self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class LicenseViewGiven(generic.ListView):
|
||||||
|
model = License
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return License.objects.filter(patient=self.request.user).order_by('patient')
|
||||||
|
|
||||||
|
|
||||||
|
class LicenseViewOwn(generic.ListView):
|
||||||
|
model = License
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return License.objects.filter(justified=self.request.user).order_by('patient')
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def get_license_details(request, pk):
|
||||||
|
model = License
|
||||||
|
if "own" in request.get_full_path():
|
||||||
|
if not License.objects.filter(pk=pk, justified=request.user).exists():
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
license = get_object_or_404(License, pk=pk, justified=request.user)
|
||||||
|
if "given" in request.get_full_path():
|
||||||
|
if not License.objects.filter(pk=pk, patient=request.user).exists():
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
license = get_object_or_404(License, pk=pk, patient=request.user)
|
||||||
|
exp_date = license.exp_date
|
||||||
|
permission = license.permissions.all().values_list()
|
||||||
|
permission_string = ""
|
||||||
|
for perm in permission:
|
||||||
|
permission_string += perm[2]
|
||||||
|
permission_string += ", "
|
||||||
|
folderparts_string = ""
|
||||||
|
folderparts = license.folder_parts.all().values_list()
|
||||||
|
for e in folderparts:
|
||||||
|
folderparts_string += e[2]
|
||||||
|
folderparts_string += ", "
|
||||||
|
key = license.patient.folderinfo.content_key
|
||||||
|
sig = license.signature
|
||||||
|
key_split = (key[0:64], key[64:128], key[128:192], key[192:256])
|
||||||
|
sig_split = (sig[0:64], sig[64:128], sig[128:192], sig[192:256])
|
||||||
|
license_creator = license.license_creator
|
||||||
|
patient = license.patient
|
||||||
|
justified = license.justified
|
||||||
|
if "own" in request.get_full_path():
|
||||||
|
license_string = str(patient) + "&" + str(justified) + "&" + str(license_creator.username) + "&" + str(exp_date.replace(" ", ",") ) + "&" + get_string_byanser(permission) + "&" + get_string_byanser(folderparts) + "&" + sig + "&" + key
|
||||||
|
server_sign = sign(license_string, priv_key_own)
|
||||||
|
serversign_split = (server_sign[0:64], server_sign[64:128], server_sign[128:192])
|
||||||
|
else:
|
||||||
|
serversign_split=0
|
||||||
|
context = {
|
||||||
|
'patient': patient,
|
||||||
|
'justified': justified,
|
||||||
|
'license_creator': license_creator,
|
||||||
|
'exp_date': exp_date,
|
||||||
|
'permission': permission_string[:-2],
|
||||||
|
'folderparts': folderparts_string[:-2],
|
||||||
|
'content_key': key,
|
||||||
|
'signature': sig_split,
|
||||||
|
'serversign': serversign_split,
|
||||||
|
'key_split': key_split}
|
||||||
|
return render(request, 'health_view/license_detail.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
def get_string_byrequest(index_list, model_call):
|
||||||
|
objectstring = ""
|
||||||
|
for i in index_list:
|
||||||
|
objectstring += str(model_call.objects.get(id=i))
|
||||||
|
objectstring += ","
|
||||||
|
return objectstring[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def check_expiration_date(license):
|
||||||
|
exp_date = license.exp_date
|
||||||
|
datetime_object = ""
|
||||||
|
for fmt in ('%d/%m/%Y %H:%M', '%d-%m-%Y %H:%M', '%d/%m/%Y'):
|
||||||
|
try:
|
||||||
|
datetime_object = datetime.strptime(exp_date, fmt)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
return datetime.now() < datetime_object
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_string_byanser(model_call):
|
||||||
|
objectstring = ""
|
||||||
|
for i in model_call:
|
||||||
|
objectstring += str(i[2])
|
||||||
|
objectstring += ","
|
||||||
|
print(objectstring)
|
||||||
|
return objectstring[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def create_license(request, fid):
|
||||||
|
model = License
|
||||||
|
user = get_object_or_404(User, id=fid)
|
||||||
|
if request.method == 'POST':
|
||||||
|
post = request.POST.copy() # to make it mutable
|
||||||
|
pubkey = request.user.folderinfo.pub_key
|
||||||
|
patient = User.objects.get(id=post['patient'])
|
||||||
|
justified = User.objects.get(id=post['justified'])
|
||||||
|
license_creator = request.user
|
||||||
|
exp_date = post['exp_date']
|
||||||
|
permission_ground = request.POST.getlist("permissions")
|
||||||
|
folderparts_ground = request.POST.getlist("folder_parts")
|
||||||
|
permission = get_string_byrequest(permission_ground, Permission)
|
||||||
|
folderparts = get_string_byrequest(folderparts_ground, FolderPart)
|
||||||
|
signature_string = str(patient) + "&" + str(justified) + "&" + str(license_creator.username) + "&" + str(exp_date.replace(" ", ",")) + "&" + permission + "&" + folderparts
|
||||||
|
signature = post['signature']
|
||||||
|
new_folder = False
|
||||||
|
if not verify(signature_string, signature, pubkey):
|
||||||
|
form = CreateLicenseForm(request.user)
|
||||||
|
context = {'form': form}
|
||||||
|
return render(request, 'health_view/create_license.html', context)
|
||||||
|
if request.user.folderinfo.content_key == "no_key":
|
||||||
|
request.user.folderinfo.content_key = make_encrypted_key_content_server()
|
||||||
|
request.user.folderinfo.save()
|
||||||
|
new_folder = True
|
||||||
|
new_license = License(patient=patient, justified=justified, exp_date=exp_date, license_creator=license_creator, signature=signature)
|
||||||
|
new_license.save()
|
||||||
|
for e in permission_ground:
|
||||||
|
new_license.permissions.add(Permission.objects.get(id=e))
|
||||||
|
for i in folderparts_ground:
|
||||||
|
new_license.folder_parts.add(FolderPart.objects.get(id=i))
|
||||||
|
new_license.save()
|
||||||
|
request.POST = post
|
||||||
|
key = request.user.folderinfo.content_key
|
||||||
|
key_split = (key[0:64], key[64:128], key[128:192], key[192:256])
|
||||||
|
sig_split = (signature[0:64], signature[64:128], signature[128:192], signature[192:256])
|
||||||
|
license_string = signature_string + "&" + new_license.signature + "&" + key
|
||||||
|
serversign = sign(license_string, priv_key_own)
|
||||||
|
serversign_split = (serversign[0:64], serversign[64:128], serversign[128:192])
|
||||||
|
context = {
|
||||||
|
'patient': patient,
|
||||||
|
'justified': justified,
|
||||||
|
'license_creator': license_creator,
|
||||||
|
'exp_date': exp_date,
|
||||||
|
'permission': permission,
|
||||||
|
'folderparts': folderparts,
|
||||||
|
'content_key': key,
|
||||||
|
'signature': sig_split,
|
||||||
|
'key_split': key_split,
|
||||||
|
'serversign': serversign_split,
|
||||||
|
'new_folder': new_folder}
|
||||||
|
return render(request, 'health_view/license_detail.html', context)
|
||||||
|
else:
|
||||||
|
form = CreateLicenseForm(request.user)
|
||||||
|
context = {'form': form}
|
||||||
|
return render(request, 'health_view/create_license.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_license(request):
|
||||||
|
print("test")
|
30
Licenseserver/health_view/webpack.config.js
Normal file
30
Licenseserver/health_view/webpack.config.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
resolve:{fallback: { "crypto": require.resolve("crypto-browserify"),
|
||||||
|
"stream": require.resolve("stream-browserify"),
|
||||||
|
"buffer": require.resolve("buffer-browserify"),
|
||||||
|
"path": require.resolve("path-browserify"),
|
||||||
|
"assert": require.resolve("assert/")}},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
presets: ["@babel/preset-env", "@babel/preset-react"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
process: 'process/browser',
|
||||||
|
'process.env.POUCHDB_NAME': JSON.stringify(process.env.POUCHDB_NAME || 'mydb'),
|
||||||
|
})
|
||||||
|
],
|
||||||
|
}
|
6
Licenseserver/templates/registration/logged_out.html
Normal file
6
Licenseserver/templates/registration/logged_out.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p>Logged out!</p>
|
||||||
|
<a href="{% url 'login'%}">Click here to login again.</a>
|
||||||
|
{% endblock %}
|
44
Licenseserver/templates/registration/login.html
Normal file
44
Licenseserver/templates/registration/login.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% if form.errors %}
|
||||||
|
<p>Your username and password didn't match. Please try again.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if next %}
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<p>Your account doesn't have access to this page. To proceed,
|
||||||
|
please login with an account that has access.</p>
|
||||||
|
{% else %}
|
||||||
|
<p>Please login...</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form id="submit_login" method="post" action="{% url 'login' %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.username.label_tag }}</td>
|
||||||
|
<td>{{ form.username }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.password.label_tag }}</td>
|
||||||
|
<td>{{ form.password }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Private Key :P</td>
|
||||||
|
<td><textarea id="privkey" cols="40" rows="5"></textarea></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Public Key:</td>
|
||||||
|
<td><textarea id="pubkey" cols="40" rows="5"></textarea> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<input type="submit" value="login"/>
|
||||||
|
<input type="hidden" name="next" value="{{ next }}" />
|
||||||
|
</form>
|
||||||
|
{# Assumes you setup the password_reset view in your URLconf #}
|
||||||
|
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,6 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>The password has been changed!</h1>
|
||||||
|
<p><a href="{% url 'login' %}">log in again?</a></p>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,29 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if validlink %}
|
||||||
|
<p>Please enter (and confirm) your new password.</p>
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.new_password1.errors }}
|
||||||
|
<label for="id_new_password1">New password:</label></td>
|
||||||
|
<td>{{ form.new_password1 }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.new_password2.errors }}
|
||||||
|
<label for="id_new_password2">Confirm password:</label></td>
|
||||||
|
<td>{{ form.new_password2 }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" value="Change my password" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<h1>Password reset failed</h1>
|
||||||
|
<p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,2 @@
|
|||||||
|
Someone asked for password reset for email {{ email }}. Follow the link below:
|
||||||
|
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
|
@ -0,0 +1,12 @@
|
|||||||
|
{% extends "base_generic.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% if form.email.errors %}
|
||||||
|
{{ form.email.errors }}
|
||||||
|
{% endif %}
|
||||||
|
<p>{{ form.email }}</p>
|
||||||
|
<input type="submit" class="btn btn-default btn-lg" value="Reset password">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user