diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index d4d0a1a..8174a32 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -239,7 +239,6 @@ class ImportCertificateForm(forms.Form): def clean(self): data = super().clean() - # import pdb; pdb.set_trace() file_import = data.get('file_import') self.pfx_file = file_import.read() self.file_name = file_import.name diff --git a/idhub/migrations/0001_initial.py b/idhub/migrations/0001_initial.py index 6982654..5aeabdb 100644 --- a/idhub/migrations/0001_initial.py +++ b/idhub/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-10 11:52 +# Generated by Django 4.2.5 on 2024-01-11 10:17 from django.conf import settings from django.db import migrations, models @@ -151,6 +151,8 @@ class Migration(migrations.Migration): ('issued_on', models.DateTimeField(null=True)), ('data', models.TextField()), ('csv_data', models.TextField()), + ('public', models.BooleanField(default=True)), + ('hash', models.CharField(max_length=260)), ( 'status', models.PositiveSmallIntegerField( diff --git a/idhub/models.py b/idhub/models.py index 93f8c20..7d48543 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -1,5 +1,6 @@ import json import pytz +import hashlib import datetime from django.db import models from django.conf import settings @@ -467,6 +468,8 @@ class VerificableCredential(models.Model): issued_on = models.DateTimeField(null=True) data = models.TextField() csv_data = models.TextField() + public = models.BooleanField(default=settings.DEFAULT_PUBLIC_CREDENTIALS) + hash = models.CharField(max_length=260) status = models.PositiveSmallIntegerField( choices=Status.choices, default=Status.ENABLED @@ -520,6 +523,8 @@ class VerificableCredential(models.Model): self.render(), self.issuer_did.key_material ) + if self.public: + self.hash = hashlib.sha3_256(self.data.encode()).hexdigest() def get_context(self): d = json.loads(self.csv_data) @@ -528,8 +533,12 @@ class VerificableCredential(models.Model): format = "%Y-%m-%dT%H:%M:%SZ" issuance_date = self.issued_on.strftime(format) - url_id = "{}/credentials/{}".format( + cred_path = 'credentials' + if self.public: + cred_path = 'public/credentials' + url_id = "{}/{}/{}".format( settings.DOMAIN.strip("/"), + cred_path, self.id ) context = { diff --git a/idhub/templates/idhub/user/credential.html b/idhub/templates/idhub/user/credential.html index f1b0f42..1e0e9ca 100644 --- a/idhub/templates/idhub/user/credential.html +++ b/idhub/templates/idhub/user/credential.html @@ -37,6 +37,11 @@
+ {% if object.public %} +
+ {% trans 'View in PDF format' %} +
+ {% endif %}
{% trans 'View in JSON format' %}
diff --git a/idhub/urls.py b/idhub/urls.py index d139c32..1e41a5b 100644 --- a/idhub/urls.py +++ b/idhub/urls.py @@ -80,8 +80,12 @@ urlpatterns = [ name='user_credentials'), path('user/credentials/', views_user.CredentialView.as_view(), name='user_credential'), - path('user/credentials//json', views_user.CredentialJsonView.as_view(), + path('user/credentials//pdf', views_user.CredentialPdfView.as_view(), + name='user_credential_pdf'), + path('credentials//', views_user.CredentialJsonView.as_view(), name='user_credential_json'), + path('public/credentials//', views_user.PublicCredentialJsonView.as_view(), + name='public_credential_json'), path('user/credentials/request/', views_user.CredentialsRequestView.as_view(), name='user_credentials_request'), diff --git a/idhub/user/views.py b/idhub/user/views.py index 906cf43..b04746b 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -14,6 +14,7 @@ from pyhanko import stamp from pyhanko.pdf_utils import text from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter from django.utils.translation import gettext_lazy as _ +from django.views.generic import View from django.views.generic.edit import ( UpdateView, CreateView, @@ -25,6 +26,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.conf import settings from idhub.user.forms import ( ProfileForm, RequestCredentialForm, @@ -125,7 +127,7 @@ class CredentialView(MyWallet, TemplateView): return context -class CredentialJsonView(MyWallet, TemplateView): +class CredentialPdfView(MyWallet, TemplateView): template_name = "certificates/4_Model_Certificat.html" subtitle = _('Credential management') icon = 'bi bi-patch-check-fill' @@ -138,11 +140,19 @@ class CredentialJsonView(MyWallet, TemplateView): self.object = get_object_or_404( VerificableCredential, pk=pk, + public=True, user=self.request.user ) + self.url_id = "{}/public/credentials/{}".format( + settings.DOMAIN.strip("/"), + self.object.hash + ) data = self.build_certificate() - doc = self.insert_signature(data) + if DID.objects.filter(eidas1=True).exists(): + doc = self.insert_signature(data) + else: + doc = data response = HttpResponse(doc, content_type="application/pdf") response['Content-Disposition'] = 'attachment; filename={}'.format(self.file_name) return response @@ -160,9 +170,7 @@ class CredentialJsonView(MyWallet, TemplateView): with open(img_header, 'rb') as _f: img_head = base64.b64encode(_f.read()).decode('utf-8') - qr = self.generate_qr_code("http://localhost") - if DID.objects.filter(eidas1=True).exists(): - qr = "" + qr = self.generate_qr_code(self.url_id) first_name = self.user.first_name and self.user.first_name.upper() or "" last_name = self.user.first_name and self.user.last_name.upper() or "" @@ -231,7 +239,6 @@ class CredentialJsonView(MyWallet, TemplateView): return s def insert_signature(self, doc): - # import pdb; pdb.set_trace() sig = self.signer_init() if not sig: return @@ -247,18 +254,17 @@ class CredentialJsonView(MyWallet, TemplateView): meta = signers.PdfSignatureMetadata(field_name='Signature') pdf_signer = signers.PdfSigner( - meta, signer=sig, stamp_style=stamp.QRStampStyle( + meta, signer=sig, stamp_style=stamp.TextStampStyle( stamp_text='Signed by: %(signer)s\nTime: %(ts)s\nURL: %(url)s', text_box_style=text.TextBoxStyle() ) ) _bf_out = BytesIO() - url = "https://localhost:8000/" - pdf_signer.sign_pdf(w, output=_bf_out, appearance_text_params={'url': url}) + pdf_signer.sign_pdf(w, output=_bf_out, appearance_text_params={'url': self.url_id}) return _bf_out.read() -class CredentialJsonView2(MyWallet, TemplateView): +class CredentialJsonView(MyWallet, TemplateView): def get(self, request, *args, **kwargs): pk = kwargs['pk'] @@ -272,6 +278,19 @@ class CredentialJsonView2(MyWallet, TemplateView): return response +class PublicCredentialJsonView(View): + + def get(self, request, *args, **kwargs): + pk = kwargs['pk'] + self.object = get_object_or_404( + VerificableCredential, + hash=pk, + ) + response = HttpResponse(self.object.data, content_type="application/json") + response['Content-Disposition'] = 'attachment; filename={}'.format("credential.json") + return response + + class CredentialsRequestView(MyWallet, FormView): template_name = "idhub/user/credentials_request.html" subtitle = _('Credential request') diff --git a/idhub_auth/migrations/0001_initial.py b/idhub_auth/migrations/0001_initial.py index 41a937b..45e8f28 100644 --- a/idhub_auth/migrations/0001_initial.py +++ b/idhub_auth/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-10 11:52 +# Generated by Django 4.2.5 on 2024-01-11 10:17 from django.db import migrations, models diff --git a/oidc4vp/migrations/0001_initial.py b/oidc4vp/migrations/0001_initial.py index 55792e2..ab5b0d5 100644 --- a/oidc4vp/migrations/0001_initial.py +++ b/oidc4vp/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-10 11:52 +# Generated by Django 4.2.5 on 2024-01-11 10:17 from django.conf import settings from django.db import migrations, models diff --git a/promotion/migrations/0001_initial.py b/promotion/migrations/0001_initial.py index 5373e75..2befe90 100644 --- a/promotion/migrations/0001_initial.py +++ b/promotion/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-10 11:52 +# Generated by Django 4.2.5 on 2024-01-11 10:17 from django.db import migrations, models import django.db.models.deletion diff --git a/trustchain_idhub/settings.py b/trustchain_idhub/settings.py index b9eecc5..8230d11 100644 --- a/trustchain_idhub/settings.py +++ b/trustchain_idhub/settings.py @@ -222,3 +222,4 @@ LOGGING = { } } +DEFAULT_PUBLIC_CREDENTIALS = True