resolve merge

This commit is contained in:
Cayo Puigdefabregas 2024-01-16 14:05:28 +01:00
commit 79cd9bd6e7
11 changed files with 96 additions and 20 deletions

View File

@ -639,7 +639,7 @@ class DidRegisterView(Credentials, CreateView):
icon = 'bi bi-patch-check-fill' icon = 'bi bi-patch-check-fill'
wallet = True wallet = True
model = DID model = DID
fields = ('label',) fields = ('label', 'type')
success_url = reverse_lazy('idhub:admin_dids') success_url = reverse_lazy('idhub:admin_dids')
object = None object = None

View File

@ -64,7 +64,7 @@ class Command(BaseCommand):
def create_defaults_dids(self): def create_defaults_dids(self):
for u in User.objects.all(): for u in User.objects.all():
did = DID(label="Default", user=u) did = DID(label="Default", user=u, type=DID.Types.KEY)
did.set_did() did.set_did()
did.save() did.save()

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.5 on 2023-12-11 08:35 # Generated by Django 4.2.5 on 2024-01-16 13:04
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -25,10 +25,17 @@ class Migration(migrations.Migration):
verbose_name='ID', verbose_name='ID',
), ),
), ),
(
'type',
models.PositiveSmallIntegerField(
choices=[(1, 'Key'), (2, 'Web')], verbose_name='Type'
),
),
('created_at', models.DateTimeField(auto_now=True)), ('created_at', models.DateTimeField(auto_now=True)),
('label', models.CharField(max_length=50)), ('label', models.CharField(max_length=50, verbose_name='Label')),
('did', models.CharField(max_length=250)), ('did', models.CharField(max_length=250)),
('key_material', models.CharField(max_length=250)), ('key_material', models.CharField(max_length=250)),
('didweb_document', models.TextField()),
( (
'user', 'user',
models.ForeignKey( models.ForeignKey(
@ -256,8 +263,11 @@ class Migration(migrations.Migration):
verbose_name='ID', verbose_name='ID',
), ),
), ),
('created', models.DateTimeField(auto_now=True)), ('created', models.DateTimeField(auto_now=True, verbose_name='Date')),
('message', models.CharField(max_length=350)), (
'message',
models.CharField(max_length=350, verbose_name='Description'),
),
( (
'type', 'type',
models.PositiveSmallIntegerField( models.PositiveSmallIntegerField(
@ -295,7 +305,8 @@ class Migration(migrations.Migration):
(28, 'Organisational DID deleted by admin'), (28, 'Organisational DID deleted by admin'),
(29, 'User deactivated'), (29, 'User deactivated'),
(30, 'User activated'), (30, 'User activated'),
] ],
verbose_name='Event',
), ),
), ),
( (
@ -327,6 +338,7 @@ class Migration(migrations.Migration):
on_delete=django.db.models.deletion.CASCADE, on_delete=django.db.models.deletion.CASCADE,
related_name='users', related_name='users',
to='idhub.service', to='idhub.service',
verbose_name='Service',
), ),
), ),
( (

View File

@ -11,7 +11,7 @@ from utils.idhub_ssikit import (
generate_did_controller_key, generate_did_controller_key,
keydid_from_controller_key, keydid_from_controller_key,
sign_credential, sign_credential,
verify_credential webdid_from_controller_key,
) )
from idhub_auth.models import User from idhub_auth.models import User
@ -406,6 +406,13 @@ class Event(models.Model):
class DID(models.Model): class DID(models.Model):
class Types(models.IntegerChoices):
KEY = 1, "Key"
WEB = 2, "Web"
type = models.PositiveSmallIntegerField(
_("Type"),
choices=Types.choices,
)
created_at = models.DateTimeField(auto_now=True) created_at = models.DateTimeField(auto_now=True)
label = models.CharField(_("Label"), max_length=50) label = models.CharField(_("Label"), max_length=50)
did = models.CharField(max_length=250) did = models.CharField(max_length=250)
@ -419,6 +426,7 @@ class DID(models.Model):
related_name='dids', related_name='dids',
null=True, null=True,
) )
didweb_document = models.TextField()
@property @property
def is_organization_did(self): def is_organization_did(self):
@ -428,7 +436,12 @@ class DID(models.Model):
def set_did(self): def set_did(self):
self.key_material = generate_did_controller_key() self.key_material = generate_did_controller_key()
if self.type == self.Types.KEY:
self.did = keydid_from_controller_key(self.key_material) self.did = keydid_from_controller_key(self.key_material)
elif self.type == self.Types.WEB:
didurl, document = webdid_from_controller_key(self.key_material)
self.did = didurl
self.didweb_document = document
def get_key(self): def get_key(self):
return json.loads(self.key_material) return json.loads(self.key_material)

View File

@ -17,7 +17,7 @@ Including another URLconf
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.views.generic import RedirectView from django.views.generic import RedirectView
from django.urls import path, reverse_lazy from django.urls import path, reverse_lazy
from .views import LoginView from .views import LoginView, serve_did
from .admin import views as views_admin from .admin import views as views_admin
from .user import views as views_user from .user import views as views_user
# from .verification_portal import views as views_verification_portal # from .verification_portal import views as views_verification_portal
@ -173,6 +173,8 @@ urlpatterns = [
path('admin/import/new', views_admin.ImportAddView.as_view(), path('admin/import/new', views_admin.ImportAddView.as_view(),
name='admin_import_add'), name='admin_import_add'),
path('did-registry/<str:did_id>', serve_did)
# path('verification_portal/verify/', views_verification_portal.verify, # path('verification_portal/verify/', views_verification_portal.verify,
# name="verification_portal_verify") # name="verification_portal_verify")
] ]

View File

@ -202,7 +202,7 @@ class DidRegisterView(MyWallet, CreateView):
icon = 'bi bi-patch-check-fill' icon = 'bi bi-patch-check-fill'
wallet = True wallet = True
model = DID model = DID
fields = ('label',) fields = ('label', 'type')
success_url = reverse_lazy('idhub:user_dids') success_url = reverse_lazy('idhub:user_dids')
object = None object = None

View File

@ -1,8 +1,12 @@
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.contrib.auth import login as auth_login from django.contrib.auth import login as auth_login
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect, HttpResponse
from idhub.models import DID
from trustchain_idhub import settings
class LoginView(auth_views.LoginView): class LoginView(auth_views.LoginView):
@ -26,3 +30,12 @@ class LoginView(auth_views.LoginView):
self.extra_context['success_url'] = admin_dashboard self.extra_context['success_url'] = admin_dashboard
auth_login(self.request, user) auth_login(self.request, user)
return HttpResponseRedirect(self.extra_context['success_url']) return HttpResponseRedirect(self.extra_context['success_url'])
def serve_did(request, did_id):
id_did = f'did:web:{settings.DOMAIN}:did-registry:{did_id}'
did = get_object_or_404(DID, did=id_did)
document = did.didweb_document
retval = HttpResponse(document)
retval.headers["Content-Type"] = "application/json"
return retval

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.5 on 2023-12-11 08:35 # Generated by Django 4.2.5 on 2024-01-16 13:04
from django.db import migrations, models from django.db import migrations, models
@ -31,13 +31,23 @@ class Migration(migrations.Migration):
( (
'email', 'email',
models.EmailField( models.EmailField(
max_length=255, unique=True, verbose_name='email address' max_length=255, unique=True, verbose_name='Email address'
), ),
), ),
('is_active', models.BooleanField(default=True)), ('is_active', models.BooleanField(default=True)),
('is_admin', models.BooleanField(default=False)), ('is_admin', models.BooleanField(default=False)),
('first_name', models.CharField(blank=True, max_length=255, null=True)), (
('last_name', models.CharField(blank=True, max_length=255, null=True)), 'first_name',
models.CharField(
blank=True, max_length=255, null=True, verbose_name='First name'
),
),
(
'last_name',
models.CharField(
blank=True, max_length=255, null=True, verbose_name='Last name'
),
),
], ],
options={ options={
'abstract': False, 'abstract': False,

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.5 on 2023-12-11 08:35 # Generated by Django 4.2.5 on 2024-01-16 13:04
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -30,7 +30,7 @@ class Migration(migrations.Migration):
'code', 'code',
models.CharField(default=oidc4vp.models.set_code, max_length=24), models.CharField(default=oidc4vp.models.set_code, max_length=24),
), ),
('code_used', models.BooleanField()), ('code_used', models.BooleanField(default=False)),
('created', models.DateTimeField(auto_now=True)), ('created', models.DateTimeField(auto_now=True)),
('presentation_definition', models.CharField(max_length=250)), ('presentation_definition', models.CharField(max_length=250)),
], ],
@ -91,7 +91,7 @@ class Migration(migrations.Migration):
models.ForeignKey( models.ForeignKey(
null=True, null=True,
on_delete=django.db.models.deletion.SET_NULL, on_delete=django.db.models.deletion.SET_NULL,
related_name='oauth2vptoken', related_name='vp_tokens',
to='oidc4vp.authorization', to='oidc4vp.authorization',
), ),
), ),

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.5 on 2023-12-11 08:35 # Generated by Django 4.2.5 on 2024-01-16 13:04
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion

View File

@ -6,6 +6,8 @@ import jinja2
from django.template.backends.django import Template from django.template.backends.django import Template
from django.template.loader import get_template from django.template.loader import get_template
from trustchain_idhub import settings
def generate_did_controller_key(): def generate_did_controller_key():
return didkit.generate_ed25519_key() return didkit.generate_ed25519_key()
@ -15,6 +17,30 @@ def keydid_from_controller_key(key):
return didkit.key_to_did("key", key) return didkit.key_to_did("key", key)
async def resolve_keydid(keydid):
return await didkit.resolve_did(keydid, "{}")
def webdid_from_controller_key(key):
"""
Se siguen los pasos para generar un webdid a partir de un keydid.
Documentado en la docu de spruceid.
"""
keydid = keydid_from_controller_key(key) # "did:key:<...>"
pubkeyid = keydid.rsplit(":")[-1] # <...>
document = json.loads(asyncio.run(resolve_keydid(keydid))) # Documento DID en terminos "key"
webdid_url = f"did:web:{settings.DOMAIN}:did-registry:{pubkeyid}" # nueva URL: "did:web:idhub.pangea.org:<...>"
webdid_url_owner = webdid_url + "#owner"
# Reemplazamos los campos del documento DID necesarios:
document["id"] = webdid_url
document["verificationMethod"][0]["id"] = webdid_url_owner
document["verificationMethod"][0]["controller"] = webdid_url
document["authentication"][0] = webdid_url_owner
document["assertionMethod"][0] = webdid_url_owner
document_fixed_serialized = json.dumps(document)
return webdid_url, document_fixed_serialized
def generate_generic_vc_id(): def generate_generic_vc_id():
# TODO agree on a system for Verifiable Credential IDs # TODO agree on a system for Verifiable Credential IDs
return "https://pangea.org/credentials/42" return "https://pangea.org/credentials/42"