Skip to content

Commit

Permalink
Merge pull request #667 from sklump/endpoint-type-merge
Browse files Browse the repository at this point in the history
Endpoint type merge
  • Loading branch information
andrewwhitehead authored Aug 18, 2020
2 parents c3d12c7 + 3188a03 commit 4a80d88
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 26 deletions.
15 changes: 13 additions & 2 deletions aries_cloudagent/ledger/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from ..issuer.base import BaseIssuer

from .util import EndpointType


class BaseLedger(ABC, metaclass=ABCMeta):
"""Base class for ledger."""
Expand Down Expand Up @@ -39,20 +41,29 @@ async def get_key_for_did(self, did: str) -> str:
"""

@abstractmethod
async def get_endpoint_for_did(self, did: str) -> str:
async def get_endpoint_for_did(
self, did: str, endpoint_type: EndpointType = EndpointType.ENDPOINT
) -> str:
"""Fetch the endpoint for a ledger DID.
Args:
did: The DID to look up on the ledger or in the cache
endpoint_type: The type of the endpoint (default 'endpoint')
"""

@abstractmethod
async def update_endpoint_for_did(self, did: str, endpoint: str) -> bool:
async def update_endpoint_for_did(
self,
did: str,
endpoint: str,
endpoint_type: EndpointType = EndpointType.ENDPOINT,
) -> bool:
"""Check and update the endpoint on the ledger.
Args:
did: The ledger DID
endpoint: The endpoint address
endpoint_type: The type of the endpoint (default 'endpoint')
"""

@abstractmethod
Expand Down
61 changes: 54 additions & 7 deletions aries_cloudagent/ledger/indy.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
LedgerError,
LedgerTransactionError,
)
from .util import TAA_ACCEPTED_RECORD_TYPE
from .util import TAA_ACCEPTED_RECORD_TYPE, EndpointType


GENESIS_TRANSACTION_PATH = tempfile.gettempdir()
Expand Down Expand Up @@ -753,12 +753,41 @@ async def get_key_for_did(self, did: str) -> str:
data_json = (json.loads(response_json))["result"]["data"]
return json.loads(data_json)["verkey"] if data_json else None

async def get_endpoint_for_did(self, did: str) -> str:
async def get_all_endpoints_for_did(self, did: str) -> dict:
"""Fetch all endpoints for a ledger DID.
Args:
did: The DID to look up on the ledger or in the cache
"""
nym = self.did_to_nym(did)
public_info = await self.wallet.get_public_did()
public_did = public_info.did if public_info else None
with IndyErrorHandler("Exception when building attribute request", LedgerError):
request_json = await indy.ledger.build_get_attrib_request(
public_did, nym, "endpoint", None, None
)
response_json = await self._submit(request_json, sign_did=public_info)
data_json = json.loads(response_json)["result"]["data"]

if data_json:
endpoints = json.loads(data_json).get("endpoint", None)
else:
endpoints = None

return endpoints

async def get_endpoint_for_did(
self, did: str, endpoint_type: EndpointType = None
) -> str:
"""Fetch the endpoint for a ledger DID.
Args:
did: The DID to look up on the ledger or in the cache
endpoint_type: The type of the endpoint. If none given, returns all
"""

if not endpoint_type:
endpoint_type = EndpointType.ENDPOINT
nym = self.did_to_nym(did)
public_info = await self.wallet.get_public_did()
public_did = public_info.did if public_info else None
Expand All @@ -770,28 +799,46 @@ async def get_endpoint_for_did(self, did: str) -> str:
data_json = json.loads(response_json)["result"]["data"]
if data_json:
endpoint = json.loads(data_json).get("endpoint", None)
address = endpoint.get("endpoint", None) if endpoint else None
address = endpoint.get(endpoint_type.value, None) if endpoint else None
else:
address = None

return address

async def update_endpoint_for_did(self, did: str, endpoint: str) -> bool:
async def update_endpoint_for_did(
self, did: str, endpoint: str, endpoint_type: EndpointType = None
) -> bool:
"""Check and update the endpoint on the ledger.
Args:
did: The ledger DID
endpoint: The endpoint address
endpoint_type: The type of the endpoint
"""
exist_endpoint = await self.get_endpoint_for_did(did)
if exist_endpoint != endpoint:
if not endpoint_type:
endpoint_type = EndpointType.ENDPOINT

all_exist_endpoints = await self.get_all_endpoints_for_did(did)
exist_endpoint_of_type = (
all_exist_endpoints.get(endpoint_type.value, None)
if all_exist_endpoints
else None
)

if exist_endpoint_of_type != endpoint:
if self.read_only:
raise LedgerError(
"Error cannot update endpoint when ledger is in read only mode"
)

nym = self.did_to_nym(did)
attr_json = json.dumps({"endpoint": {"endpoint": endpoint}})

if all_exist_endpoints:
all_exist_endpoints[endpoint_type.value] = endpoint
attr_json = json.dumps({"endpoint": all_exist_endpoints})
else:
attr_json = json.dumps({"endpoint": {endpoint_type.value: endpoint}})

with IndyErrorHandler(
"Exception when building attribute request", LedgerError
):
Expand Down
21 changes: 18 additions & 3 deletions aries_cloudagent/ledger/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
from marshmallow import fields, validate

from ..messaging.models.openapi import OpenAPISchema
from ..messaging.valid import INDY_DID, INDY_RAW_PUBLIC_KEY
from ..messaging.valid import ENDPOINT_TYPE, INDY_DID, INDY_RAW_PUBLIC_KEY
from ..storage.error import StorageError
from ..wallet.error import WalletError
from .base import BaseLedger
from .indy import Role
from .error import BadLedgerRequestError, LedgerError, LedgerTransactionError

from .util import EndpointType


class AMLRecordSchema(OpenAPISchema):
"""Ledger AML record."""
Expand Down Expand Up @@ -83,6 +85,17 @@ class QueryStringDIDSchema(OpenAPISchema):
did = fields.Str(description="DID of interest", required=True, **INDY_DID)


class QueryStringEndpointSchema(OpenAPISchema):
"""Parameters and validators for query string with DID and endpoint type."""

did = fields.Str(description="DID of interest", required=True, **INDY_DID)
endpoint_type = fields.Str(
description="Endpoint type of interest (default 'endpoint')",
required=False,
**ENDPOINT_TYPE,
)


@docs(
tags=["ledger"], summary="Send a NYM registration to the ledger.",
)
Expand Down Expand Up @@ -185,7 +198,7 @@ async def get_did_verkey(request: web.BaseRequest):
@docs(
tags=["ledger"], summary="Get the endpoint for a DID from the ledger.",
)
@querystring_schema(QueryStringDIDSchema())
@querystring_schema(QueryStringEndpointSchema())
async def get_did_endpoint(request: web.BaseRequest):
"""
Request handler for getting a verkey for a DID from the ledger.
Expand All @@ -202,12 +215,14 @@ async def get_did_endpoint(request: web.BaseRequest):
raise web.HTTPForbidden(reason=reason)

did = request.query.get("did")
endpoint_type = EndpointType(request.query.get("endpoint_type", "endpoint"))

if not did:
raise web.HTTPBadRequest(reason="Request query must include DID")

async with ledger:
try:
r = await ledger.get_endpoint_for_did(did)
r = await ledger.get_endpoint_for_did(did, endpoint_type)
except LedgerError as err:
raise web.HTTPBadRequest(reason=err.roll_up) from err

Expand Down
Loading

0 comments on commit 4a80d88

Please sign in to comment.