Skip to content

Commit

Permalink
feat(CredentialSubject): compare credential subject against credentia…
Browse files Browse the repository at this point in the history
…l schema before issuance
  • Loading branch information
lemoustachiste committed Mar 5, 2024
1 parent 77d219b commit 2618b20
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
20 changes: 17 additions & 3 deletions cert_issuer/models/verifiable_credential.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import re
import logging
import json
from urllib.parse import urlparse
from cert_schema import ContextUrls
from urllib.request import urlretrieve
from jsonschema import validate as jsonschema_validate

# TODO: move the v3 checks to cert-schema
def validate_RFC3339_date (date):
Expand Down Expand Up @@ -62,7 +65,16 @@ def validate_context (context, type):

pass

def validate_credential_subject (credential_subject):
def validate_credential_subject (credential_subject, credential_schema):
if not isinstance(credential_schema, list):
credential_schema = [credential_schema]

for schema in credential_schema:
schema_url = schema['id']
local_filename, headers = urlretrieve(schema_url)
with open(local_filename) as f:
schema = json.load(f)
jsonschema_validate(credential_subject, schema)
pass

def validate_issuer (certificate_issuer):
Expand Down Expand Up @@ -157,7 +169,7 @@ def validate_credential_schema (certificate_credential_schema):
def verify_credential(certificate_metadata):
try:
# if undefined will throw KeyError
validate_credential_subject(certificate_metadata['credentialSubject'])
credential_subject = certificate_metadata['credentialSubject']
except:
raise ValueError('`credentialSubject` property must be defined')

Expand Down Expand Up @@ -232,7 +244,9 @@ def verify_credential(certificate_metadata):

try:
# if undefined will throw KeyError
validate_credential_schema(certificate_metadata['credentialSchema'])
credential_schema = certificate_metadata['credentialSchema']
validate_credential_schema(credential_schema)
validate_credential_subject(credential_subject, credential_schema)
except KeyError:
# optional property
pass
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ pyld==2.0.3
pysha3>=1.0.2
python-bitcoinlib>=0.10.1
tox>=3.0.0
jsonschema<3.0.0
jsonschema>=4.0.0
lds-merkle-proof-2019>=0.1.0
connexion<3.0.0
56 changes: 56 additions & 0 deletions tests/v3_certificate_validation/test_unit_credential_subject.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import unittest

from cert_issuer.models.verifiable_credential import validate_credential_subject

class UnitValidationV3 (unittest.TestCase):
def test_conforms_to_schema (self):
credential_subject = {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"name": "John Smith",
"nationality": "Canada",
"DOB": "05/10/1983",
"height": "1.80m",
"residentialAddressStreet": "6 Maple Tree street",
"residentialAddressTown": "Toronto",
"residentialAddressPostCode": "YYZYUL"
}

# TODO: ideally this would be stubbed to have better control over the test
# TODO: however urlretrieve and consumption is a bit convoluted to mock
credential_schema = {
"id": "https://www.blockcerts.org/samples/3.0/example-id-card-schema.json",
"type": "JsonSchema"
}

try:
validate_credential_subject(credential_subject, credential_schema)
except:
assert False
return

assert True
def test_does_not_conform_to_schema (self):
credential_subject = {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"name": "John Smith",
"DOB": "05/10/1983",
"height": "1.80m",
"residentialAddressStreet": "6 Maple Tree street",
"residentialAddressTown": "Toronto",
"residentialAddressPostCode": "YYZYUL"
}

# TODO: ideally this would be stubbed to have better control over the test
# TODO: however urlretrieve and consumption is a bit convoluted to mock
credential_schema = {
"id": "https://www.blockcerts.org/samples/3.0/example-id-card-schema.json",
"type": "JsonSchema"
}

try:
validate_credential_subject(credential_subject, credential_schema)
except:
assert True
return

assert False

0 comments on commit 2618b20

Please sign in to comment.