Skip to content

Commit

Permalink
Merge pull request openwallet-foundation#110 from Indicio-tech/featur…
Browse files Browse the repository at this point in the history
…e/anoncreds-split-resolver-registrar

feat: split interface, basic impl of core registry
  • Loading branch information
dbluhm authored Mar 16, 2023
2 parents 96d3fd0 + c0097c7 commit 092b2f4
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 41 deletions.
117 changes: 104 additions & 13 deletions aries_cloudagent/anoncreds/anoncreds/anoncreds_registry.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,160 @@
"""AnonCreds Registry"""
import logging
from typing import List
from typing import List, Optional

from .base_registry import BaseRegistry
from ...config.injection_context import InjectionContext
from .base_registry import (
AnonCredsObjectNotFound,
AnonCredsRegistrationFailed,
BaseAnonCredsError,
BaseAnonCredsHandler,
BaseAnonCredsRegistrar,
BaseAnonCredsResolver,
)
from .models import (
AnonCredsRegistryGetCredentialDefinition,
AnonCredsRegistryGetRevocationList,
AnonCredsRegistryGetRevocationRegistryDefinition,
AnonCredsRegistryGetSchema,
)
from ...config.injection_context import InjectionContext


LOGGER = logging.getLogger(__name__)


class AnonCredsRegistry(BaseRegistry):
class AnonCredsRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar):
"""AnonCredsRegistry"""

def __init__(self, registries: List[BaseRegistry] = None):
def __init__(self, registries: Optional[List[BaseAnonCredsHandler]] = None):
"""Create DID Resolver."""
super().__init__(supported_identifiers=[], method_name="")
# TODO: need both supported_identifiers and method_name?
self.registries = registries or []
self.resolvers = []
self.registrars = []
if registries:
for registry in registries:
self.register(registry)

# TODO: use supported_identifier and method_name to select which registry should
# resolve or register a given object + identifier

def register_registry(self, registry: BaseRegistry):
def register(self, registry: BaseAnonCredsHandler):
"""Register a new registry."""
self.registries.append(registry)
if isinstance(registry, BaseAnonCredsResolver):
self.resolvers.append(registry)
if isinstance(registry, BaseAnonCredsRegistrar):
self.registrars.append(registry)

async def _resolvers_for_identifier(self, identifier: str):
return [
resolver
for resolver in self.resolvers
if await resolver.supports(identifier)
]

async def _registrars_for_identifiers(self, identifier: str):
return [
registrar
for registrar in self.registrars
if await registrar.supports(identifier)
]

async def setup(self, context: InjectionContext):
"""Setup method."""

async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema:
"""Get a schema from the registry."""
for resolver in await self._resolvers_for_identifier(schema_id):
try:
return await resolver.get_schema(schema_id)
except BaseAnonCredsError:
LOGGER.exception("Error getting schema from resolver")

raise AnonCredsObjectNotFound(f"{schema_id} could not be resolved")

# TODO: determine keyword arguments
async def register_schema(self):
"""Register a schema on the registry."""
for registrar in await self._registrars_for_identifiers("something"):
try:
return await registrar.register_schema()
except BaseAnonCredsError:
LOGGER.exception("Error registering schema with registrar")

raise AnonCredsRegistrationFailed("Failed to register schema")

async def get_credential_definition(
self, credential_definition_id: str
) -> AnonCredsRegistryGetCredentialDefinition:
"""Get a credential definition from the registry."""
for resolver in await self._resolvers_for_identifier(credential_definition_id):
try:
return await resolver.get_credential_definition(
credential_definition_id
)
except BaseAnonCredsError:
LOGGER.exception("Error getting credential definition from resolver")

raise AnonCredsObjectNotFound(
f"{credential_definition_id} could not be resolved"
)

# TODO: determine keyword arguments
async def register_credential_definition(self):
"""Register a credential definition on the registry."""
for registrar in await self._registrars_for_identifiers("something"):
try:
return await registrar.register_credential_definition()
except BaseAnonCredsError:
LOGGER.exception("Error registering schema with registrar")

raise AnonCredsRegistrationFailed("Failed to register credential definition")

