Pushed ssi functionality to idhub repo

This commit is contained in:
Daniel Armengod 2023-11-10 06:48:52 +01:00
parent d581ce0a19
commit 628ca0554d
7 changed files with 104 additions and 53 deletions

View File

@ -31,6 +31,18 @@ class DID(models.Model):
return False
class DIDControllerKey(models.Model):
# In JWK format. Must be stored as-is and passed whole to library functions.
# Example key material:
# '{"kty":"OKP","crv":"Ed25519","x":"oB2cPGFx5FX4dtS1Rtep8ac6B__61HAP_RtSzJdPxqs","d":"OJw80T1CtcqV0hUcZdcI-vYNBN1dlubrLaJa0_se_gU"}'
key_material = models.CharField(max_length=250)
owner_did = models.ForeignKey(
DID,
on_delete=models.CASCADE,
related_name="keys"
)
class Schemas(models.Model):
file_schema = models.CharField(max_length=250)
data = models.TextField()

0
idhub_ssikit/README.md Normal file
View File

58
idhub_ssikit/__init__.py Normal file
View File

@ -0,0 +1,58 @@
import asyncio
import datetime
import didkit
import json
import jinja2
def generate_did_controller_key():
return didkit.generate_ed25519_key()
def keydid_from_controller_key(key):
return didkit.key_to_did("key", key)
def generate_generic_vc_id():
# TODO agree on a system for Verifiable Credential IDs
return "https://pangea.org/credentials/42"
def render_and_sign_credential(vc_template: jinja2.Template, jwk_issuer, vc_data: dict[str, str]):
"""
Populates a VC template with data for issuance, and signs the result with the provided key.
The `vc_data` parameter must at a minimum include:
* issuer_did
* subject_did
* vc_id
and must include whatever other fields are relevant for the vc_template to be instantiated.
The following field(s) will be auto-generated if not passed in `vc_data`:
* issuance_date (to `datetime.datetime.now()`)
"""
async def inner():
unsigned_vc = vc_template.render(vc_data)
signed_vc = await didkit.issue_credential(
unsigned_vc,
'{"proofFormat": "ldp"}',
jwk_issuer
)
return signed_vc
if vc_data.get("issuance_date") is None:
vc_data["issuance_date"] = datetime.datetime.now().replace(microsecond=0).isoformat()
return asyncio.run(inner())
def verify_credential(vc, proof_options):
"""
Returns a (bool, str) tuple indicating whether the credential is valid.
If the boolean is true, the credential is valid and the second argument can be ignored.
If it is false, the VC is invalid and the second argument contains a JSON object with further information.
"""
async def inner():
return didkit.verify_credential(vc, proof_options)
return asyncio.run(inner())

View File

@ -6,4 +6,5 @@ python-decouple==3.8
jsonschema==4.19.1
pandas==2.1.1
requests==2.31.0
didkit==0.3.2
jinja2==3.1.2

View File

@ -0,0 +1,32 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
{
"name": "https://schema.org/name",
"email": "https://schema.org/email",
"membershipType": "https://schema.org/memberOf",
"individual": "https://schema.org/Person",
"organization": "https://schema.org/Organization",
"Member": "https://schema.org/Member",
"startDate": "https://schema.org/startDate",
"jsonSchema": "https://schema.org/jsonSchema",
"$ref": "https://schema.org/jsonSchemaRef"
}
],
"type": ["VerifiableCredential", "VerifiableAttestation"],
"id": "{{ vc_id }}",
"issuer": "{{ issuer_did }}",
"issuanceDate": "{{ issuance_date }}",
"credentialSubject": {
"id": "{{ subject_did }}",
"Member": {
"name": "{{ name }}",
"email": "{{ email }}",
"membershipType": "{{ membershipType }}",
"startDate": "{{ startDate }}"
},
"jsonSchema": {
"$ref": "https://gitea.pangea.org/trustchain-oc1-orchestral/schemas/member-schema.json"
}
}
}

View File

@ -1,52 +0,0 @@
from pathlib import Path
import requests
import json
WALLETKITD = 'http://localhost:8080/'
ISSUER = f'{WALLETKITD}issuer-api/default/'
VERIFIER = f'{WALLETKITD}verifier-api/default/'
default_ctype_header = {
'Content-Type': 'application/json', # specify the type of data you're sending
'Accept': 'application/json', # specify the type of data you can accept
}
def include_str(path):
with open(path, "r") as f:
return f.read().strip()
# Create DID for tenant
# Valid methods: 'key'|'web'
def user_create_did(did_method):
url = f'{ISSUER}config/did/create'
data = {
'method': did_method
}
response = requests.post(url, json=data, headers=default_ctype_header)
response.raise_for_status()
return response.text
def admin_create_template(template_name, template_body):
url = f'{ISSUER}config/templates/{template_name}'
body = template_body
response = requests.post(url, data=body, headers=default_ctype_header)
response.raise_for_status()
return
def user_issue_vc(vc_name, vc_params):
url = f'{ISSUER}credentials/issuance/request'
# ...
# TODO examine cross-device issuance workflow
pass
TENANT_CFG_TMEPLATE = include_str("./TENANT_CFG_TEMPLATE")