From 0247c5007dac70ee1d8fdda2c7e7f9ee00643279 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 20 Feb 2024 17:50:45 +0100 Subject: [PATCH 01/20] new encriptation system of sensible datas --- idhub/admin/forms.py | 45 ++++++++-- idhub/admin/views.py | 37 +++++--- idhub/management/commands/initial_datas.py | 19 ++--- idhub/mixins.py | 19 ++++- idhub/models.py | 84 ++++++++----------- .../idhub/admin/issue_credentials.html | 2 +- idhub/templates/idhub/user/credential.html | 2 +- idhub/urls.py | 4 + idhub/user/forms.py | 4 +- idhub/user/views.py | 51 +++++------ idhub/views.py | 23 ++--- idhub_auth/models.py | 56 +++++++------ 12 files changed, 192 insertions(+), 154 deletions(-) diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index aa453ce..fd57e64 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -1,23 +1,19 @@ -import csv import json -import copy import base64 import jsonschema import pandas as pd -from pyhanko.sign import signers - +from nacl.exceptions import CryptoError from django import forms from django.core.cache import cache from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError -from utils import credtools, certs +from utils import certs from idhub.models import ( DID, File_datas, Membership, Schemas, - Service, UserRol, VerificableCredential, ) @@ -51,6 +47,37 @@ class TermsConditionsForm2(forms.Form): return +class EncryptionKeyForm(forms.Form): + key = forms.CharField( + label=_("Key for encrypt the secrets of all system"), + required=True + ) + + def clean(self): + data = self.cleaned_data + self._key = data["key"] + if not DID.objects.exists(): + return data + + did = DID.objects.first() + cache.set("KEY_DIDS", self._key, None) + try: + did.get_key_material() + except CryptoError: + cache.set("KEY_DIDS", None) + txt = _("Key no valid!") + raise ValidationError(txt) + + return data + + def save(self, commit=True): + + if commit: + cache.set("KEY_DIDS", self._key, None) + + return + + class TermsConditionsForm(forms.Form): accept_privacy = forms.BooleanField( widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), @@ -133,7 +160,7 @@ class ImportForm(forms.Form): self.fields['did'].choices = [ (x.did, x.label) for x in dids.filter(eidas1=False) ] - self.fields['schema'].choices = [ + self.fields['schema'].choices = [(0, _('Select one'))] + [ (x.id, x.name) for x in Schemas.objects.filter() ] if dids.filter(eidas1=True).exists(): @@ -197,6 +224,9 @@ class ImportForm(forms.Form): if not data_pd: self.exception("This file is empty!") + if not self._schema: + return data + for n in range(df.last_valid_index()+1): row = {} for k in data_pd.keys(): @@ -382,7 +412,6 @@ class ImportCertificateForm(forms.Form): return data def new_did(self): - cert = self.pfx_file keys = { "cert": base64.b64encode(self.pfx_file).decode('utf-8'), "passphrase": self._pss diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 25ac28d..8a9bb63 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -1,9 +1,6 @@ import os import json -import logging -import pandas as pd from pathlib import Path -from jsonschema import validate from smtplib import SMTPException from django_tables2 import SingleTableView @@ -18,7 +15,6 @@ from django.views.generic.edit import ( UpdateView, ) from django.shortcuts import get_object_or_404, redirect -from django.core.cache import cache from django.urls import reverse_lazy from django.http import HttpResponse from django.contrib import messages @@ -28,12 +24,13 @@ from idhub_auth.forms import ProfileForm from idhub.mixins import AdminView, Http403 from idhub.email.views import NotifyActivateUserByEmail from idhub.admin.forms import ( + EncryptionKeyForm, + ImportCertificateForm, ImportForm, MembershipForm, TermsConditionsForm, SchemaForm, - UserRolForm, - ImportCertificateForm, + UserRolForm ) from idhub.admin.tables import ( DashboardTable, @@ -79,7 +76,27 @@ class TermsAndConditionsView(AdminView, FormView): return kwargs def form_valid(self, form): - user = form.save() + form.save() + return super().form_valid(form) + + +class EncryptionKeyView(AdminView, FormView): + template_name = "idhub/admin/encryption_key.html" + title = _('Encryption Key') + section = "" + subtitle = _('Encryption Key') + icon = 'bi bi-key' + form_class = EncryptionKeyForm + success_url = reverse_lazy('idhub:admin_dashboard') + + def get(self, request, *args, **kwargs): + if self.admin_validated: + return redirect(self.success_url) + + return super().get(request, *args, **kwargs) + + def form_valid(self, form): + form.save() return super().form_valid(form) @@ -649,7 +666,7 @@ class CredentialJsonView(Credentials): VerificableCredential, pk=pk, ) - response = HttpResponse(self.object.data, content_type="application/json") + response = HttpResponse(self.object.get_data(), content_type="application/json") response['Content-Disposition'] = 'attachment; filename={}'.format("credential.json") return response @@ -730,7 +747,7 @@ class DidRegisterView(Credentials, CreateView): def form_valid(self, form): form.instance.user = self.request.user - form.instance.set_did(cache.get("KEY_DIDS")) + form.instance.set_did() form.save() messages.success(self.request, _('DID created successfully')) Event.set_EV_ORG_DID_CREATED_BY_ADMIN(form.instance) @@ -752,7 +769,7 @@ class DidEditView(Credentials, UpdateView): return super().get(request, *args, **kwargs) def form_valid(self, form): - user = form.save() + form.save() messages.success(self.request, _('DID updated successfully')) return super().form_valid(form) diff --git a/idhub/management/commands/initial_datas.py b/idhub/management/commands/initial_datas.py index e8abf19..15f74ea 100644 --- a/idhub/management/commands/initial_datas.py +++ b/idhub/management/commands/initial_datas.py @@ -23,6 +23,8 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): ADMIN_EMAIL = config('ADMIN_EMAIL', 'admin@example.org') ADMIN_PASSWORD = config('ADMIN_PASSWORD', '1234') + KEY_DIDS = config('KEY_DIDS', '1234') + cache.set("KEY_DIDS", KEY_DIDS, None) self.create_admin_users(ADMIN_EMAIL, ADMIN_PASSWORD) if settings.CREATE_TEST_USERS: @@ -43,21 +45,17 @@ class Command(BaseCommand): def create_admin_users(self, email, password): su = User.objects.create_superuser(email=email, password=password) - su.set_encrypted_sensitive_data(password) + su.set_encrypted_sensitive_data() su.save() - key = su.decrypt_sensitive_data(password) - key_dids = {su.id: key} - cache.set("KEY_DIDS", key_dids, None) - self.create_defaults_dids(su, key) + self.create_defaults_dids(su) def create_users(self, email, password): u = User.objects.create(email=email, password=password) u.set_password(password) - u.set_encrypted_sensitive_data(password) + u.set_encrypted_sensitive_data() u.save() - key = u.decrypt_sensitive_data(password) - self.create_defaults_dids(u, key) + self.create_defaults_dids(u) def create_organizations(self, name, url): @@ -72,9 +70,10 @@ class Command(BaseCommand): org1.my_client_secret = org2.client_secret org1.save() org2.save() - def create_defaults_dids(self, u, password): + + def create_defaults_dids(self, u): did = DID(label="Default", user=u, type=DID.Types.WEB) - did.set_did(password) + did.set_did() did.save() def create_schemas(self): diff --git a/idhub/mixins.py b/idhub/mixins.py index b2b3fbe..ad1379b 100644 --- a/idhub/mixins.py +++ b/idhub/mixins.py @@ -12,8 +12,8 @@ class Http403(PermissionDenied): default_detail = _('Permission denied. User is not authenticated') default_code = 'forbidden' - def __init__(self, detail=None, code=None): - if detail is not None: + def __init__(self, details=None, code=None): + if details is not None: self.detail = details or self.default_details if code is not None: self.code = code or self.default_code @@ -22,15 +22,30 @@ class Http403(PermissionDenied): class UserView(LoginRequiredMixin): login_url = "/login/" wallet = False + admin_validated = False path_terms = [ 'admin_terms_and_conditions', 'user_terms_and_conditions', 'user_gdpr', + 'user_waiting', + 'user_waiting', + 'encryption_key', ] def get(self, request, *args, **kwargs): self.admin_validated = cache.get("KEY_DIDS") response = super().get(request, *args, **kwargs) + + if not self.admin_validated: + actual_path = resolve(self.request.path).url_name + if not self.request.user.is_admin: + if actual_path != 'user_waiting': + return redirect(reverse_lazy("idhub:user_waiting")) + + if self.request.user.is_admin: + if actual_path != 'encryption_key': + return redirect(reverse_lazy("idhub:encryption_key")) + url = self.check_gdpr() return url or response diff --git a/idhub/models.py b/idhub/models.py index ae61c56..7d6a1c6 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -9,7 +9,6 @@ from django.conf import settings from django.core.cache import cache from django.template.loader import get_template from django.utils.translation import gettext_lazy as _ -from nacl import secret from utils.idhub_ssikit import ( generate_did_controller_key, @@ -34,26 +33,27 @@ class Event(models.Model): EV_DID_CREATED = 9, "DID created" EV_DID_DELETED = 10, "DID deleted" EV_CREDENTIAL_DELETED_BY_USER = 11, "Credential deleted by user" - EV_CREDENTIAL_DELETED = 12, "Credential deleted" - EV_CREDENTIAL_ISSUED_FOR_USER = 13, "Credential issued for user" - EV_CREDENTIAL_ISSUED = 14, "Credential issued" - EV_CREDENTIAL_PRESENTED_BY_USER = 15, "Credential presented by user" - EV_CREDENTIAL_PRESENTED = 16, "Credential presented" - EV_CREDENTIAL_ENABLED = 17, "Credential enabled" - EV_CREDENTIAL_CAN_BE_REQUESTED = 18, "Credential available" - EV_CREDENTIAL_REVOKED_BY_ADMIN = 19, "Credential revoked by admin" - EV_CREDENTIAL_REVOKED = 20, "Credential revoked" - EV_ROLE_CREATED_BY_ADMIN = 21, "Role created by admin" - EV_ROLE_MODIFIED_BY_ADMIN = 22, "Role modified by admin" - EV_ROLE_DELETED_BY_ADMIN = 23, "Role deleted by admin" - EV_SERVICE_CREATED_BY_ADMIN = 24, "Service created by admin" - EV_SERVICE_MODIFIED_BY_ADMIN = 25, "Service modified by admin" - EV_SERVICE_DELETED_BY_ADMIN = 26, "Service deleted by admin" - EV_ORG_DID_CREATED_BY_ADMIN = 27, "Organisational DID created by admin" - EV_ORG_DID_DELETED_BY_ADMIN = 28, "Organisational DID deleted by admin" - EV_USR_DEACTIVATED_BY_ADMIN = 29, "User deactivated" - EV_USR_ACTIVATED_BY_ADMIN = 30, "User activated" - EV_USR_SEND_VP = 31, "User send Verificable Presentation" + EV_CREDENTIAL_DELETED_BY_ADMIN = 12, "Credential deleted by admin" + EV_CREDENTIAL_DELETED = 13, "Credential deleted" + EV_CREDENTIAL_ISSUED_FOR_USER = 14, "Credential issued for user" + EV_CREDENTIAL_ISSUED = 15, "Credential issued" + EV_CREDENTIAL_PRESENTED_BY_USER = 16, "Credential presented by user" + EV_CREDENTIAL_PRESENTED = 17, "Credential presented" + EV_CREDENTIAL_ENABLED = 18, "Credential enabled" + EV_CREDENTIAL_CAN_BE_REQUESTED = 19, "Credential available" + EV_CREDENTIAL_REVOKED_BY_ADMIN = 20, "Credential revoked by admin" + EV_CREDENTIAL_REVOKED = 21, "Credential revoked" + EV_ROLE_CREATED_BY_ADMIN = 22, "Role created by admin" + EV_ROLE_MODIFIED_BY_ADMIN = 23, "Role modified by admin" + EV_ROLE_DELETED_BY_ADMIN = 24, "Role deleted by admin" + EV_SERVICE_CREATED_BY_ADMIN = 25, "Service created by admin" + EV_SERVICE_MODIFIED_BY_ADMIN = 26, "Service modified by admin" + EV_SERVICE_DELETED_BY_ADMIN = 27, "Service deleted by admin" + EV_ORG_DID_CREATED_BY_ADMIN = 28, "Organisational DID created by admin" + EV_ORG_DID_DELETED_BY_ADMIN = 29, "Organisational DID deleted by admin" + EV_USR_DEACTIVATED_BY_ADMIN = 30, "User deactivated" + EV_USR_ACTIVATED_BY_ADMIN = 31, "User activated" + EV_USR_SEND_VP = 32, "User send Verificable Presentation" created = models.DateTimeField(_("Date"), auto_now=True) message = models.CharField(_("Description"), max_length=350) @@ -99,9 +99,8 @@ class Event(models.Model): @classmethod def set_EV_DATA_UPDATE_REQUESTED_BY_USER(cls, user): msg = _("The user '{username}' has request the update of the following information: ") - msg += "['field1':'value1', 'field2':'value2'>,...]".format( - username=user.username, - ) + msg += "['field1':'value1', 'field2':'value2'>,...]" + msg = msg.format(username=user.username) cls.objects.create( type=cls.Types.EV_DATA_UPDATE_REQUESTED_BY_USER, message=msg, @@ -444,11 +443,11 @@ class DID(models.Model): # JSON-serialized DID document didweb_document = models.TextField() - def get_key_material(self, password): - return self.user.decrypt_data(self.key_material, password) + def get_key_material(self): + return self.user.decrypt_data(self.key_material) - def set_key_material(self, value, password): - self.key_material = self.user.encrypt_data(value, password) + def set_key_material(self, value): + self.key_material = self.user.encrypt_data(value) @property def is_organization_did(self): @@ -456,9 +455,9 @@ class DID(models.Model): return True return False - def set_did(self, password): + def set_did(self): new_key_material = generate_did_controller_key() - self.set_key_material(new_key_material, password) + self.set_key_material(new_key_material) if self.type == self.Types.KEY: self.did = keydid_from_controller_key(new_key_material) @@ -621,17 +620,14 @@ class VerificableCredential(models.Model): return True return False - def get_data(self, password): + def get_data(self): if not self.data: return "" - if self.eidas1_did: - return self.data - - return self.user.decrypt_data(self.data, password) + return self.user.decrypt_data(self.data) - def set_data(self, value, password): - self.data = self.user.encrypt_data(value, password) + def set_data(self, value): + self.data = self.user.encrypt_data(value) def get_description(self): return self.schema._description or '' @@ -652,32 +648,24 @@ class VerificableCredential(models.Model): data = json.loads(self.csv_data).items() return data - def issue(self, did, password, domain=settings.DOMAIN.strip("/")): + def issue(self, did, domain=settings.DOMAIN.strip("/")): if self.status == self.Status.ISSUED: return self.subject_did = did self.issued_on = datetime.datetime.now().astimezone(pytz.utc) - issuer_pass = cache.get("KEY_DIDS") - # issuer_pass = self.user.decrypt_data( - # cache.get("KEY_DIDS"), - # settings.SECRET_KEY, - # ) # hash of credential without sign self.hash = hashlib.sha3_256(self.render(domain).encode()).hexdigest() data = sign_credential( self.render(domain), - self.issuer_did.get_key_material(issuer_pass) + self.issuer_did.get_key_material() ) valid, reason = verify_credential(data) if not valid: return - if self.eidas1_did: - self.data = data - else: - self.data = self.user.encrypt_data(data, password) + self.data = self.user.encrypt_data(data) self.status = self.Status.ISSUED diff --git a/idhub/templates/idhub/admin/issue_credentials.html b/idhub/templates/idhub/admin/issue_credentials.html index ac93171..3c29289 100644 --- a/idhub/templates/idhub/admin/issue_credentials.html +++ b/idhub/templates/idhub/admin/issue_credentials.html @@ -38,7 +38,7 @@ {% trans 'Issuance date' %}:
- {{ object.issuer_on|default_if_none:"" }} + {{ object.issued_on|default_if_none:"" }}
diff --git a/idhub/templates/idhub/user/credential.html b/idhub/templates/idhub/user/credential.html index 1ee66a4..415c280 100644 --- a/idhub/templates/idhub/user/credential.html +++ b/idhub/templates/idhub/user/credential.html @@ -25,7 +25,7 @@ {% trans 'Issuance date' %}:
- {{ object.issuer_on|default_if_none:"" }} + {{ object.issued_on|default_if_none:"" }}
diff --git a/idhub/urls.py b/idhub/urls.py index 30338b3..d0230c9 100644 --- a/idhub/urls.py +++ b/idhub/urls.py @@ -88,6 +88,9 @@ urlpatterns = [ path('user/terms/', views_user.TermsAndConditionsView.as_view(), name='user_terms_and_conditions'), + path('waiting/', views_user.WaitingView.as_view(), + name='user_waiting'), + # Admin path('admin/dashboard/', views_admin.DashboardView.as_view(), name='admin_dashboard'), @@ -173,6 +176,7 @@ urlpatterns = [ name='admin_terms_and_conditions'), path('admin/import/new', views_admin.ImportAddView.as_view(), name='admin_import_add'), + path('admin/enc/', views_admin.EncryptionKeyView.as_view(), name='encryption_key'), path('admin/auth/', views_admin.DobleFactorAuthView.as_view(), name='admin_2fauth'), path('admin/auth/2f/', DobleFactorSendView.as_view(), name='confirm_send_2f'), diff --git a/idhub/user/forms.py b/idhub/user/forms.py index 9561eb7..1102e9a 100644 --- a/idhub/user/forms.py +++ b/idhub/user/forms.py @@ -81,7 +81,6 @@ class RequestCredentialForm(forms.Form): self.user = kwargs.pop('user', None) self.lang = kwargs.pop('lang', None) self._domain = kwargs.pop('domain', None) - self.password = kwargs.pop('password', None) super().__init__(*args, **kwargs) self.fields['did'].choices = [ (x.did, x.label) for x in DID.objects.filter(user=self.user) @@ -109,8 +108,7 @@ class RequestCredentialForm(forms.Form): did = did[0] cred = cred[0] try: - if self.password: - cred.issue(did, self.password, domain=self._domain) + cred.issue(did, domain=self._domain) except Exception: return diff --git a/idhub/user/views.py b/idhub/user/views.py index 27c8f77..a31fc63 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -161,10 +161,25 @@ class TermsAndConditionsView(UserView, FormView): return kwargs def form_valid(self, form): - user = form.save() + form.save() return super().form_valid(form) +class WaitingView(UserView, TemplateView): + template_name = "idhub/user/waiting.html" + title = _("Comunication with admin") + subtitle = _('Service temporary close') + section = "" + icon = 'bi bi-file-earmark-medical' + success_url = reverse_lazy('idhub:user_dashboard') + + def get(self, request, *args, **kwargs): + if cache.get("KEY_DIDS"): + return redirect(self.success_url) + return super().get(request, *args, **kwargs) + + + class CredentialView(MyWallet, TemplateView): template_name = "idhub/user/credential.html" subtitle = _('Credential') @@ -194,7 +209,8 @@ class CredentialPdfView(MyWallet, TemplateView): file_name = "certificate.pdf" def get(self, request, *args, **kwargs): - self.admin_validated = cache.get("KEY_DIDS") + if not self.admin_validated: + return redirect(reverse_lazy('idhub:user_dashboard')) pk = kwargs['pk'] self.user = self.request.user self.object = get_object_or_404( @@ -282,10 +298,9 @@ class CredentialPdfView(MyWallet, TemplateView): def get_pfx_data(self): did = self.object.eidas1_did - pw = self.admin_validated - if not did or not pw: + if not did: return None, None - key_material = json.loads(did.get_key_material(pw)) + key_material = json.loads(did.get_key_material()) cert = key_material.get("cert") passphrase = key_material.get("passphrase") if cert and passphrase: @@ -337,14 +352,7 @@ class CredentialJsonView(MyWallet, TemplateView): pk=pk, user=self.request.user ) - pass_enc = self.request.session.get("key_did") - data = "" - if pass_enc: - user_pass = self.request.user.decrypt_data( - pass_enc, - self.request.user.password+self.request.session._session_key - ) - data = self.object.get_data(user_pass) + data = self.object.get_data() response = HttpResponse(data, content_type="application/json") response['Content-Disposition'] = 'attachment; filename={}'.format("credential.json") return response @@ -383,15 +391,6 @@ class CredentialsRequestView(MyWallet, FormView): kwargs['lang'] = self.request.LANGUAGE_CODE domain = "{}://{}".format(self.request.scheme, self.request.get_host()) kwargs['domain'] = domain - pass_enc = self.request.session.get("key_did") - if pass_enc: - user_pass = self.request.user.decrypt_data( - pass_enc, - self.request.user.password+self.request.session._session_key - ) - else: - pass_enc = None - kwargs['password'] = user_pass return kwargs def form_valid(self, form): @@ -468,11 +467,7 @@ class DidRegisterView(MyWallet, CreateView): def form_valid(self, form): form.instance.user = self.request.user - pw = self.request.user.decrypt_data( - self.request.session.get("key_did"), - self.request.user.password+self.request.session._session_key - ) - form.instance.set_did(pw) + form.instance.set_did() form.save() messages.success(self.request, _('DID created successfully')) @@ -496,7 +491,7 @@ class DidEditView(MyWallet, UpdateView): return super().get(request, *args, **kwargs) def form_valid(self, form): - user = form.save() + form.save() messages.success(self.request, _('DID updated successfully')) return super().form_valid(form) diff --git a/idhub/views.py b/idhub/views.py index 0d0ee68..8cdecb5 100644 --- a/idhub/views.py +++ b/idhub/views.py @@ -18,7 +18,6 @@ from django.http import HttpResponseRedirect, HttpResponse, Http404 from idhub.models import DID, VerificableCredential from idhub.email.views import NotifyActivateUserByEmail -from trustchain_idhub import settings logger = logging.getLogger(__name__) @@ -46,30 +45,20 @@ class LoginView(auth_views.LoginView): def form_valid(self, form): user = form.get_user() - password = form.cleaned_data.get("password") auth_login(self.request, user) - sensitive_data_encryption_key = user.decrypt_sensitive_data(password) + if user.is_anonymous: + return redirect(reverse_lazy("idhub:login")) - if not user.is_anonymous and user.is_admin: - admin_dashboard = reverse_lazy('idhub:admin_dashboard') - self.extra_context['success_url'] = admin_dashboard - # encryption_key = user.encrypt_data( - # sensitive_data_encryption_key, - # settings.SECRET_KEY - # ) - # cache.set("KEY_DIDS", encryption_key, None) - cache.set("KEY_DIDS", sensitive_data_encryption_key, None) + if user.is_admin: if settings.ENABLE_2FACTOR_AUTH: self.request.session["2fauth"] = str(uuid.uuid4()) return redirect(reverse_lazy('idhub:confirm_send_2f')) - self.request.session["key_did"] = user.encrypt_data( - sensitive_data_encryption_key, - user.password+self.request.session._session_key - ) + admin_dashboard = reverse_lazy('idhub:admin_dashboard') + self.extra_context['success_url'] = admin_dashboard - return HttpResponseRedirect(self.extra_context['success_url']) + return redirect(self.extra_context['success_url']) class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): diff --git a/idhub_auth/models.py b/idhub_auth/models.py index ca4b422..49a6281 100644 --- a/idhub_auth/models.py +++ b/idhub_auth/models.py @@ -1,7 +1,7 @@ import nacl import base64 -from nacl import pwhash +from nacl import pwhash, secret from django.db import models from django.core.cache import cache from django.utils.translation import gettext_lazy as _ @@ -95,21 +95,24 @@ class User(AbstractBaseUser): roles.append(r.name) return ", ".join(set(roles)) - def derive_key_from_password(self, password): + def derive_key_from_password(self, password=None): + if not password: + password = cache.get("KEY_DIDS").encode('utf-8') + kdf = pwhash.argon2i.kdf ops = pwhash.argon2i.OPSLIMIT_INTERACTIVE mem = pwhash.argon2i.MEMLIMIT_INTERACTIVE return kdf( - nacl.secret.SecretBox.KEY_SIZE, + secret.SecretBox.KEY_SIZE, password, self.get_salt(), opslimit=ops, memlimit=mem ) - def decrypt_sensitive_data(self, password, data=None): - sb_key = self.derive_key_from_password(password.encode('utf-8')) - sb = nacl.secret.SecretBox(sb_key) + def decrypt_sensitive_data(self, data=None): + sb_key = self.derive_key_from_password() + sb = secret.SecretBox(sb_key) if not data: data = self.get_encrypted_sensitive_data() if not isinstance(data, bytes): @@ -117,9 +120,9 @@ class User(AbstractBaseUser): return sb.decrypt(data).decode('utf-8') - def encrypt_sensitive_data(self, password, data): - sb_key = self.derive_key_from_password(password.encode('utf-8')) - sb = nacl.secret.SecretBox(sb_key) + def encrypt_sensitive_data(self, data): + sb_key = self.derive_key_from_password() + sb = secret.SecretBox(sb_key) if not isinstance(data, bytes): data = data.encode('utf-8') @@ -134,32 +137,33 @@ class User(AbstractBaseUser): def get_encrypted_sensitive_data(self): return base64.b64decode(self.encrypted_sensitive_data.encode('utf-8')) - def set_encrypted_sensitive_data(self, password): + def set_encrypted_sensitive_data(self): key = base64.b64encode(nacl.utils.random(64)) self.set_salt() - key_crypted = self.encrypt_sensitive_data(password, key) + key_crypted = self.encrypt_sensitive_data(key) self.encrypted_sensitive_data = key_crypted - def encrypt_data(self, data, password): - sb = self.get_secret_box(password) + def encrypt_data(self, data): + sb = self.get_secret_box() value_enc = sb.encrypt(data.encode('utf-8')) return base64.b64encode(value_enc).decode('utf-8') - def decrypt_data(self, data, password): - sb = self.get_secret_box(password) + def decrypt_data(self, data): + sb = self.get_secret_box() value = base64.b64decode(data.encode('utf-8')) return sb.decrypt(value).decode('utf-8') - def get_secret_box(self, password): - pw = base64.b64decode(password.encode('utf-8')*4) - sb_key = self.derive_key_from_password(pw) - return nacl.secret.SecretBox(sb_key) + def get_secret_box(self): + sb_key = self.derive_key_from_password() + return secret.SecretBox(sb_key) - def change_password(self, old_password, new_password): - sensitive_data = self.decrypt_sensitive_data(old_password) - self.encrypted_sensitive_data = self.encrypt_sensitive_data( - new_password, - sensitive_data - ) - self.set_password(new_password) + def change_password_key(self, new_password): + data = self.decrypt_sensitive_data() + sb_key = self.derive_key_from_password(new_password) + sb = secret.SecretBox(sb_key) + if not isinstance(data, bytes): + data = data.encode('utf-8') + + encrypted_data = base64.b64encode(sb.encrypt(data)).decode('utf-8') + self.encrypted_sensitive_data = encrypted_data From ee43b7f9743277671b71c6eac697d3761e827506 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 09:28:22 +0100 Subject: [PATCH 02/20] clean code --- idhub/management/commands/initial_datas.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/idhub/management/commands/initial_datas.py b/idhub/management/commands/initial_datas.py index 15f74ea..236c8ab 100644 --- a/idhub/management/commands/initial_datas.py +++ b/idhub/management/commands/initial_datas.py @@ -78,8 +78,6 @@ class Command(BaseCommand): def create_schemas(self): schemas_files = os.listdir(settings.SCHEMAS_DIR) - schemas = [x for x in schemas_files - if not Schemas.objects.filter(file_schema=x).exists()] for x in schemas_files: if Schemas.objects.filter(file_schema=x).exists(): continue From 996288460c96d880ae9d667ff820959698db3613 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 10:16:32 +0100 Subject: [PATCH 03/20] fix public credential --- idhub/user/views.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/idhub/user/views.py b/idhub/user/views.py index a31fc63..d01c977 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -35,9 +35,7 @@ from idhub.user.tables import ( CredentialsTable ) from django.core.cache import cache -from django.conf import settings from idhub.user.forms import ( - ProfileForm, RequestCredentialForm, DemandAuthorizationForm, TermsConditionsForm @@ -367,7 +365,7 @@ class PublicCredentialJsonView(View): hash=pk, eidas1_did__isnull=False, ) - response = HttpResponse(self.object.data, content_type="application/json") + response = HttpResponse(self.object.get_data(), content_type="application/json") response['Content-Disposition'] = 'attachment; filename={}'.format("credential.json") return response From d45be274ee134e47ee1addc3176fe1e51e0e9262 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 10:17:00 +0100 Subject: [PATCH 04/20] show datas from credential in credential view --- idhub/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/idhub/models.py b/idhub/models.py index 7d6a1c6..8373373 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -645,8 +645,9 @@ class VerificableCredential(models.Model): return self.Status(self.status).label def get_datas(self): - data = json.loads(self.csv_data).items() - return data + data = self.render() + credential_subject = ujson.loads(data).get("credentialSubject", {}) + return credential_subject.items() def issue(self, did, domain=settings.DOMAIN.strip("/")): if self.status == self.Status.ISSUED: @@ -702,7 +703,7 @@ class VerificableCredential(models.Model): context.update(d) return context - def render(self, domain): + def render(self, domain=""): context = self.get_context(domain) template_name = 'credentials/{}'.format( self.schema.file_schema From e558d9145d0db573a817bda51f0adc81043a33c7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 10:46:33 +0100 Subject: [PATCH 05/20] limit access to cache --- idhub/admin/forms.py | 4 ++-- idhub/admin/views.py | 13 ++++--------- idhub/mixins.py | 1 - idhub/models.py | 1 - idhub/user/views.py | 5 +---- idhub/views.py | 1 - 6 files changed, 7 insertions(+), 18 deletions(-) diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index fd57e64..5db83bd 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -68,6 +68,7 @@ class EncryptionKeyForm(forms.Form): txt = _("Key no valid!") raise ValidationError(txt) + cache.set("KEY_DIDS", None) return data def save(self, commit=True): @@ -426,8 +427,7 @@ class ImportCertificateForm(forms.Form): type=DID.Types.KEY ) - pw = cache.get("KEY_DIDS") - self._did.set_key_material(key_material, pw) + self._did.set_key_material(key_material) def save(self, commit=True): diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 8a9bb63..60ac63a 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -701,15 +701,10 @@ class DeleteCredentialsView(Credentials): VerificableCredential, pk=pk, ) - status = [ - VerificableCredential.Status.REVOKED, - VerificableCredential.Status.ISSUED - ] - if self.object.status in status: - self.object.delete() - messages.success(self.request, _('Credential deleted successfully')) - Event.set_EV_CREDENTIAL_DELETED(self.object) - Event.set_EV_CREDENTIAL_DELETED_BY_ADMIN(self.object) + self.object.delete() + messages.success(self.request, _('Credential deleted successfully')) + Event.set_EV_CREDENTIAL_DELETED(self.object) + Event.set_EV_CREDENTIAL_DELETED_BY_ADMIN(self.object) return redirect(self.success_url) diff --git a/idhub/mixins.py b/idhub/mixins.py index ad1379b..6e793a8 100644 --- a/idhub/mixins.py +++ b/idhub/mixins.py @@ -1,6 +1,5 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.translation import gettext_lazy as _ -from django.contrib.auth import views as auth_views from django.core.exceptions import PermissionDenied from django.urls import reverse_lazy, resolve from django.shortcuts import redirect diff --git a/idhub/models.py b/idhub/models.py index 8373373..2f563bf 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -6,7 +6,6 @@ import datetime from collections import OrderedDict from django.db import models from django.conf import settings -from django.core.cache import cache from django.template.loader import get_template from django.utils.translation import gettext_lazy as _ diff --git a/idhub/user/views.py b/idhub/user/views.py index d01c977..fe45fb4 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -1,8 +1,6 @@ -import os import json import base64 import qrcode -import logging import datetime import weasyprint import qrcode.image.svg @@ -34,7 +32,6 @@ from idhub.user.tables import ( DIDTable, CredentialsTable ) -from django.core.cache import cache from idhub.user.forms import ( RequestCredentialForm, DemandAuthorizationForm, @@ -172,7 +169,7 @@ class WaitingView(UserView, TemplateView): success_url = reverse_lazy('idhub:user_dashboard') def get(self, request, *args, **kwargs): - if cache.get("KEY_DIDS"): + if self.admin_validated: return redirect(self.success_url) return super().get(request, *args, **kwargs) diff --git a/idhub/views.py b/idhub/views.py index 8cdecb5..940687b 100644 --- a/idhub/views.py +++ b/idhub/views.py @@ -6,7 +6,6 @@ import zlib import pyroaring from django.conf import settings -from django.core.cache import cache from django.urls import reverse_lazy from django.views.generic.base import TemplateView from django.contrib.auth import views as auth_views From a52a5cd15dd346be2a5134f970973ade4411a86f Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 10:46:57 +0100 Subject: [PATCH 06/20] add delete credential in all cases --- idhub/templates/idhub/admin/issue_credentials.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/idhub/templates/idhub/admin/issue_credentials.html b/idhub/templates/idhub/admin/issue_credentials.html index 3c29289..d7d6092 100644 --- a/idhub/templates/idhub/admin/issue_credentials.html +++ b/idhub/templates/idhub/admin/issue_credentials.html @@ -12,11 +12,8 @@
{% if object.get_status == 'Issued' %} {% trans 'Revoke' %} - {% trans 'Delete' %} {% endif %} - {% if object.get_status == 'Revoked' %} {% trans 'Delete' %} - {% endif %}
From 010cd169f7e4174b45fef37af7f27f47bdb294eb Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 11:37:19 +0100 Subject: [PATCH 07/20] show download credentials if it is issued --- idhub/templates/idhub/admin/issue_credentials.html | 2 ++ idhub/templates/idhub/user/credential.html | 2 ++ 2 files changed, 4 insertions(+) diff --git a/idhub/templates/idhub/admin/issue_credentials.html b/idhub/templates/idhub/admin/issue_credentials.html index d7d6092..7497808 100644 --- a/idhub/templates/idhub/admin/issue_credentials.html +++ b/idhub/templates/idhub/admin/issue_credentials.html @@ -46,11 +46,13 @@ {{ object.get_status}}
+ {% if object.issued_on %}
+ {% endif %} diff --git a/idhub/templates/idhub/user/credential.html b/idhub/templates/idhub/user/credential.html index 415c280..b78e81b 100644 --- a/idhub/templates/idhub/user/credential.html +++ b/idhub/templates/idhub/user/credential.html @@ -38,6 +38,7 @@ + {% if object.issued_on %}
{% if object.eidas1_did and admin_validated %}
@@ -47,5 +48,6 @@ + {% endif %}
{% endblock %} From 910aa7c8886fbd73062eca271215281660adc038 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 11:38:00 +0100 Subject: [PATCH 08/20] fix bugs with redirections --- idhub/admin/views.py | 3 ++- idhub/user/views.py | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 60ac63a..e720f22 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -18,6 +18,7 @@ from django.shortcuts import get_object_or_404, redirect from django.urls import reverse_lazy from django.http import HttpResponse from django.contrib import messages +from django.core.cache import cache from utils import credtools from idhub_auth.models import User from idhub_auth.forms import ProfileForm @@ -90,7 +91,7 @@ class EncryptionKeyView(AdminView, FormView): success_url = reverse_lazy('idhub:admin_dashboard') def get(self, request, *args, **kwargs): - if self.admin_validated: + if cache.get("KEY_DIDS"): return redirect(self.success_url) return super().get(request, *args, **kwargs) diff --git a/idhub/user/views.py b/idhub/user/views.py index fe45fb4..7e6a6eb 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -21,6 +21,7 @@ from django.views.generic.edit import ( ) from django.views.generic.base import TemplateView from django.shortcuts import get_object_or_404, redirect +from django.core.cache import cache from django.urls import reverse_lazy from django.http import HttpResponse from django.contrib import messages @@ -169,7 +170,7 @@ class WaitingView(UserView, TemplateView): success_url = reverse_lazy('idhub:user_dashboard') def get(self, request, *args, **kwargs): - if self.admin_validated: + if cache.get("KEY_DIDS"): return redirect(self.success_url) return super().get(request, *args, **kwargs) @@ -204,7 +205,7 @@ class CredentialPdfView(MyWallet, TemplateView): file_name = "certificate.pdf" def get(self, request, *args, **kwargs): - if not self.admin_validated: + if not cache.get("KEY_DIDS"): return redirect(reverse_lazy('idhub:user_dashboard')) pk = kwargs['pk'] self.user = self.request.user @@ -231,7 +232,7 @@ class CredentialPdfView(MyWallet, TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - this_folder = str(Path.cwd()) + # this_folder = str(Path.cwd()) path_img_sig = "idhub/static/images/4_Model_Certificat_html_58d7f7eeb828cf29.jpg" img_signature = next(Path.cwd().glob(path_img_sig)) with open(img_signature, 'rb') as _f: @@ -376,8 +377,8 @@ class CredentialsRequestView(MyWallet, FormView): def get(self, request, *args, **kwargs): response = super().get(request, *args, **kwargs) - if not self.admin_validated: - return redirect(reverse_lazy('idhub:user_dashboard')) + if not cache.get("KEY_DIDS"): + return redirect(reverse_lazy('idhub:user_waiting')) return response def get_form_kwargs(self): From 79f299adda8d15ac1591e349c018020cef438765 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 12:13:08 +0100 Subject: [PATCH 09/20] fix new encrypted for oidc4vp --- oidc4vp/forms.py | 7 +------ oidc4vp/models.py | 1 - oidc4vp/views.py | 11 ++--------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/oidc4vp/forms.py b/oidc4vp/forms.py index 560531c..1c4b19a 100644 --- a/oidc4vp/forms.py +++ b/oidc4vp/forms.py @@ -1,14 +1,11 @@ import json -import requests from django import forms -from django.conf import settings from django.template.loader import get_template from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError from utils.idhub_ssikit import create_verifiable_presentation -from oidc4vp.models import Organization from idhub.models import VerificableCredential @@ -19,7 +16,6 @@ class AuthorizeForm(forms.Form): self.user = kwargs.pop('user', None) self.org = kwargs.pop('org', None) self.code = kwargs.pop('code', None) - self.pw = kwargs.pop('pw', None) self.presentation_definition = kwargs.pop('presentation_definition', []) self.subject_did = None @@ -53,7 +49,6 @@ class AuthorizeForm(forms.Form): cred = self.user.decrypt_data( c.data, - self.pw ) self.subject_did = c.subject_did self.list_credentials.append(cred) @@ -85,5 +80,5 @@ class AuthorizeForm(forms.Form): "verifiable_credential_list": vc_list } unsigned_vp = vp_template.render(context) - key_material = did.get_key_material(self.pw) + key_material = did.get_key_material() self.vp = create_verifiable_presentation(key_material, unsigned_vp) diff --git a/oidc4vp/models.py b/oidc4vp/models.py index 42b0d93..9a4a4d4 100644 --- a/oidc4vp/models.py +++ b/oidc4vp/models.py @@ -5,7 +5,6 @@ import secrets from django.conf import settings from django.http import QueryDict from django.utils.translation import gettext_lazy as _ -from django.shortcuts import get_object_or_404 from idhub_auth.models import User from django.db import models from utils.idhub_ssikit import verify_presentation diff --git a/oidc4vp/views.py b/oidc4vp/views.py index 7161aed..fb869ce 100644 --- a/oidc4vp/views.py +++ b/oidc4vp/views.py @@ -16,7 +16,6 @@ from idhub.mixins import UserView from idhub.models import Event from oidc4vp.forms import AuthorizeForm -from utils.idhub_ssikit import verify_presentation class AuthorizeView(UserView, FormView): @@ -39,16 +38,11 @@ class AuthorizeView(UserView, FormView): kwargs['user'] = self.request.user try: vps = json.loads(self.request.GET.get('presentation_definition')) - except: + except Exception: vps = [] kwargs['presentation_definition'] = vps kwargs["org"] = self.get_org() kwargs["code"] = self.request.GET.get('code') - enc_pw = self.request.session["key_did"] - kwargs['pw'] = self.request.user.decrypt_data( - enc_pw, - self.request.user.password+self.request.session._session_key - ) return kwargs def get_form(self, form_class=None): @@ -64,7 +58,7 @@ class AuthorizeView(UserView, FormView): return redirect(self.success_url) try: authorization = authorization.json() - except: + except Exception: messages.error(self.request, _("Error sending credential!")) return redirect(self.success_url) @@ -148,7 +142,6 @@ class VerifyView(View): if len(auth_data) == 2 and auth_data[0].lower() == 'basic': decoded_auth = base64.b64decode(auth_data[1]).decode('utf-8') client_id, client_secret = decoded_auth.split(':', 1) - org_url = request.GET.get('demand_uri') org = get_object_or_404( Organization, client_id=client_id, From 603e7f65ba864b60a9cde6b5242e3cf59dc42e78 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 14:19:59 +0100 Subject: [PATCH 10/20] more debug --- idhub/user/forms.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/idhub/user/forms.py b/idhub/user/forms.py index 9561eb7..48eb15d 100644 --- a/idhub/user/forms.py +++ b/idhub/user/forms.py @@ -1,3 +1,5 @@ +import logging + from django import forms from django.conf import settings from django.utils.translation import gettext_lazy as _ @@ -6,6 +8,9 @@ from oidc4vp.models import Organization from idhub_auth.models import User +logger = logging.getLogger(__name__) + + class ProfileForm(forms.ModelForm): MANDATORY_FIELDS = ['first_name', 'last_name', 'email'] @@ -111,7 +116,9 @@ class RequestCredentialForm(forms.Form): try: if self.password: cred.issue(did, self.password, domain=self._domain) - except Exception: + assert 1==2 + except Exception as err: + logger.debug(err) return if commit: From 57be4dca2ef8f9b0a0bad7f8dc8e8da726f4fb7b Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 21 Feb 2024 14:20:38 +0100 Subject: [PATCH 11/20] more debug --- idhub/user/forms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/idhub/user/forms.py b/idhub/user/forms.py index 48eb15d..c62e352 100644 --- a/idhub/user/forms.py +++ b/idhub/user/forms.py @@ -116,7 +116,6 @@ class RequestCredentialForm(forms.Form): try: if self.password: cred.issue(did, self.password, domain=self._domain) - assert 1==2 except Exception as err: logger.debug(err) return From f6de135016b3a2b7a98e1ba5523317b1a33d8280 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 22 Feb 2024 13:47:58 +0100 Subject: [PATCH 12/20] fix add logger --- trustchain_idhub/settings.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/trustchain_idhub/settings.py b/trustchain_idhub/settings.py index 043054d..538fa63 100644 --- a/trustchain_idhub/settings.py +++ b/trustchain_idhub/settings.py @@ -212,13 +212,11 @@ LOGGING = { "version": 1, "disable_existing_loggers": False, "handlers": { - "console": {"class": "logging.StreamHandler"}, + "console": {"level": "DEBUG", "class": "logging.StreamHandler"}, }, - "loggers": { - "django": { - "handlers": ["console"], - "level": "INFO", - }, + "root": { + "handlers": ["console"], + "level": "DEBUG", } } From c4049d966b29823cc384798f5cd7eb887e682cbf Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 22 Feb 2024 13:48:26 +0100 Subject: [PATCH 13/20] fix resetpassword --- idhub/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/idhub/views.py b/idhub/views.py index 940687b..d3da1b4 100644 --- a/idhub/views.py +++ b/idhub/views.py @@ -68,7 +68,6 @@ class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): password = form.cleaned_data.get("new_password1") user = form.user user.set_password(password) - user.set_encrypted_sensitive_data(password) user.save() return HttpResponseRedirect(self.success_url) From a44a5b170fdba94def3450c74384024a181a76b0 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 22 Feb 2024 13:49:08 +0100 Subject: [PATCH 14/20] add did for manual new user --- idhub/admin/views.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/idhub/admin/views.py b/idhub/admin/views.py index e720f22..1c0588d 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -283,7 +283,11 @@ class PeopleRegisterView(NotifyActivateUserByEmail, People, CreateView): return self.success_url def form_valid(self, form): - user = form.save() + super().form_valid(form) + user = form.instance + user.set_encrypted_sensitive_data() + user.save() + self.create_defaults_dids(user) messages.success(self.request, _('The account was created successfully')) Event.set_EV_USR_REGISTERED(user) Event.set_EV_USR_WELCOME(user) @@ -295,6 +299,11 @@ class PeopleRegisterView(NotifyActivateUserByEmail, People, CreateView): messages.error(self.request, e) return super().form_valid(form) + def create_defaults_dids(self, user): + did = DID(label="Default", user=user, type=DID.Types.WEB) + did.set_did() + did.save() + class PeopleMembershipRegisterView(People, FormView): template_name = "idhub/admin/people_membership_register.html" From d218df4ddc3a4f850ae7ebd77015fe60ebe8c0e1 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 22 Feb 2024 13:50:07 +0100 Subject: [PATCH 15/20] add did for new user from import excel --- idhub/admin/forms.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index 5db83bd..29ce073 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -257,18 +257,21 @@ class ImportForm(forms.Form): except jsonschema.exceptions.ValidationError as err: msg = "line {}: {}".format(line+1, err) return self.exception(msg) - # try: - # check = credtools.validate_json(row, self.json_schema) - # if check is not True: - # raise ValidationError("Not valid row") - # except Exception as e: user, new = User.objects.get_or_create(email=row.get('email')) if new: self.users.append(user) + user.set_encrypted_sensitive_data() + user.save() + self.create_defaults_dids(user) return user + def create_defaults_dids(self, user): + did = DID(label="Default", user=user, type=DID.Types.WEB) + did.set_did() + did.save() + def create_credential(self, user, row): bcred = VerificableCredential.objects.filter( user=user, From 73d20a1e6e35d58c16ed6e63c8b3f5bf9667c5a7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 22 Feb 2024 14:32:14 +0100 Subject: [PATCH 16/20] reset password --- idhub/templates/auth/login.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idhub/templates/auth/login.html b/idhub/templates/auth/login.html index 1a1775c..18abfd8 100644 --- a/idhub/templates/auth/login.html +++ b/idhub/templates/auth/login.html @@ -46,7 +46,7 @@ class="btn btn-primary form-control" id="submit-id-submit">
-