Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

admin api for generic tails file upload #125

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions anoncreds_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ async def main():
"maxCredNum": 10,
},
)
rev_reg_def_id = rev_reg_def["revocation_registry_definition_state"][
"revocation_registry_definition_id"
]
tails = await alice.put(
f"/anoncreds/registry/{rev_reg_def_id}/tails-file",
)
rev_status_list = await alice.post(
"/anoncreds/revocation-list",
json={
Expand Down
4 changes: 2 additions & 2 deletions aries_cloudagent/anoncreds/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
)
from .models.anoncreds_revocation import (
GetRevListResult,
AnonCredsRegistryGetRevocationRegistryDefinition,
GetRevRegDefResult,
RevRegDef,
RevRegDefResult,
RevList,
Expand Down Expand Up @@ -115,7 +115,7 @@ async def get_credential_definition(
@abstractmethod
async def get_revocation_registry_definition(
self, profile: Profile, revocation_registry_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
) -> GetRevRegDefResult:
"""Get a revocation registry definition from the registry."""

@abstractmethod
Expand Down
4 changes: 2 additions & 2 deletions aries_cloudagent/anoncreds/default/did_indy/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
)
from ...models.anoncreds_revocation import (
GetRevListResult,
AnonCredsRegistryGetRevocationRegistryDefinition,
GetRevRegDefResult,
RevRegDef,
RevRegDefResult,
RevList,
Expand Down Expand Up @@ -70,7 +70,7 @@ async def register_credential_definition(

async def get_revocation_registry_definition(
self, profile: Profile, revocation_registry_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
) -> GetRevRegDefResult:
"""Get a revocation registry definition from the registry."""
raise NotImplementedError()

Expand Down
19 changes: 4 additions & 15 deletions aries_cloudagent/anoncreds/default/did_web/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,15 @@

from ....config.injection_context import InjectionContext
from ....core.profile import Profile
from ...models.anoncreds_cred_def import (
GetCredDefResult,
)
from ...models.anoncreds_revocation import (
GetRevListResult,
AnonCredsRegistryGetRevocationRegistryDefinition,
RevRegDef,
RevList,
RevListResult,
)
from ...models.anoncreds_schema import GetSchemaResult
from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver
from ...models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult
from ...models.anoncreds_revocation import (
AnonCredsRegistryGetRevocationRegistryDefinition,
GetRevListResult,
RevRegDef,
RevRegDefResult,
GetRevRegDefResult,
RevList,
RevListResult,
RevRegDef,
RevRegDefResult,
)
from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult

Expand Down Expand Up @@ -76,7 +65,7 @@ async def register_credential_definition(

async def get_revocation_registry_definition(
self, profile: Profile, revocation_registry_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
) -> GetRevRegDefResult:
"""Get a revocation registry definition from the registry."""
raise NotImplementedError()

Expand Down
55 changes: 44 additions & 11 deletions aries_cloudagent/anoncreds/default/legacy_indy/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@
IndyLedgerRequestsExecutor,
)
from ....multitenant.base import BaseMultitenantManager
from ....revocation.anoncreds import AnonCredsRevocation
from ....revocation.models.issuer_cred_rev_record import IssuerCredRevRecord
from ....revocation.recover import generate_ledger_rrrecovery_txn
from ....storage.error import StorageNotFoundError
from ...base import (
AnonCredsObjectAlreadyExists,
AnonCredsObjectNotFound,
Expand All @@ -41,14 +39,15 @@
GetCredDefResult,
)
from ...models.anoncreds_revocation import (
AnonCredsRegistryGetRevocationRegistryDefinition,
GetRevRegDefResult,
GetRevListResult,
RevRegDef,
RevRegDefResult,
RevRegDefState,
RevList,
RevListResult,
RevListState,
RevRegDefValue,
)
from ...models.anoncreds_schema import (
AnonCredsSchema,
Expand Down Expand Up @@ -357,17 +356,51 @@ async def register_credential_definition(

async def get_revocation_registry_definition(
self, profile: Profile, rev_reg_def_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
) -> GetRevRegDefResult:
"""Get a revocation registry definition from the registry."""
async with profile.session() as session:
multitenant_mgr = session.inject_or(BaseMultitenantManager)
if multitenant_mgr:
ledger_exec_inst = IndyLedgerRequestsExecutor(profile)
else:
ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor)

try:
revoc = AnonCredsRevocation(profile)
rev_reg = await revoc.get_issuer_rev_reg_record(rev_reg_def_id)
except StorageNotFoundError as err:
raise AnonCredsResolutionError(err)
ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier(
rev_reg_def_id,
txn_record_type=GET_CRED_DEF,
)
if not ledger:
reason = "No ledger available"
if not profile.settings.get_value("wallet.type"):
reason += ": missing wallet-type?"
raise AnonCredsResolutionError(reason)

async with ledger:
rev_reg_def = await ledger.get_revoc_reg_def(rev_reg_def_id)

return rev_reg.serialize
# use AnonCredsRevocationRegistryDefinition object
if rev_reg_def is None:
raise AnonCredsObjectNotFound(
f"Revocation registry definition not found: {rev_reg_def_id}",
{"ledger_id": ledger_id},
)

LOGGER.debug("Retrieved revocation registry definition: %s", rev_reg_def)
rev_reg_def_value = RevRegDefValue.deserialize(rev_reg_def["value"])
anoncreds_rev_reg_def = RevRegDef(
issuer_id=rev_reg_def["id"].split(":")[0],
cred_def_id=rev_reg_def["credDefId"],
type=rev_reg_def["revocDefType"],
value=rev_reg_def_value,
tag=rev_reg_def["tag"],
)
result = GetRevRegDefResult(
revocation_registry=anoncreds_rev_reg_def,
revocation_registry_id=rev_reg_def["id"],
resolution_metadata={},
revocation_registry_metadata={},
)

return result

async def get_revocation_registry_definitions(self, profile: Profile, filter: str):
"""Get credential definition ids filtered by filter"""
Expand Down
2 changes: 2 additions & 0 deletions aries_cloudagent/anoncreds/issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,8 @@ async def upload_tails_file(self, rev_reg_def: RevRegDef):
f"Tails file for rev reg for {rev_reg_def.cred_def_id} "
"uploaded to wrong location: {result}"
)
# TODO: do we need to set uri? something like..
# await self.set_tails_file_public_uri(profile, result)

async def update_revocation_registry_definition_state(
self, rev_reg_def_id: str, state: str
Expand Down
14 changes: 7 additions & 7 deletions aries_cloudagent/anoncreds/models/anoncreds_revocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,13 @@ class Meta:
revocation_registry_definition_metadata = fields.Dict()


class AnonCredsRegistryGetRevocationRegistryDefinition(BaseModel):
"""AnonCredsRegistryGetRevocationRegistryDefinition"""
class GetRevRegDefResult(BaseModel):
"""GetRevRegDefResult"""

class Meta:
"""AnonCredsRegistryGetRevocationRegistryDefinition metadata."""
"""GetRevRegDefResult metadata."""

schema_class = "AnonCredsRegistryGetRevocationRegistryDefinitionSchema"
schema_class = "GetRevRegDefResultSchema"

def __init__(
self,
Expand All @@ -228,11 +228,11 @@ def __init__(
self.revocation_registry_metadata = revocation_registry_metadata


class AnonCredsRegistryGetRevocationRegistryDefinitionSchema(BaseModelSchema):
class GetRevRegDefResultSchema(BaseModelSchema):
class Meta:
"""AnonCredsRegistryGetRevocationRegistryDefinitionSchema metadata."""
"""GetRevRegDefResultSchema metadata."""

model_class = AnonCredsRegistryGetRevocationRegistryDefinition
model_class = GetRevRegDefResult
unknown = EXCLUDE

revocation_registry = fields.Nested(RevRegDefSchema())
Expand Down
4 changes: 2 additions & 2 deletions aries_cloudagent/anoncreds/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)
from .models.anoncreds_revocation import (
GetRevListResult,
AnonCredsRegistryGetRevocationRegistryDefinition,
GetRevRegDefResult,
RevRegDef,
RevRegDefResult,
RevList,
Expand Down Expand Up @@ -119,7 +119,7 @@ async def register_credential_definition(

async def get_revocation_registry_definition(
self, profile: Profile, revocation_registry_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
) -> GetRevRegDefResult:
"""Get a revocation registry definition from the registry."""
resolver = await self._resolver_for_identifier(revocation_registry_id)
return await resolver.get_revocation_registry_definition(
Expand Down
45 changes: 45 additions & 0 deletions aries_cloudagent/anoncreds/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
response_schema,
)
from marshmallow import fields
from aries_cloudagent.askar.profile import AskarProfile

from aries_cloudagent.revocation.routes import (
RevRegIdMatchInfoSchema,
RevocationModuleResponseSchema,
)

from ..admin.request_context import AdminRequestContext
from ..messaging.models.openapi import OpenAPISchema
Expand All @@ -21,6 +27,7 @@
from .issuer import AnonCredsIssuer, AnonCredsIssuerError
from .models.anoncreds_cred_def import CredDefResultSchema, GetCredDefResultSchema
from .models.anoncreds_revocation import (
RevRegDef,
RevRegDefResultSchema,
RevListResultSchema,
)
Expand Down Expand Up @@ -439,6 +446,43 @@ async def rev_list_post(request: web.BaseRequest):
return web.json_response(result.serialize())


@docs(
tags=["revocation"],
summary="Upload local tails file to server",
)
@match_info_schema(RevRegIdMatchInfoSchema())
@response_schema(RevocationModuleResponseSchema(), description="")
async def upload_tails_file(request: web.BaseRequest):
"""
Request handler to upload local tails file for revocation registry.

Args:
request: aiohttp request object

"""
context: AdminRequestContext = request["context"]
profile: AskarProfile = context.profile
anoncreds_registry: AnonCredsRegistry = context.inject(AnonCredsRegistry)
rev_reg_id = request.match_info["rev_reg_id"]
try:
issuer = AnonCredsIssuer(profile)
rev_reg_def_result = (
await anoncreds_registry.get_revocation_registry_definition(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check we're performing here should be making sure that we have the rev reg def locally so we can upload the tails file (which should also be present locally). The get_revocation_registry_definition method on the anoncreds registry retrieves a rev reg def from a remote registry though. So what I think we want is actually something more like get_created_revocation_registry_definitions, similar to the method we have for cred defs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or rather, I think I was thinking of match_created_credential_definitions

profile, rev_reg_id
)
)
rev_reg_def: RevRegDef = rev_reg_def_result.revocation_registry
# TODO: Should we check if tails file exists
except StorageNotFoundError as err: # TODO: update error
raise web.HTTPNotFound(reason=err.roll_up) from err
try:
await issuer.upload_tails_file(rev_reg_def)
except AnonCredsIssuerError as e:
raise web.HTTPInternalServerError(reason=str(e)) from e

return web.json_response({})


async def register(app: web.Application):
"""Register routes."""

Expand All @@ -460,6 +504,7 @@ async def register(app: web.Application):
),
web.post("/anoncreds/revocation-registry-definition", rev_reg_def_post),
web.post("/anoncreds/revocation-list", rev_list_post),
web.put("/anoncreds/registry/{rev_reg_id}/tails-file", upload_tails_file),
]
)

Expand Down
Loading