Pushed ssi functionality to idhub repo
This commit is contained in:
parent
d581ce0a19
commit
628ca0554d
|
@ -31,6 +31,18 @@ class DID(models.Model):
|
||||||
return False
|
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):
|
class Schemas(models.Model):
|
||||||
file_schema = models.CharField(max_length=250)
|
file_schema = models.CharField(max_length=250)
|
||||||
data = models.TextField()
|
data = models.TextField()
|
||||||
|
|
|
@ -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())
|
|
@ -6,4 +6,5 @@ python-decouple==3.8
|
||||||
jsonschema==4.19.1
|
jsonschema==4.19.1
|
||||||
pandas==2.1.1
|
pandas==2.1.1
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
didkit==0.3.2
|
||||||
|
jinja2==3.1.2
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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")
|
|
||||||
|
|
Loading…
Reference in New Issue