From 2f5cb4613e8e732ead153f53af2bd1a899164b37 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Tue, 5 Sep 2023 13:21:54 -0700 Subject: [PATCH 01/37] supress askar logging by default Signed-off-by: Jason Syrotuck --- .devcontainer/devcontainer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8b36d741b2..2f4a7c17c6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -44,6 +44,7 @@ "remoteUser": "vscode", "remoteEnv": { + "RUST_LOG":"aries-askar::log::target=error" //"PATH": "${containerEnv:PATH}:${workspaceRoot}/.venv/bin" }, From 0eeb254c106ef662cc70f7790be0e337699e8c9c Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Tue, 5 Sep 2023 15:32:48 -0700 Subject: [PATCH 02/37] import peer did, simple test and resolver classes Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/__init__.py | 12 ++ aries_cloudagent/resolver/default/peer.py | 137 +++++++++++++++ .../resolver/default/tests/test_peer.py | 59 +++++++ poetry.lock | 160 +++++++++++++++++- pyproject.toml | 1 + 5 files changed, 366 insertions(+), 3 deletions(-) create mode 100644 aries_cloudagent/resolver/default/peer.py create mode 100644 aries_cloudagent/resolver/default/tests/test_peer.py diff --git a/aries_cloudagent/resolver/__init__.py b/aries_cloudagent/resolver/__init__.py index 793bc383f8..3f9d18deb5 100644 --- a/aries_cloudagent/resolver/__init__.py +++ b/aries_cloudagent/resolver/__init__.py @@ -50,3 +50,15 @@ async def setup(context: InjectionContext): ).provide(context.settings, context.injector) await universal_resolver.setup(context) registry.register_resolver(universal_resolver) + + peer_did_2_resolver = ClassProvider( + "aries_cloudagent.resolver.default.peer.PeerDID2Resolver" + ).provide(context.settings, context.injector) + await peer_did_2_resolver.setup(context) + registry.register_resolver(peer_did_2_resolver) + + peer_did_3_resolver = ClassProvider( + "aries_cloudagent.resolver.default.peer.PeerDID3Resolver" + ).provide(context.settings, context.injector) + await peer_did_3_resolver.setup(context) + registry.register_resolver(peer_did_3_resolver) \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/peer.py b/aries_cloudagent/resolver/default/peer.py new file mode 100644 index 0000000000..a651664566 --- /dev/null +++ b/aries_cloudagent/resolver/default/peer.py @@ -0,0 +1,137 @@ +"""Peer DID Resolver. +Resolution is performed using the peer-did-python library https://github.com/sicpa-dlab/peer-did-python. +""" + +import re +from hashlib import sha256 +from typing import Optional, Pattern, Sequence, Text, Union, Tuple, Dict, List + +from peerdid.dids import is_peer_did, PEER_DID_PATTERN, resolve_peer_did, DID, MalformedPeerDIDError, DIDDocument, DIDUrl +from peerdid.keys import to_multibase, MultibaseFormat + +from ...connections.base_manager import BaseConnectionManager +from ...config.injection_context import InjectionContext +from ...core.profile import Profile +from ...messaging.valid import DIDKey as DIDKeyType +from ..base import BaseDIDResolver, DIDNotFound, ResolverType + + +class PeerDID2Resolver(BaseDIDResolver): + """Peer DID Resolver.""" + + def __init__(self): + """Initialize Key Resolver.""" + super().__init__(ResolverType.NATIVE) + + async def setup(self, context: InjectionContext): + """Perform required setup for Key DID resolution.""" + + @property + def supported_did_regex(self) -> Pattern: + """Return supported_did_regex of Key DID Resolver.""" + return PEER_DID_PATTERN + + async def _resolve( + self, + profile: Profile, + did: str, + service_accept: Optional[Sequence[Text]] = None, + ) -> dict: + """Resolve a Key DID.""" + try: + peer_did = is_peer_did(did) + except Exception as e: + raise DIDNotFound(f"peer_did is not formatted correctly: {did}") from e + if peer_did: + did_doc = self.resolve_peer_did_with_service_key_reference(did) + else: + raise DIDNotFound(f"did is not a peer did: {did}") + + return did_doc.dict() + + def resolve_peer_did_with_service_key_reference(self, peer_did_2: Union[str,DID]) -> DIDDocument: + return _resolve_peer_did_with_service_key_reference(peer_did_2) + + + +class PeerDID3Resolver(BaseDIDResolver): + """Peer DID Resolver.""" + + def __init__(self): + """Initialize Key Resolver.""" + super().__init__(ResolverType.NATIVE) + + async def setup(self, context: InjectionContext): + """Perform required setup for Key DID resolution.""" + + @property + def supported_did_regex(self) -> Pattern: + """Return supported_did_regex of Key DID Resolver.""" + return re.compile(r"^did:peer:3(.*)") + + async def _resolve( + self, + profile: Profile, + did: str, + service_accept: Optional[Sequence[Text]] = None, + ) -> dict: + """Resolve a Key DID.""" + if did.startswith('did:peer:3'): + # retrieve did_doc from storage using did:peer:3 + did_doc, rec = await BaseConnectionManager(profile).fetch_did_document(did=did) + else: + raise DIDNotFound(f"did is not a peer did: {did}") + + return did_doc.dict() + +def _resolve_peer_did_with_service_key_reference(peer_did_2: Union[str,DID]) -> DIDDocument: + try: + doc = resolve_peer_did(peer_did_2) + ## WORKAROUND LIBRARY NOT REREFERENCING RECEIPIENT_KEY + services = doc.service + signing_keys = [vm for vm in doc.verification_method or [] if vm.type == "Ed25519VerificationKey2020"] + if services and signing_keys: + services[0].__dict__["recipient_keys"]=[signing_keys[0].id] + else: + raise Exception("no recipient_key signing_key pair") + except Exception as e: + raise ValueError ("pydantic validation error:" + str(e)) + return doc + + +def gen_did_peer_3(peer_did_2 : Union[str,DID]) -> Tuple[DID,DIDDocument]: + if not peer_did_2.startswith("did:peer:2"): + raise MalformedPeerDIDError("did:peer:2 expected") + + content = to_multibase(sha256(peer_did_2.lstrip("did:peer:2").encode()).digest(),MultibaseFormat.BASE58) + dp3 = DID("did:peer:3"+content) + + doc = _resolve_peer_did_with_service_key_reference(peer_did_2) + convert_to_did_peer_3_document(dp3,doc) + return dp3, doc + +def _replace_all_values(input,org,new): + for k,v in input.items(): + typ = type(v) + if isinstance(v,type(dict)): + _replace_all_values(v,org,new) + if isinstance(v,List): + for i,item in enumerate(v): + if isinstance(item,type(dict)): + _replace_all_values(item,org,new) + elif isinstance(item,str) or isinstance(item,DID) or isinstance(item,DIDUrl): + v.pop(i) + v.append(item.replace(org,new,1)) + elif hasattr(item,"__dict__"): + _replace_all_values(item.__dict__,org,new) + else: + pass + + elif isinstance(v,str) or isinstance(v,DID) or isinstance(v,DIDUrl): + input[k] = v.replace(org,new,1) + else: + pass + +def convert_to_did_peer_3_document(dp3, dp2_document:DIDDocument) -> None: + dp2 = dp2_document.id + _replace_all_values(dp2_document.__dict__, dp2,dp3) \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer.py b/aries_cloudagent/resolver/default/tests/test_peer.py new file mode 100644 index 0000000000..6d2e23dec3 --- /dev/null +++ b/aries_cloudagent/resolver/default/tests/test_peer.py @@ -0,0 +1,59 @@ +"""Test PeerDIDResolver.""" + +from asynctest import mock as async_mock +from peerdid.dids import resolve_peer_did +import pydid +import pytest + +from .. import legacy_peer as test_module +from ....cache.base import BaseCache +from ....cache.in_memory import InMemoryCache +from ....connections.models.diddoc.diddoc import DIDDoc +from ....core.in_memory import InMemoryProfile +from ....core.profile import Profile +from ....storage.error import StorageNotFoundError +from ..legacy_peer import LegacyPeerDIDResolver + + +TEST_DID0 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" +TEST_DID0_DOC = resolve_peer_did(TEST_DID0).dict() + +@pytest.fixture +def resolver(): + """Resolver fixture.""" + yield LegacyPeerDIDResolver() + + +@pytest.fixture +def profile(): + """Profile fixture.""" + profile = InMemoryProfile.test_profile() + profile.context.injector.bind_instance(BaseCache, InMemoryCache()) + yield profile + + +class TestPeerDIDResolver: + @pytest.mark.asyncio + async def test_supports(self, resolver: LegacyPeerDIDResolver, profile: Profile): + """Test supports.""" + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) + + @pytest.mark.asyncio + async def test_supports_no_cache( + self, resolver: LegacyPeerDIDResolver, profile: Profile + ): + """Test supports.""" + profile.context.injector.clear_binding(BaseCache) + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 090dcc83dd..5d90735bb6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "aiohttp" version = "3.8.5" description = "Async http client/server framework (asyncio)" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -112,6 +113,7 @@ speedups = ["Brotli", "aiodns", "cchardet"] name = "aiohttp-apispec" version = "2.2.3" description = "Build and document REST APIs with aiohttp and apispec" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -128,6 +130,7 @@ webargs = "<6.0" name = "aiohttp-cors" version = "0.7.0" description = "CORS support for aiohttp" +category = "main" optional = false python-versions = "*" files = [ @@ -142,6 +145,7 @@ aiohttp = ">=1.1" name = "aioredis" version = "2.0.1" description = "asyncio (PEP 3156) Redis support" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -160,6 +164,7 @@ hiredis = ["hiredis (>=1.0)"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -174,6 +179,7 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -185,6 +191,7 @@ files = [ name = "apispec" version = "3.3.2" description = "A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -204,6 +211,7 @@ yaml = ["PyYAML (>=3.10)"] name = "aries-askar" version = "0.2.9" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -219,6 +227,7 @@ cached-property = ">=1.5,<2.0" name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -230,6 +239,7 @@ files = [ name = "asyncpg" version = "0.25.0" description = "An asyncio PostgreSQL driver" +category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -270,6 +280,7 @@ test = ["flake8 (>=3.9.2,<3.10.0)", "pycodestyle (>=2.7.0,<2.8.0)", "uvloop (>=0 name = "asynctest" version = "0.13.0" description = "Enhance the standard unittest package with features for testing asyncio libraries" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -281,6 +292,7 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -299,6 +311,7 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "babel" version = "2.12.1" description = "Internationalization utilities" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -310,6 +323,7 @@ files = [ name = "base58" version = "2.1.1" description = "Base58 and Base58Check implementation." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -324,6 +338,7 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " name = "bases" version = "0.2.1" description = "Python library for general Base-N encodings." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -342,6 +357,7 @@ dev = ["base58", "mypy", "pylint", "pytest", "pytest-cov"] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." +category = "main" optional = true python-versions = "*" files = [ @@ -353,6 +369,7 @@ files = [ name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -364,6 +381,7 @@ files = [ name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -375,6 +393,7 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = "*" files = [ @@ -451,6 +470,7 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -462,6 +482,7 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -546,6 +567,7 @@ files = [ name = "cheroot" version = "10.0.0" description = "Highly-optimized, pure-python HTTP server" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -564,6 +586,7 @@ docs = ["furo", "jaraco.packaging (>=3.2)", "python-dateutil", "sphinx (>=1.8.2) name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -575,6 +598,7 @@ files = [ name = "configargparse" version = "1.5.5" description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -590,6 +614,7 @@ yaml = ["PyYAML"] name = "coverage" version = "7.3.0" description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -654,6 +679,7 @@ toml = ["tomli"] name = "cytoolz" version = "0.12.2" description = "Cython implementation of Toolz: High performance functional utilities" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -762,6 +788,7 @@ cython = ["cython"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -773,6 +800,7 @@ files = [ name = "deepmerge" version = "0.3.0" description = "a toolset to deeply merge python dictionaries." +category = "main" optional = false python-versions = ">=3" files = [ @@ -784,6 +812,7 @@ files = [ name = "distlib" version = "0.3.7" description = "Distribution utilities" +category = "dev" optional = false python-versions = "*" files = [ @@ -795,6 +824,7 @@ files = [ name = "docutils" version = "0.18.1" description = "Docutils -- Python Documentation Utilities" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -806,6 +836,7 @@ files = [ name = "ecdsa" version = "0.16.1" description = "ECDSA cryptographic signature library (pure python)" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -824,6 +855,7 @@ gmpy2 = ["gmpy2"] name = "eth-hash" version = "0.3.3" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" +category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -843,6 +875,7 @@ test = ["pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)"] name = "eth-typing" version = "2.3.0" description = "eth-typing: Common type annotations for ethereum python packages" +category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -860,6 +893,7 @@ test = ["pytest (>=4.4,<4.5)", "pytest-xdist", "tox (>=2.9.1,<3)"] name = "eth-utils" version = "1.10.0" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" +category = "main" optional = false python-versions = ">=3.5,!=3.5.2,<4" files = [ @@ -883,6 +917,7 @@ test = ["hypothesis (>=4.43.0,<5.0.0)", "pytest (==5.4.1)", "pytest-xdist", "tox name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -897,6 +932,7 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.12.2" description = "A platform independent file lock." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -912,6 +948,7 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "frozendict" version = "2.3.8" description = "A simple immutable dictionary" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -958,6 +995,7 @@ files = [ name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1028,6 +1066,7 @@ files = [ name = "identify" version = "2.5.27" description = "File identification library for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1042,6 +1081,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1053,6 +1093,7 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1064,6 +1105,7 @@ files = [ name = "indy-credx" version = "1.0.0" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -1077,6 +1119,7 @@ files = [ name = "indy-vdr" version = "0.3.4" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -1089,6 +1132,7 @@ files = [ name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1100,6 +1144,7 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1111,6 +1156,7 @@ files = [ name = "jaraco-functools" version = "3.8.1" description = "Functools like those found in stdlib" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1129,6 +1175,7 @@ testing = ["jaraco.classes", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-c name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1146,6 +1193,7 @@ i18n = ["Babel (>=2.7)"] name = "jsonpath-ng" version = "1.5.2" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +category = "main" optional = false python-versions = "*" files = [ @@ -1162,6 +1210,7 @@ six = "*" name = "lxml" version = "4.9.3" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -1269,6 +1318,7 @@ source = ["Cython (>=0.29.35)"] name = "markdown" version = "3.1.1" description = "Python implementation of Markdown." +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -1286,6 +1336,7 @@ testing = ["coverage", "pyyaml"] name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1364,6 +1415,7 @@ files = [ name = "marshmallow" version = "3.20.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1384,6 +1436,7 @@ tests = ["pytest", "pytz", "simplejson"] name = "mock" version = "4.0.3" description = "Rolling backport of unittest.mock for all Pythons" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1400,6 +1453,7 @@ test = ["pytest (<5.4)", "pytest-cov"] name = "more-itertools" version = "10.1.0" description = "More routines for operating on iterables, beyond itertools" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1411,6 +1465,7 @@ files = [ name = "msgpack" version = "1.0.5" description = "MessagePack serializer" +category = "main" optional = false python-versions = "*" files = [ @@ -1483,6 +1538,7 @@ files = [ name = "multidict" version = "6.0.4" description = "multidict implementation" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1566,6 +1622,7 @@ files = [ name = "multiformats" version = "0.2.1" description = "Python implementation of multiformats protocols." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1587,6 +1644,7 @@ full = ["blake3", "mmh3", "pycryptodomex", "pysha3", "pyskein"] name = "multiformats-config" version = "0.2.0.post4" description = "Pre-loading configuration module for the 'multiformats' package." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1604,6 +1662,7 @@ dev = ["mypy", "pylint", "pytest", "pytest-cov"] name = "nest-asyncio" version = "1.5.7" description = "Patch asyncio to allow nested event loops" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1615,6 +1674,7 @@ files = [ name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -1629,6 +1689,7 @@ setuptools = "*" name = "packaging" version = "23.1" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1636,10 +1697,31 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[[package]] +name = "peerdid" +version = "0.5.2" +description = "PeerDID for Python" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "peerdid-0.5.2-py3-none-any.whl", hash = "sha256:e92be3ba483cf3e37e87d9855afae2346266f8e4d86809071edb6dbce510d569"}, + {file = "peerdid-0.5.2.tar.gz", hash = "sha256:efc4c16a4cf2b3802a62e0d5be459a5019ccf48befdc17d1c97f6d47be4f7130"}, +] + +[package.dependencies] +base58 = ">=2.1.0,<2.2.0" +pydid = ">=0.3.5,<0.4.0" +varint = ">=1.0.2,<1.1.0" + +[package.extras] +tests = ["pytest (==6.2.5)", "pytest-xdist (==2.3.0)"] + [[package]] name = "pillow" version = "10.0.0" description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1709,6 +1791,7 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1724,6 +1807,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1739,6 +1823,7 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" +category = "main" optional = false python-versions = "*" files = [ @@ -1750,6 +1835,7 @@ files = [ name = "portalocker" version = "2.7.0" description = "Wraps the portalocker recipe for easy usage" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1769,6 +1855,7 @@ tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "p name = "pre-commit" version = "3.3.3" description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1787,8 +1874,9 @@ virtualenv = ">=20.10.0" name = "prompt-toolkit" version = "2.0.10" description = "Library for building powerful interactive command lines in Python" +category = "main" optional = false -python-versions = ">=2.6,<3.0.dev0 || >=3.3.dev0" +python-versions = ">=2.6,<3.0.0 || >=3.3.0" files = [ {file = "prompt_toolkit-2.0.10-py2-none-any.whl", hash = "sha256:e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31"}, {file = "prompt_toolkit-2.0.10-py3-none-any.whl", hash = "sha256:46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4"}, @@ -1803,6 +1891,7 @@ wcwidth = "*" name = "ptvsd" version = "4.3.2" description = "Remote debugging server for Python support in Visual Studio and Visual Studio Code" +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" files = [ @@ -1837,6 +1926,7 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1848,6 +1938,7 @@ files = [ name = "pydantic" version = "1.9.2" description = "Data validation and settings management using python type hints" +category = "main" optional = false python-versions = ">=3.6.1" files = [ @@ -1899,6 +1990,7 @@ email = ["email-validator (>=1.0.3)"] name = "pydevd" version = "1.5.1" description = "PyDev.Debugger (used in PyDev, PyCharm and VSCode Python)" +category = "dev" optional = false python-versions = "*" files = [ @@ -1919,6 +2011,7 @@ files = [ name = "pydevd-pycharm" version = "193.6015.41" description = "PyCharm Debugger (used in PyCharm and PyDev)" +category = "dev" optional = false python-versions = "*" files = [ @@ -1929,6 +2022,7 @@ files = [ name = "pydid" version = "0.3.8" description = "Python library for validating, constructing, and representing DIDs and DID Documents" +category = "main" optional = false python-versions = ">=3.6.9,<4.0.0" files = [ @@ -1945,6 +2039,7 @@ typing-extensions = ">=4.0.0,<4.1.0" name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1959,6 +2054,7 @@ plugins = ["importlib-metadata"] name = "pyjwt" version = "2.8.0" description = "JSON Web Token implementation in Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1976,6 +2072,7 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pyld" version = "2.0.3" description = "Python implementation of the JSON-LD API" +category = "main" optional = false python-versions = "*" files = [ @@ -1997,6 +2094,7 @@ requests = ["requests"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2023,6 +2121,7 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2045,6 +2144,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.14.0" description = "Pytest support for asyncio." +category = "dev" optional = false python-versions = ">= 3.5" files = [ @@ -2062,6 +2162,7 @@ testing = ["async-generator (>=1.3)", "coverage", "hypothesis (>=5.7.1)"] name = "pytest-cov" version = "2.10.1" description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -2080,6 +2181,7 @@ testing = ["fields", "hunter", "process-tests (==2.0.2)", "pytest-xdist", "six", name = "pytest-ruff" version = "0.1.1" description = "pytest plugin to check ruff requirements." +category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -2094,6 +2196,7 @@ ruff = ">=0.0.242" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2108,6 +2211,7 @@ six = ">=1.5" name = "python-json-logger" version = "2.0.7" description = "A python library adding a json log formatter" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2119,6 +2223,7 @@ files = [ name = "python3-indy" version = "1.16.0.post286" description = "This is the official SDK for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org). The major artifact of the SDK is a c-callable library." +category = "main" optional = true python-versions = "*" files = [ @@ -2135,6 +2240,7 @@ test = ["base58", "pytest (<3.7)", "pytest-asyncio (==0.10.0)"] name = "pytz" version = "2021.1" description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" files = [ @@ -2146,6 +2252,7 @@ files = [ name = "pywin32" version = "306" description = "Python for Window Extensions" +category = "main" optional = false python-versions = "*" files = [ @@ -2169,6 +2276,7 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2177,6 +2285,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2184,8 +2293,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2202,6 +2318,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2209,6 +2326,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2218,6 +2336,7 @@ files = [ name = "qrcode" version = "6.1" description = "QR Code image generator" +category = "main" optional = false python-versions = "*" files = [ @@ -2240,6 +2359,7 @@ test = ["mock", "pytest", "pytest-cov"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2261,6 +2381,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rlp" version = "1.2.0" description = "A package for Recursive Length Prefix encoding and decoding" +category = "main" optional = false python-versions = "*" files = [ @@ -2281,6 +2402,7 @@ test = ["hypothesis (==3.56.5)", "pytest (==3.3.2)", "tox (>=2.9.1,<3)"] name = "ruff" version = "0.0.285" description = "An extremely fast Python linter, written in Rust." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2307,6 +2429,7 @@ files = [ name = "setuptools" version = "68.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2323,6 +2446,7 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "simplejson" version = "3.19.1" description = "Simple, fast, extensible JSON encoder/decoder for Python" +category = "main" optional = false python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2417,6 +2541,7 @@ files = [ name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2428,6 +2553,7 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" optional = false python-versions = "*" files = [ @@ -2439,6 +2565,7 @@ files = [ name = "sphinx" version = "1.8.4" description = "Python documentation generator" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2469,6 +2596,7 @@ websupport = ["sqlalchemy (>=0.9)", "whoosh (>=2.0)"] name = "sphinx-rtd-theme" version = "1.3.0" description = "Read the Docs theme for Sphinx" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2488,6 +2616,7 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] name = "sphinxcontrib-jquery" version = "4.1" description = "Extension to include jQuery on newer Sphinx releases" +category = "dev" optional = false python-versions = ">=2.7" files = [ @@ -2502,6 +2631,7 @@ Sphinx = ">=1.8" name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2517,6 +2647,7 @@ test = ["pytest"] name = "sphinxcontrib-websupport" version = "1.2.4" description = "Sphinx API for Web Apps" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2535,6 +2666,7 @@ test = ["Sphinx", "pytest", "sqlalchemy", "whoosh"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2546,6 +2678,7 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2557,6 +2690,7 @@ files = [ name = "typing-extensions" version = "4.0.1" description = "Backported and Experimental Type Hints for Python 3.6+" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2568,6 +2702,7 @@ files = [ name = "typing-validation" version = "1.0.0.post2" description = "A simple library for runtime type-checking." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2582,6 +2717,7 @@ dev = ["mypy", "pylint", "pytest", "pytest-cov", "rich"] name = "unflatten" version = "0.1.1" description = "Unflatten dict to dict with nested dict/arrays" +category = "main" optional = false python-versions = "*" files = [ @@ -2593,6 +2729,7 @@ files = [ name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2610,6 +2747,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "ursa-bbs-signatures" version = "1.0.1" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -2618,10 +2756,22 @@ files = [ {file = "ursa_bbs_signatures-1.0.1-py3-none-win_amd64.whl", hash = "sha256:ffd5f8cf1518c706b372feccac5d727a9d6c64a68f54f4d109133c4101108368"}, ] +[[package]] +name = "varint" +version = "1.0.2" +description = "Simple python varint implementation" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "varint-1.0.2.tar.gz", hash = "sha256:a6ecc02377ac5ee9d65a6a8ad45c9ff1dac8ccee19400a5950fb51d594214ca5"}, +] + [[package]] name = "virtualenv" version = "20.24.3" description = "Virtual Python Environment builder" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2642,6 +2792,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" +category = "main" optional = false python-versions = "*" files = [ @@ -2653,6 +2804,7 @@ files = [ name = "web-py" version = "0.62" description = "web.py: makes web apps" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2666,6 +2818,7 @@ cheroot = "*" name = "webargs" version = "5.5.3" description = "Declarative parsing and validation of HTTP request objects, with built-in support for popular web frameworks, including Flask, Django, Bottle, Tornado, Pyramid, webapp2, Falcon, and aiohttp." +category = "main" optional = false python-versions = "*" files = [ @@ -2689,6 +2842,7 @@ tests = ["Django (>=1.11.16)", "Flask (>=0.12.2)", "aiohttp (>=3.0.0)", "bottle name = "yarl" version = "1.9.2" description = "Yet another URL library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2780,4 +2934,4 @@ indy = ["python3-indy"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "61b6b1c547647c9ea6a369aa236059f4de525b65dc1780430c3a20ff852d51a9" +content-hash = "7943a32e5ea658011887ae8722f2da8b913f69dd46967427b511bf1298d0ac5c" diff --git a/pyproject.toml b/pyproject.toml index 7c5bc24d29..c56a80b0b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ unflatten="~0.1" asyncpg = ">=0.25.0,<0.26.0" web-py = ">=0.62,<1.0" pygments = ">=2.10,<3.0" +peerdid = "^0.5.2" # askar aries-askar= { version = "~0.2.5", optional = true } From 36b068192c6d0be4c1fe6735cccac31d2a559fb1 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Tue, 5 Sep 2023 16:49:02 -0700 Subject: [PATCH 03/37] did service check Signed-off-by: Jason Syrotuck --- .../resolver/default/tests/test_peer.py | 41 ++++++++++++++----- aries_cloudagent/resolver/did_resolver.py | 4 +- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/aries_cloudagent/resolver/default/tests/test_peer.py b/aries_cloudagent/resolver/default/tests/test_peer.py index 6d2e23dec3..f118f7e1c7 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer.py +++ b/aries_cloudagent/resolver/default/tests/test_peer.py @@ -1,27 +1,32 @@ """Test PeerDIDResolver.""" from asynctest import mock as async_mock -from peerdid.dids import resolve_peer_did -import pydid +from peerdid.dids import resolve_peer_did, DIDDocument import pytest from .. import legacy_peer as test_module from ....cache.base import BaseCache from ....cache.in_memory import InMemoryCache -from ....connections.models.diddoc.diddoc import DIDDoc from ....core.in_memory import InMemoryProfile from ....core.profile import Profile -from ....storage.error import StorageNotFoundError -from ..legacy_peer import LegacyPeerDIDResolver +from ...did_resolver import DIDResolver +from ..peer import PeerDID2Resolver, _resolve_peer_did_with_service_key_reference TEST_DID0 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" -TEST_DID0_DOC = resolve_peer_did(TEST_DID0).dict() +TEST_DID0_DOC = _resolve_peer_did_with_service_key_reference(TEST_DID0).dict() +TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DID0).dict() + +@pytest.fixture +def common_resolver(): + """Resolver fixture.""" + yield DIDResolver([PeerDID2Resolver()]) + @pytest.fixture def resolver(): """Resolver fixture.""" - yield LegacyPeerDIDResolver() + yield PeerDID2Resolver() @pytest.fixture @@ -34,7 +39,7 @@ def profile(): class TestPeerDIDResolver: @pytest.mark.asyncio - async def test_supports(self, resolver: LegacyPeerDIDResolver, profile: Profile): + async def test_supports(self, resolver: PeerDID2Resolver, profile: Profile): """Test supports.""" with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: mock_mgr.return_value = async_mock.MagicMock( @@ -46,7 +51,21 @@ async def test_supports(self, resolver: LegacyPeerDIDResolver, profile: Profile) @pytest.mark.asyncio async def test_supports_no_cache( - self, resolver: LegacyPeerDIDResolver, profile: Profile + self, resolver: PeerDID2Resolver, profile: Profile + ): + """Test supports.""" + profile.context.injector.clear_binding(BaseCache) + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) + + @pytest.mark.asyncio + async def test_supports_service_referenced( + self, resolver: PeerDID2Resolver, common_resolver: DIDResolver, profile: Profile ): """Test supports.""" profile.context.injector.clear_binding(BaseCache) @@ -56,4 +75,6 @@ async def test_supports_no_cache( return_value=(TEST_DID0_DOC, None) ) ) - assert await resolver.supports(profile, TEST_DID0) \ No newline at end of file + recipient_key = await common_resolver.dereference(profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], document=DIDDocument.deserialize(TEST_DID0_DOC)) + assert recipient_key + \ No newline at end of file diff --git a/aries_cloudagent/resolver/did_resolver.py b/aries_cloudagent/resolver/did_resolver.py index 1ed7e55868..f2e2a1172c 100644 --- a/aries_cloudagent/resolver/did_resolver.py +++ b/aries_cloudagent/resolver/did_resolver.py @@ -123,14 +123,14 @@ async def dereference( # TODO Use cached DID Docs when possible try: parsed = DIDUrl.parse(did_url) - if not parsed.did: + if not parsed.did and not document: raise ValueError("Invalid DID URL") except DIDError as err: raise ResolverError( "Failed to parse DID URL from {}".format(did_url) ) from err - if document and parsed.did != document.id: + if document and parsed.did and parsed.did != document.id: document = None if not document: From 57395db81a7557e4d032b3c1c4c0e5024c2d500c Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 11:11:53 -0700 Subject: [PATCH 04/37] separate peer did 2 and 3 into separate files Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 23 ++- aries_cloudagent/resolver/default/peer2.py | 63 ++++++++ .../resolver/default/{peer.py => peer3.py} | 67 ++------- .../resolver/default/tests/test_peer2.py | 136 ++++++++++++++++++ .../tests/{test_peer.py => test_peer3.py} | 49 ++++--- 5 files changed, 257 insertions(+), 81 deletions(-) create mode 100644 aries_cloudagent/resolver/default/peer2.py rename aries_cloudagent/resolver/default/{peer.py => peer3.py} (58%) create mode 100644 aries_cloudagent/resolver/default/tests/test_peer2.py rename aries_cloudagent/resolver/default/tests/{test_peer.py => test_peer3.py} (53%) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 74a6384356..8544f3191c 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -11,6 +11,7 @@ BaseDIDDocument as ResolvedDocument, DIDCommService, VerificationMethod, + DID ) import pydid from pydid.verification_method import ( @@ -18,7 +19,6 @@ Ed25519VerificationKey2020, JsonWebKey2020, ) - from ..cache.base import BaseCache from ..config.base import InjectionError from ..config.logging import get_logger_inst @@ -61,7 +61,8 @@ class BaseConnectionManagerError(BaseError): class BaseConnectionManager: """Class to provide utilities regarding connection_targets.""" - RECORD_TYPE_DID_DOC = "did_doc" + RECORD_TYPE_DID_DOC = "did_doc" #legacy + RECORD_TYPE_DID_DOCUMENT = "did_document" #pydid DIDDocument RECORD_TYPE_DID_KEY = "did_key" def __init__(self, profile: Profile): @@ -123,6 +124,7 @@ async def create_did_document( f"Router connection not completed: {router_id}" ) routing_doc, _ = await self.fetch_did_document(router.their_did) + assert isinstance(routing_doc, DIDDoc) if not routing_doc.service: raise BaseConnectionManagerError( f"No services defined by routing DIDDoc: {router_id}" @@ -665,16 +667,23 @@ def diddoc_connection_targets( ) return targets - async def fetch_did_document(self, did: str) -> Tuple[DIDDoc, StorageRecord]: + async def fetch_did_document(self, did: str) -> Tuple[Union[DIDDoc, ResolvedDocument], StorageRecord]: """Retrieve a DID Document for a given DID. Args: did: The DID to search for """ - async with self._profile.session() as session: - storage = session.inject(BaseStorage) - record = await storage.find_record(self.RECORD_TYPE_DID_DOC, {"did": did}) - return DIDDoc.from_json(record.value), record + if DID.is_valid(did): + async with self._profile.session() as session: + storage = session.inject(BaseStorage) + record = await storage.find_record(self.RECORD_TYPE_DID_DOCUMENT, {"did": did}) + return ResolvedDocument.from_json(record.value), record + + else: #legacy documents for unqualified dids + async with self._profile.session() as session: + storage = session.inject(BaseStorage) + record = await storage.find_record(self.RECORD_TYPE_DID_DOC, {"did": did}) + return DIDDoc.from_json(record.value), record async def find_connection( self, diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py new file mode 100644 index 0000000000..e245eae212 --- /dev/null +++ b/aries_cloudagent/resolver/default/peer2.py @@ -0,0 +1,63 @@ +"""Peer DID Resolver. +Resolution is performed using the peer-did-python library https://github.com/sicpa-dlab/peer-did-python. +""" + +from typing import Optional, Pattern, Sequence, Text, Union + +from peerdid.dids import is_peer_did, PEER_DID_PATTERN, resolve_peer_did, DID, DIDDocument, DIDUrl + +from ...config.injection_context import InjectionContext +from ...core.profile import Profile +from ..base import BaseDIDResolver, DIDNotFound, ResolverType + + +class PeerDID2Resolver(BaseDIDResolver): + """Peer DID Resolver.""" + + def __init__(self): + """Initialize Key Resolver.""" + super().__init__(ResolverType.NATIVE) + + async def setup(self, context: InjectionContext): + """Perform required setup for Key DID resolution.""" + + @property + def supported_did_regex(self) -> Pattern: + """Return supported_did_regex of Key DID Resolver.""" + return PEER_DID_PATTERN + + async def _resolve( + self, + profile: Profile, + did: str, + service_accept: Optional[Sequence[Text]] = None, + ) -> dict: + """Resolve a Key DID.""" + try: + peer_did = is_peer_did(did) + except Exception as e: + raise DIDNotFound(f"peer_did is not formatted correctly: {did}") from e + if peer_did: + did_doc = self.resolve_peer_did_with_service_key_reference(did) + else: + raise DIDNotFound(f"did is not a peer did: {did}") + + return did_doc.dict() + + def resolve_peer_did_with_service_key_reference(self, peer_did_2: Union[str,DID]) -> DIDDocument: + return _resolve_peer_did_with_service_key_reference(peer_did_2) + + +def _resolve_peer_did_with_service_key_reference(peer_did_2: Union[str,DID]) -> DIDDocument: + try: + doc = resolve_peer_did(peer_did_2) + ## WORKAROUND LIBRARY NOT REREFERENCING RECEIPIENT_KEY + services = doc.service + signing_keys = [vm for vm in doc.verification_method or [] if vm.type == "Ed25519VerificationKey2020"] + if services and signing_keys: + services[0].__dict__["recipient_keys"]=[signing_keys[0].id] + else: + raise Exception("no recipient_key signing_key pair") + except Exception as e: + raise ValueError ("pydantic validation error:" + str(e)) + return doc diff --git a/aries_cloudagent/resolver/default/peer.py b/aries_cloudagent/resolver/default/peer3.py similarity index 58% rename from aries_cloudagent/resolver/default/peer.py rename to aries_cloudagent/resolver/default/peer3.py index a651664566..a292d581fe 100644 --- a/aries_cloudagent/resolver/default/peer.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -6,53 +6,14 @@ from hashlib import sha256 from typing import Optional, Pattern, Sequence, Text, Union, Tuple, Dict, List -from peerdid.dids import is_peer_did, PEER_DID_PATTERN, resolve_peer_did, DID, MalformedPeerDIDError, DIDDocument, DIDUrl +from peerdid.dids import resolve_peer_did, DID, MalformedPeerDIDError, DIDDocument, DIDUrl from peerdid.keys import to_multibase, MultibaseFormat from ...connections.base_manager import BaseConnectionManager from ...config.injection_context import InjectionContext from ...core.profile import Profile -from ...messaging.valid import DIDKey as DIDKeyType from ..base import BaseDIDResolver, DIDNotFound, ResolverType - - -class PeerDID2Resolver(BaseDIDResolver): - """Peer DID Resolver.""" - - def __init__(self): - """Initialize Key Resolver.""" - super().__init__(ResolverType.NATIVE) - - async def setup(self, context: InjectionContext): - """Perform required setup for Key DID resolution.""" - - @property - def supported_did_regex(self) -> Pattern: - """Return supported_did_regex of Key DID Resolver.""" - return PEER_DID_PATTERN - - async def _resolve( - self, - profile: Profile, - did: str, - service_accept: Optional[Sequence[Text]] = None, - ) -> dict: - """Resolve a Key DID.""" - try: - peer_did = is_peer_did(did) - except Exception as e: - raise DIDNotFound(f"peer_did is not formatted correctly: {did}") from e - if peer_did: - did_doc = self.resolve_peer_did_with_service_key_reference(did) - else: - raise DIDNotFound(f"did is not a peer did: {did}") - - return did_doc.dict() - - def resolve_peer_did_with_service_key_reference(self, peer_did_2: Union[str,DID]) -> DIDDocument: - return _resolve_peer_did_with_service_key_reference(peer_did_2) - - +from .peer2 import _resolve_peer_did_with_service_key_reference class PeerDID3Resolver(BaseDIDResolver): """Peer DID Resolver.""" @@ -79,25 +40,12 @@ async def _resolve( if did.startswith('did:peer:3'): # retrieve did_doc from storage using did:peer:3 did_doc, rec = await BaseConnectionManager(profile).fetch_did_document(did=did) + assert isinstance(did_doc, DIDDocument) else: raise DIDNotFound(f"did is not a peer did: {did}") return did_doc.dict() -def _resolve_peer_did_with_service_key_reference(peer_did_2: Union[str,DID]) -> DIDDocument: - try: - doc = resolve_peer_did(peer_did_2) - ## WORKAROUND LIBRARY NOT REREFERENCING RECEIPIENT_KEY - services = doc.service - signing_keys = [vm for vm in doc.verification_method or [] if vm.type == "Ed25519VerificationKey2020"] - if services and signing_keys: - services[0].__dict__["recipient_keys"]=[signing_keys[0].id] - else: - raise Exception("no recipient_key signing_key pair") - except Exception as e: - raise ValueError ("pydantic validation error:" + str(e)) - return doc - def gen_did_peer_3(peer_did_2 : Union[str,DID]) -> Tuple[DID,DIDDocument]: if not peer_did_2.startswith("did:peer:2"): @@ -134,4 +82,11 @@ def _replace_all_values(input,org,new): def convert_to_did_peer_3_document(dp3, dp2_document:DIDDocument) -> None: dp2 = dp2_document.id - _replace_all_values(dp2_document.__dict__, dp2,dp3) \ No newline at end of file + _replace_all_values(dp2_document.__dict__, dp2,dp3) + + #update document indexes + new_indexes = {} + for ind,val in dp2_document._index.items(): + new_indexes[ind.replace(dp2,dp3)] = val + + dp2_document._index = new_indexes \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer2.py b/aries_cloudagent/resolver/default/tests/test_peer2.py new file mode 100644 index 0000000000..be83637e1e --- /dev/null +++ b/aries_cloudagent/resolver/default/tests/test_peer2.py @@ -0,0 +1,136 @@ +"""Test PeerDIDResolver.""" + +from asynctest import mock as async_mock +from peerdid.dids import resolve_peer_did, DIDDocument, DID +import pytest + +from .. import legacy_peer as test_module +from ....cache.base import BaseCache +from ....cache.in_memory import InMemoryCache +from ....core.in_memory import InMemoryProfile +from ....core.profile import Profile +from ...did_resolver import DIDResolver +from ..peer2 import PeerDID2Resolver, _resolve_peer_did_with_service_key_reference + + +TEST_DID0 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" +TEST_DID0_DOC = _resolve_peer_did_with_service_key_reference(TEST_DID0).dict() +TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DID0).dict() + +@pytest.fixture +def common_resolver(): + """Resolver fixture.""" + yield DIDResolver([PeerDID2Resolver()]) + + +@pytest.fixture +def resolver(): + """Resolver fixture.""" + yield PeerDID2Resolver() + + +@pytest.fixture +def profile(): + """Profile fixture.""" + profile = InMemoryProfile.test_profile() + profile.context.injector.bind_instance(BaseCache, InMemoryCache()) + yield profile + + +class TestPeerDID2Resolver: + @pytest.mark.asyncio + async def test_resolution_types(self, resolver: PeerDID2Resolver, profile: Profile): + """Test supports.""" + assert DID.is_valid(TEST_DID0) + assert isinstance(resolve_peer_did(TEST_DID0), DIDDocument) + assert isinstance(_resolve_peer_did_with_service_key_reference(TEST_DID0),DIDDocument) + + @pytest.mark.asyncio + async def test_supports(self, resolver: PeerDID2Resolver, profile: Profile): + """Test supports.""" + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) + + @pytest.mark.asyncio + async def test_supports_no_cache( + self, resolver: PeerDID2Resolver, profile: Profile + ): + """Test supports.""" + profile.context.injector.clear_binding(BaseCache) + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) + + @pytest.mark.asyncio + async def test_supports_service_referenced( + self, resolver: PeerDID2Resolver, common_resolver: DIDResolver, profile: Profile + ): + """Test supports.""" + profile.context.injector.clear_binding(BaseCache) + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + recipient_key = await common_resolver.dereference(profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], document=DIDDocument.deserialize(TEST_DID0_DOC)) + assert recipient_key + + + +class TestPeerDID3Resolver: + @pytest.mark.asyncio + async def test_resolution_types(self, resolver: PeerDID2Resolver, profile: Profile): + """Test supports.""" + assert DID.is_valid(TEST_DID0) + assert isinstance(resolve_peer_did(TEST_DID0), DIDDocument) + assert isinstance(_resolve_peer_did_with_service_key_reference(TEST_DID0),DIDDocument) + + @pytest.mark.asyncio + async def test_supports(self, resolver: PeerDID2Resolver, profile: Profile): + """Test supports.""" + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) + + @pytest.mark.asyncio + async def test_supports_no_cache( + self, resolver: PeerDID2Resolver, profile: Profile + ): + """Test supports.""" + profile.context.injector.clear_binding(BaseCache) + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + assert await resolver.supports(profile, TEST_DID0) + + @pytest.mark.asyncio + async def test_supports_service_referenced( + self, resolver: PeerDID2Resolver, common_resolver: DIDResolver, profile: Profile + ): + """Test supports.""" + profile.context.injector.clear_binding(BaseCache) + with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: + mock_mgr.return_value = async_mock.MagicMock( + fetch_did_document=async_mock.CoroutineMock( + return_value=(TEST_DID0_DOC, None) + ) + ) + recipient_key = await common_resolver.dereference(profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], document=DIDDocument.deserialize(TEST_DID0_DOC)) + assert recipient_key \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer.py b/aries_cloudagent/resolver/default/tests/test_peer3.py similarity index 53% rename from aries_cloudagent/resolver/default/tests/test_peer.py rename to aries_cloudagent/resolver/default/tests/test_peer3.py index f118f7e1c7..8423eed34f 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -1,7 +1,10 @@ """Test PeerDIDResolver.""" +from hashlib import sha256 +from peerdid.keys import to_multibase, MultibaseFormat + from asynctest import mock as async_mock -from peerdid.dids import resolve_peer_did, DIDDocument +from peerdid.dids import resolve_peer_did, DIDDocument, DID import pytest from .. import legacy_peer as test_module @@ -10,23 +13,25 @@ from ....core.in_memory import InMemoryProfile from ....core.profile import Profile from ...did_resolver import DIDResolver -from ..peer import PeerDID2Resolver, _resolve_peer_did_with_service_key_reference +from ..peer3 import PeerDID3Resolver, gen_did_peer_3 + +TEST_DP2 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" +TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DP2).dict() -TEST_DID0 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" -TEST_DID0_DOC = _resolve_peer_did_with_service_key_reference(TEST_DID0).dict() -TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DID0).dict() +TEST_DP3 = DID("did:peer:3"+to_multibase(sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(),MultibaseFormat.BASE58)) +TEST_DP3_DOC = gen_did_peer_3(TEST_DP2)[1] @pytest.fixture def common_resolver(): """Resolver fixture.""" - yield DIDResolver([PeerDID2Resolver()]) + yield DIDResolver([PeerDID3Resolver()]) @pytest.fixture def resolver(): """Resolver fixture.""" - yield PeerDID2Resolver() + yield PeerDID3Resolver() @pytest.fixture @@ -37,44 +42,52 @@ def profile(): yield profile -class TestPeerDIDResolver: +class TestPeerDID3Resolver: + @pytest.mark.asyncio + async def test_resolution_types(self, resolver: PeerDID3Resolver, profile: Profile): + """Test supports.""" + assert DID.is_valid(TEST_DP3) + assert isinstance(gen_did_peer_3(TEST_DP2)[1], DIDDocument) + assert gen_did_peer_3(TEST_DP2)[0] == TEST_DP3 + + @pytest.mark.asyncio - async def test_supports(self, resolver: PeerDID2Resolver, profile: Profile): + async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: mock_mgr.return_value = async_mock.MagicMock( fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DID0_DOC, None) + return_value=(TEST_DP3_DOC, None) ) ) - assert await resolver.supports(profile, TEST_DID0) + assert await resolver.supports(profile, TEST_DP3) @pytest.mark.asyncio async def test_supports_no_cache( - self, resolver: PeerDID2Resolver, profile: Profile + self, resolver: PeerDID3Resolver, profile: Profile ): """Test supports.""" profile.context.injector.clear_binding(BaseCache) with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: mock_mgr.return_value = async_mock.MagicMock( fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DID0_DOC, None) + return_value=(TEST_DP3_DOC, None) ) ) - assert await resolver.supports(profile, TEST_DID0) + assert await resolver.supports(profile, TEST_DP3) @pytest.mark.asyncio async def test_supports_service_referenced( - self, resolver: PeerDID2Resolver, common_resolver: DIDResolver, profile: Profile + self, resolver: PeerDID3Resolver, common_resolver: DIDResolver, profile: Profile ): """Test supports.""" profile.context.injector.clear_binding(BaseCache) with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: mock_mgr.return_value = async_mock.MagicMock( fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DID0_DOC, None) + return_value=(TEST_DP3_DOC, None) ) ) - recipient_key = await common_resolver.dereference(profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], document=DIDDocument.deserialize(TEST_DID0_DOC)) + recipient_key = await common_resolver.dereference(profile, TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], document=TEST_DP3_DOC) assert recipient_key - \ No newline at end of file + \ No newline at end of file From b18457fa0ad48ce3dc3c4458050538a9852a8e63 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 11:26:09 -0700 Subject: [PATCH 05/37] remove and add peerdid to rebuild lock file Signed-off-by: Jason Syrotuck --- poetry.lock | 140 +++++-------------------------------------------- pyproject.toml | 2 +- 2 files changed, 14 insertions(+), 128 deletions(-) diff --git a/poetry.lock b/poetry.lock index f8b971438e..03c7d1cf76 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiohttp" version = "3.8.5" description = "Async http client/server framework (asyncio)" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -113,7 +112,6 @@ speedups = ["Brotli", "aiodns", "cchardet"] name = "aiohttp-apispec" version = "2.2.3" description = "Build and document REST APIs with aiohttp and apispec" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -130,7 +128,6 @@ webargs = "<6.0" name = "aiohttp-cors" version = "0.7.0" description = "CORS support for aiohttp" -category = "main" optional = false python-versions = "*" files = [ @@ -145,7 +142,6 @@ aiohttp = ">=1.1" name = "aioredis" version = "2.0.1" description = "asyncio (PEP 3156) Redis support" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -164,7 +160,6 @@ hiredis = ["hiredis (>=1.0)"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -179,7 +174,6 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -191,7 +185,6 @@ files = [ name = "apispec" version = "3.3.2" description = "A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -211,7 +204,6 @@ yaml = ["PyYAML (>=3.10)"] name = "aries-askar" version = "0.2.9" description = "" -category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -227,7 +219,6 @@ cached-property = ">=1.5,<2.0" name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -239,7 +230,6 @@ files = [ name = "asyncpg" version = "0.25.0" description = "An asyncio PostgreSQL driver" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -280,7 +270,6 @@ test = ["flake8 (>=3.9.2,<3.10.0)", "pycodestyle (>=2.7.0,<2.8.0)", "uvloop (>=0 name = "asynctest" version = "0.13.0" description = "Enhance the standard unittest package with features for testing asyncio libraries" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -292,7 +281,6 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -311,7 +299,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "babel" version = "2.12.1" description = "Internationalization utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -323,7 +310,6 @@ files = [ name = "base58" version = "2.1.1" description = "Base58 and Base58Check implementation." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -338,7 +324,6 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " name = "bases" version = "0.2.1" description = "Python library for general Base-N encodings." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -403,7 +388,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." -category = "main" optional = true python-versions = "*" files = [ @@ -415,7 +399,6 @@ files = [ name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -427,7 +410,6 @@ files = [ name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -439,7 +421,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -516,7 +497,6 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -528,7 +508,6 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -613,7 +592,6 @@ files = [ name = "cheroot" version = "10.0.0" description = "Highly-optimized, pure-python HTTP server" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -646,7 +624,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -658,7 +635,6 @@ files = [ name = "configargparse" version = "1.5.5" description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -674,7 +650,6 @@ yaml = ["PyYAML"] name = "coverage" version = "7.3.0" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -739,7 +714,6 @@ toml = ["tomli"] name = "cytoolz" version = "0.12.2" description = "Cython implementation of Toolz: High performance functional utilities" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -848,7 +822,6 @@ cython = ["cython"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -860,7 +833,6 @@ files = [ name = "deepmerge" version = "0.3.0" description = "a toolset to deeply merge python dictionaries." -category = "main" optional = false python-versions = ">=3" files = [ @@ -872,7 +844,6 @@ files = [ name = "distlib" version = "0.3.7" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -884,7 +855,6 @@ files = [ name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -896,7 +866,6 @@ files = [ name = "ecdsa" version = "0.16.1" description = "ECDSA cryptographic signature library (pure python)" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -915,7 +884,6 @@ gmpy2 = ["gmpy2"] name = "eth-hash" version = "0.3.3" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" -category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -935,7 +903,6 @@ test = ["pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)"] name = "eth-typing" version = "2.3.0" description = "eth-typing: Common type annotations for ethereum python packages" -category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -953,7 +920,6 @@ test = ["pytest (>=4.4,<4.5)", "pytest-xdist", "tox (>=2.9.1,<3)"] name = "eth-utils" version = "1.10.0" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" -category = "main" optional = false python-versions = ">=3.5,!=3.5.2,<4" files = [ @@ -977,7 +943,6 @@ test = ["hypothesis (>=4.43.0,<5.0.0)", "pytest (==5.4.1)", "pytest-xdist", "tox name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -992,7 +957,6 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.12.2" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1008,7 +972,6 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "frozendict" version = "2.3.8" description = "A simple immutable dictionary" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1055,7 +1018,6 @@ files = [ name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1126,7 +1088,6 @@ files = [ name = "identify" version = "2.5.27" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1141,7 +1102,6 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1153,7 +1113,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1165,7 +1124,6 @@ files = [ name = "indy-credx" version = "1.0.0" description = "" -category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -1179,7 +1137,6 @@ files = [ name = "indy-vdr" version = "0.3.4" description = "" -category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -1192,7 +1149,6 @@ files = [ name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1204,7 +1160,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1216,7 +1171,6 @@ files = [ name = "jaraco-functools" version = "3.9.0" description = "Functools like those found in stdlib" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1236,7 +1190,6 @@ testing = ["jaraco.classes", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-c name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1254,7 +1207,6 @@ i18n = ["Babel (>=2.7)"] name = "jsonpath-ng" version = "1.5.2" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." -category = "main" optional = false python-versions = "*" files = [ @@ -1271,7 +1223,6 @@ six = "*" name = "lxml" version = "4.9.3" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -1379,7 +1330,6 @@ source = ["Cython (>=0.29.35)"] name = "markdown" version = "3.1.1" description = "Python implementation of Markdown." -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -1397,7 +1347,6 @@ testing = ["coverage", "pyyaml"] name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1476,7 +1425,6 @@ files = [ name = "marshmallow" version = "3.20.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1497,7 +1445,6 @@ tests = ["pytest", "pytz", "simplejson"] name = "mock" version = "4.0.3" description = "Rolling backport of unittest.mock for all Pythons" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1514,7 +1461,6 @@ test = ["pytest (<5.4)", "pytest-cov"] name = "more-itertools" version = "10.1.0" description = "More routines for operating on iterables, beyond itertools" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1526,7 +1472,6 @@ files = [ name = "msgpack" version = "1.0.5" description = "MessagePack serializer" -category = "main" optional = false python-versions = "*" files = [ @@ -1599,7 +1544,6 @@ files = [ name = "multidict" version = "6.0.4" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1683,7 +1627,6 @@ files = [ name = "multiformats" version = "0.2.1" description = "Python implementation of multiformats protocols." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1705,7 +1648,6 @@ full = ["blake3", "mmh3", "pycryptodomex", "pysha3", "pyskein"] name = "multiformats-config" version = "0.2.0.post4" description = "Pre-loading configuration module for the 'multiformats' package." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1734,7 +1676,6 @@ files = [ name = "nest-asyncio" version = "1.5.7" description = "Patch asyncio to allow nested event loops" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1746,7 +1687,6 @@ files = [ name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -1761,7 +1701,6 @@ setuptools = "*" name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1769,11 +1708,21 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[[package]] +name = "pathspec" +version = "0.11.2" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] + [[package]] name = "peerdid" version = "0.5.2" description = "PeerDID for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1789,22 +1738,10 @@ varint = ">=1.0.2,<1.1.0" [package.extras] tests = ["pytest (==6.2.5)", "pytest-xdist (==2.3.0)"] -[[package]] -name = "pathspec" -version = "0.11.2" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, -] - [[package]] name = "pillow" version = "10.0.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1874,7 +1811,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1890,7 +1826,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.3.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1906,7 +1841,6 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" -category = "main" optional = false python-versions = "*" files = [ @@ -1918,7 +1852,6 @@ files = [ name = "portalocker" version = "2.7.0" description = "Wraps the portalocker recipe for easy usage" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1938,7 +1871,6 @@ tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "p name = "pre-commit" version = "3.3.3" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1957,7 +1889,6 @@ virtualenv = ">=20.10.0" name = "prompt-toolkit" version = "2.0.10" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=2.6,<3.0.0 || >=3.3.0" files = [ @@ -1974,7 +1905,6 @@ wcwidth = "*" name = "ptvsd" version = "4.3.2" description = "Remote debugging server for Python support in Visual Studio and Visual Studio Code" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" files = [ @@ -2009,7 +1939,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2021,7 +1950,6 @@ files = [ name = "pydantic" version = "1.9.2" description = "Data validation and settings management using python type hints" -category = "main" optional = false python-versions = ">=3.6.1" files = [ @@ -2073,7 +2001,6 @@ email = ["email-validator (>=1.0.3)"] name = "pydevd" version = "1.5.1" description = "PyDev.Debugger (used in PyDev, PyCharm and VSCode Python)" -category = "dev" optional = false python-versions = "*" files = [ @@ -2094,7 +2021,6 @@ files = [ name = "pydevd-pycharm" version = "193.6015.41" description = "PyCharm Debugger (used in PyCharm and PyDev)" -category = "dev" optional = false python-versions = "*" files = [ @@ -2105,7 +2031,6 @@ files = [ name = "pydid" version = "0.3.8" description = "Python library for validating, constructing, and representing DIDs and DID Documents" -category = "main" optional = false python-versions = ">=3.6.9,<4.0.0" files = [ @@ -2122,7 +2047,6 @@ typing-extensions = ">=4.0.0,<4.1.0" name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2137,7 +2061,6 @@ plugins = ["importlib-metadata"] name = "pyjwt" version = "2.8.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2155,7 +2078,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pyld" version = "2.0.3" description = "Python implementation of the JSON-LD API" -category = "main" optional = false python-versions = "*" files = [ @@ -2177,7 +2099,6 @@ requests = ["requests"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2204,7 +2125,6 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "pytest" version = "7.4.1" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2227,7 +2147,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.14.0" description = "Pytest support for asyncio." -category = "dev" optional = false python-versions = ">= 3.5" files = [ @@ -2245,7 +2164,6 @@ testing = ["async-generator (>=1.3)", "coverage", "hypothesis (>=5.7.1)"] name = "pytest-cov" version = "2.10.1" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -2264,7 +2182,6 @@ testing = ["fields", "hunter", "process-tests (==2.0.2)", "pytest-xdist", "six", name = "pytest-ruff" version = "0.1.1" description = "pytest plugin to check ruff requirements." -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -2279,7 +2196,6 @@ ruff = ">=0.0.242" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2294,7 +2210,6 @@ six = ">=1.5" name = "python-json-logger" version = "2.0.7" description = "A python library adding a json log formatter" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2306,7 +2221,6 @@ files = [ name = "python3-indy" version = "1.16.0.post286" description = "This is the official SDK for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org). The major artifact of the SDK is a c-callable library." -category = "main" optional = true python-versions = "*" files = [ @@ -2323,7 +2237,6 @@ test = ["base58", "pytest (<3.7)", "pytest-asyncio (==0.10.0)"] name = "pytz" version = "2021.1" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -2335,7 +2248,6 @@ files = [ name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "main" optional = false python-versions = "*" files = [ @@ -2359,7 +2271,6 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2419,7 +2330,6 @@ files = [ name = "qrcode" version = "6.1" description = "QR Code image generator" -category = "main" optional = false python-versions = "*" files = [ @@ -2442,7 +2352,6 @@ test = ["mock", "pytest", "pytest-cov"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2464,7 +2373,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rlp" version = "1.2.0" description = "A package for Recursive Length Prefix encoding and decoding" -category = "main" optional = false python-versions = "*" files = [ @@ -2485,7 +2393,6 @@ test = ["hypothesis (==3.56.5)", "pytest (==3.3.2)", "tox (>=2.9.1,<3)"] name = "ruff" version = "0.0.285" description = "An extremely fast Python linter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2512,7 +2419,6 @@ files = [ name = "setuptools" version = "68.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2529,7 +2435,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "simplejson" version = "3.19.1" description = "Simple, fast, extensible JSON encoder/decoder for Python" -category = "main" optional = false python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2624,7 +2529,6 @@ files = [ name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2636,7 +2540,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -2648,7 +2551,6 @@ files = [ name = "sphinx" version = "1.8.4" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2679,7 +2581,6 @@ websupport = ["sqlalchemy (>=0.9)", "whoosh (>=2.0)"] name = "sphinx-rtd-theme" version = "0.5.1" description = "Read the Docs theme for Sphinx" -category = "dev" optional = false python-versions = "*" files = [ @@ -2697,7 +2598,6 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2713,7 +2613,6 @@ test = ["pytest"] name = "sphinxcontrib-websupport" version = "1.2.4" description = "Sphinx API for Web Apps" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2732,7 +2631,6 @@ test = ["Sphinx", "pytest", "sqlalchemy", "whoosh"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2744,7 +2642,6 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2756,7 +2653,6 @@ files = [ name = "typing-extensions" version = "4.0.1" description = "Backported and Experimental Type Hints for Python 3.6+" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2768,7 +2664,6 @@ files = [ name = "typing-validation" version = "1.0.0.post2" description = "A simple library for runtime type-checking." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2783,7 +2678,6 @@ dev = ["mypy", "pylint", "pytest", "pytest-cov", "rich"] name = "unflatten" version = "0.1.1" description = "Unflatten dict to dict with nested dict/arrays" -category = "main" optional = false python-versions = "*" files = [ @@ -2795,7 +2689,6 @@ files = [ name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2813,7 +2706,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "ursa-bbs-signatures" version = "1.0.1" description = "" -category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -2826,7 +2718,6 @@ files = [ name = "varint" version = "1.0.2" description = "Simple python varint implementation" -category = "main" optional = false python-versions = "*" files = [ @@ -2837,7 +2728,6 @@ files = [ name = "virtualenv" version = "20.24.4" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2858,7 +2748,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -2870,7 +2759,6 @@ files = [ name = "web-py" version = "0.62" description = "web.py: makes web apps" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2884,7 +2772,6 @@ cheroot = "*" name = "webargs" version = "5.5.3" description = "Declarative parsing and validation of HTTP request objects, with built-in support for popular web frameworks, including Flask, Django, Bottle, Tornado, Pyramid, webapp2, Falcon, and aiohttp." -category = "main" optional = false python-versions = "*" files = [ @@ -2908,7 +2795,6 @@ tests = ["Django (>=1.11.16)", "Flask (>=0.12.2)", "aiohttp (>=3.0.0)", "bottle name = "yarl" version = "1.9.2" description = "Yet another URL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3000,4 +2886,4 @@ indy = ["python3-indy"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "fc9e090bc514183ff4558d42ee83e673d8af0ceefe7f4f7b66623b1ebf5a785e" +content-hash = "3572d33f01ad13410e0ae03d925d0ab238b66e7c888ccfb29501f72f9bec66e7" diff --git a/pyproject.toml b/pyproject.toml index 1981bd8887..b0474e3fa6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,6 @@ unflatten="~0.1" asyncpg = ">=0.25.0,<0.26.0" web-py = ">=0.62,<1.0" pygments = ">=2.10,<3.0" -peerdid = "^0.5.2" # askar aries-askar= { version = "~0.2.5", optional = true } @@ -63,6 +62,7 @@ ursa-bbs-signatures= { version = "~1.0.1", optional = true } # indy python3-indy= { version = "^1.11.1", optional = true } +peerdid = "^0.5.2" [tool.poetry.group.dev.dependencies] pre-commit="~3.3.3" From ca866f7ca73e1b3bedde69a732d0d3b3c60fadca Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 11:40:07 -0700 Subject: [PATCH 06/37] black formatter Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 18 ++++-- aries_cloudagent/resolver/__init__.py | 3 +- aries_cloudagent/resolver/default/peer2.py | 20 ++++-- aries_cloudagent/resolver/default/peer3.py | 45 +++++++++----- .../resolver/default/tests/test_peer2.py | 61 +++---------------- .../resolver/default/tests/test_peer3.py | 14 ++++- 6 files changed, 80 insertions(+), 81 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 8544f3191c..533c7c62c4 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -11,7 +11,7 @@ BaseDIDDocument as ResolvedDocument, DIDCommService, VerificationMethod, - DID + DID, ) import pydid from pydid.verification_method import ( @@ -61,8 +61,8 @@ class BaseConnectionManagerError(BaseError): class BaseConnectionManager: """Class to provide utilities regarding connection_targets.""" - RECORD_TYPE_DID_DOC = "did_doc" #legacy - RECORD_TYPE_DID_DOCUMENT = "did_document" #pydid DIDDocument + RECORD_TYPE_DID_DOC = "did_doc" # legacy + RECORD_TYPE_DID_DOCUMENT = "did_document" # pydid DIDDocument RECORD_TYPE_DID_KEY = "did_key" def __init__(self, profile: Profile): @@ -667,7 +667,9 @@ def diddoc_connection_targets( ) return targets - async def fetch_did_document(self, did: str) -> Tuple[Union[DIDDoc, ResolvedDocument], StorageRecord]: + async def fetch_did_document( + self, did: str + ) -> Tuple[Union[DIDDoc, ResolvedDocument], StorageRecord]: """Retrieve a DID Document for a given DID. Args: @@ -676,13 +678,17 @@ async def fetch_did_document(self, did: str) -> Tuple[Union[DIDDoc, ResolvedDocu if DID.is_valid(did): async with self._profile.session() as session: storage = session.inject(BaseStorage) - record = await storage.find_record(self.RECORD_TYPE_DID_DOCUMENT, {"did": did}) + record = await storage.find_record( + self.RECORD_TYPE_DID_DOCUMENT, {"did": did} + ) return ResolvedDocument.from_json(record.value), record else: #legacy documents for unqualified dids async with self._profile.session() as session: storage = session.inject(BaseStorage) - record = await storage.find_record(self.RECORD_TYPE_DID_DOC, {"did": did}) + record = await storage.find_record( + self.RECORD_TYPE_DID_DOC, {"did": did} + ) return DIDDoc.from_json(record.value), record async def find_connection( diff --git a/aries_cloudagent/resolver/__init__.py b/aries_cloudagent/resolver/__init__.py index 5de2469ee7..9536c0cf1d 100644 --- a/aries_cloudagent/resolver/__init__.py +++ b/aries_cloudagent/resolver/__init__.py @@ -61,4 +61,5 @@ async def setup(context: InjectionContext): "aries_cloudagent.resolver.default.peer3.PeerDID3Resolver" ).provide(context.settings, context.injector) await peer_did_3_resolver.setup(context) - registry.register_resolver(peer_did_3_resolver) \ No newline at end of file + registry.register_resolver(peer_did_3_resolver) + \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index e245eae212..8d58ce373a 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -4,7 +4,13 @@ from typing import Optional, Pattern, Sequence, Text, Union -from peerdid.dids import is_peer_did, PEER_DID_PATTERN, resolve_peer_did, DID, DIDDocument, DIDUrl +from peerdid.dids import ( + is_peer_did, + PEER_DID_PATTERN, + resolve_peer_did, + DID, + DIDDocument +) from ...config.injection_context import InjectionContext from ...core.profile import Profile @@ -48,16 +54,22 @@ def resolve_peer_did_with_service_key_reference(self, peer_did_2: Union[str,DID] return _resolve_peer_did_with_service_key_reference(peer_did_2) -def _resolve_peer_did_with_service_key_reference(peer_did_2: Union[str,DID]) -> DIDDocument: +def _resolve_peer_did_with_service_key_reference( + peer_did_2: Union[str,DID] +) -> DIDDocument: try: doc = resolve_peer_did(peer_did_2) ## WORKAROUND LIBRARY NOT REREFERENCING RECEIPIENT_KEY services = doc.service - signing_keys = [vm for vm in doc.verification_method or [] if vm.type == "Ed25519VerificationKey2020"] + signing_keys = [ + vm + for vm in doc.verification_method or [] + if vm.type == "Ed25519VerificationKey2020" + ] if services and signing_keys: services[0].__dict__["recipient_keys"]=[signing_keys[0].id] else: raise Exception("no recipient_key signing_key pair") except Exception as e: - raise ValueError ("pydantic validation error:" + str(e)) + raise ValueError("pydantic validation error:" + str(e)) return doc diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index a292d581fe..6da83805da 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -4,9 +4,14 @@ import re from hashlib import sha256 -from typing import Optional, Pattern, Sequence, Text, Union, Tuple, Dict, List - -from peerdid.dids import resolve_peer_did, DID, MalformedPeerDIDError, DIDDocument, DIDUrl +from typing import Optional, Pattern, Sequence, Text, Union, Tuple, List + +from peerdid.dids import ( + DID, + MalformedPeerDIDError, + DIDDocument, + DIDUrl, +) from peerdid.keys import to_multibase, MultibaseFormat from ...connections.base_manager import BaseConnectionManager @@ -39,7 +44,9 @@ async def _resolve( """Resolve a Key DID.""" if did.startswith('did:peer:3'): # retrieve did_doc from storage using did:peer:3 - did_doc, rec = await BaseConnectionManager(profile).fetch_did_document(did=did) + did_doc, rec = await BaseConnectionManager(profile).fetch_did_document( + did=did + ) assert isinstance(did_doc, DIDDocument) else: raise DIDNotFound(f"did is not a peer did: {did}") @@ -51,15 +58,18 @@ def gen_did_peer_3(peer_did_2 : Union[str,DID]) -> Tuple[DID,DIDDocument]: if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") - content = to_multibase(sha256(peer_did_2.lstrip("did:peer:2").encode()).digest(),MultibaseFormat.BASE58) - dp3 = DID("did:peer:3"+content) + content = to_multibase( + sha256(peer_did_2.lstrip("did:peer:2").encode()).digest(), + MultibaseFormat.BASE58 + ) + dp3 = DID("did:peer:3" + content) doc = _resolve_peer_did_with_service_key_reference(peer_did_2) - convert_to_did_peer_3_document(dp3,doc) + convert_to_did_peer_3_document(dp3, doc) return dp3, doc def _replace_all_values(input,org,new): - for k,v in input.items(): + for k, v in input.items(): typ = type(v) if isinstance(v,type(dict)): _replace_all_values(v,org,new) @@ -67,11 +77,15 @@ def _replace_all_values(input,org,new): for i,item in enumerate(v): if isinstance(item,type(dict)): _replace_all_values(item,org,new) - elif isinstance(item,str) or isinstance(item,DID) or isinstance(item,DIDUrl): + elif ( + isinstance(item,str) + or isinstance(item,DID) + or isinstance(item,DIDUrl) + ): v.pop(i) - v.append(item.replace(org,new,1)) + v.append(item.replace(org, new, 1)) elif hasattr(item,"__dict__"): - _replace_all_values(item.__dict__,org,new) + _replace_all_values(item.__dict__, org, new) else: pass @@ -82,11 +96,12 @@ def _replace_all_values(input,org,new): def convert_to_did_peer_3_document(dp3, dp2_document:DIDDocument) -> None: dp2 = dp2_document.id - _replace_all_values(dp2_document.__dict__, dp2,dp3) + _replace_all_values(dp2_document.__dict__, dp2, dp3) - #update document indexes + # update document indexes new_indexes = {} for ind,val in dp2_document._index.items(): - new_indexes[ind.replace(dp2,dp3)] = val + new_indexes[ind.replace(dp2, dp3)] = val - dp2_document._index = new_indexes \ No newline at end of file + dp2_document._index = new_indexes + \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer2.py b/aries_cloudagent/resolver/default/tests/test_peer2.py index be83637e1e..a7cbb7c616 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer2.py +++ b/aries_cloudagent/resolver/default/tests/test_peer2.py @@ -43,7 +43,9 @@ async def test_resolution_types(self, resolver: PeerDID2Resolver, profile: Profi """Test supports.""" assert DID.is_valid(TEST_DID0) assert isinstance(resolve_peer_did(TEST_DID0), DIDDocument) - assert isinstance(_resolve_peer_did_with_service_key_reference(TEST_DID0),DIDDocument) + assert isinstance( + _resolve_peer_did_with_service_key_reference(TEST_DID0),DIDDocument + ) @pytest.mark.asyncio async def test_supports(self, resolver: PeerDID2Resolver, profile: Profile): @@ -82,55 +84,10 @@ async def test_supports_service_referenced( return_value=(TEST_DID0_DOC, None) ) ) - recipient_key = await common_resolver.dereference(profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], document=DIDDocument.deserialize(TEST_DID0_DOC)) - assert recipient_key - - - -class TestPeerDID3Resolver: - @pytest.mark.asyncio - async def test_resolution_types(self, resolver: PeerDID2Resolver, profile: Profile): - """Test supports.""" - assert DID.is_valid(TEST_DID0) - assert isinstance(resolve_peer_did(TEST_DID0), DIDDocument) - assert isinstance(_resolve_peer_did_with_service_key_reference(TEST_DID0),DIDDocument) - - @pytest.mark.asyncio - async def test_supports(self, resolver: PeerDID2Resolver, profile: Profile): - """Test supports.""" - with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: - mock_mgr.return_value = async_mock.MagicMock( - fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DID0_DOC, None) - ) + recipient_key = await common_resolver.dereference( + profile, + TEST_DID0_DOC["service"][0]["recipient_keys"][0], + document=DIDDocument.deserialize(TEST_DID0_DOC) ) - assert await resolver.supports(profile, TEST_DID0) - - @pytest.mark.asyncio - async def test_supports_no_cache( - self, resolver: PeerDID2Resolver, profile: Profile - ): - """Test supports.""" - profile.context.injector.clear_binding(BaseCache) - with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: - mock_mgr.return_value = async_mock.MagicMock( - fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DID0_DOC, None) - ) - ) - assert await resolver.supports(profile, TEST_DID0) - - @pytest.mark.asyncio - async def test_supports_service_referenced( - self, resolver: PeerDID2Resolver, common_resolver: DIDResolver, profile: Profile - ): - """Test supports.""" - profile.context.injector.clear_binding(BaseCache) - with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: - mock_mgr.return_value = async_mock.MagicMock( - fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DID0_DOC, None) - ) - ) - recipient_key = await common_resolver.dereference(profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], document=DIDDocument.deserialize(TEST_DID0_DOC)) - assert recipient_key \ No newline at end of file + assert recipient_key + \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index 8423eed34f..abe6ccc100 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -19,7 +19,12 @@ TEST_DP2 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DP2).dict() -TEST_DP3 = DID("did:peer:3"+to_multibase(sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(),MultibaseFormat.BASE58)) +TEST_DP3 = DID( + "did:peer:3" + + to_multibase( + sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(),MultibaseFormat.BASE58 + ) +) TEST_DP3_DOC = gen_did_peer_3(TEST_DP2)[1] @pytest.fixture @@ -50,7 +55,6 @@ async def test_resolution_types(self, resolver: PeerDID3Resolver, profile: Profi assert isinstance(gen_did_peer_3(TEST_DP2)[1], DIDDocument) assert gen_did_peer_3(TEST_DP2)[0] == TEST_DP3 - @pytest.mark.asyncio async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" @@ -88,6 +92,10 @@ async def test_supports_service_referenced( return_value=(TEST_DP3_DOC, None) ) ) - recipient_key = await common_resolver.dereference(profile, TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], document=TEST_DP3_DOC) + recipient_key = await common_resolver.dereference( + profile, + TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], + document=TEST_DP3_DOC + ) assert recipient_key \ No newline at end of file From fdf14ba217e19e3b3602ac033f3e89aba2b01f01 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 11:50:53 -0700 Subject: [PATCH 07/37] formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 8 +++--- aries_cloudagent/resolver/default/peer2.py | 18 ++++++------ aries_cloudagent/resolver/default/peer3.py | 28 +++++++++---------- .../resolver/default/tests/test_peer2.py | 6 ++-- .../resolver/default/tests/test_peer3.py | 7 ++--- 5 files changed, 34 insertions(+), 33 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 533c7c62c4..a3f16d0556 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -61,8 +61,8 @@ class BaseConnectionManagerError(BaseError): class BaseConnectionManager: """Class to provide utilities regarding connection_targets.""" - RECORD_TYPE_DID_DOC = "did_doc" # legacy - RECORD_TYPE_DID_DOCUMENT = "did_document" # pydid DIDDocument + RECORD_TYPE_DID_DOC = "did_doc" # legacy + RECORD_TYPE_DID_DOCUMENT = "did_document" # pydid DIDDocument RECORD_TYPE_DID_KEY = "did_key" def __init__(self, profile: Profile): @@ -668,7 +668,7 @@ def diddoc_connection_targets( return targets async def fetch_did_document( - self, did: str + self, did: str ) -> Tuple[Union[DIDDoc, ResolvedDocument], StorageRecord]: """Retrieve a DID Document for a given DID. @@ -683,7 +683,7 @@ async def fetch_did_document( ) return ResolvedDocument.from_json(record.value), record - else: #legacy documents for unqualified dids + else: # legacy documents for unqualified dids async with self._profile.session() as session: storage = session.inject(BaseStorage) record = await storage.find_record( diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 8d58ce373a..094f7fb00b 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -6,10 +6,10 @@ from peerdid.dids import ( is_peer_did, - PEER_DID_PATTERN, - resolve_peer_did, - DID, - DIDDocument + PEER_DID_PATTERN, + resolve_peer_did, + DID, + DIDDocument, ) from ...config.injection_context import InjectionContext @@ -50,12 +50,14 @@ async def _resolve( return did_doc.dict() - def resolve_peer_did_with_service_key_reference(self, peer_did_2: Union[str,DID]) -> DIDDocument: + def resolve_peer_did_with_service_key_reference( + self, peer_did_2: Union[str, DID] + ) -> DIDDocument: return _resolve_peer_did_with_service_key_reference(peer_did_2) def _resolve_peer_did_with_service_key_reference( - peer_did_2: Union[str,DID] + peer_did_2: Union[str, DID] ) -> DIDDocument: try: doc = resolve_peer_did(peer_did_2) @@ -63,11 +65,11 @@ def _resolve_peer_did_with_service_key_reference( services = doc.service signing_keys = [ vm - for vm in doc.verification_method or [] + for vm in doc.verification_method or [] if vm.type == "Ed25519VerificationKey2020" ] if services and signing_keys: - services[0].__dict__["recipient_keys"]=[signing_keys[0].id] + services[0].__dict__["recipient_keys"] = [signing_keys[0].id] else: raise Exception("no recipient_key signing_key pair") except Exception as e: diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 6da83805da..a95196c3ca 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -42,8 +42,8 @@ async def _resolve( service_accept: Optional[Sequence[Text]] = None, ) -> dict: """Resolve a Key DID.""" - if did.startswith('did:peer:3'): - # retrieve did_doc from storage using did:peer:3 + if did.startswith("did:peer:3"): + # retrieve did_doc from storage using did:peer:3 did_doc, rec = await BaseConnectionManager(profile).fetch_did_document( did=did ) @@ -54,13 +54,13 @@ async def _resolve( return did_doc.dict() -def gen_did_peer_3(peer_did_2 : Union[str,DID]) -> Tuple[DID,DIDDocument]: +def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") content = to_multibase( sha256(peer_did_2.lstrip("did:peer:2").encode()).digest(), - MultibaseFormat.BASE58 + MultibaseFormat.BASE58, ) dp3 = DID("did:peer:3" + content) @@ -68,19 +68,19 @@ def gen_did_peer_3(peer_did_2 : Union[str,DID]) -> Tuple[DID,DIDDocument]: convert_to_did_peer_3_document(dp3, doc) return dp3, doc -def _replace_all_values(input,org,new): +def _replace_all_values(input, org, new): for k, v in input.items(): typ = type(v) if isinstance(v,type(dict)): - _replace_all_values(v,org,new) + _replace_all_values(v, org, new) if isinstance(v,List): for i,item in enumerate(v): - if isinstance(item,type(dict)): - _replace_all_values(item,org,new) + if isinstance(item, type(dict)): + _replace_all_values(item, org, new) elif ( - isinstance(item,str) - or isinstance(item,DID) - or isinstance(item,DIDUrl) + isinstance(item, str) + or isinstance(item, DID) + or isinstance(item, DIDUrl) ): v.pop(i) v.append(item.replace(org, new, 1)) @@ -89,8 +89,8 @@ def _replace_all_values(input,org,new): else: pass - elif isinstance(v,str) or isinstance(v,DID) or isinstance(v,DIDUrl): - input[k] = v.replace(org,new,1) + elif isinstance(v, str) or isinstance(v, DID) or isinstance(v, DIDUrl): + input[k] = v.replace(org, new, 1) else: pass @@ -100,7 +100,7 @@ def convert_to_did_peer_3_document(dp3, dp2_document:DIDDocument) -> None: # update document indexes new_indexes = {} - for ind,val in dp2_document._index.items(): + for ind, val in dp2_document._index.items(): new_indexes[ind.replace(dp2, dp3)] = val dp2_document._index = new_indexes diff --git a/aries_cloudagent/resolver/default/tests/test_peer2.py b/aries_cloudagent/resolver/default/tests/test_peer2.py index a7cbb7c616..c384b934ff 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer2.py +++ b/aries_cloudagent/resolver/default/tests/test_peer2.py @@ -17,6 +17,7 @@ TEST_DID0_DOC = _resolve_peer_did_with_service_key_reference(TEST_DID0).dict() TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DID0).dict() + @pytest.fixture def common_resolver(): """Resolver fixture.""" @@ -44,7 +45,7 @@ async def test_resolution_types(self, resolver: PeerDID2Resolver, profile: Profi assert DID.is_valid(TEST_DID0) assert isinstance(resolve_peer_did(TEST_DID0), DIDDocument) assert isinstance( - _resolve_peer_did_with_service_key_reference(TEST_DID0),DIDDocument + _resolve_peer_did_with_service_key_reference(TEST_DID0), DIDDocument ) @pytest.mark.asyncio @@ -87,7 +88,6 @@ async def test_supports_service_referenced( recipient_key = await common_resolver.dereference( profile, TEST_DID0_DOC["service"][0]["recipient_keys"][0], - document=DIDDocument.deserialize(TEST_DID0_DOC) + document=DIDDocument.deserialize(TEST_DID0_DOC), ) assert recipient_key - \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index abe6ccc100..83b1a8abc4 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -22,7 +22,7 @@ TEST_DP3 = DID( "did:peer:3" + to_multibase( - sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(),MultibaseFormat.BASE58 + sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(), MultibaseFormat.BASE58 ) ) TEST_DP3_DOC = gen_did_peer_3(TEST_DP2)[1] @@ -95,7 +95,6 @@ async def test_supports_service_referenced( recipient_key = await common_resolver.dereference( profile, TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], - document=TEST_DP3_DOC + document=TEST_DP3_DOC, ) - assert recipient_key - \ No newline at end of file + assert recipient_key \ No newline at end of file From 990ca0814d4ede66a8714efa591d3c84d85ea2a8 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 11:56:06 -0700 Subject: [PATCH 08/37] pytest enforces linting?? Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 1 + aries_cloudagent/resolver/default/peer3.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 094f7fb00b..64d4b2cee9 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -1,4 +1,5 @@ """Peer DID Resolver. + Resolution is performed using the peer-did-python library https://github.com/sicpa-dlab/peer-did-python. """ diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index a95196c3ca..b6ed8232eb 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -1,5 +1,7 @@ """Peer DID Resolver. -Resolution is performed using the peer-did-python library https://github.com/sicpa-dlab/peer-did-python. + +Resolution is performed by converting did:peer:2 to did:peer:3 according to https://identity.foundation/peer-did-method-spec/#generation-method:~:text=Method%203%3A%20DID%20Shortening%20with%20SHA%2D256%20Hash +DID Document is just a did:peer:2 document (resolved by peer-did-python) where the did has been replaced. """ import re From dbccf5a794c6a4678e4d4ac8508c52405d367f9e Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 12:01:19 -0700 Subject: [PATCH 09/37] linting Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 1 + aries_cloudagent/resolver/default/peer3.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 64d4b2cee9..84883dc97c 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -54,6 +54,7 @@ async def _resolve( def resolve_peer_did_with_service_key_reference( self, peer_did_2: Union[str, DID] ) -> DIDDocument: + """Generate a DIDDocument from the did:peer:2 based on peer-did-python library and ensure recipient key references verificationmethod in same document.""" return _resolve_peer_did_with_service_key_reference(peer_did_2) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index b6ed8232eb..656c9e932a 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -72,7 +72,6 @@ def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: def _replace_all_values(input, org, new): for k, v in input.items(): - typ = type(v) if isinstance(v,type(dict)): _replace_all_values(v, org, new) if isinstance(v,List): From 580ef8b611f7958e170805066e78f11f79f5fd76 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 12:11:23 -0700 Subject: [PATCH 10/37] found black command Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/__init__.py | 1 - aries_cloudagent/resolver/default/peer2.py | 2 +- aries_cloudagent/resolver/default/peer3.py | 24 ++++++++++--------- .../resolver/default/tests/test_peer3.py | 3 ++- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/aries_cloudagent/resolver/__init__.py b/aries_cloudagent/resolver/__init__.py index 9536c0cf1d..a72b017dbe 100644 --- a/aries_cloudagent/resolver/__init__.py +++ b/aries_cloudagent/resolver/__init__.py @@ -62,4 +62,3 @@ async def setup(context: InjectionContext): ).provide(context.settings, context.injector) await peer_did_3_resolver.setup(context) registry.register_resolver(peer_did_3_resolver) - \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 84883dc97c..378270a525 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -66,7 +66,7 @@ def _resolve_peer_did_with_service_key_reference( ## WORKAROUND LIBRARY NOT REREFERENCING RECEIPIENT_KEY services = doc.service signing_keys = [ - vm + vm for vm in doc.verification_method or [] if vm.type == "Ed25519VerificationKey2020" ] diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 656c9e932a..8361a23194 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -22,6 +22,7 @@ from ..base import BaseDIDResolver, DIDNotFound, ResolverType from .peer2 import _resolve_peer_did_with_service_key_reference + class PeerDID3Resolver(BaseDIDResolver): """Peer DID Resolver.""" @@ -70,23 +71,24 @@ def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: convert_to_did_peer_3_document(dp3, doc) return dp3, doc + def _replace_all_values(input, org, new): for k, v in input.items(): - if isinstance(v,type(dict)): - _replace_all_values(v, org, new) - if isinstance(v,List): - for i,item in enumerate(v): + if isinstance(v, type(dict)): + _replace_all_values(v, org, new) + if isinstance(v, List): + for i, item in enumerate(v): if isinstance(item, type(dict)): - _replace_all_values(item, org, new) + _replace_all_values(item, org, new) elif ( - isinstance(item, str) - or isinstance(item, DID) + isinstance(item, str) + or isinstance(item, DID) or isinstance(item, DIDUrl) ): v.pop(i) v.append(item.replace(org, new, 1)) - elif hasattr(item,"__dict__"): - _replace_all_values(item.__dict__, org, new) + elif hasattr(item, "__dict__"): + _replace_all_values(item.__dict__, org, new) else: pass @@ -95,7 +97,8 @@ def _replace_all_values(input, org, new): else: pass -def convert_to_did_peer_3_document(dp3, dp2_document:DIDDocument) -> None: + +def convert_to_did_peer_3_document(dp3, dp2_document: DIDDocument) -> None: dp2 = dp2_document.id _replace_all_values(dp2_document.__dict__, dp2, dp3) @@ -105,4 +108,3 @@ def convert_to_did_peer_3_document(dp3, dp2_document:DIDDocument) -> None: new_indexes[ind.replace(dp2, dp3)] = val dp2_document._index = new_indexes - \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index 83b1a8abc4..fd5dc58009 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -27,6 +27,7 @@ ) TEST_DP3_DOC = gen_did_peer_3(TEST_DP2)[1] + @pytest.fixture def common_resolver(): """Resolver fixture.""" @@ -97,4 +98,4 @@ async def test_supports_service_referenced( TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], document=TEST_DP3_DOC, ) - assert recipient_key \ No newline at end of file + assert recipient_key From c73715204eaf01fac54e798daba07f6e0fb7432d Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 12:20:48 -0700 Subject: [PATCH 11/37] lines to long Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 6 +++++- aries_cloudagent/resolver/default/peer3.py | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 378270a525..4bcaf3fc84 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -54,7 +54,11 @@ async def _resolve( def resolve_peer_did_with_service_key_reference( self, peer_did_2: Union[str, DID] ) -> DIDDocument: - """Generate a DIDDocument from the did:peer:2 based on peer-did-python library and ensure recipient key references verificationmethod in same document.""" + """Generate a DIDDocument from the did:peer:2 based on peer-did-python library + + And additional modification to ensure recipient key + references verificationmethod in same document. + """ return _resolve_peer_did_with_service_key_reference(peer_did_2) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 8361a23194..2e6fe9d44e 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -1,6 +1,7 @@ """Peer DID Resolver. -Resolution is performed by converting did:peer:2 to did:peer:3 according to https://identity.foundation/peer-did-method-spec/#generation-method:~:text=Method%203%3A%20DID%20Shortening%20with%20SHA%2D256%20Hash +Resolution is performed by converting did:peer:2 to did:peer:3 according to +https://identity.foundation/peer-did-method-spec/#generation-method:~:text=Method%203%3A%20DID%20Shortening%20with%20SHA%2D256%20Hash DID Document is just a did:peer:2 document (resolved by peer-did-python) where the did has been replaced. """ From 7f9a826a9a271a95ea660433a4e8019fb7100db4 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 12:25:12 -0700 Subject: [PATCH 12/37] resolver pulls directly from storage Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 2e6fe9d44e..60589346f6 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -16,10 +16,10 @@ DIDUrl, ) from peerdid.keys import to_multibase, MultibaseFormat - from ...connections.base_manager import BaseConnectionManager from ...config.injection_context import InjectionContext from ...core.profile import Profile +from ...storage.base import BaseStorage from ..base import BaseDIDResolver, DIDNotFound, ResolverType from .peer2 import _resolve_peer_did_with_service_key_reference @@ -48,12 +48,14 @@ async def _resolve( """Resolve a Key DID.""" if did.startswith("did:peer:3"): # retrieve did_doc from storage using did:peer:3 - did_doc, rec = await BaseConnectionManager(profile).fetch_did_document( - did=did - ) - assert isinstance(did_doc, DIDDocument) + async with profile.session() as session: + storage = session.inject(BaseStorage) + record = await storage.find_record( + BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, {"did": did} + ) + did_doc = DIDDocument.from_json(record.value) else: - raise DIDNotFound(f"did is not a peer did: {did}") + raise DIDNotFound(f"did is not a did:peer:3 {did}") return did_doc.dict() From 0494462a2b9566c5aab4e208bb37d37b8634d255 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 12:36:16 -0700 Subject: [PATCH 13/37] more dp3 laoding to dp3 resolver Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 22 ++++------- .../resolver/default/tests/test_peer3.py | 37 ++++++++----------- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index a3f16d0556..aaffb6d90b 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -675,21 +675,13 @@ async def fetch_did_document( Args: did: The DID to search for """ - if DID.is_valid(did): - async with self._profile.session() as session: - storage = session.inject(BaseStorage) - record = await storage.find_record( - self.RECORD_TYPE_DID_DOCUMENT, {"did": did} - ) - return ResolvedDocument.from_json(record.value), record - - else: # legacy documents for unqualified dids - async with self._profile.session() as session: - storage = session.inject(BaseStorage) - record = await storage.find_record( - self.RECORD_TYPE_DID_DOC, {"did": did} - ) - return DIDDoc.from_json(record.value), record + # legacy documents for unqualified dids + async with self._profile.session() as session: + storage = session.inject(BaseStorage) + record = await storage.find_record( + self.RECORD_TYPE_DID_DOC, {"did": did} + ) + return DIDDoc.from_json(record.value), record async def find_connection( self, diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index fd5dc58009..cf7977be1e 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -7,7 +7,7 @@ from peerdid.dids import resolve_peer_did, DIDDocument, DID import pytest -from .. import legacy_peer as test_module +from .. import peer3 as test_module from ....cache.base import BaseCache from ....cache.in_memory import InMemoryCache from ....core.in_memory import InMemoryProfile @@ -59,10 +59,10 @@ async def test_resolution_types(self, resolver: PeerDID3Resolver, profile: Profi @pytest.mark.asyncio async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" - with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: - mock_mgr.return_value = async_mock.MagicMock( - fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DP3_DOC, None) + with async_mock.patch.object(test_module, "PeerDID3Resolver") as mock_resolve: + mock_resolve.return_value = async_mock.MagicMock( + _resolve=async_mock.CoroutineMock( + return_value=TEST_DP3_DOC ) ) assert await resolver.supports(profile, TEST_DP3) @@ -73,10 +73,10 @@ async def test_supports_no_cache( ): """Test supports.""" profile.context.injector.clear_binding(BaseCache) - with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: - mock_mgr.return_value = async_mock.MagicMock( - fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DP3_DOC, None) + with async_mock.patch.object(test_module, "PeerDID3Resolver") as mock_resolve: + mock_resolve.return_value = async_mock.MagicMock( + _resolve=async_mock.CoroutineMock( + return_value=TEST_DP3_DOC ) ) assert await resolver.supports(profile, TEST_DP3) @@ -87,15 +87,10 @@ async def test_supports_service_referenced( ): """Test supports.""" profile.context.injector.clear_binding(BaseCache) - with async_mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr: - mock_mgr.return_value = async_mock.MagicMock( - fetch_did_document=async_mock.CoroutineMock( - return_value=(TEST_DP3_DOC, None) - ) - ) - recipient_key = await common_resolver.dereference( - profile, - TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], - document=TEST_DP3_DOC, - ) - assert recipient_key + + recipient_key = await common_resolver.dereference( + profile, + TEST_DP3_DOC.dict()["service"][0]["recipient_keys"][0], + document=TEST_DP3_DOC, + ) + assert recipient_key From 1404fcc475577aa09bc1eb7b490441fc8ddc6b3d Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 13:28:19 -0700 Subject: [PATCH 14/37] pytest linting.. but there is also black linting? Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 1 - aries_cloudagent/resolver/default/peer2.py | 2 +- aries_cloudagent/resolver/default/peer3.py | 8 +++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index aaffb6d90b..a5a6f92dd1 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -11,7 +11,6 @@ BaseDIDDocument as ResolvedDocument, DIDCommService, VerificationMethod, - DID, ) import pydid from pydid.verification_method import ( diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 4bcaf3fc84..75dda50dc9 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -54,7 +54,7 @@ async def _resolve( def resolve_peer_did_with_service_key_reference( self, peer_did_2: Union[str, DID] ) -> DIDDocument: - """Generate a DIDDocument from the did:peer:2 based on peer-did-python library + """Generate a DIDDocument from the did:peer:2 based on peer-did-python library. And additional modification to ensure recipient key references verificationmethod in same document. diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 60589346f6..e3976e65c9 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -2,7 +2,8 @@ Resolution is performed by converting did:peer:2 to did:peer:3 according to https://identity.foundation/peer-did-method-spec/#generation-method:~:text=Method%203%3A%20DID%20Shortening%20with%20SHA%2D256%20Hash -DID Document is just a did:peer:2 document (resolved by peer-did-python) where the did has been replaced. +DID Document is just a did:peer:2 document (resolved by peer-did-python) where +the did:peer:2 has been replaced with the did:peer:3. """ import re @@ -61,6 +62,7 @@ async def _resolve( def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: + """generate did:peer:3 and corresponding DIDDocument.""" if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") @@ -71,7 +73,7 @@ def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: dp3 = DID("did:peer:3" + content) doc = _resolve_peer_did_with_service_key_reference(peer_did_2) - convert_to_did_peer_3_document(dp3, doc) + _convert_to_did_peer_3_document(dp3, doc) return dp3, doc @@ -101,7 +103,7 @@ def _replace_all_values(input, org, new): pass -def convert_to_did_peer_3_document(dp3, dp2_document: DIDDocument) -> None: +def _convert_to_did_peer_3_document(dp3, dp2_document: DIDDocument) -> None: dp2 = dp2_document.id _replace_all_values(dp2_document.__dict__, dp2, dp3) From 76b9a410ce1f98b81226d372683483d1319ca672 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 13:32:29 -0700 Subject: [PATCH 15/37] black formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 4 +--- aries_cloudagent/resolver/default/peer2.py | 2 +- aries_cloudagent/resolver/default/tests/test_peer3.py | 8 ++------ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index a5a6f92dd1..23c63baffa 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -677,9 +677,7 @@ async def fetch_did_document( # legacy documents for unqualified dids async with self._profile.session() as session: storage = session.inject(BaseStorage) - record = await storage.find_record( - self.RECORD_TYPE_DID_DOC, {"did": did} - ) + record = await storage.find_record(self.RECORD_TYPE_DID_DOC, {"did": did}) return DIDDoc.from_json(record.value), record async def find_connection( diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 75dda50dc9..47336e6596 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -56,7 +56,7 @@ def resolve_peer_did_with_service_key_reference( ) -> DIDDocument: """Generate a DIDDocument from the did:peer:2 based on peer-did-python library. - And additional modification to ensure recipient key + And additional modification to ensure recipient key references verificationmethod in same document. """ return _resolve_peer_did_with_service_key_reference(peer_did_2) diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index cf7977be1e..f840615e43 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -61,9 +61,7 @@ async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" with async_mock.patch.object(test_module, "PeerDID3Resolver") as mock_resolve: mock_resolve.return_value = async_mock.MagicMock( - _resolve=async_mock.CoroutineMock( - return_value=TEST_DP3_DOC - ) + _resolve=async_mock.CoroutineMock(return_value=TEST_DP3_DOC) ) assert await resolver.supports(profile, TEST_DP3) @@ -75,9 +73,7 @@ async def test_supports_no_cache( profile.context.injector.clear_binding(BaseCache) with async_mock.patch.object(test_module, "PeerDID3Resolver") as mock_resolve: mock_resolve.return_value = async_mock.MagicMock( - _resolve=async_mock.CoroutineMock( - return_value=TEST_DP3_DOC - ) + _resolve=async_mock.CoroutineMock(return_value=TEST_DP3_DOC) ) assert await resolver.supports(profile, TEST_DP3) From 5f202a424f4729fff31ef9d71f450ecc44aabe5e Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 13:40:35 -0700 Subject: [PATCH 16/37] spelling police Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index e3976e65c9..a3618fa994 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -62,7 +62,7 @@ async def _resolve( def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: - """generate did:peer:3 and corresponding DIDDocument.""" + """Generate did:peer:3 and corresponding DIDDocument.""" if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") From 557df3e62b05f70317dac580e4ef0d5446923815 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 14:30:46 -0700 Subject: [PATCH 17/37] after resolving did:peer:2. alwasys save it's did:peer:3 Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 3 +- aries_cloudagent/resolver/default/peer3.py | 79 ++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 47336e6596..ef31df80e8 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -16,7 +16,7 @@ from ...config.injection_context import InjectionContext from ...core.profile import Profile from ..base import BaseDIDResolver, DIDNotFound, ResolverType - +from .peer3 import PeerDID3Resolver class PeerDID2Resolver(BaseDIDResolver): """Peer DID Resolver.""" @@ -46,6 +46,7 @@ async def _resolve( raise DIDNotFound(f"peer_did is not formatted correctly: {did}") from e if peer_did: did_doc = self.resolve_peer_did_with_service_key_reference(did) + await PeerDID3Resolver().create_and_store_document(profile, did_doc.id) else: raise DIDNotFound(f"did is not a peer did: {did}") diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index a3618fa994..e459b12177 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -9,6 +9,7 @@ import re from hashlib import sha256 from typing import Optional, Pattern, Sequence, Text, Union, Tuple, List +from multiformats import multibase, multicodec from peerdid.dids import ( DID, @@ -17,10 +18,15 @@ DIDUrl, ) from peerdid.keys import to_multibase, MultibaseFormat +from ...wallet.util import b64_to_bytes, bytes_to_b58 + from ...connections.base_manager import BaseConnectionManager from ...config.injection_context import InjectionContext from ...core.profile import Profile from ...storage.base import BaseStorage +from ...storage.error import StorageDuplicateError, StorageNotFoundError +from ...storage.record import StorageRecord + from ..base import BaseDIDResolver, DIDNotFound, ResolverType from .peer2 import _resolve_peer_did_with_service_key_reference @@ -60,6 +66,79 @@ async def _resolve( return did_doc.dict() + async def create_and_store_document(self, profile: Profile, peer_did_2: Union[str, DID]): + if not peer_did_2.startswith("did:peer:2"): + raise MalformedPeerDIDError("did:peer:2 expected") + + dp3, dp3_doc = gen_did_peer_3(peer_did_2) + + try: + async with profile.session() as session: + storage = session.inject(BaseStorage) + record = await storage.find_record( + BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, {"did": dp3} + ) + except StorageNotFoundError: + record = StorageRecord( + BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, + dp3_doc.to_json(), + {"did": dp3_doc.id}, + ) + async with profile.session() as session: + storage: BaseStorage = session.inject(BaseStorage) + await storage.add_record(record) + else: + async with profile.session() as session: + storage: BaseStorage = session.inject(BaseStorage) + await storage.update_record( + record, dp3_doc.to_json(), {"did": dp3_doc.id} + ) + await _reset_keys_from_did_doc(profile, dp3_doc) + + return dp3_doc + + +async def _reset_keys_from_did_doc(profile, did_doc): + async with profile.session() as session: + storage: BaseStorage = session.inject(BaseStorage) + await storage.delete_all_records(BaseConnectionManager.RECORD_TYPE_DID_KEY, {"did": did_doc.id}) + + for vm in did_doc.verification_method or []: + if vm.controller == did_doc.id: + if vm.public_key_base58: + await _add_key_for_did(profile, did_doc.id, vm.public_key_base58) + if vm.public_key_multibase: + pk = multibase.decode(vm.public_key_multibase) + if len(pk) == 32: # No multicodec prefix + pk = bytes_to_b58(pk) + else: + codec, key = multicodec.unwrap(pk) + if codec == multicodec.multicodec("ed25519-pub"): + pk = bytes_to_b58(key) + else: + continue + await _add_key_for_did(profile, did_doc.id, pk) + + + +async def _add_key_for_did(profile, did: str, key: str): + """Store a verkey for lookup against a DID. + + Args: + did: The DID to associate with this key + key: The verkey to be added + """ + record = StorageRecord(BaseConnectionManager.RECORD_TYPE_DID_KEY, key, {"did": did, "key": key}) + async with profile.session() as session: + storage: BaseStorage = session.inject(BaseStorage) + try: + await storage.find_record(BaseConnectionManager.RECORD_TYPE_DID_KEY, {"key": key}) + except StorageNotFoundError: + await storage.add_record(record) + except StorageDuplicateError: + pass + # "Key already associated with DID: %s; this is likely caused by " + # "routing keys being erroneously stored in the past", def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: """Generate did:peer:3 and corresponding DIDDocument.""" From 1a0dc624a73bef9cce61804fe2b9899aa20c256a Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 14:40:56 -0700 Subject: [PATCH 18/37] black formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 1 + aries_cloudagent/resolver/default/peer3.py | 27 ++++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index ef31df80e8..2bce9d4125 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -18,6 +18,7 @@ from ..base import BaseDIDResolver, DIDNotFound, ResolverType from .peer3 import PeerDID3Resolver + class PeerDID2Resolver(BaseDIDResolver): """Peer DID Resolver.""" diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index e459b12177..625a019f5f 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -66,10 +66,12 @@ async def _resolve( return did_doc.dict() - async def create_and_store_document(self, profile: Profile, peer_did_2: Union[str, DID]): + async def create_and_store_document( + self, profile: Profile, peer_did_2: Union[str, DID] + ): if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") - + dp3, dp3_doc = gen_did_peer_3(peer_did_2) try: @@ -86,7 +88,7 @@ async def create_and_store_document(self, profile: Profile, peer_did_2: Union[st ) async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) - await storage.add_record(record) + await storage.add_record(record) else: async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) @@ -101,7 +103,9 @@ async def create_and_store_document(self, profile: Profile, peer_did_2: Union[st async def _reset_keys_from_did_doc(profile, did_doc): async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) - await storage.delete_all_records(BaseConnectionManager.RECORD_TYPE_DID_KEY, {"did": did_doc.id}) + await storage.delete_all_records( + BaseConnectionManager.RECORD_TYPE_DID_KEY, {"did": did_doc.id} + ) for vm in did_doc.verification_method or []: if vm.controller == did_doc.id: @@ -115,12 +119,11 @@ async def _reset_keys_from_did_doc(profile, did_doc): codec, key = multicodec.unwrap(pk) if codec == multicodec.multicodec("ed25519-pub"): pk = bytes_to_b58(key) - else: + else: continue await _add_key_for_did(profile, did_doc.id, pk) - async def _add_key_for_did(profile, did: str, key: str): """Store a verkey for lookup against a DID. @@ -128,17 +131,21 @@ async def _add_key_for_did(profile, did: str, key: str): did: The DID to associate with this key key: The verkey to be added """ - record = StorageRecord(BaseConnectionManager.RECORD_TYPE_DID_KEY, key, {"did": did, "key": key}) + record = StorageRecord( + BaseConnectionManager.RECORD_TYPE_DID_KEY, key, {"did": did, "key": key} + ) async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) try: - await storage.find_record(BaseConnectionManager.RECORD_TYPE_DID_KEY, {"key": key}) + await storage.find_record( + BaseConnectionManager.RECORD_TYPE_DID_KEY, {"key": key} + ) except StorageNotFoundError: await storage.add_record(record) except StorageDuplicateError: pass - # "Key already associated with DID: %s; this is likely caused by " - # "routing keys being erroneously stored in the past", + # "Key already associated with DID: %s; this is likely caused by " + # "routing keys being erroneously stored in the past", def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: """Generate did:peer:3 and corresponding DIDDocument.""" From b888c4a791a09cd5e700e25b45195a24b66a45c9 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 14:44:55 -0700 Subject: [PATCH 19/37] black formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 625a019f5f..842db20589 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -67,7 +67,7 @@ async def _resolve( return did_doc.dict() async def create_and_store_document( - self, profile: Profile, peer_did_2: Union[str, DID] + self, profile: Profile, peer_did_2: Union[str, DID] ): if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") @@ -96,7 +96,7 @@ async def create_and_store_document( record, dp3_doc.to_json(), {"did": dp3_doc.id} ) await _reset_keys_from_did_doc(profile, dp3_doc) - + return dp3_doc @@ -134,7 +134,7 @@ async def _add_key_for_did(profile, did: str, key: str): record = StorageRecord( BaseConnectionManager.RECORD_TYPE_DID_KEY, key, {"did": did, "key": key} ) - async with profile.session() as session: + async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) try: await storage.find_record( @@ -147,6 +147,7 @@ async def _add_key_for_did(profile, did: str, key: str): # "Key already associated with DID: %s; this is likely caused by " # "routing keys being erroneously stored in the past", + def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: """Generate did:peer:3 and corresponding DIDDocument.""" if not peer_did_2.startswith("did:peer:2"): From bb9244b7d4d22a6431e7796cfec74362856502d7 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 14:58:04 -0700 Subject: [PATCH 20/37] issue with circular import Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 14 ++++++- aries_cloudagent/resolver/default/peer3.py | 38 +++++++------------ .../resolver/default/tests/test_peer3.py | 9 +++-- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 2bce9d4125..3f33c36123 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -11,12 +11,13 @@ resolve_peer_did, DID, DIDDocument, + MalformedPeerDIDError, ) from ...config.injection_context import InjectionContext from ...core.profile import Profile from ..base import BaseDIDResolver, DIDNotFound, ResolverType -from .peer3 import PeerDID3Resolver +from .peer3 import PeerDID3Resolver, _convert_to_did_peer_3_document class PeerDID2Resolver(BaseDIDResolver): @@ -47,7 +48,7 @@ async def _resolve( raise DIDNotFound(f"peer_did is not formatted correctly: {did}") from e if peer_did: did_doc = self.resolve_peer_did_with_service_key_reference(did) - await PeerDID3Resolver().create_and_store_document(profile, did_doc.id) + await PeerDID3Resolver().create_and_store_document(profile, did_doc) else: raise DIDNotFound(f"did is not a peer did: {did}") @@ -83,3 +84,12 @@ def _resolve_peer_did_with_service_key_reference( except Exception as e: raise ValueError("pydantic validation error:" + str(e)) return doc + +def convert_to_did_peer_3(peer_did_2: Union[str, DID]) -> DIDDocument: + """Generate did:peer:3 and corresponding DIDDocument.""" + if not peer_did_2.startswith("did:peer:2"): + raise MalformedPeerDIDError("did:peer:2 expected") + + doc = _resolve_peer_did_with_service_key_reference(peer_did_2) + _convert_to_did_peer_3_document(doc) + return doc diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 842db20589..94bb941221 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -7,6 +7,7 @@ """ import re +from copy import deepcopy from hashlib import sha256 from typing import Optional, Pattern, Sequence, Text, Union, Tuple, List from multiformats import multibase, multicodec @@ -28,7 +29,6 @@ from ...storage.record import StorageRecord from ..base import BaseDIDResolver, DIDNotFound, ResolverType -from .peer2 import _resolve_peer_did_with_service_key_reference class PeerDID3Resolver(BaseDIDResolver): @@ -67,18 +67,18 @@ async def _resolve( return did_doc.dict() async def create_and_store_document( - self, profile: Profile, peer_did_2: Union[str, DID] + self, profile: Profile, peer_did_2_doc: DIDDocument ): - if not peer_did_2.startswith("did:peer:2"): + if not peer_did_2_doc.id.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") - - dp3, dp3_doc = gen_did_peer_3(peer_did_2) - + + dp3_doc = deepcopy(peer_did_2_doc) + _convert_to_did_peer_3_document(dp3_doc) try: async with profile.session() as session: storage = session.inject(BaseStorage) record = await storage.find_record( - BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, {"did": dp3} + BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, {"did": dp3_doc.id} ) except StorageNotFoundError: record = StorageRecord( @@ -148,22 +148,6 @@ async def _add_key_for_did(profile, did: str, key: str): # "routing keys being erroneously stored in the past", -def gen_did_peer_3(peer_did_2: Union[str, DID]) -> Tuple[DID, DIDDocument]: - """Generate did:peer:3 and corresponding DIDDocument.""" - if not peer_did_2.startswith("did:peer:2"): - raise MalformedPeerDIDError("did:peer:2 expected") - - content = to_multibase( - sha256(peer_did_2.lstrip("did:peer:2").encode()).digest(), - MultibaseFormat.BASE58, - ) - dp3 = DID("did:peer:3" + content) - - doc = _resolve_peer_did_with_service_key_reference(peer_did_2) - _convert_to_did_peer_3_document(dp3, doc) - return dp3, doc - - def _replace_all_values(input, org, new): for k, v in input.items(): if isinstance(v, type(dict)): @@ -190,7 +174,12 @@ def _replace_all_values(input, org, new): pass -def _convert_to_did_peer_3_document(dp3, dp2_document: DIDDocument) -> None: +def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: + content = to_multibase( + sha256(dp2_document.id.lstrip("did:peer:2").encode()).digest(), + MultibaseFormat.BASE58, + ) + dp3 = DID("did:peer:3" + content) dp2 = dp2_document.id _replace_all_values(dp2_document.__dict__, dp2, dp3) @@ -200,3 +189,4 @@ def _convert_to_did_peer_3_document(dp3, dp2_document: DIDDocument) -> None: new_indexes[ind.replace(dp2, dp3)] = val dp2_document._index = new_indexes + return dp2_document \ No newline at end of file diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index f840615e43..f630c19bcc 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -13,7 +13,8 @@ from ....core.in_memory import InMemoryProfile from ....core.profile import Profile from ...did_resolver import DIDResolver -from ..peer3 import PeerDID3Resolver, gen_did_peer_3 +from ..peer2 import convert_to_did_peer_3 +from ..peer3 import PeerDID3Resolver TEST_DP2 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" @@ -25,7 +26,7 @@ sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(), MultibaseFormat.BASE58 ) ) -TEST_DP3_DOC = gen_did_peer_3(TEST_DP2)[1] +TEST_DP3_DOC = convert_to_did_peer_3(TEST_DP2) @pytest.fixture @@ -53,8 +54,8 @@ class TestPeerDID3Resolver: async def test_resolution_types(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" assert DID.is_valid(TEST_DP3) - assert isinstance(gen_did_peer_3(TEST_DP2)[1], DIDDocument) - assert gen_did_peer_3(TEST_DP2)[0] == TEST_DP3 + assert isinstance(convert_to_did_peer_3(TEST_DP2), DIDDocument) + assert convert_to_did_peer_3(TEST_DP2).id == TEST_DP3 @pytest.mark.asyncio async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): From 3bcd14fa8333a2ecced3a7d97b6481726dfc1e91 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 15:04:38 -0700 Subject: [PATCH 21/37] black formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 1 + aries_cloudagent/resolver/default/peer3.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 3f33c36123..70e35218a0 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -85,6 +85,7 @@ def _resolve_peer_did_with_service_key_reference( raise ValueError("pydantic validation error:" + str(e)) return doc + def convert_to_did_peer_3(peer_did_2: Union[str, DID]) -> DIDDocument: """Generate did:peer:3 and corresponding DIDDocument.""" if not peer_did_2.startswith("did:peer:2"): diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 94bb941221..7c088fdff8 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -71,7 +71,7 @@ async def create_and_store_document( ): if not peer_did_2_doc.id.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") - + dp3_doc = deepcopy(peer_did_2_doc) _convert_to_did_peer_3_document(dp3_doc) try: @@ -189,4 +189,4 @@ def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: new_indexes[ind.replace(dp2, dp3)] = val dp2_document._index = new_indexes - return dp2_document \ No newline at end of file + return dp2_document From c46a6683601270eefec6727d18fa260eebfeae0b Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 15:06:13 -0700 Subject: [PATCH 22/37] docstring Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 7c088fdff8..95823fc406 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -69,6 +69,7 @@ async def _resolve( async def create_and_store_document( self, profile: Profile, peer_did_2_doc: DIDDocument ): + """Injest did:peer:2 document create did:peer:3 and store document""" if not peer_did_2_doc.id.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") From a2be7444dcf42410e538d99d4d4198bf29d442b4 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 15:08:35 -0700 Subject: [PATCH 23/37] remove unused import Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 95823fc406..ea2a56d492 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -9,7 +9,7 @@ import re from copy import deepcopy from hashlib import sha256 -from typing import Optional, Pattern, Sequence, Text, Union, Tuple, List +from typing import Optional, Pattern, Sequence, Text, List from multiformats import multibase, multicodec from peerdid.dids import ( @@ -19,7 +19,7 @@ DIDUrl, ) from peerdid.keys import to_multibase, MultibaseFormat -from ...wallet.util import b64_to_bytes, bytes_to_b58 +from ...wallet.util import bytes_to_b58 from ...connections.base_manager import BaseConnectionManager from ...config.injection_context import InjectionContext From a260f19ad07a2dc7e439fb7b56f170f06d89df8d Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 6 Sep 2023 15:16:15 -0700 Subject: [PATCH 24/37] period Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index ea2a56d492..a29e634ad8 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -69,7 +69,7 @@ async def _resolve( async def create_and_store_document( self, profile: Profile, peer_did_2_doc: DIDDocument ): - """Injest did:peer:2 document create did:peer:3 and store document""" + """Injest did:peer:2 document create did:peer:3 and store document.""" if not peer_did_2_doc.id.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") From d779b8a1158457e1058e3c621ac62c2bff44bfff Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 08:02:23 -0700 Subject: [PATCH 25/37] convert to string to do a string replace..... Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 37 +++------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index a29e634ad8..e7a9685ea6 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -149,31 +149,6 @@ async def _add_key_for_did(profile, did: str, key: str): # "routing keys being erroneously stored in the past", -def _replace_all_values(input, org, new): - for k, v in input.items(): - if isinstance(v, type(dict)): - _replace_all_values(v, org, new) - if isinstance(v, List): - for i, item in enumerate(v): - if isinstance(item, type(dict)): - _replace_all_values(item, org, new) - elif ( - isinstance(item, str) - or isinstance(item, DID) - or isinstance(item, DIDUrl) - ): - v.pop(i) - v.append(item.replace(org, new, 1)) - elif hasattr(item, "__dict__"): - _replace_all_values(item.__dict__, org, new) - else: - pass - - elif isinstance(v, str) or isinstance(v, DID) or isinstance(v, DIDUrl): - input[k] = v.replace(org, new, 1) - else: - pass - def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: content = to_multibase( @@ -182,12 +157,8 @@ def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: ) dp3 = DID("did:peer:3" + content) dp2 = dp2_document.id - _replace_all_values(dp2_document.__dict__, dp2, dp3) - - # update document indexes - new_indexes = {} - for ind, val in dp2_document._index.items(): - new_indexes[ind.replace(dp2, dp3)] = val + dp2_doc_str = dp2_document.to_json() + dp3_doc_str = dp2_doc_str.replace(dp2,dp3) + dp3_doc = DIDDocument.from_json(dp3_doc_str) - dp2_document._index = new_indexes - return dp2_document + return dp3_doc From 07a54c0da5969044bb1d1eda060cde530334743b Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 08:09:42 -0700 Subject: [PATCH 26/37] pr feedback Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 37 ++++------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index e7a9685ea6..265117e2e2 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -30,6 +30,7 @@ from ..base import BaseDIDResolver, DIDNotFound, ResolverType +RECORD_TYPE_DID_DOCUMENT = "did_document" # pydid DIDDocument class PeerDID3Resolver(BaseDIDResolver): """Peer DID Resolver.""" @@ -58,7 +59,7 @@ async def _resolve( async with profile.session() as session: storage = session.inject(BaseStorage) record = await storage.find_record( - BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, {"did": did} + RECORD_TYPE_DID_DOCUMENT, {"did": did} ) did_doc = DIDDocument.from_json(record.value) else: @@ -79,11 +80,11 @@ async def create_and_store_document( async with profile.session() as session: storage = session.inject(BaseStorage) record = await storage.find_record( - BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, {"did": dp3_doc.id} + RECORD_TYPE_DID_DOCUMENT, {"did": dp3_doc.id} ) except StorageNotFoundError: record = StorageRecord( - BaseConnectionManager.RECORD_TYPE_DID_DOCUMENT, + RECORD_TYPE_DID_DOCUMENT, dp3_doc.to_json(), {"did": dp3_doc.id}, ) @@ -102,6 +103,7 @@ async def create_and_store_document( async def _reset_keys_from_did_doc(profile, did_doc): + conn_mgr = BaseConnectionManager(profile) async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) await storage.delete_all_records( @@ -111,7 +113,7 @@ async def _reset_keys_from_did_doc(profile, did_doc): for vm in did_doc.verification_method or []: if vm.controller == did_doc.id: if vm.public_key_base58: - await _add_key_for_did(profile, did_doc.id, vm.public_key_base58) + await conn_mgr.add_key_for_did(did_doc.id, vm.public_key_base58) if vm.public_key_multibase: pk = multibase.decode(vm.public_key_multibase) if len(pk) == 32: # No multicodec prefix @@ -122,32 +124,7 @@ async def _reset_keys_from_did_doc(profile, did_doc): pk = bytes_to_b58(key) else: continue - await _add_key_for_did(profile, did_doc.id, pk) - - -async def _add_key_for_did(profile, did: str, key: str): - """Store a verkey for lookup against a DID. - - Args: - did: The DID to associate with this key - key: The verkey to be added - """ - record = StorageRecord( - BaseConnectionManager.RECORD_TYPE_DID_KEY, key, {"did": did, "key": key} - ) - async with profile.session() as session: - storage: BaseStorage = session.inject(BaseStorage) - try: - await storage.find_record( - BaseConnectionManager.RECORD_TYPE_DID_KEY, {"key": key} - ) - except StorageNotFoundError: - await storage.add_record(record) - except StorageDuplicateError: - pass - # "Key already associated with DID: %s; this is likely caused by " - # "routing keys being erroneously stored in the past", - + await conn_mgr.add_key_for_did(did_doc.id, pk) def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: From 8248ec01f0a1e857ed7e5b6b35fa0104f4886503 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 08:10:14 -0700 Subject: [PATCH 27/37] readability Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 265117e2e2..506c1b5fda 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -134,8 +134,9 @@ def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: ) dp3 = DID("did:peer:3" + content) dp2 = dp2_document.id + dp2_doc_str = dp2_document.to_json() - dp3_doc_str = dp2_doc_str.replace(dp2,dp3) - dp3_doc = DIDDocument.from_json(dp3_doc_str) + dp3_doc_str = dp2_doc_str.replace(dp2, dp3) + dp3_doc = DIDDocument.from_json(dp3_doc_str) return dp3_doc From 61e0dd579f3165b4fd49545bdbea4d4198f6820d Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 08:12:26 -0700 Subject: [PATCH 28/37] remove unused, move a constant Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 1 - aries_cloudagent/resolver/default/peer3.py | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 23c63baffa..152022ceea 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -61,7 +61,6 @@ class BaseConnectionManager: """Class to provide utilities regarding connection_targets.""" RECORD_TYPE_DID_DOC = "did_doc" # legacy - RECORD_TYPE_DID_DOCUMENT = "did_document" # pydid DIDDocument RECORD_TYPE_DID_KEY = "did_key" def __init__(self, profile: Profile): diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 506c1b5fda..0e235e954b 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -9,14 +9,13 @@ import re from copy import deepcopy from hashlib import sha256 -from typing import Optional, Pattern, Sequence, Text, List +from typing import Optional, Pattern, Sequence, Text from multiformats import multibase, multicodec from peerdid.dids import ( DID, MalformedPeerDIDError, DIDDocument, - DIDUrl, ) from peerdid.keys import to_multibase, MultibaseFormat from ...wallet.util import bytes_to_b58 @@ -25,7 +24,7 @@ from ...config.injection_context import InjectionContext from ...core.profile import Profile from ...storage.base import BaseStorage -from ...storage.error import StorageDuplicateError, StorageNotFoundError +from ...storage.error import StorageNotFoundError from ...storage.record import StorageRecord from ..base import BaseDIDResolver, DIDNotFound, ResolverType @@ -134,7 +133,7 @@ def _convert_to_did_peer_3_document(dp2_document: DIDDocument) -> DIDDocument: ) dp3 = DID("did:peer:3" + content) dp2 = dp2_document.id - + dp2_doc_str = dp2_document.to_json() dp3_doc_str = dp2_doc_str.replace(dp2, dp3) From e51d803731cbe8153c975e7b4dc594eb30ad6136 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 08:22:12 -0700 Subject: [PATCH 29/37] return value needs to captured Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 6 +++--- aries_cloudagent/resolver/default/tests/test_peer3.py | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 70e35218a0..c6499fb9d9 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -91,6 +91,6 @@ def convert_to_did_peer_3(peer_did_2: Union[str, DID]) -> DIDDocument: if not peer_did_2.startswith("did:peer:2"): raise MalformedPeerDIDError("did:peer:2 expected") - doc = _resolve_peer_did_with_service_key_reference(peer_did_2) - _convert_to_did_peer_3_document(doc) - return doc + dp2_doc = _resolve_peer_did_with_service_key_reference(peer_did_2) + dp3_doc = _convert_to_did_peer_3_document(dp2_doc) + return dp3_doc diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index f630c19bcc..768d32c418 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -53,9 +53,10 @@ class TestPeerDID3Resolver: @pytest.mark.asyncio async def test_resolution_types(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" + dp3_doc = convert_to_did_peer_3(TEST_DP2) assert DID.is_valid(TEST_DP3) - assert isinstance(convert_to_did_peer_3(TEST_DP2), DIDDocument) - assert convert_to_did_peer_3(TEST_DP2).id == TEST_DP3 + assert isinstance(dp3_doc, DIDDocument) + assert dp3_doc.id == TEST_DP3 @pytest.mark.asyncio async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): From b50c2bd05a0ecd75df12c239997334b73d94fbcd Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 08:24:59 -0700 Subject: [PATCH 30/37] formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 0e235e954b..00c80c15cd 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -31,6 +31,7 @@ RECORD_TYPE_DID_DOCUMENT = "did_document" # pydid DIDDocument + class PeerDID3Resolver(BaseDIDResolver): """Peer DID Resolver.""" From 7ee1370d565a63c6c5a750be258624cd3cfd9226 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 09:34:48 -0700 Subject: [PATCH 31/37] revert return type Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 152022ceea..06ffa53869 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -667,7 +667,7 @@ def diddoc_connection_targets( async def fetch_did_document( self, did: str - ) -> Tuple[Union[DIDDoc, ResolvedDocument], StorageRecord]: + ) -> Tuple[DIDDoc, StorageRecord]: """Retrieve a DID Document for a given DID. Args: From 46857b8cebf15c080b348f79d13c63341f5676f6 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 09:56:28 -0700 Subject: [PATCH 32/37] remove unused Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 10 ---------- .../resolver/default/tests/test_peer3.py | 13 ++++++------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index c6499fb9d9..3a7c8b2f0d 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -84,13 +84,3 @@ def _resolve_peer_did_with_service_key_reference( except Exception as e: raise ValueError("pydantic validation error:" + str(e)) return doc - - -def convert_to_did_peer_3(peer_did_2: Union[str, DID]) -> DIDDocument: - """Generate did:peer:3 and corresponding DIDDocument.""" - if not peer_did_2.startswith("did:peer:2"): - raise MalformedPeerDIDError("did:peer:2 expected") - - dp2_doc = _resolve_peer_did_with_service_key_reference(peer_did_2) - dp3_doc = _convert_to_did_peer_3_document(dp2_doc) - return dp3_doc diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index 768d32c418..f10b5d636e 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -13,12 +13,12 @@ from ....core.in_memory import InMemoryProfile from ....core.profile import Profile from ...did_resolver import DIDResolver -from ..peer2 import convert_to_did_peer_3 -from ..peer3 import PeerDID3Resolver +from ..peer2 import _resolve_peer_did_with_service_key_reference +from ..peer3 import PeerDID3Resolver, _convert_to_did_peer_3_document TEST_DP2 = "did:peer:2.Ez6LSpkcni2KTTxf4nAp6cPxjRbu26Tj4b957BgHcknVeNFEj.Vz6MksXhfmxm2i3RnoHH2mKQcx7EY4tToJR9JziUs6bp8a6FM.SeyJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJzIjoiaHR0cDovL2hvc3QuZG9ja2VyLmludGVybmFsOjkwNzAiLCJyZWNpcGllbnRfa2V5cyI6W119" -TEST_DID0_RAW_DOC = resolve_peer_did(TEST_DP2).dict() +TEST_DID0_DOC = _resolve_peer_did_with_service_key_reference(TEST_DP2) TEST_DP3 = DID( "did:peer:3" @@ -26,7 +26,7 @@ sha256(TEST_DP2.lstrip("did:peer:2").encode()).digest(), MultibaseFormat.BASE58 ) ) -TEST_DP3_DOC = convert_to_did_peer_3(TEST_DP2) +TEST_DP3_DOC = _convert_to_did_peer_3_document(TEST_DID0_DOC) @pytest.fixture @@ -53,10 +53,9 @@ class TestPeerDID3Resolver: @pytest.mark.asyncio async def test_resolution_types(self, resolver: PeerDID3Resolver, profile: Profile): """Test supports.""" - dp3_doc = convert_to_did_peer_3(TEST_DP2) assert DID.is_valid(TEST_DP3) - assert isinstance(dp3_doc, DIDDocument) - assert dp3_doc.id == TEST_DP3 + assert isinstance(TEST_DP3_DOC, DIDDocument) + assert TEST_DP3_DOC.id == TEST_DP3 @pytest.mark.asyncio async def test_supports(self, resolver: PeerDID3Resolver, profile: Profile): From e2cb29e53966093df69902ec38fa1ee1699eb95e Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 10:00:25 -0700 Subject: [PATCH 33/37] formatting Signed-off-by: Jason Syrotuck --- aries_cloudagent/connections/base_manager.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 06ffa53869..f1d2ce9fa8 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -665,9 +665,7 @@ def diddoc_connection_targets( ) return targets - async def fetch_did_document( - self, did: str - ) -> Tuple[DIDDoc, StorageRecord]: + async def fetch_did_document(self, did: str) -> Tuple[DIDDoc, StorageRecord]: """Retrieve a DID Document for a given DID. Args: From 4518dc5ab76e7f54cce700e1cb664a078934e22b Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 10:10:59 -0700 Subject: [PATCH 34/37] linting Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer2.py | 3 +-- aries_cloudagent/resolver/default/tests/test_peer3.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer2.py b/aries_cloudagent/resolver/default/peer2.py index 3a7c8b2f0d..62520fa306 100644 --- a/aries_cloudagent/resolver/default/peer2.py +++ b/aries_cloudagent/resolver/default/peer2.py @@ -11,13 +11,12 @@ resolve_peer_did, DID, DIDDocument, - MalformedPeerDIDError, ) from ...config.injection_context import InjectionContext from ...core.profile import Profile from ..base import BaseDIDResolver, DIDNotFound, ResolverType -from .peer3 import PeerDID3Resolver, _convert_to_did_peer_3_document +from .peer3 import PeerDID3Resolver class PeerDID2Resolver(BaseDIDResolver): diff --git a/aries_cloudagent/resolver/default/tests/test_peer3.py b/aries_cloudagent/resolver/default/tests/test_peer3.py index f10b5d636e..e311ce4149 100644 --- a/aries_cloudagent/resolver/default/tests/test_peer3.py +++ b/aries_cloudagent/resolver/default/tests/test_peer3.py @@ -4,7 +4,7 @@ from peerdid.keys import to_multibase, MultibaseFormat from asynctest import mock as async_mock -from peerdid.dids import resolve_peer_did, DIDDocument, DID +from peerdid.dids import DIDDocument, DID import pytest from .. import peer3 as test_module From bf23cbfefaf44554dee8a4a6f1dfd5f1d7c5cfe6 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 11:29:53 -0700 Subject: [PATCH 35/37] simplify methods because did and did_doc are linked Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 00c80c15cd..60e86c9417 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -91,25 +91,17 @@ async def create_and_store_document( async with profile.session() as session: storage: BaseStorage = session.inject(BaseStorage) await storage.add_record(record) + await set_keys_from_did_doc(profile, dp3_doc) else: - async with profile.session() as session: - storage: BaseStorage = session.inject(BaseStorage) - await storage.update_record( - record, dp3_doc.to_json(), {"did": dp3_doc.id} - ) - await _reset_keys_from_did_doc(profile, dp3_doc) - + # If doc already exists for did:peer:3 then it cannot have been modified + pass return dp3_doc -async def _reset_keys_from_did_doc(profile, did_doc): +async def set_keys_from_did_doc(profile, did_doc): + """add verification method keys for lookup by conductor""" conn_mgr = BaseConnectionManager(profile) - async with profile.session() as session: - storage: BaseStorage = session.inject(BaseStorage) - await storage.delete_all_records( - BaseConnectionManager.RECORD_TYPE_DID_KEY, {"did": did_doc.id} - ) - + for vm in did_doc.verification_method or []: if vm.controller == did_doc.id: if vm.public_key_base58: From 3ab76efe6fe310104e809eb361ab1395647dc350 Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 11:35:05 -0700 Subject: [PATCH 36/37] asda Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 60e86c9417..3e1462e1ef 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -99,9 +99,9 @@ async def create_and_store_document( async def set_keys_from_did_doc(profile, did_doc): - """add verification method keys for lookup by conductor""" + """add verificationMethod keys for lookup by conductor""" conn_mgr = BaseConnectionManager(profile) - + for vm in did_doc.verification_method or []: if vm.controller == did_doc.id: if vm.public_key_base58: From 8a1178e6936369fb3e5f955aaae4be952279932f Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 7 Sep 2023 11:43:12 -0700 Subject: [PATCH 37/37] puncutation Signed-off-by: Jason Syrotuck --- aries_cloudagent/resolver/default/peer3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aries_cloudagent/resolver/default/peer3.py b/aries_cloudagent/resolver/default/peer3.py index 3e1462e1ef..bfe79ce15c 100644 --- a/aries_cloudagent/resolver/default/peer3.py +++ b/aries_cloudagent/resolver/default/peer3.py @@ -99,7 +99,7 @@ async def create_and_store_document( async def set_keys_from_did_doc(profile, did_doc): - """add verificationMethod keys for lookup by conductor""" + """Add verificationMethod keys for lookup by conductor.""" conn_mgr = BaseConnectionManager(profile) for vm in did_doc.verification_method or []: