diff --git a/idhub/admin/views.py b/idhub/admin/views.py index f8fd6d0..08e0052 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -772,11 +772,14 @@ class SchemasNewView(SchemasMix): return try: data = f.read().decode('utf-8') - assert credtools.validate_schema(json.loads(data)) + ldata = json.loads(data) + assert credtools.validate_schema(ldata) + name = ldata.get('name') + assert name except Exception: messages.error(self.request, _('This is not a valid schema!')) return - schema = Schemas.objects.create(file_schema=file_name, data=data) + schema = Schemas.objects.create(file_schema=file_name, data=data, type=name) schema.save() return schema @@ -818,10 +821,14 @@ class SchemasImportAddView(SchemasMix): data = self.open_file(file_name) try: json.loads(data) + ldata = json.loads(data) + assert credtools.validate_schema(ldata) + name = ldata.get('name') + assert name except Exception: messages.error(self.request, _('This is not a valid schema!')) return - schema = Schemas.objects.create(file_schema=file_name, data=data) + schema = Schemas.objects.create(file_schema=file_name, data=data, type=name) schema.save() return schema diff --git a/idhub/migrations/0001_initial.py b/idhub/migrations/0001_initial.py index b4d6ac7..b163ccc 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-15 09:58 +# Generated by Django 4.2.5 on 2023-11-29 16:14 from django.conf import settings from django.db import migrations, models @@ -57,27 +57,6 @@ class Migration(migrations.Migration): ('created_at', models.DateTimeField(auto_now=True)), ], ), - migrations.CreateModel( - name='Organization', - fields=[ - ( - 'id', - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID', - ), - ), - ('name', models.CharField(max_length=250)), - ( - 'url', - models.CharField( - help_text='Url where to send the presentation', max_length=250 - ), - ), - ], - ), migrations.CreateModel( name='Rol', fields=[ @@ -111,6 +90,7 @@ class Migration(migrations.Migration): verbose_name='ID', ), ), + ('type', models.CharField(max_length=250)), ('file_schema', models.CharField(max_length=250)), ('data', models.TextField()), ('created_at', models.DateTimeField(auto_now=True)), @@ -274,36 +254,39 @@ class Migration(migrations.Migration): 'type', models.PositiveSmallIntegerField( choices=[ - (1, 'EV_USR_REGISTERED'), - (2, 'EV_USR_WELCOME'), - (3, 'EV_DATA_UPDATE_REQUESTED_BY_USER'), - (4, 'EV_DATA_UPDATE_REQUESTED'), - (5, 'EV_USR_UPDATED_BY_ADMIN'), - (6, 'EV_USR_UPDATED'), - (7, 'EV_USR_DELETED_BY_ADMIN'), - (8, 'EV_DID_CREATED_BY_USER'), - (9, 'EV_DID_CREATED'), - (10, 'EV_DID_DELETED'), - (11, 'EV_CREDENTIAL_DELETED_BY_ADMIN'), - (12, 'EV_CREDENTIAL_DELETED'), - (13, 'EV_CREDENTIAL_ISSUED_FOR_USER'), - (14, 'EV_CREDENTIAL_ISSUED'), - (15, 'EV_CREDENTIAL_PRESENTED_BY_USER'), - (16, 'EV_CREDENTIAL_PRESENTED'), - (17, 'EV_CREDENTIAL_ENABLED'), - (18, 'EV_CREDENTIAL_CAN_BE_REQUESTED'), - (19, 'EV_CREDENTIAL_REVOKED_BY_ADMIN'), - (20, 'EV_CREDENTIAL_REVOKED'), - (21, 'EV_ROLE_CREATED_BY_ADMIN'), - (22, 'EV_ROLE_MODIFIED_BY_ADMIN'), - (23, 'EV_ROLE_DELETED_BY_ADMIN'), - (24, 'EV_SERVICE_CREATED_BY_ADMIN'), - (25, 'EV_SERVICE_MODIFIED_BY_ADMIN'), - (26, 'EV_SERVICE_DELETED_BY_ADMIN'), - (27, 'EV_ORG_DID_CREATED_BY_ADMIN'), - (28, 'EV_ORG_DID_DELETED_BY_ADMIN'), - (29, 'EV_USR_DEACTIVATED_BY_ADMIN'), - (30, 'EV_USR_ACTIVATED_BY_ADMIN'), + (1, 'User registered'), + (2, 'User welcomed'), + (3, 'Data update requested by user'), + ( + 4, + 'Data update requested. Pending approval by administrator', + ), + (5, "User's data updated by admin"), + (6, 'Your data updated by admin'), + (7, 'User deactivated by admin'), + (8, 'DID created by user'), + (9, 'DID created'), + (10, 'DID deleted'), + (11, 'Credential deleted by user'), + (12, 'Credential deleted'), + (13, 'Credential issued for user'), + (14, 'Credential issued'), + (15, 'Credential presented by user'), + (16, 'Credential presented'), + (17, 'Credential enabled'), + (18, 'Credential available'), + (19, 'Credential revoked by admin'), + (20, 'Credential revoked'), + (21, 'Role created by admin'), + (22, 'Role modified by admin'), + (23, 'Role deleted by admin'), + (24, 'Service created by admin'), + (25, 'Service modified by admin'), + (26, 'Service deleted by admin'), + (27, 'Organisational DID created by admin'), + (28, 'Organisational DID deleted by admin'), + (29, 'User deactivated'), + (30, 'User activated'), ] ), ), diff --git a/idhub/models.py b/idhub/models.py index 09ba43b..384d3ed 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -431,6 +431,7 @@ class DID(models.Model): class Schemas(models.Model): + type = models.CharField(max_length=250) file_schema = models.CharField(max_length=250) data = models.TextField() created_at = models.DateTimeField(auto_now=True) @@ -492,10 +493,9 @@ class VerificableCredential(models.Model): return json.loads(self.data) def type(self): - if self.data: - return self.get_schema.get('type')[-1] - - return self.schema.name() + # if self.data and: + # return self.get_schema.get('type')[-1] + return self.schema.type def description(self): if not self.data: diff --git a/oidc4vp/forms.py b/oidc4vp/forms.py index f4f56d5..cdef22e 100644 --- a/oidc4vp/forms.py +++ b/oidc4vp/forms.py @@ -1,41 +1,78 @@ from django import forms +from django.conf import settings + +from oidc4vp.models import Organization -class Organization(forms.Form): - wallet = forms.ChoiceField( - "Wallet", - choices=[(x.id, x.name) for x in Organization.objects.all()] - ) +# class OrganizationForm(forms.Form): +# wallet = forms.ChoiceField( +# "Wallet", +# choices=[(x.id, x.name) for x in Organization.objects.all()] +# ) - def clean_wallet(self): - data = self.cleaned_data["wallet"] - organization = Organization.objects.filter( - id=data - ) +# def clean_wallet(self): +# data = self.cleaned_data["wallet"] +# organization = Organization.objects.filter( +# id=data +# ) - if not organization.exists(): - raise ValidationError("organization is not valid!") +# if not organization.exists(): +# raise ValidationError("organization is not valid!") - self.organization = organization.first() +# self.organization = organization.first() - return data +# return data - def authorize(self): - data = { - "response_type": "vp_token", - "response_mode": "direct_post", - "client_id": self.organization.client_id, - "response_uri": settings.RESPONSE_URI, - "presentation_definition": self.pv_definition(), - "nonce": "" - } - query_dict = QueryDict('', mutable=True) - query_dict.update(data) +# def authorize(self): +# data = { +# "response_type": "vp_token", +# "response_mode": "direct_post", +# "client_id": self.organization.client_id, +# "response_uri": settings.RESPONSE_URI, +# "presentation_definition": self.pv_definition(), +# "nonce": "" +# } +# query_dict = QueryDict('', mutable=True) +# query_dict.update(data) - url = '{response_uri}/authorize?{params}'.format( - response_uri=self.organization.response_uri, - params=query_dict.urlencode() +# url = '{response_uri}/authorize?{params}'.format( +# response_uri=self.organization.response_uri, +# params=query_dict.urlencode() +# ) + +# def pv_definition(self): +# return "" + + +class AuthorizeForm(forms.Form): + organization = forms.ChoiceField(choices=[]) + + def __init__(self, *args, **kwargs): + # import pdb; pdb.set_trace() + self.user = kwargs.pop('user', None) + self.presentation_definition = kwargs.pop('presentation_definition', []) + self.credentials = self.user.vcredentials.filter( + schema__type__in=self.presentation_definition ) + super().__init__(*args, **kwargs) + self.fields['organization'].choices = [ + (x.id, x.name) for x in Organization.objects.filter() + if x.response_uri != settings.RESPONSE_URI + ] + + def save(self, commit=True): + self.org = Organization.objects.filter( + id=self.data['organization'] + ) + if not self.org.exists(): + return + + self.org = self.org[0] + + if commit: + url = self.org.demand_authorization() + if url.status_code == 200: + return url.json().get('redirect_uri') + + return - def pv_definition(self): - return "" diff --git a/oidc4vp/views.py b/oidc4vp/views.py index 699f926..5a5427e 100644 --- a/oidc4vp/views.py +++ b/oidc4vp/views.py @@ -11,9 +11,8 @@ from django.urls import reverse_lazy from oidc4vp.models import Authorization, Organization from idhub.mixins import UserView -from idhub.user.forms import ( - DemandAuthorizationForm -) +from oidc4vp.forms import AuthorizeForm + # from django.core.mail import send_mail # from django.http import HttpResponse, HttpResponseRedirect @@ -29,12 +28,15 @@ class AuthorizeView(UserView, FormView): template_name = "credentials_presentation.html" subtitle = _('Credential presentation') icon = 'bi bi-patch-check-fill' - form_class = DemandAuthorizationForm + form_class = AuthorizeForm success_url = reverse_lazy('idhub:user_demand_authorization') def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user + vps = self.request.GET.get('presentation_definition') + # import pdb; pdb.set_trace() + kwargs['presentation_definition'] = json.loads(vps) return kwargs def form_valid(self, form): @@ -77,7 +79,7 @@ class VerifyView(View): def post(self, request, *args, **kwargs): org = self.validate(request) - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() # # TODO: incorporate request.POST["presentation_submission"] as schema definition # (presentation_valid, _) = verify_presentation(request.POST["vp_token"]) # if not presentation_valid: