add more details to flow
This commit is contained in:
parent
7db6d1f4e3
commit
9e8596f39d
134
oidc4vp/migrations/0001_initial.py
Normal file
134
oidc4vp/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
# Generated by Django 4.2.5 on 2023-11-24 16:53
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import oidc4vp.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Authorization',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name='ID',
|
||||
),
|
||||
),
|
||||
(
|
||||
'code',
|
||||
models.CharField(default=oidc4vp.models.set_code, max_length=24),
|
||||
),
|
||||
('created', models.DateTimeField(auto_now=True)),
|
||||
('presentation_definition', models.CharField(max_length=250)),
|
||||
],
|
||||
),
|
||||
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)),
|
||||
(
|
||||
'client_id',
|
||||
models.CharField(
|
||||
default=oidc4vp.models.set_client_id, max_length=24
|
||||
),
|
||||
),
|
||||
(
|
||||
'client_secret',
|
||||
models.CharField(
|
||||
default=oidc4vp.models.set_client_secret, max_length=48
|
||||
),
|
||||
),
|
||||
(
|
||||
'response_uri',
|
||||
models.URLField(
|
||||
help_text='Url where to send the verificable presentation',
|
||||
max_length=250,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OAuth2VPToken',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name='ID',
|
||||
),
|
||||
),
|
||||
('created', models.DateTimeField(auto_now=True)),
|
||||
('code', models.CharField(max_length=250)),
|
||||
('result_verify', models.BooleanField(max_length=250)),
|
||||
('presentation_definition', models.CharField(max_length=250)),
|
||||
(
|
||||
'authorization',
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to='oidc4vp.authorization',
|
||||
),
|
||||
),
|
||||
(
|
||||
'organization',
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='vp_tokens',
|
||||
to='oidc4vp.organization',
|
||||
),
|
||||
),
|
||||
(
|
||||
'user',
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='vp_tokens',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='authorization',
|
||||
name='organization',
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='authorizations',
|
||||
to='oidc4vp.organization',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='authorization',
|
||||
name='user',
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
]
|
|
@ -1,34 +1,80 @@
|
|||
import requests
|
||||
import secrets
|
||||
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.http import QueryDict
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from idhub_auth.models import User
|
||||
from django.db import models
|
||||
|
||||
|
||||
SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
|
||||
def gen_salt(length: int) -> str:
|
||||
"""Generate a random string of SALT_CHARS with specified ``length``."""
|
||||
if length <= 0:
|
||||
raise ValueError("Salt length must be positive")
|
||||
|
||||
return "".join(secrets.choice(SALT_CHARS) for _ in range(length))
|
||||
|
||||
|
||||
def set_client_id():
|
||||
return gen_salt(24)
|
||||
|
||||
|
||||
def set_client_secret():
|
||||
return gen_salt(48)
|
||||
|
||||
|
||||
def set_code():
|
||||
return gen_salt(24)
|
||||
|
||||
|
||||
class Organization(models.Model):
|
||||
"""
|
||||
This class represent a member of one net trust or federated host
|
||||
"""
|
||||
name = models.CharField(max_length=250)
|
||||
client_id = models.CharField()
|
||||
client_secret = models.CharField()
|
||||
client_id = models.CharField(max_length=24, default=set_client_id)
|
||||
client_secret = models.CharField(max_length=48, default=set_client_secret)
|
||||
response_uri = models.URLField(
|
||||
help_text=_("Url where to send the presentation"),
|
||||
help_text=_("Url where to send the verificable presentation"),
|
||||
max_length=250
|
||||
)
|
||||
|
||||
def send(self, vp):
|
||||
"""
|
||||
Send the verificable presentation to Verifier
|
||||
"""
|
||||
org = Organization.objects.get(
|
||||
response_uri=settings.RESPONSE_URI
|
||||
)
|
||||
auth = (org.client_id, org.client_secret)
|
||||
return requests.post(self.url, data=vp, auth=auth)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def send(self, vcred):
|
||||
return requests.post(self.url, data=vcred)
|
||||
|
||||
###################
|
||||
# Verifier clases #
|
||||
###################
|
||||
|
||||
|
||||
class Authorization(models.Model):
|
||||
"""
|
||||
This class represent a query through browser the client to the wallet.
|
||||
The Verifier need to do a redirection to the user to Wallet.
|
||||
The code we use as a soft foreing key between Authorization and OAuth2VPToken.
|
||||
"""
|
||||
code = models.CharField(max_length=24, default=set_code)
|
||||
created = models.DateTimeField(auto_now=True)
|
||||
presentation_definition = models.CharField()
|
||||
presentation_definition = models.CharField(max_length=250)
|
||||
organization = models.ForeignKey(
|
||||
Organization,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='vp_tokens',
|
||||
related_name='authorizations',
|
||||
null=True,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
|
@ -44,10 +90,10 @@ class Authorization(models.Model):
|
|||
data = {
|
||||
"response_type": "vp_token",
|
||||
"response_mode": "direct_post",
|
||||
"client_id": "...",
|
||||
"client_id": self.organization.client_id,
|
||||
"response_uri": response_uri,
|
||||
"presentation_definition": "...",
|
||||
"nonce": ""
|
||||
"nonce": gen_salt(5),
|
||||
}
|
||||
query_dict = QueryDict('', mutable=True)
|
||||
query_dict.update(data)
|
||||
|
@ -56,12 +102,18 @@ class Authorization(models.Model):
|
|||
response_uri=self.organization.response_uri,
|
||||
params=query_dict.urlencode()
|
||||
)
|
||||
return url
|
||||
|
||||
|
||||
class OAuth2VPToken(models.Model):
|
||||
"""
|
||||
This class represent the response of Wallet to Verifier
|
||||
and the result of verify.
|
||||
"""
|
||||
created = models.DateTimeField(auto_now=True)
|
||||
response_code = models.CharField()
|
||||
result_verify = models.BooleanField()
|
||||
presentation_definition = models.CharField()
|
||||
code = models.CharField(max_length=250)
|
||||
result_verify = models.BooleanField(max_length=250)
|
||||
presentation_definition = models.CharField(max_length=250)
|
||||
organization = models.ForeignKey(
|
||||
Organization,
|
||||
on_delete=models.CASCADE,
|
||||
|
@ -74,4 +126,12 @@ class OAuth2VPToken(models.Model):
|
|||
related_name='vp_tokens',
|
||||
null=True,
|
||||
)
|
||||
authorization = models.ForeignKey(
|
||||
Authorization,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
)
|
||||
|
||||
def verifing(self):
|
||||
pass
|
||||
|
||||
|
|
Loading…
Reference in a new issue