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
|
||||
|
||||
|
||||
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,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
|
||||
pandas==2.1.1
|
||||
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