Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ianco authored May 11, 2021
2 parents 17c0548 + e208697 commit 8130e52
Show file tree
Hide file tree
Showing 16 changed files with 292 additions and 134 deletions.
5 changes: 3 additions & 2 deletions aries_cloudagent/admin/tests/test_admin_server.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import json
import pytest

from aiohttp import ClientSession, DummyCookieJar, TCPConnector, web
from aiohttp.test_utils import unused_port
import pytest

from asynctest import TestCase as AsyncTestCase
from asynctest import mock as async_mock

from .. import server as test_module
from ...config.default_context import DefaultContextBuilder
from ...config.injection_context import InjectionContext
from ...core.event_bus import Event
Expand All @@ -16,6 +15,8 @@
from ...transport.outbound.message import OutboundMessage
from ...utils.stats import Collector
from ...utils.task_queue import TaskQueue

from .. import server as test_module
from ..server import AdminServer, AdminSetupError


Expand Down
26 changes: 26 additions & 0 deletions aries_cloudagent/connections/models/tests/test_conn_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,32 @@ async def test_attach_retrieve_request(self):
retrieved = await record.retrieve_request(self.session)
assert isinstance(retrieved, ConnectionRequest)

async def test_attach_request_abstain_on_alien_deco(self):
record = ConnRecord(
my_did=self.test_did,
state=ConnRecord.State.INVITATION.rfc23,
)
connection_id = await record.save(self.session)

req = ConnectionRequest(
connection=ConnectionDetail(
did=self.test_did, did_doc=DIDDoc(self.test_did)
),
label="abc123",
)
ser = req.serialize()
ser["~alien"] = [{"nickname": "profile-image", "data": {"links": ["face.png"]}}]
alien_req = ConnectionRequest.deserialize(ser)
await record.attach_request(self.session, alien_req)
alien_ser = alien_req.serialize()
assert "~alien" in alien_ser

ser["~alien"] = None
alien_req = ConnectionRequest.deserialize(ser)
await record.attach_request(self.session, alien_req)
alien_ser = alien_req.serialize()
assert "~alien" not in alien_ser

async def test_ser_rfc23_state_present(self):
record = ConnRecord(
state=ConnRecord.State.INVITATION,
Expand Down
3 changes: 0 additions & 3 deletions aries_cloudagent/messaging/decorators/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from ..models.base import BaseModel


DECORATOR_PREFIX = "~"


Expand Down Expand Up @@ -92,8 +91,6 @@ def remove_model(self, key: str):

def __setitem__(self, key, value):
"""Add a decorator."""
if not isinstance(value, (bool, int, str, float, dict, OrderedDict, BaseModel)):
raise ValueError(f"Unsupported decorator value: {value}")
self.load_decorator(key, value)

def load_decorator(self, key: str, value, serialized=False):
Expand Down
7 changes: 5 additions & 2 deletions aries_cloudagent/messaging/decorators/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from ....messaging.models.base import BaseModel, BaseModelSchema

from .. import base as test_module
from ..base import BaseDecoratorSet, DECORATOR_PREFIX


Expand Down Expand Up @@ -67,8 +68,10 @@ def test_base_decorator_set(self):
deco_set.remove_model("c")
assert "c" not in deco_set.models

with pytest.raises(ValueError):
deco_set["a"] = None
deco_set["a"] = None #
deco_set.load_decorator("a", None)
assert "a" not in deco_set

deco_set["a"] = {"score": 23}
deco_set["a"] = SampleDecorator(23)
deco_set.load_decorator("a", None)
18 changes: 14 additions & 4 deletions aries_cloudagent/messaging/jsonld/create_verify_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def _created_at():
return stamp.strftime("%Y-%m-%dT%H:%M:%SZ")


def create_verify_data(data, signature_options):
"""Encapsulate the process of constructing the string used during sign and verify."""
def create_verify_data(data, signature_options, document_loader=None):
"""Encapsulate process of constructing string used during sign and verify."""

type_ = signature_options.get("type", "Ed25519Signature2018")
if type_ and type_ != "Ed25519Signature2018":
Expand All @@ -66,9 +66,19 @@ def create_verify_data(data, signature_options):
)