async def get_revocation_registry_definition(
self, revocation_registry_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
"""Get a revocation registry definition from the registry."""
for resolver in await self._resolvers_for_identifier(revocation_registry_id):
try:
return await resolver.get_revocation_registry_definition(
revocation_registry_id
)
except BaseAnonCredsError:
LOGGER.exception(
"Error getting revocation registry definition from resolver"
)

raise AnonCredsObjectNotFound(f"{revocation_registry_id} could not be resolved")

# TODO: determine keyword arguments
async def register_revocation_registry_definition(self):
"""Register a revocation registry definition on the registry."""
for registrar in await self._registrars_for_identifiers("something"):
try:
return await registrar.register_revocation_registry_definition()
except BaseAnonCredsError:
LOGGER.exception("Error registering schema with registrar")

raise AnonCredsRegistrationFailed(
"Failed to register revocation registry definition"
)

async def get_revocation_list(
self, revocation_registry_id: str, timestamp: str
) -> AnonCredsRegistryGetRevocationList:
"""Get a revocation list from the registry."""
for resolver in await self._resolvers_for_identifier(revocation_registry_id):
try:
return await resolver.get_revocation_list(
revocation_registry_id, timestamp
)
except BaseAnonCredsError:
LOGGER.exception("Error getting revocation list from resolver")

raise AnonCredsObjectNotFound(f"{revocation_registry_id} could not be resolved")

# TODO: determine keyword arguments
async def register_revocation_list(self):
"""Register a revocation list on the registry."""
for registrar in await self._registrars_for_identifiers("something"):
try:
return await registrar.register_revocation_registry_definition()
except BaseAnonCredsError:
LOGGER.exception("Error registering schema with registrar")

raise AnonCredsRegistrationFailed("Failed to register revocation list")
65 changes: 43 additions & 22 deletions aries_cloudagent/anoncreds/anoncreds/base_registry.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Base Registry"""
from abc import ABC, abstractmethod
from typing import List
from ...config.injection_context import InjectionContext
from abc import ABC, abstractmethod, abstractproperty
from typing import Pattern

from ...config.injection_context import InjectionContext
from .models import (
AnonCredsRegistryGetCredentialDefinition,
AnonCredsRegistryGetRevocationList,
Expand All @@ -11,53 +11,74 @@
)


class BaseRegistry(ABC):
"""BaseRegistry"""
class BaseAnonCredsError(Exception):
"""Base error class for AnonCreds."""


class AnonCredsObjectNotFound(BaseAnonCredsError):
"""Raised when object is not found in resolver."""


class AnonCredsRegistrationFailed(BaseAnonCredsError):
"""Raised when registering an AnonCreds object fails."""

def __init__(self, supported_identifiers: List[str], method_name: str):
"""Initialize Base Registry."""

class BaseAnonCredsHandler(ABC):
@abstractproperty
def supported_identifiers_regex(self) -> Pattern:
"""Regex to match supported identifiers."""
...

async def supports(self, identifier: str) -> bool:
"""Determine whether this registry supports the given identifier."""
return bool(self.supported_identifiers_regex.match(identifier))

@abstractmethod
async def setup(self, context: InjectionContext):
"""Setup method."""


class BaseAnonCredsResolver(BaseAnonCredsHandler):
@abstractmethod
async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema:
"""Get a schema from the registry."""

# TODO: determine keyword arguments
@abstractmethod
async def register_schema(self):
"""Register a schema on the registry."""

@abstractmethod
async def get_credential_definition(
self, credential_definition_id: str
) -> AnonCredsRegistryGetCredentialDefinition:
"""Get a credential definition from the registry."""

# TODO: determine keyword arguments
@abstractmethod
async def register_credential_definition(self):
"""Register a credential definition on the registry."""

@abstractmethod
async def get_revocation_registry_definition(
self, revocation_registry_id: str
) -> AnonCredsRegistryGetRevocationRegistryDefinition:
"""Get a revocation registry definition from the registry."""

# TODO: determine keyword arguments
@abstractmethod
async def register_revocation_registry_definition(self):
"""Register a revocation registry definition on the registry."""

@abstractmethod
async def get_revocation_list(
self, revocation_registry_id: str, timestamp: str
) -> AnonCredsRegistryGetRevocationList:
"""Get a revocation list from the registry."""


class BaseAnonCredsRegistrar(BaseAnonCredsHandler):

# TODO: determine keyword arguments
@abstractmethod
async def register_schema(self):
"""Register a schema on the registry."""

# TODO: determine keyword arguments
@abstractmethod
async def register_credential_definition(self):
"""Register a credential definition on the registry."""

# TODO: determine keyword arguments
@abstractmethod
async def register_revocation_registry_definition(self):
"""Register a revocation registry definition on the registry."""

# TODO: determine keyword arguments
@abstractmethod
async def register_revocation_list(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
AnonCredsRegistryGetSchema,
)
from .....config.injection_context import InjectionContext
from ...anoncreds_registry import BaseRegistry
from ...base_registry import BaseAnonCredsResolver, BaseAnonCredsRegistrar


class DIDIndyRegistry(BaseRegistry):
class DIDIndyRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar):
"""DIDIndyRegistry"""

async def setup(self, context: InjectionContext):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
AnonCredsRegistryGetSchema,
)
from .....config.injection_context import InjectionContext
from ...anoncreds_registry import BaseRegistry
from ...base_registry import BaseAnonCredsResolver, BaseAnonCredsRegistrar


class DIDWebRegistry(BaseRegistry):
class DIDWebRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar):
"""DIDWebRegistry"""

async def setup(self, context: InjectionContext):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
AnonCredsRegistryGetSchema,
)
from .....config.injection_context import InjectionContext
from ...anoncreds_registry import BaseRegistry
from ...base_registry import BaseAnonCredsResolver, BaseAnonCredsRegistrar


class LegacyIndyRegistry(BaseRegistry):
class LegacyIndyRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar):
"""LegacyIndyRegistry"""

async def setup(self, context: InjectionContext):
Expand Down

0 comments on commit 092b2f4

Please sign in to comment.