add view list of credentials
This commit is contained in:
parent
4eb02e9218
commit
6db0090bfe
|
@ -0,0 +1,2 @@
|
||||||
|
name email membershipType
|
||||||
|
Pepe user1@example.org individual
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
|
import copy
|
||||||
import logging
|
import logging
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -19,6 +20,7 @@ from idhub_auth.models import User
|
||||||
from idhub.mixins import AdminView
|
from idhub.mixins import AdminView
|
||||||
from idhub.email.views import NotifyActivateUserByEmail
|
from idhub.email.views import NotifyActivateUserByEmail
|
||||||
from idhub.models import (
|
from idhub.models import (
|
||||||
|
DID,
|
||||||
File_datas,
|
File_datas,
|
||||||
Membership,
|
Membership,
|
||||||
Rol,
|
Rol,
|
||||||
|
@ -419,6 +421,13 @@ class AdminCredentialsView(Credentials):
|
||||||
subtitle = _('Credentials list')
|
subtitle = _('Credentials list')
|
||||||
icon = ''
|
icon = ''
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context.update({
|
||||||
|
'credentials': VerifiableCredential.objects,
|
||||||
|
})
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class AdminIssueCredentialsView(Credentials):
|
class AdminIssueCredentialsView(Credentials):
|
||||||
template_name = "idhub/admin/issue_credentials.html"
|
template_name = "idhub/admin/issue_credentials.html"
|
||||||
|
@ -438,6 +447,13 @@ class AdminWalletIdentitiesView(Credentials):
|
||||||
icon = 'bi bi-patch-check-fill'
|
icon = 'bi bi-patch-check-fill'
|
||||||
wallet = True
|
wallet = True
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context.update({
|
||||||
|
'dids': DID.objects,
|
||||||
|
})
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class AdminWalletCredentialsView(Credentials):
|
class AdminWalletCredentialsView(Credentials):
|
||||||
template_name = "idhub/admin/wallet_credentials.html"
|
template_name = "idhub/admin/wallet_credentials.html"
|
||||||
|
@ -693,9 +709,11 @@ class AdminImportStep3View(ImportExport):
|
||||||
return user.first()
|
return user.first()
|
||||||
|
|
||||||
def create_credential(self, user, row):
|
def create_credential(self, user, row):
|
||||||
|
d = copy.copy(self.json_schema)
|
||||||
|
d['instance'] = row
|
||||||
return VerifiableCredential.objects.create(
|
return VerifiableCredential.objects.create(
|
||||||
verified=False,
|
verified=False,
|
||||||
user=user,
|
user=user,
|
||||||
data=json.dumps(row)
|
data=json.dumps(d)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 4.2.5 on 2023-10-25 15:47
|
# Generated by Django 4.2.5 on 2023-10-26 11:29
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
@ -110,9 +110,22 @@ class Migration(migrations.Migration):
|
||||||
('id_string', models.CharField(max_length=250)),
|
('id_string', models.CharField(max_length=250)),
|
||||||
('verified', models.BooleanField()),
|
('verified', models.BooleanField()),
|
||||||
('created_on', models.DateTimeField(auto_now=True)),
|
('created_on', models.DateTimeField(auto_now=True)),
|
||||||
|
('issuer_on', models.DateTimeField(null=True)),
|
||||||
('did_issuer', models.CharField(max_length=250)),
|
('did_issuer', models.CharField(max_length=250)),
|
||||||
('did_subject', models.CharField(max_length=250)),
|
('did_subject', models.CharField(max_length=250)),
|
||||||
('data', models.TextField()),
|
('data', models.TextField()),
|
||||||
|
(
|
||||||
|
'status',
|
||||||
|
models.PositiveSmallIntegerField(
|
||||||
|
choices=[
|
||||||
|
(1, 'Enable'),
|
||||||
|
(2, 'Issued'),
|
||||||
|
(3, 'Revoked'),
|
||||||
|
(4, 'Expired'),
|
||||||
|
],
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
'user',
|
'user',
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
|
@ -217,6 +230,7 @@ class Migration(migrations.Migration):
|
||||||
(
|
(
|
||||||
'user',
|
'user',
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
|
null=True,
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
related_name='dids',
|
related_name='dids',
|
||||||
to=settings.AUTH_USER_MODEL,
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from idhub_auth.models import User
|
from idhub_auth.models import User
|
||||||
|
@ -26,6 +27,7 @@ class DID(models.Model):
|
||||||
User,
|
User,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='dids',
|
related_name='dids',
|
||||||
|
null=True,
|
||||||
)
|
)
|
||||||
# kind = "KEY|WEB"
|
# kind = "KEY|WEB"
|
||||||
|
|
||||||
|
@ -35,20 +37,60 @@ class Schemas(models.Model):
|
||||||
data = models.TextField()
|
data = models.TextField()
|
||||||
created_at = models.DateTimeField(auto_now=True)
|
created_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_schema(self):
|
||||||
|
if not self.data:
|
||||||
|
return {}
|
||||||
|
return json.loads(self.data)
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return self.get_schema.get('name', '')
|
||||||
|
|
||||||
|
def description(self):
|
||||||
|
return self.get_schema.get('description', '')
|
||||||
|
|
||||||
|
|
||||||
class VerifiableCredential(models.Model):
|
class VerifiableCredential(models.Model):
|
||||||
|
"""
|
||||||
|
Definition of Verificable Credentials
|
||||||
|
"""
|
||||||
|
class Status(models.IntegerChoices):
|
||||||
|
ENABLE = 1, _("Enable")
|
||||||
|
ISSUED = 2, _("Issued")
|
||||||
|
REVOKED = 3, _("Revoked")
|
||||||
|
EXPIRED = 4, _("Expired")
|
||||||
|
|
||||||
id_string = models.CharField(max_length=250)
|
id_string = models.CharField(max_length=250)
|
||||||
verified = models.BooleanField()
|
verified = models.BooleanField()
|
||||||
created_on = models.DateTimeField(auto_now=True)
|
created_on = models.DateTimeField(auto_now=True)
|
||||||
|
issuer_on = models.DateTimeField(null=True)
|
||||||
did_issuer = models.CharField(max_length=250)
|
did_issuer = models.CharField(max_length=250)
|
||||||
did_subject = models.CharField(max_length=250)
|
did_subject = models.CharField(max_length=250)
|
||||||
|
data = models.TextField()
|
||||||
|
status = models.PositiveSmallIntegerField(
|
||||||
|
choices=Status.choices,
|
||||||
|
default=Status.ENABLE
|
||||||
|
)
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
User,
|
User,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='vcredentials',
|
related_name='vcredentials',
|
||||||
)
|
)
|
||||||
data = models.TextField()
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_schema(self):
|
||||||
|
if not self.data:
|
||||||
|
return {}
|
||||||
|
return json.loads(self.data)
|
||||||
|
|
||||||
|
def type(self):
|
||||||
|
return self.get_schema.get('name', '')
|
||||||
|
|
||||||
|
def description(self):
|
||||||
|
return self.get_schema.get('description', '')
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
return self.Status(self.status).label
|
||||||
|
|
||||||
class VCTemplate(models.Model):
|
class VCTemplate(models.Model):
|
||||||
wkit_template_id = models.CharField(max_length=250)
|
wkit_template_id = models.CharField(max_length=250)
|
||||||
|
|
|
@ -6,4 +6,34 @@
|
||||||
<i class="{{ icon }}"></i>
|
<i class="{{ icon }}"></i>
|
||||||
{{ subtitle }}
|
{{ subtitle }}
|
||||||
</h3>
|
</h3>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Type' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Details' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Issue' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Status' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'User' %}</button></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for f in credentials.all %}
|
||||||
|
<tr style="font-size:15px;">
|
||||||
|
<td>{{ f.type }}</td>
|
||||||
|
<td>{{ f.description }}</td>
|
||||||
|
<td>{{ f.issue_on }}</td>
|
||||||
|
<td>{{ f.get_status }}</td>
|
||||||
|
<td>{{ f.user.email }}</td>
|
||||||
|
<td><button type="button" class="btn btn-green-admin">{% trans 'View' %}</button></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Created at' %}</button></th>
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Created at' %}</button></th>
|
||||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Template file' %}</button></th>
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Template file' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Name' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Description' %}</button></th>
|
||||||
<th scope="col"></th>
|
<th scope="col"></th>
|
||||||
<th scope="col"></th>
|
<th scope="col"></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -23,6 +25,8 @@
|
||||||
<tr style="font-size:15px;">
|
<tr style="font-size:15px;">
|
||||||
<td>{{ schema.created_at }}</td>
|
<td>{{ schema.created_at }}</td>
|
||||||
<td>{{ schema.file_schema }}</td>
|
<td>{{ schema.file_schema }}</td>
|
||||||
|
<td>{{ schema.name }}</td>
|
||||||
|
<td>{{ schema.description }}</td>
|
||||||
<td><a class="btn btn-green-admin" href="{% url 'idhub:admin_schemas_download' schema.id %}" target="_blank" title="{% trans 'View' %}">{% trans 'View' %}</a></td>
|
<td><a class="btn btn-green-admin" href="{% url 'idhub:admin_schemas_download' schema.id %}" target="_blank" title="{% trans 'View' %}">{% trans 'View' %}</a></td>
|
||||||
<td><a class="text-danger" href="jacascript:void()" data-bs-toggle="modal" data-bs-target="#confirm-delete-{{ schema.id }}" title="{% trans 'Remove' %}"><i class="bi bi-x-circle"></i></a></td>
|
<td><a class="text-danger" href="jacascript:void()" data-bs-toggle="modal" data-bs-target="#confirm-delete-{{ schema.id }}" title="{% trans 'Remove' %}"><i class="bi bi-x-circle"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -6,4 +6,55 @@
|
||||||
<i class="{{ icon }}"></i>
|
<i class="{{ icon }}"></i>
|
||||||
{{ subtitle }}
|
{{ subtitle }}
|
||||||
</h3>
|
</h3>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Date' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Label' %}</button></th>
|
||||||
|
<th scope="col"><button type="button" class="btn btn-grey border border-dark">ID</button></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for d in dids.all %}
|
||||||
|
<tr style="font-size:15px;">
|
||||||
|
<td>{{ d.created_at }}</td>
|
||||||
|
<td>{{ d.label }}</td>
|
||||||
|
<td>{{ d.id }}</td>
|
||||||
|
<td><button type="button" class="btn btn-green-admin">{% trans 'Modify' %}</button></td>
|
||||||
|
<td><a class="text-danger" href="jacascript:void()" data-bs-toggle="modal" data-bs-target="#confirm-delete-{{ d.id }}" title="{% trans 'Remove' %}"><i class="bi bi-x-circle"></i></a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="form-actions-no-box">
|
||||||
|
<a class="btn btn-green-admin" href="{# url 'idhub:admin_dids_add' #}">{% translate "Add Identity" %} <i class="bi bi-plus"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
{% for d in dids.all %}
|
||||||
|
<div class="modal" id="confirm-delete-{{ d.id}}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">{% trans 'Delete DID' %} {{ d.file_schema }}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
{% trans 'Are you sure that you want delete this template?' %}
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Clancel</button>
|
||||||
|
<a href="{# url 'idhub:admin_dids_del' d.id #}" type="button" class="btn btn-danger">{% trans 'Delete' %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -117,16 +117,6 @@
|
||||||
Credentials list
|
Credentials list
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link{% if path == 'admin_credentials_new' %} active2{% endif %}" href="{% url 'idhub:admin_credentials_new' %}">
|
|
||||||
Issue credentials
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link{% if path == 'admin_credentials_revoke' %} active2{% endif %}" href="{% url 'idhub:admin_credentials_revoke' %}">
|
|
||||||
Revoke Credentials
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a id="wallet" class="nav-link" data-bs-toggle="collapse" data-bs-target="#lwallet" aria-expanded="false" aria-controls="lwallet" href="javascript:void()">
|
<a id="wallet" class="nav-link" data-bs-toggle="collapse" data-bs-target="#lwallet" aria-expanded="false" aria-controls="lwallet" href="javascript:void()">
|
||||||
Wallet
|
Wallet
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 4.2.5 on 2023-10-25 15:16
|
# Generated by Django 4.2.5 on 2023-10-26 11:29
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import os
|
||||||
|
import django
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'trustchain_idhub.settings') # noqa
|
||||||
|
django.setup() # noqa
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
def create_admin_users(email, password):
|
||||||
|
User.objects.create_superuser(email=email, password=password)
|
||||||
|
|
||||||
|
|
||||||
|
def create_users(email, password):
|
||||||
|
User.objects.create(email=email, password=password)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
admin = 'admin@example.org'
|
||||||
|
pw_admin = '1234'
|
||||||
|
|
||||||
|
user = 'user1@example.org'
|
||||||
|
pw_user = '1234'
|
||||||
|
|
||||||
|
create_admin_users(admin, pw_admin)
|
||||||
|
create_users(user, pw_user)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"$id": "https://pangea.org/schemas/member-credential-schema.json",
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"name": "MemberCredential",
|
||||||
|
"description": "MemberCredential using JsonSchemaCredential",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email"
|
||||||
|
},
|
||||||
|
"membershipType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["individual", "organization"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name", "email", "membershipType"]
|
||||||
|
}
|
Loading…
Reference in New Issue