Skip to content

Commit

Permalink
Merge pull request #1863 from dbluhm/fix/did-sov-resolver
Browse files Browse the repository at this point in the history
fix: resolve dids following new endpoint rules
  • Loading branch information
andrewwhitehead authored Aug 5, 2022
2 parents 2b4c307 + 609f2e9 commit eeebb9d
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 15 deletions.
79 changes: 67 additions & 12 deletions aries_cloudagent/resolver/default/indy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Resolution is performed using the IndyLedger class.
"""

from typing import Pattern
from typing import Any, Mapping, Pattern

from pydid import DID, DIDDocumentBuilder
from pydid.verification_method import Ed25519VerificationKey2018
from pydid.verification_method import Ed25519VerificationKey2018, VerificationMethod

from ...config.injection_context import InjectionContext
from ...core.profile import Profile
Expand All @@ -29,7 +29,10 @@ class NoIndyLedger(ResolverError):
class IndyDIDResolver(BaseDIDResolver):
"""Indy DID Resolver."""

AGENT_SERVICE_TYPE = "did-communication"
SERVICE_TYPE_DID_COMMUNICATION = "did-communication"
SERVICE_TYPE_DIDCOMM = "DIDComm"
SERVICE_TYPE_ENDPOINT = "endpoint"
CONTEXT_DIDCOMM_V2 = "https://didcomm.org/messaging/contexts/v2"

def __init__(self):
"""Initialize Indy Resolver."""
Expand All @@ -43,6 +46,60 @@ def supported_did_regex(self) -> Pattern:
"""Return supported_did_regex of Indy DID Resolver."""
return IndyDID.PATTERN

def _add_endpoint_as_endpoint_value_pair(
self,
builder: DIDDocumentBuilder,
endpoint: str,
recipient_key: VerificationMethod,
):
builder.service.add_didcomm(
ident=self.SERVICE_TYPE_DID_COMMUNICATION,
type_=self.SERVICE_TYPE_DID_COMMUNICATION,
service_endpoint=endpoint,
priority=1,
recipient_keys=[recipient_key],
routing_keys=[],
)

def _add_endpoint_as_map(
self,
builder: DIDDocumentBuilder,
endpoint: Mapping[str, Any],
recipient_key: VerificationMethod,
):
types = endpoint.get("types", [self.SERVICE_TYPE_DID_COMMUNICATION])
routing_keys = endpoint.get("routingKeys", [])
endpoint_url = endpoint.get("endpoint")
if not endpoint_url:
raise ValueError("endpoint url not found in endpoint attrib")

if self.SERVICE_TYPE_DIDCOMM in types:
builder.service.add(
ident="#didcomm-1",
type_=self.SERVICE_TYPE_DIDCOMM,
service_endpoint=endpoint_url,
recipient_keys=[recipient_key.id],
routing_keys=routing_keys,
accept=["didcomm/v2"],
)
builder.context.append(self.CONTEXT_DIDCOMM_V2)
if self.SERVICE_TYPE_DID_COMMUNICATION in types:
builder.service.add(
ident="did-communication",
type_=self.SERVICE_TYPE_DID_COMMUNICATION,
service_endpoint=endpoint_url,
priority=1,
routing_keys=routing_keys,
recipient_keys=[recipient_key.id],
accept=["didcomm/aip2;env=rfc19"],
)
if self.SERVICE_TYPE_ENDPOINT in types:
builder.service.add(
ident="endpoint",
service_endpoint=endpoint_url,
type_=self.SERVICE_TYPE_ENDPOINT,
)

async def _resolve(self, profile: Profile, did: str) -> dict:
"""Resolve an indy DID."""
multitenant_mgr = profile.inject_or(BaseMultitenantManager)
Expand Down Expand Up @@ -76,16 +133,14 @@ async def _resolve(self, profile: Profile, did: str) -> dict:
if endpoints:
for type_, endpoint in endpoints.items():
if type_ == EndpointType.ENDPOINT.indy:
builder.service.add_didcomm(
ident=self.AGENT_SERVICE_TYPE,
type_=self.AGENT_SERVICE_TYPE,
service_endpoint=endpoint,
priority=1,
recipient_keys=[vmethod],
routing_keys=[],
)
if isinstance(endpoint, dict):
self._add_endpoint_as_map(builder, endpoint, vmethod)
else:
self._add_endpoint_as_endpoint_value_pair(
builder, endpoint, vmethod
)
else:
# Accept all service types for now
# Accept all service types for now, i.e. profile, linked_domains
builder.service.add(
ident=type_,
type_=type_,
Expand Down
44 changes: 41 additions & 3 deletions aries_cloudagent/resolver/default/tests/test_indy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from ....multitenant.manager import MultitenantManager

from ...base import DIDNotFound, ResolverError
from .. import indy as test_module
from ..indy import IndyDIDResolver

# pylint: disable=W0621
Expand All @@ -33,8 +32,11 @@ def resolver():
def ledger():
"""Ledger fixture."""
ledger = async_mock.MagicMock(spec=BaseLedger)
ledger.get_endpoint_for_did = async_mock.CoroutineMock(
return_value="https://github.com/"
ledger.get_all_endpoints_for_did = async_mock.CoroutineMock(
return_value={
"endpoint": "https://github.com/",
"profile": "https://example.com/profile",
}
)
ledger.get_key_for_did = async_mock.CoroutineMock(return_value="key")
yield ledger
Expand Down Expand Up @@ -107,3 +109,39 @@ async def test_resolve_x_did_not_found(
ledger.get_key_for_did.side_effect = LedgerError
with pytest.raises(DIDNotFound):
await resolver.resolve(profile, TEST_DID0)

@pytest.mark.asyncio
async def test_supports_updated_did_sov_rules(
self, resolver: IndyDIDResolver, ledger: BaseLedger, profile: Profile
):
"""Test that new attrib structure is supported."""
example = {
"endpoint": {
"endpoint": "https://example.com/endpoint",
"routingKeys": ["a-routing-key"],
"types": ["DIDComm", "did-communication", "endpoint"],
}
}

ledger.get_all_endpoints_for_did = async_mock.CoroutineMock(
return_value=example
)
assert await resolver.resolve(profile, TEST_DID0)

@pytest.mark.asyncio
async def test_supports_updated_did_sov_rules_x_no_endpoint_url(
self, resolver: IndyDIDResolver, ledger: BaseLedger, profile: Profile
):
"""Test that new attrib structure is supported."""
example = {
"endpoint": {
"routingKeys": ["a-routing-key"],
"types": ["DIDComm", "did-communication", "endpoint"],
}
}

ledger.get_all_endpoints_for_did = async_mock.CoroutineMock(
return_value=example
)
with pytest.raises(ValueError):
await resolver.resolve(profile, TEST_DID0)

0 comments on commit eeebb9d

Please sign in to comment.