signature_options["created"] = signature_options.get("created", _created_at())
[expanded] = jsonld.expand(data)
[expanded] = jsonld.expand(
data,
options={
**{opt: document_loader for opt in ["documentLoader"] if document_loader}
},
)
framed = jsonld.compact(
expanded, "https://w3id.org/security/v2", {"skipExpansion": True}
expanded,
"https://w3id.org/security/v2",
options={
"skipExpansion": True,
**{opt: document_loader for opt in ["documentLoader"] if document_loader},
},
)

# Detect any dropped attributes during the expand/contract step.
Expand Down
20 changes: 16 additions & 4 deletions aries_cloudagent/messaging/jsonld/credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import json

from ...wallet.util import b64_to_bytes, b64_to_str, bytes_to_b64, str_to_b64
from ...wallet.key_type import KeyType
from ...did.did_key import DIDKey
from ...vc.ld_proofs import DocumentLoader
from ...wallet.base import BaseWallet
from ...wallet.key_type import KeyType
from ...wallet.util import b64_to_bytes, b64_to_str, bytes_to_b64, str_to_b64

from .create_verify_data import create_verify_data
from .error import BadJWSHeaderError

Expand Down Expand Up @@ -83,7 +85,12 @@ async def jws_verify(session, verify_data, signature, public_key):
async def sign_credential(session, credential, signature_options, verkey):
"""Sign Credential."""

framed, verify_data_hex_string = create_verify_data(credential, signature_options)
document_loader = session.profile.inject(DocumentLoader, required=False)
framed, verify_data_hex_string = create_verify_data(
credential,
signature_options,
document_loader,
)
verify_data_bytes = bytes.fromhex(verify_data_hex_string)
jws = await jws_sign(session, verify_data_bytes, verkey)
return {**credential, "proof": {**signature_options, "jws": jws}}
Expand All @@ -92,7 +99,12 @@ async def sign_credential(session, credential, signature_options, verkey):
async def verify_credential(session, doc, verkey):
"""Verify credential."""

framed, verify_data_hex_string = create_verify_data(doc, doc["proof"])
document_loader = session.profile.inject(DocumentLoader, required=False)
framed, verify_data_hex_string = create_verify_data(
doc,
doc["proof"],
document_loader,
)
verify_data_bytes = bytes.fromhex(verify_data_hex_string)
valid = await jws_verify(session, verify_data_bytes, framed["proof"]["jws"], verkey)
return valid
49 changes: 44 additions & 5 deletions aries_cloudagent/messaging/jsonld/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
TEST_SEED = "testseed000000000000000000000001"
TEST_DID = "55GkHamhTU1ZbTbV2ab9DE"
TEST_VERKEY = "3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx"

