From 72a356ffc8f85da21f66cbc223bb58661de3d99a Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 15 Nov 2023 11:43:13 +0100 Subject: [PATCH] issue real credentials --- idhub/admin/forms.py | 2 +- idhub/migrations/0001_initial.py | 67 +++++++++++++++------------ idhub/models.py | 42 +++++++++++++++-- idhub_auth/migrations/0001_initial.py | 2 +- utils/idhub_ssikit/__init__.py | 16 +++++++ 5 files changed, 94 insertions(+), 35 deletions(-) diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index 1f01555..90a9c0c 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -118,7 +118,7 @@ class ImportForm(forms.Form): verified=False, user=user, csv_data=json.dumps(row), - did_issuer=self._did.did, + issuer_did=self._did, schema=self._schema, ) diff --git a/idhub/migrations/0001_initial.py b/idhub/migrations/0001_initial.py index d06dde8..b4d6ac7 100644 --- a/idhub/migrations/0001_initial.py +++ b/idhub/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2023-11-14 17:48 +# Generated by Django 4.2.5 on 2023-11-15 09:58 from django.conf import settings from django.db import migrations, models @@ -13,6 +13,33 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='DID', + fields=[ + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), + ('created_at', models.DateTimeField(auto_now=True)), + ('label', models.CharField(max_length=50)), + ('did', models.CharField(max_length=250)), + ('key_material', models.CharField(max_length=250)), + ( + 'user', + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='dids', + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), migrations.CreateModel( name='File_datas', fields=[ @@ -141,8 +168,7 @@ class Migration(migrations.Migration): ('verified', models.BooleanField()), ('created_on', models.DateTimeField(auto_now=True)), ('issued_on', models.DateTimeField(null=True)), - ('did_issuer', models.CharField(max_length=250)), - ('did_subject', models.CharField(max_length=250)), + ('subject_did', models.CharField(max_length=250)), ('data', models.TextField()), ('csv_data', models.TextField()), ( @@ -157,6 +183,14 @@ class Migration(migrations.Migration): default=1, ), ), + ( + 'issuer_did', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='vcredentials', + to='idhub.did', + ), + ), ( 'schema', models.ForeignKey( @@ -284,33 +318,6 @@ class Migration(migrations.Migration): ), ], ), - migrations.CreateModel( - name='DID', - fields=[ - ( - 'id', - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID', - ), - ), - ('created_at', models.DateTimeField(auto_now=True)), - ('label', models.CharField(max_length=50)), - ('did', models.CharField(max_length=250)), - ('key_material', models.CharField(max_length=250)), - ( - 'user', - models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name='dids', - to=settings.AUTH_USER_MODEL, - ), - ), - ], - ), migrations.CreateModel( name='UserRol', fields=[ diff --git a/idhub/models.py b/idhub/models.py index 58fe233..4e9cf6f 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -2,10 +2,12 @@ import json import requests import datetime from django.db import models +from django.template.loader import get_template from django.utils.translation import gettext_lazy as _ from utils.idhub_ssikit import ( generate_did_controller_key, keydid_from_controller_key, + sign_credential, ) from idhub_auth.models import User @@ -459,8 +461,7 @@ class VerificableCredential(models.Model): verified = models.BooleanField() created_on = models.DateTimeField(auto_now=True) issued_on = models.DateTimeField(null=True) - did_issuer = models.CharField(max_length=250) - did_subject = models.CharField(max_length=250) + subject_did = models.CharField(max_length=250) data = models.TextField() csv_data = models.TextField() status = models.PositiveSmallIntegerField( @@ -472,6 +473,11 @@ class VerificableCredential(models.Model): on_delete=models.CASCADE, related_name='vcredentials', ) + issuer_did = models.ForeignKey( + DID, + on_delete=models.CASCADE, + related_name='vcredentials', + ) schema = models.ForeignKey( Schemas, on_delete=models.CASCADE, @@ -498,9 +504,39 @@ class VerificableCredential(models.Model): return data def issue(self, did): + if self.status == self.Status.ISSUED: + return + self.status = self.Status.ISSUED - self.did_subject = did + self.subject_did = did self.issued_on = datetime.datetime.now() + self.data = sign_credential( + self.render(), + self.issuer_did.key_material + ) + + def get_context(self): + d = json.loads(self.csv_data) + format = "%Y-%m-%dT%H:%M:%SZ" + issuance_date = self.issued_on.strftime(format) + + context = { + 'vc_id': self.id, + 'issuer_did': self.issuer_did.did, + 'subject_did': self.subject_did, + 'issuance_date': issuance_date, + } + context.update(d) + return context + + def render(self): + context = self.get_context() + template_name = 'credentials/{}'.format( + self.schema.file_schema + ) + tmpl = get_template(template_name) + return tmpl.render(context) + def get_issued_on(self): if self.issued_on: diff --git a/idhub_auth/migrations/0001_initial.py b/idhub_auth/migrations/0001_initial.py index 205b13a..d40f0a4 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 2023-11-14 17:48 +# Generated by Django 4.2.5 on 2023-11-15 09:58 from django.db import migrations, models diff --git a/utils/idhub_ssikit/__init__.py b/utils/idhub_ssikit/__init__.py index dced08e..18a5ff2 100644 --- a/utils/idhub_ssikit/__init__.py +++ b/utils/idhub_ssikit/__init__.py @@ -3,6 +3,7 @@ import datetime import didkit import json import jinja2 +from django.template.backends.django import Template def generate_did_controller_key(): @@ -45,6 +46,21 @@ def render_and_sign_credential(vc_template: jinja2.Template, jwk_issuer, vc_data return asyncio.run(inner()) + +def sign_credential(unsigned_vc: str, jwk_issuer): + """ + Signs the and unsigned credential with the provided key. + """ + async def inner(): + signed_vc = await didkit.issue_credential( + unsigned_vc, + '{"proofFormat": "ldp"}', + jwk_issuer + ) + return signed_vc + + return asyncio.run(inner()) + def verify_credential(vc, proof_options): """