Skip to content

Commit

Permalink
Merge pull request #2 from pengyuc/feature/rev-reg
Browse files Browse the repository at this point in the history
Publish revocation registry to ledger
  • Loading branch information
andrewwhitehead authored Feb 11, 2020
2 parents 3f63113 + 831a798 commit 26c8228
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 46 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,4 @@ $RECYCLE.BIN/

# Docs build
_build/
**/*.iml
34 changes: 32 additions & 2 deletions aries_cloudagent/ledger/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""Ledger base class."""

from abc import ABC, abstractmethod
from abc import ABC, abstractmethod, ABCMeta
import re
from typing import Tuple, Sequence


class BaseLedger(ABC):
class BaseLedger(ABC, metaclass=ABCMeta):
"""Base class for ledger."""

LEDGER_TYPE = None
Expand Down Expand Up @@ -86,3 +87,32 @@ async def get_latest_txn_author_acceptance(self):

def taa_digest(self, version: str, text: str):
"""Generate the digest of a TAA record."""

@abstractmethod
async def create_and_send_schema(
self, schema_name: str, schema_version: str, attribute_names: Sequence[str]
) -> Tuple[str, dict]:
"""
Send schema to ledger.
Args:
schema_name: The schema name
schema_version: The schema version
attribute_names: A list of schema attributes
"""

@abstractmethod
def get_revoc_reg_def(self, revoc_reg_id):
"""Look up a revocation registry definition by ID."""
pass

@abstractmethod
def send_revoc_reg_def(self, revoc_reg_def, issuer_did):
"""Publish a revocation registry definition to the ledger."""
pass

@abstractmethod
def send_revoc_reg_entry(self, revoc_reg_id, revoc_def_type, revoc_reg_entry, issuer_did):
"""Publish a revocation registry entry to the ledger."""
pass
13 changes: 8 additions & 5 deletions aries_cloudagent/protocols/issue_credential/v1_0/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,10 +685,13 @@ async def credential_exchange_revoke(request: web.BaseRequest):

context = request.app["request_context"]

credential_exchange_id = request.match_info["id"]
credential_exchange_record = await V10CredentialExchange.retrieve_by_id(
context, credential_exchange_id
)
try:
credential_exchange_id = request.match_info["cred_ex_id"]
credential_exchange_record = await V10CredentialExchange.retrieve_by_id(
context, credential_exchange_id
)
except StorageNotFoundError:
raise web.HTTPNotFound()

if (
credential_exchange_record.state
Expand Down Expand Up @@ -764,7 +767,7 @@ async def register(app: web.Application):
credential_exchange_store,
),
web.post(
"/issue-credential/records/{id}/revoke", credential_exchange_revoke
"/issue-credential/records/{cred_ex_id}/revoke", credential_exchange_revoke
),
web.post(
"/issue-credential/records/{cred_ex_id}/problem-report",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ async def generate_registry(self, context: InjectionContext, base_dir: str):
self.tails_local_path = self.revoc_reg_def["value"]["tailsLocation"]
await self.save(context, reason="Generated registry")

def set_tail_file_public_uri(self, tail_file_uri):
self.tails_public_uri = tail_file_uri
self.revoc_reg_def["value"]["tailsLocation"] = tail_file_uri

async def publish_registry_definition(self, context: InjectionContext):
"""Send the revocation registry definition to the ledger."""
ledger: BaseLedger = await context.inject(BaseLedger)
Expand Down
149 changes: 126 additions & 23 deletions aries_cloudagent/revocation/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,25 @@ class RevRegCreateRequestSchema(Schema):
description="Credential definition identifier", **INDY_CRED_DEF_ID
)

max_cred_num = fields.Int(
description="Maximum credential numbers", required=False
)


class RevRegCreateResultSchema(Schema):
"""Result schema for revocation registry creation request."""

result = IssuerRevocationRecordSchema()


class RevRegUpdateTailFileUriSchema(Schema):
"""Request schema for updating tail file URI."""

tails_public_uri = fields.Url(
description="Public URI to the tail file", required=True
)


@docs(tags=["revocation"], summary="Creates a new revocation registry")
@request_schema(RevRegCreateRequestSchema())
@response_schema(RevRegCreateResultSchema(), 200)
Expand All @@ -50,6 +62,7 @@ async def revocation_create_registry(request: web.BaseRequest):
body = await request.json()

credential_definition_id = body.get("credential_definition_id")
max_cred_num = body.get("max_cred_num")

# check we published this cred def
storage = await context.inject(BaseStorage)
Expand All @@ -64,7 +77,7 @@ async def revocation_create_registry(request: web.BaseRequest):
issuer_did = credential_definition_id.split(":")[0]
revoc = IndyRevocation(context)
registry_record = await revoc.init_issuer_registry(
credential_definition_id, issuer_did
credential_definition_id, issuer_did, max_cred_num=max_cred_num
)
except RevocationNotSupportedError as e:
raise web.HTTPBadRequest() from e
Expand All @@ -75,8 +88,12 @@ async def revocation_create_registry(request: web.BaseRequest):
return web.json_response({"result": registry_record.serialize()})


@docs(tags=["revocation"], summary="Get current revocation registry")
@request_schema(RevRegCreateRequestSchema())
@docs(tags=["revocation"], summary="Get current revocation registry",
parameters=[{
"in": "path",
"name": "id",
"description": "use credential definition id as the revocation registry id."
}])
@response_schema(RevRegCreateResultSchema(), 200)
async def get_current_registry(request: web.BaseRequest):
"""
Expand All @@ -91,9 +108,7 @@ async def get_current_registry(request: web.BaseRequest):
"""
context = request.app["request_context"]

body = await request.json()

credential_definition_id = body.get("credential_definition_id")
credential_definition_id = request.match_info["id"]

# check we published this cred def
storage = await context.inject(BaseStorage)
Expand All @@ -114,9 +129,62 @@ async def get_current_registry(request: web.BaseRequest):

return web.json_response({"result": registry_record.serialize()})

@docs(tags=["revocation"], summary="Get the tail file of revocation registry",
produces="application/octet-stream",
parameters=[{
"in": "path",
"name": "id",
"description": "use credential definition id as the revocation registry id."
}],
responses={
200: {
"description": "tail file",
"schema": {
"type": "file"
}
}
})
async def get_tail_file(request: web.BaseRequest) -> web.FileResponse:
"""
Request handler for getting the tail file of the revocation registry.
@docs(tags=["revocation"], summary="Publish a given revocation registry")
@request_schema(RevRegCreateRequestSchema())
Args:
request: aiohttp request object
Returns:
The tail file in FileResponse
"""
context = request.app["request_context"]

credential_definition_id = request.match_info["id"]

# check we published this cred def
storage = await context.inject(BaseStorage)
found = await storage.search_records(
type_filter=CRED_DEF_SENT_RECORD_TYPE,
tag_query={"cred_def_id": credential_definition_id},
).fetch_all()
if not found:
raise web.HTTPNotFound()

try:
revoc = IndyRevocation(context)
registry_record = await revoc.get_active_issuer_revocation_record(
credential_definition_id
)
except RevocationNotSupportedError as e:
raise web.HTTPBadRequest() from e

return web.FileResponse(path=registry_record.tails_local_path, status=200)


@docs(tags=["revocation"], summary="Publish a given revocation registry",
parameters=[{
"in": "path",
"name": "id",
"description": "use credential definition id as the revocation registry id."
}])
@response_schema(RevRegCreateResultSchema(), 200)
async def publish_registry(request: web.BaseRequest):
"""
Expand All @@ -126,16 +194,12 @@ async def publish_registry(request: web.BaseRequest):
request: aiohttp request object
Returns:
The revocation registry identifier
The revocation registry record
"""
context = request.app["request_context"]

registry_id = request.match_info["id"]

body = await request.json()

credential_definition_id = body.get("credential_definition_id")
credential_definition_id = request.match_info["id"]

# check we published this cred def
storage = await context.inject(BaseStorage)
Expand All @@ -147,27 +211,66 @@ async def publish_registry(request: web.BaseRequest):
raise web.HTTPNotFound()

try:
revoc = IndyRevocation(context)
registry_record = await revoc.get_ledger_registry(registry_id)
revoc_registry = await IndyRevocation(context).get_active_issuer_revocation_record(credential_definition_id)
except RevocationNotSupportedError as e:
raise web.HTTPBadRequest() from e

print("generated tails file")
# print(registry_record)
await registry_record.publish_registry_definition(context)
await revoc_registry.publish_registry_definition(context)
print("published registry definition")
await registry_record.publish_registry_entry(context)
await revoc_registry.publish_registry_entry(context)
print("published registry entry")

return web.json_response({"result": registry_record.serialize()})
return web.json_response({"result": revoc_registry.serialize()})


@docs(tags=["revocation"], summary="Update revocation registry with new public URI to the tail file.",
parameters=[{
"in": "path",
"name": "id",
"description": "use credential definition id as the revocation registry id."
}])
@request_schema(RevRegUpdateTailFileUriSchema())
@response_schema(RevRegCreateResultSchema(), 200)
async def update_registry(request: web.BaseRequest):
"""
Request handler for updating a revocation registry based on the registry id.
Args:
request: aiohttp request object
Returns:
The revocation registry record
"""
context = request.app["request_context"]

credential_definition_id = request.match_info["id"]

body = await request.json()

tails_public_uri = body.get("tails_public_uri")

try:
revoc = IndyRevocation(context)
registry_record = await revoc.get_active_issuer_revocation_record(
credential_definition_id
)
except RevocationNotSupportedError as e:
raise web.HTTPBadRequest() from e

registry_record.set_tail_file_public_uri(tails_public_uri)
await registry_record.save(context, reason="Updating tail file public URI.")

return web.json_response({"result": registry_record.serialize()})

async def register(app: web.Application):
"""Register routes."""
app.add_routes(
[
web.post("/revocation/create-registry", revocation_create_registry),
web.post("/revocation/get-current-registry", get_current_registry),
web.post("/revocation/records/{id}/publish", publish_registry),
web.get("/revocation/registry/{id}", get_current_registry),
web.get("/revocation/registry/{id}/tail-file", get_tail_file),
web.patch("/revocation/registry/{id}", update_registry),
web.post("/revocation/registry/{id}/publish", publish_registry),
]
)
17 changes: 17 additions & 0 deletions bin/aca-py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
import os
import sys


ENABLE_PTVSD = os.getenv("ENABLE_PTVSD", "").lower()
ENABLE_PTVSD = ENABLE_PTVSD and ENABLE_PTVSD not in ("false", "0")

ENABLE_PYDEVD_PYCHARM = os.getenv("ENABLE_PYDEVD_PYCHARM", "").lower()
ENABLE_PYDEVD_PYCHARM = ENABLE_PYDEVD_PYCHARM and ENABLE_PYDEVD_PYCHARM not in ("false", "0")
PYDEVD_PYCHARM_HOST = os.getenv("PYDEVD_PYCHARM_HOST", "localhost")
PYDEVD_PYCHARM_AGENT_PORT = int(os.getenv("PYDEVD_PYCHARM_AGENT_PORT", 5001))

# --debug-vs to use microsoft's visual studio remote debugger
if ENABLE_PTVSD or "--debug" in sys.argv:
try:
Expand All @@ -20,6 +26,17 @@ if ENABLE_PTVSD or "--debug" in sys.argv:
print("ptvsd library was not found")


if ENABLE_PYDEVD_PYCHARM or "--debug-pycharm" in sys.argv:
try:
import pydevd_pycharm

print(f"aca-py remote debugging to {PYDEVD_PYCHARM_HOST}:{PYDEVD_PYCHARM_AGENT_PORT}")
pydevd_pycharm.settrace(host=PYDEVD_PYCHARM_HOST, port=PYDEVD_PYCHARM_AGENT_PORT,
stdoutToServer=True, stderrToServer=True, suspend=False)
except ImportError:
print("pydevd_pycharm library was not found")


from aries_cloudagent.commands import run_command # noqa

if len(sys.argv) > 1 and sys.argv[1] and sys.argv[1][0] != "-":
Expand Down
Loading

0 comments on commit 26c8228

Please sign in to comment.