TEST_SIGN_OBJ0 = {
"doc": {
"@context": [
Expand Down Expand Up @@ -33,7 +34,7 @@
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1",
],
"id": "http://example.gov/credentials/3732",
"id": "http://example.gov/credentials/3735",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "did:example:123",
"issuanceDate": "2020-03-16T22:37:26.544Z",
Expand Down Expand Up @@ -123,7 +124,7 @@
"issuer": "did:example:28394728934792387",
"name": "European Health Insurance Card",
"description": "Example of a European Health Insurance Card",
"attribute2drop": "drop it like its a tot.",
"attribute2drop": "drop it like it's hot",
"issuanceDate": "2021-01-01T12:19:52Z",
"expirationDate": "2029-12-03T12:19:52Z",
"institutionID": "09999 - GE KVG",
Expand Down Expand Up @@ -164,7 +165,7 @@
"credentialSubject": {
"id": "did:example:b34ca6cd37bbf23",
"type": ["EuropeanHealthInsuranceHolder", "Person"],
"attribute2drop": "drop it like its a tot.",
"attribute2drop": "drop it like it's hot",
"familyName": "Muster",
"giveName": "Maria",
"birthDate": "1958-07-17",
Expand Down Expand Up @@ -218,7 +219,7 @@
],
"proof": {
"verificationMethod": "did:example:123#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
"attribute2drop": "drop it like its a tot.",
"attribute2drop": "drop it like it's hot",
"proofPurpose": "assertionMethod",
"created": "2020-04-02T18:48:36Z",
"domain": "example.com",
Expand Down Expand Up @@ -353,7 +354,7 @@
TEST_VERIFY_OBJ2,
]
TEST_VERIFY_ERROR = {
"verkey": ("5yKdnU7ToTjAoRNDzfuzVTfWBH38qyhE1b9xh4v8JaWF"),
"verkey": "5yKdnU7ToTjAoRNDzfuzVTfWBH38qyhE1b9xh4v8JaWF",
"doc": {
"@context": [
"https://www.w3.org/2018/credentials/v1",
Expand Down Expand Up @@ -388,3 +389,41 @@
},
},
}
TEST_EURO_HEALTH = {
"@context": {
"@version": 1.1,
"@protected": True,
"name": "http://schema.org/name",
"description": "http://schema.org/description",
"EuropeanHealthInsuranceCard": {
"@id": "https://essif-lab.pages.grnet.gr/interoperability/eidas-generic-use-case#EuropeanHealthInsuranceCard",
"@context": {
"@version": 1.1,
"@protected": True,
"id": "@id",
"type": "@type",
"ehic": "https://essif-lab.pages.grnet.gr/interoperability/eidas-generic-use-case#",
"description": "http://schema.org/description",
"name": "http://schema.org/name",
"institutionID": "ehic:identificationNumberOfTheInstitution",
"cardNo": "ehic:identificationNumberOfTheCard",
"personalID": "ehic:personalIdentificationNumber",
},
},
"EuropeanHealthInsuranceHolder": {
"@id": "https://essif-lab.pages.grnet.gr/interoperability/eidas-generic-use-case#EuropeanHealthInsuranceHolder",
"@context": {
"@version": 1.1,
"@protected": True,
"schema": "http://schema.org/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"id": "@id",
"type": "@type",
"birthDate": {"@id": "schema:birthDate", "@type": "xsd:dateTime"},
"familyName": "schema:familyName",
"givenName": "schema:givenName",
},
},
"Person": "http://schema.org/Person",
}
}
63 changes: 63 additions & 0 deletions aries_cloudagent/messaging/jsonld/tests/document_loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from ....vc.tests.contexts import (
CITIZENSHIP_V1,
CREDENTIALS_V1,
EXAMPLES_V1,
ODRL,
SCHEMA_ORG,
SECURITY_V1,
SECURITY_V2,
)

from . import (
TEST_EURO_HEALTH,
TEST_SIGN_OBJ0,
TEST_SIGN_OBJ1,
TEST_SIGN_OBJ2,
TEST_VALIDATE_ERROR_OBJ2,
TEST_VERIFY_ERROR,
TEST_VERIFY_OBJ0,
TEST_VERIFY_OBJ1,
TEST_VERIFY_OBJ2,
)

DOCUMENTS = {
TEST_SIGN_OBJ0["doc"]["id"]: TEST_SIGN_OBJ0["doc"],
TEST_SIGN_OBJ1["doc"]["id"]: TEST_SIGN_OBJ1["doc"],
TEST_VERIFY_ERROR["doc"]["id"]: TEST_VERIFY_ERROR["doc"],
TEST_VERIFY_OBJ0["doc"]["id"]: TEST_VERIFY_OBJ0["doc"],
TEST_VERIFY_OBJ1["doc"]["id"]: TEST_VERIFY_OBJ1["doc"],
"https://w3id.org/citizenship/v1": CITIZENSHIP_V1,
"https://www.w3.org/2018/credentials/v1": CREDENTIALS_V1,
"https://www.w3.org/2018/credentials/examples/v1": EXAMPLES_V1,
"https://www.w3.org/ns/odrl.jsonld": ODRL,
"http://schema.org/": SCHEMA_ORG,
"https://w3id.org/security/v1": SECURITY_V1,
"https://w3id.org/security/v2": SECURITY_V2,
(
"https://essif-lab.pages.grnet.gr/interoperability/"
"eidas-generic-use-case/contexts/ehic-v1.jsonld"
): TEST_EURO_HEALTH,
}


def custom_document_loader(url: str, options: dict):
# Check if full url (with fragments is in document map)
if url in DOCUMENTS:
return {
"contentType": "application/ld+json",
"contextUrl": None,
"document": DOCUMENTS[url],
"documentUrl": url,
}

# Otherwise look if it is present without fragment
without_fragment = url.split("#")[0]
if without_fragment in DOCUMENTS:
return {
"contentType": "application/ld+json",
"contextUrl": None,
"document": DOCUMENTS[without_fragment],
"documentUrl": url,
}

raise Exception(f"No custom context support for {url}")
Loading

0 comments on commit 8130e52

Please sign in to comment.