diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 74302d3ee4..1f7584e464 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -17,5 +17,5 @@ jobs: - name: Ruff Format and Lint Check uses: chartboost/ruff-action@v1 with: - version: 0.5.7 + version: 0.8.0 args: "format --check" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9b9edb79c9..9374f5f431 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook - rev: v9.16.0 + rev: v9.18.0 hooks: - id: commitlint stages: [commit-msg] @@ -8,7 +8,7 @@ repos: additional_dependencies: ['@commitlint/config-conventional'] - repo: https://github.com/astral-sh/ruff-pre-commit # Ensure this is synced with pyproject.toml - rev: v0.5.7 + rev: v0.8.0 hooks: # Run the linter - id: ruff diff --git a/acapy_agent/__main__.py b/acapy_agent/__main__.py index bd0c964705..9669588b83 100644 --- a/acapy_agent/__main__.py +++ b/acapy_agent/__main__.py @@ -1,8 +1,11 @@ """acapy_agent package entry point.""" +import logging import os import sys +LOGGER = logging.getLogger(__name__) + def init_debug(args): """Initialize debugging environment.""" @@ -26,16 +29,18 @@ def init_debug(args): import debugpy debugpy.listen((DAP_HOST, DAP_PORT)) - print(f"=== Waiting for debugger to attach to {DAP_HOST}:{DAP_PORT} ===") + LOGGER.info( + f"=== Waiting for debugger to attach to {DAP_HOST}:{DAP_PORT} ===" + ) debugpy.wait_for_client() except ImportError: - print("debugpy library was not found") + LOGGER.error("debugpy library was not found") if ENABLE_PYDEVD_PYCHARM or "--debug-pycharm" in args: try: import pydevd_pycharm - print( + LOGGER.info( "aca-py remote debugging to " f"{PYDEVD_PYCHARM_HOST}:{PYDEVD_PYCHARM_AGENT_PORT}" ) @@ -47,7 +52,7 @@ def init_debug(args): suspend=False, ) except ImportError: - print("pydevd_pycharm library was not found") + LOGGER.error("pydevd_pycharm library was not found") def run(args): diff --git a/acapy_agent/admin/decorators/auth.py b/acapy_agent/admin/decorators/auth.py index 818f297d40..3d1f209893 100644 --- a/acapy_agent/admin/decorators/auth.py +++ b/acapy_agent/admin/decorators/auth.py @@ -1,6 +1,8 @@ """Authentication decorators for the admin API.""" import functools +import re +from typing import Optional, Pattern from aiohttp import web @@ -48,6 +50,8 @@ def tenant_authentication(handler): - check for a valid bearer token in the Autorization header if running in multi-tenant mode - check for a valid x-api-key header if running in single-tenant mode + - check if the base wallet has access to the requested path if running + in multi-tenant mode """ @functools.wraps(handler) @@ -61,11 +65,15 @@ async def tenant_auth(request): ) insecure_mode = bool(profile.settings.get("admin.admin_insecure_mode")) multitenant_enabled = profile.settings.get("multitenant.enabled") + base_wallet_allowed_route = _base_wallet_route_access( + profile.settings.get("multitenant.base_wallet_routes"), request.path + ) # CORS fix: allow OPTIONS method access to paths without a token if ( (multitenant_enabled and authorization_header) or (not multitenant_enabled and valid_key) + or (multitenant_enabled and valid_key and base_wallet_allowed_route) or insecure_mode or request.method == "OPTIONS" ): @@ -78,3 +86,25 @@ async def tenant_auth(request): ) return tenant_auth + + +def _base_wallet_route_access(additional_routes: str, request_path: str) -> bool: + """Check if request path matches additional routes.""" + additional_routes_pattern = _build_additional_routes_pattern(additional_routes) + return _matches_additional_routes(additional_routes_pattern, request_path) + + +def _build_additional_routes_pattern(pattern_string: str) -> Optional[Pattern]: + """Build pattern from space delimited list of paths.""" + # create array and add word boundary to avoid false positives + if pattern_string: + paths = pattern_string.split(" ") + return re.compile("^((?:)" + "|".join(paths) + ")$") + return None + + +def _matches_additional_routes(pattern: Pattern, path: str) -> bool: + """Matches request path to provided pattern.""" + if pattern and path: + return bool(pattern.match(path)) + return False diff --git a/acapy_agent/admin/server.py b/acapy_agent/admin/server.py index 84650ed11b..111d2f2a52 100644 --- a/acapy_agent/admin/server.py +++ b/acapy_agent/admin/server.py @@ -5,7 +5,7 @@ import re import warnings import weakref -from typing import Callable, Coroutine, Optional, Pattern, Sequence, cast +from typing import Callable, Coroutine, Optional import aiohttp_cors import jwt @@ -280,29 +280,6 @@ def __init__( self.websocket_queues = {} self.site = None self.multitenant_manager = context.inject_or(BaseMultitenantManager) - self._additional_route_pattern: Optional[Pattern] = None - - @property - def additional_routes_pattern(self) -> Optional[Pattern]: - """Pattern for configured additional routes to permit base wallet to access.""" - if self._additional_route_pattern: - return self._additional_route_pattern - - base_wallet_routes = self.context.settings.get("multitenant.base_wallet_routes") - base_wallet_routes = cast(Sequence[str], base_wallet_routes) - if base_wallet_routes: - self._additional_route_pattern = re.compile( - "^(?:" + "|".join(base_wallet_routes) + ")" - ) - return None - - def _matches_additional_routes(self, path: str) -> bool: - """Path matches additional_routes_pattern.""" - pattern = self.additional_routes_pattern - if pattern: - return bool(pattern.match(path)) - - return False async def make_application(self) -> web.Application: """Get the aiohttp application instance.""" diff --git a/acapy_agent/admin/tests/test_auth.py b/acapy_agent/admin/tests/test_auth.py index 1ebd0cd171..73680a1b00 100644 --- a/acapy_agent/admin/tests/test_auth.py +++ b/acapy_agent/admin/tests/test_auth.py @@ -133,3 +133,27 @@ async def test_multi_tenant_valid_auth_header(self): decor_func = tenant_authentication(self.decorated_handler) await decor_func(self.request) self.decorated_handler.assert_called_once_with(self.request) + + async def test_base_wallet_additional_route_allowed(self): + self.profile.settings["multitenant.base_wallet_routes"] = "/extra-route" + self.request = mock.MagicMock( + __getitem__=lambda _, k: self.request_dict[k], + headers={"x-api-key": "admin_api_key"}, + method="POST", + path="/extra-route", + ) + decor_func = tenant_authentication(self.decorated_handler) + await decor_func(self.request) + self.decorated_handler.assert_called_once_with(self.request) + + async def test_base_wallet_additional_route_denied(self): + self.profile.settings["multitenant.base_wallet_routes"] = "/extra-route" + self.request = mock.MagicMock( + __getitem__=lambda _, k: self.request_dict[k], + headers={"x-api-key": "admin_api_key"}, + method="POST", + path="/extra-route-wrong", + ) + decor_func = tenant_authentication(self.decorated_handler) + with self.assertRaises(web.HTTPUnauthorized): + await decor_func(self.request) diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index 6cb5940bb2..32c0a1c1f1 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -6,8 +6,8 @@ from ..config.injection_context import InjectionContext from ..core.error import BaseError from ..core.profile import Profile -from .models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from .models.anoncreds_revocation import ( +from .models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from .models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -15,7 +15,7 @@ RevRegDef, RevRegDefResult, ) -from .models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from .models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult T = TypeVar("T") diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 5bef819f82..388dfe5022 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -7,8 +7,8 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver -from ...models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from ...models.anoncreds_revocation import ( +from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from ...models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -16,7 +16,7 @@ RevRegDef, RevRegDefResult, ) -from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 0585e2b924..710412aa22 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -7,8 +7,8 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver -from ...models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from ...models.anoncreds_revocation import ( +from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from ...models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -16,7 +16,9 @@ RevRegDef, RevRegDefResult, ) -from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult + +LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/default/legacy_indy/recover.py b/acapy_agent/anoncreds/default/legacy_indy/recover.py index cd183adf15..4c3eaf0517 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/recover.py +++ b/acapy_agent/anoncreds/default/legacy_indy/recover.py @@ -9,7 +9,7 @@ import indy_vdr from anoncreds import RevocationRegistry, RevocationRegistryDefinition -from ...models.anoncreds_revocation import RevList +from ...models.revocation import RevList LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index 892a9d17fe..2f91937580 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -56,14 +56,14 @@ ) from ...events import RevListFinishedEvent from ...issuer import CATEGORY_CRED_DEF, AnonCredsIssuer, AnonCredsIssuerError -from ...models.anoncreds_cred_def import ( +from ...models.credential_definition import ( CredDef, CredDefResult, CredDefState, CredDefValue, GetCredDefResult, ) -from ...models.anoncreds_revocation import ( +from ...models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -74,7 +74,7 @@ RevRegDefState, RevRegDefValue, ) -from ...models.anoncreds_schema import ( +from ...models.schema import ( AnonCredsSchema, GetSchemaResult, SchemaResult, diff --git a/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py b/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py index 61c0a90f40..b504690c5e 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py +++ b/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py @@ -9,9 +9,8 @@ import pytest from anoncreds import RevocationRegistryDefinition -from acapy_agent.tests import mock - -from ....models.anoncreds_revocation import RevList, RevRegDef, RevRegDefValue +from .....tests import mock +from ....models.revocation import RevList, RevRegDef, RevRegDefValue from ..recover import ( RevocRecoveryException, _check_tails_hash_for_inconsistency, diff --git a/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py b/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py index 2b6b6c0b76..c41eb80797 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py @@ -16,25 +16,6 @@ from .....anoncreds.base import AnonCredsSchemaAlreadyExists from .....anoncreds.default.legacy_indy import registry as test_module from .....anoncreds.issuer import AnonCredsIssuer -from .....anoncreds.models.anoncreds_cred_def import ( - CredDef, - CredDefResult, - CredDefValue, - CredDefValuePrimary, -) -from .....anoncreds.models.anoncreds_revocation import ( - RevList, - RevListResult, - RevRegDef, - RevRegDefResult, - RevRegDefState, - RevRegDefValue, -) -from .....anoncreds.models.anoncreds_schema import ( - AnonCredsSchema, - GetSchemaResult, - SchemaResult, -) from .....askar.profile_anon import ( AskarAnoncredsProfileSession, ) @@ -55,6 +36,21 @@ ) from .....tests import mock from .....utils.testing import create_test_profile +from ....models.credential_definition import ( + CredDef, + CredDefResult, + CredDefValue, + CredDefValuePrimary, +) +from ....models.revocation import ( + RevList, + RevListResult, + RevRegDef, + RevRegDefResult, + RevRegDefState, + RevRegDefValue, +) +from ....models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult B58 = alphabet if isinstance(alphabet, str) else alphabet.decode("ascii") INDY_DID = rf"^(did:sov:)?[{B58}]{{21,22}}$" diff --git a/acapy_agent/anoncreds/events.py b/acapy_agent/anoncreds/events.py index 4511b546f7..98477bf4e1 100644 --- a/acapy_agent/anoncreds/events.py +++ b/acapy_agent/anoncreds/events.py @@ -4,7 +4,7 @@ from typing import NamedTuple, Optional from ..core.event_bus import Event -from .models.anoncreds_revocation import RevRegDef +from .models.revocation import RevRegDef CRED_DEF_FINISHED_EVENT = "anoncreds::credential-definition::finished" REV_REG_DEF_FINISHED_EVENT = "anoncreds::revocation-registry-definition::finished" diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index ae14e4be5d..6da4456c72 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -23,7 +23,6 @@ from pyld.jsonld import JsonLdProcessor from uuid_utils import uuid4 -from ..anoncreds.models.anoncreds_schema import AnonCredsSchema from ..askar.profile_anon import AskarAnoncredsProfile from ..core.error import BaseError from ..core.profile import Profile @@ -33,7 +32,8 @@ from ..vc.vc_ld import VerifiableCredential from ..wallet.error import WalletNotFoundError from .error_messages import ANONCREDS_PROFILE_REQUIRED_MSG -from .models.anoncreds_cred_def import CredDef +from .models.credential_definition import CredDef +from .models.schema import AnonCredsSchema from .registry import AnonCredsRegistry LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/issuer.py b/acapy_agent/anoncreds/issuer.py index ad79173e16..6dc3fababa 100644 --- a/acapy_agent/anoncreds/issuer.py +++ b/acapy_agent/anoncreds/issuer.py @@ -24,8 +24,8 @@ from .base import AnonCredsSchemaAlreadyExists, BaseAnonCredsError from .error_messages import ANONCREDS_PROFILE_REQUIRED_MSG from .events import CredDefFinishedEvent -from .models.anoncreds_cred_def import CredDef, CredDefResult -from .models.anoncreds_schema import AnonCredsSchema, SchemaResult, SchemaState +from .models.credential_definition import CredDef, CredDefResult +from .models.schema import AnonCredsSchema, SchemaResult, SchemaState from .registry import AnonCredsRegistry LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/models/credential.py b/acapy_agent/anoncreds/models/credential.py new file mode 100644 index 0000000000..c008fc16c7 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential.py @@ -0,0 +1,167 @@ +"""Credential artifacts.""" + +from typing import Mapping, Optional + +from marshmallow import EXCLUDE, ValidationError, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ANONCREDS_REV_REG_ID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, + NUM_STR_ANY_EXAMPLE, + NUM_STR_ANY_VALIDATE, +) + + +class AnoncredsAttrValue(BaseModel): + """Anoncreds attribute value.""" + + class Meta: + """Anoncreds attribute value.""" + + schema_class = "AnoncredsAttrValueSchema" + + def __init__( + self, raw: Optional[str] = None, encoded: Optional[str] = None, **kwargs + ): + """Initialize anoncreds (credential) attribute value.""" + super().__init__(**kwargs) + self.raw = raw + self.encoded = encoded + + +class AnoncredsAttrValueSchema(BaseModelSchema): + """Anoncreds attribute value schema.""" + + class Meta: + """Anoncreds attribute value schema metadata.""" + + model_class = AnoncredsAttrValue + unknown = EXCLUDE + + raw = fields.Str(required=True, metadata={"description": "Attribute raw value"}) + encoded = fields.Str( + required=True, + validate=NUM_STR_ANY_VALIDATE, + metadata={ + "description": "Attribute encoded value", + "example": NUM_STR_ANY_EXAMPLE, + }, + ) + + +class DictWithAnoncredsAttrValueSchema(fields.Dict): + """Dict with anoncreds attribute value schema.""" + + def __init__(self, **kwargs): + """Initialize the custom schema for a dictionary with AnoncredsAttrValue.""" + super().__init__( + keys=fields.Str(metadata={"description": "Attribute name"}), + values=fields.Nested(AnoncredsAttrValueSchema()), + **kwargs, + ) + + def _deserialize(self, value, attr, data, **kwargs): + """Deserialize dict with anoncreds attribute value.""" + if not isinstance(value, dict): + raise ValidationError("Value must be a dict.") + + errors = {} + anoncreds_attr_value_schema = AnoncredsAttrValueSchema() + + for k, v in value.items(): + if isinstance(v, dict): + validation_errors = anoncreds_attr_value_schema.validate(v) + if validation_errors: + errors[k] = validation_errors + + if errors: + raise ValidationError(errors) + + return value + + +class AnoncredsCredential(BaseModel): + """Anoncreds credential.""" + + class Meta: + """Anoncreds credential metadata.""" + + schema_class = "AnoncredsCredentialSchema" + + def __init__( + self, + schema_id: Optional[str] = None, + cred_def_id: Optional[str] = None, + rev_reg_id: Optional[str] = None, + values: Mapping[str, AnoncredsAttrValue] = None, + signature: Optional[Mapping] = None, + signature_correctness_proof: Optional[Mapping] = None, + rev_reg: Optional[Mapping] = None, + witness: Optional[Mapping] = None, + ): + """Initialize anoncreds credential.""" + self.schema_id = schema_id + self.cred_def_id = cred_def_id + self.rev_reg_id = rev_reg_id + self.values = values + self.signature = signature + self.signature_correctness_proof = signature_correctness_proof + self.rev_reg = rev_reg + self.witness = witness + + +class AnoncredsCredentialSchema(BaseModelSchema): + """Anoncreds credential schema.""" + + class Meta: + """Anoncreds credential schemametadata.""" + + model_class = AnoncredsCredential + unknown = EXCLUDE + + schema_id = fields.Str( + required=True, + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + cred_def_id = fields.Str( + required=True, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + rev_reg_id = fields.Str( + allow_none=True, + validate=ANONCREDS_REV_REG_ID_VALIDATE, + metadata={ + "description": "Revocation registry identifier", + "example": ANONCREDS_REV_REG_ID_EXAMPLE, + }, + ) + values = DictWithAnoncredsAttrValueSchema( + required=True, + metadata={"description": "Credential attributes"}, + ) + signature = fields.Dict( + required=True, metadata={"description": "Credential signature"} + ) + signature_correctness_proof = fields.Dict( + required=True, + metadata={"description": "Credential signature correctness proof"}, + ) + rev_reg = fields.Dict( + allow_none=True, metadata={"description": "Revocation registry state"} + ) + witness = fields.Dict( + allow_none=True, metadata={"description": "Witness for revocation proof"} + ) diff --git a/acapy_agent/anoncreds/models/anoncreds_cred_def.py b/acapy_agent/anoncreds/models/credential_definition.py similarity index 97% rename from acapy_agent/anoncreds/models/anoncreds_cred_def.py rename to acapy_agent/anoncreds/models/credential_definition.py index 17d41098e7..4e543eaf57 100644 --- a/acapy_agent/anoncreds/models/anoncreds_cred_def.py +++ b/acapy_agent/anoncreds/models/credential_definition.py @@ -9,9 +9,9 @@ from ...messaging.models.base import BaseModel, BaseModelSchema from ...messaging.valid import ( - INDY_CRED_DEF_ID_EXAMPLE, - INDY_OR_KEY_DID_EXAMPLE, - INDY_SCHEMA_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, NUM_STR_WHOLE_EXAMPLE, NUM_STR_WHOLE_VALIDATE, ) @@ -256,7 +256,7 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) @@ -264,7 +264,7 @@ class Meta: data_key="schemaId", metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, }, ) type = fields.Str(validate=OneOf(["CL"])) @@ -333,7 +333,7 @@ class Meta: credential_definition_id = fields.Str( metadata={ "description": "credential definition id", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, allow_none=True, ) @@ -434,7 +434,7 @@ class Meta: credential_definition_id = fields.Str( metadata={ "description": "credential definition id", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, ) credential_definition = fields.Nested( diff --git a/acapy_agent/anoncreds/models/credential_offer.py b/acapy_agent/anoncreds/models/credential_offer.py new file mode 100644 index 0000000000..c77419eba3 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential_offer.py @@ -0,0 +1,149 @@ +"""Anoncreds Credential Offer format for v2.0 of the issue-credential protocol.""" + +from typing import Optional, Sequence + +from marshmallow import EXCLUDE, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, +) + + +class AnoncredsKeyCorrectnessProof(BaseModel): + """Anoncreds key correctness proof.""" + + class Meta: + """AnoncredsKeyCorrectnessProof metadata.""" + + schema_class = "AnoncredsKeyCorrectnessProofSchema" + + def __init__( + self, + c: Optional[str] = None, + xz_cap: Optional[str] = None, + xr_cap: Sequence[Sequence[str]] = None, + **kwargs, + ): + """Initialize XR cap for anoncreds key correctness proof.""" + super().__init__(**kwargs) + + self.c = c + self.xz_cap = xz_cap + self.xr_cap = xr_cap + + +class AnoncredsCorrectnessProofSchema(BaseModelSchema): + """Anoncreds key correctness proof schema.""" + + class Meta: + """Anoncreds key correctness proof schema metadata.""" + + model_class = AnoncredsKeyCorrectnessProof + unknown = EXCLUDE + + c = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "c in key correctness proof", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) + xz_cap = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "xz_cap in key correctness proof", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) + xr_cap = fields.List( + fields.List( + fields.Str( + required=True, + metadata={ + "description": "xr_cap component values in key correctness proof" + }, + ), + required=True, + metadata={ + "description": "xr_cap components in key correctness proof", + "many": True, + }, + ), + required=True, + metadata={"description": "xr_cap in key correctness proof", "many": True}, + ) + + +class AnoncredsCredentialOffer(BaseModel): + """Anoncreds Credential Offer.""" + + class Meta: + """AnoncredsCredentialOffer metadata.""" + + schema_class = "AnoncredsCredentialOfferSchema" + + def __init__( + self, + schema_id: Optional[str] = None, + cred_def_id: Optional[str] = None, + nonce: Optional[str] = None, + key_correctness_proof: Optional[str] = None, + **kwargs, + ): + """Initialize values .""" + super().__init__(**kwargs) + self.schema_id = schema_id + self.cred_def_id = cred_def_id + self.nonce = nonce + self.key_correctness_proof = key_correctness_proof + + +class AnoncredsCredentialOfferSchema(BaseModelSchema): + """Anoncreds Credential Offer Schema.""" + + class Meta: + """AnoncredsCredentialOffer schema metadata.""" + + model_class = AnoncredsCredentialOffer + unknown = EXCLUDE + + schema_id = fields.Str( + required=True, + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + + cred_def_id = fields.Str( + required=True, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + + nonce = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "Nonce in credential abstract", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) + + key_correctness_proof = fields.Nested( + AnoncredsCorrectnessProofSchema(), + required=True, + metadata={"description": "Key correctness proof"}, + ) diff --git a/acapy_agent/anoncreds/models/credential_proposal.py b/acapy_agent/anoncreds/models/credential_proposal.py new file mode 100644 index 0000000000..3d41d08747 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential_proposal.py @@ -0,0 +1,58 @@ +"""Anoncreds credential definition proposal.""" + +import re + +from marshmallow import fields + +from ...core.profile import Profile +from ...messaging.models.openapi import OpenAPISchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_DID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, +) + + +class AnoncredsCredentialDefinitionProposal(OpenAPISchema): + """Query string parameters for credential definition searches.""" + + schema_id = fields.Str( + required=False, + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + issuer_id = fields.Str( + required=False, + validate=ANONCREDS_DID_VALIDATE, + metadata={"description": "Issuer DID", "example": ANONCREDS_DID_EXAMPLE}, + ) + cred_def_id = fields.Str( + required=False, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition id", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + + +CRED_DEF_TAGS = list( + vars(AnoncredsCredentialDefinitionProposal).get("_declared_fields", []) +) + +CRED_DEF_EVENT_PREFIX = "acapy::CRED_DEF::" +EVENT_LISTENER_PATTERN = re.compile(f"^{CRED_DEF_EVENT_PREFIX}(.*)?$") + + +async def notify_cred_def_event(profile: Profile, cred_def_id: str, meta_data: dict): + """Send notification for a cred def post-process event.""" + await profile.notify( + CRED_DEF_EVENT_PREFIX + cred_def_id, + meta_data, + ) diff --git a/acapy_agent/anoncreds/models/credential_request.py b/acapy_agent/anoncreds/models/credential_request.py new file mode 100644 index 0000000000..49fd58e996 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential_request.py @@ -0,0 +1,81 @@ +"""Cred request artifacts to attach to RFC 453 messages.""" + +from typing import Mapping, Optional + +from marshmallow import EXCLUDE, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, + UUID4_EXAMPLE, +) + + +class AnoncredsCredRequest(BaseModel): + """Anoncreds credential request.""" + + class Meta: + """Anoncreds credential request metadata.""" + + schema_class = "AnoncredsCredRequestSchema" + + def __init__( + self, + prover_did: Optional[str] = None, + cred_def_id: Optional[str] = None, + blinded_ms: Optional[Mapping] = None, + blinded_ms_correctness_proof: Optional[Mapping] = None, + nonce: Optional[str] = None, + **kwargs, + ): + """Initialize anoncreds credential request.""" + super().__init__(**kwargs) + self.prover_did = prover_did + self.cred_def_id = cred_def_id + self.blinded_ms = blinded_ms + self.blinded_ms_correctness_proof = blinded_ms_correctness_proof + self.nonce = nonce + + +class AnoncredsCredRequestSchema(BaseModelSchema): + """Anoncreds credential request schema.""" + + class Meta: + """Anoncreds credential request schema metadata.""" + + model_class = AnoncredsCredRequest + unknown = EXCLUDE + + prover_did = fields.Str( + required=True, + metadata={ + "description": "Prover DID/Random String/UUID", + "example": UUID4_EXAMPLE, + }, + ) + cred_def_id = fields.Str( + required=True, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + blinded_ms = fields.Dict( + required=True, metadata={"description": "Blinded master secret"} + ) + blinded_ms_correctness_proof = fields.Dict( + required=True, + metadata={"description": "Blinded master secret correctness proof"}, + ) + nonce = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "Nonce in credential request", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) diff --git a/acapy_agent/anoncreds/models/non_rev_interval.py b/acapy_agent/anoncreds/models/non_rev_interval.py new file mode 100644 index 0000000000..a224891189 --- /dev/null +++ b/acapy_agent/anoncreds/models/non_rev_interval.py @@ -0,0 +1,78 @@ +"""Anoncreds non-revocation interval.""" + +from time import time +from typing import Optional + +from marshmallow import EXCLUDE, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE + + +class AnoncredsNonRevocationInterval(BaseModel): + """Anoncreds non-revocation interval.""" + + class Meta: + """NonRevocationInterval metadata.""" + + schema_class = "AnoncredsNonRevocationIntervalSchema" + + def __init__(self, fro: Optional[int] = None, to: Optional[int] = None, **kwargs): + """Initialize non-revocation interval. + + Args: + fro: earliest time of interest + to: latest time of interest + kwargs: additional attributes + + """ + super().__init__(**kwargs) + self.fro = fro + self.to = to + + def covers(self, timestamp: Optional[int] = None) -> bool: + """Whether input timestamp (default now) lies within non-revocation interval. + + Args: + timestamp: time of interest + + Returns: + whether input time satisfies non-revocation interval + + """ + timestamp = timestamp or int(time()) + return (self.fro or 0) <= timestamp <= (self.to or timestamp) + + def timestamp(self) -> bool: + """Return a timestamp that the non-revocation interval covers.""" + return self.to or self.fro or int(time()) + + +class AnoncredsNonRevocationIntervalSchema(BaseModelSchema): + """Schema to allow serialization/deserialization of non-revocation intervals.""" + + class Meta: + """AnoncredsNonRevocationIntervalSchema metadata.""" + + model_class = AnoncredsNonRevocationInterval + unknown = EXCLUDE + + fro = fields.Int( + required=False, + data_key="from", + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": "Earliest time of interest in non-revocation interval", + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ) + to = fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": "Latest time of interest in non-revocation interval", + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ) diff --git a/acapy_agent/anoncreds/models/predicate.py b/acapy_agent/anoncreds/models/predicate.py new file mode 100644 index 0000000000..9810a7bb78 --- /dev/null +++ b/acapy_agent/anoncreds/models/predicate.py @@ -0,0 +1,82 @@ +"""Utilities for dealing with predicates.""" + +from collections import namedtuple +from enum import Enum +from typing import Any + +Relation = namedtuple("Relation", "fortran wql math yes no") + + +class Predicate(Enum): + """Enum for predicate types that anoncreds-sdk supports.""" + + LT = Relation( + "LT", + "$lt", + "<", + lambda x, y: Predicate.to_int(x) < Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) >= Predicate.to_int(y), + ) + LE = Relation( + "LE", + "$lte", + "<=", + lambda x, y: Predicate.to_int(x) <= Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) > Predicate.to_int(y), + ) + GE = Relation( + "GE", + "$gte", + ">=", + lambda x, y: Predicate.to_int(x) >= Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) < Predicate.to_int(y), + ) + GT = Relation( + "GT", + "$gt", + ">", + lambda x, y: Predicate.to_int(x) > Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) <= Predicate.to_int(y), + ) + + @property + def fortran(self) -> str: + """Fortran nomenclature.""" + return self.value.fortran + + @property + def wql(self) -> str: + """WQL nomenclature.""" + return self.value.wql + + @property + def math(self) -> str: + """Mathematical nomenclature.""" + return self.value.math + + @staticmethod + def get(relation: str) -> "Predicate": + """Return enum instance corresponding to input relation string.""" + + for pred in Predicate: + if relation.upper() in ( + pred.value.fortran, + pred.value.wql.upper(), + pred.value.math, + ): + return pred + return None + + @staticmethod + def to_int(value: Any) -> int: + """Cast a value as its equivalent int for anoncreds predicate argument. + + Raise ValueError for any input but int, stringified int, or boolean. + + Args: + value: value to coerce + """ + + if isinstance(value, (bool, int)): + return int(value) + return int(str(value)) # kick out floats diff --git a/acapy_agent/anoncreds/models/presentation_request.py b/acapy_agent/anoncreds/models/presentation_request.py new file mode 100644 index 0000000000..05881dfdc8 --- /dev/null +++ b/acapy_agent/anoncreds/models/presentation_request.py @@ -0,0 +1,306 @@ +"""Classes to represent anoncreds presentation request.""" + +from typing import Mapping, Optional + +from marshmallow import ( + EXCLUDE, + Schema, + ValidationError, + fields, + validate, + validates_schema, +) + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.models.openapi import OpenAPISchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + INT_EPOCH_EXAMPLE, + INT_EPOCH_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, + NUM_STR_NATURAL_EXAMPLE, + NUM_STR_NATURAL_VALIDATE, + PREDICATE_EXAMPLE, + PREDICATE_VALIDATE, +) + + +class AnoncredsPresentationReqPredSpecSchema(OpenAPISchema): + """Schema for predicate specification in anoncreds proof request.""" + + name = fields.Str( + required=True, metadata={"example": "index", "description": "Attribute name"} + ) + p_type = fields.Str( + required=True, + validate=PREDICATE_VALIDATE, + metadata={ + "description": "Predicate type ('<', '<=', '>=', or '>')", + "example": PREDICATE_EXAMPLE, + }, + ) + p_value = fields.Int( + required=True, metadata={"description": "Threshold value", "strict": True} + ) + restrictions = fields.List( + fields.Dict( + keys=fields.Str( + validate=validate.Regexp( + "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" + "cred_def_id|attr::.+::value$" + ), + metadata={"example": "cred_def_id"}, + ), + values=fields.Str(metadata={"example": ANONCREDS_CRED_DEF_ID_EXAMPLE}), + ), + required=False, + metadata={ + "description": ( + "If present, credential must satisfy one of given restrictions: specify" + " schema_id, schema_issuer_did, schema_name, schema_version," + " issuer_did, cred_def_id, and/or attr::::value where" + " represents a credential attribute name" + ) + }, + ) + non_revoked = fields.Nested( + Schema.from_dict( + { + "from": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Earliest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + "to": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Latest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + }, + name="AnoncredsPresentationReqPredSpecNonRevokedSchema", + ), + allow_none=True, + required=False, + ) + + +class AnoncredsPresentationReqAttrSpecSchema(OpenAPISchema): + """Schema for attribute specification in anoncreds proof request.""" + + name = fields.Str( + required=False, + metadata={"example": "favouriteDrink", "description": "Attribute name"}, + ) + names = fields.List( + fields.Str(metadata={"example": "age"}), + required=False, + metadata={"description": "Attribute name group"}, + ) + restrictions = fields.List( + fields.Dict( + keys=fields.Str( + validate=validate.Regexp( + "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" + "cred_def_id|attr::.+::value$" + ), + metadata={"example": "cred_def_id"}, + ), + values=fields.Str(metadata={"example": ANONCREDS_CRED_DEF_ID_EXAMPLE}), + ), + required=False, + metadata={ + "description": ( + "If present, credential must satisfy one of given restrictions: specify" + " schema_id, schema_issuer_did, schema_name, schema_version," + " issuer_did, cred_def_id, and/or attr::::value where" + " represents a credential attribute name" + ) + }, + ) + non_revoked = fields.Nested( + Schema.from_dict( + { + "from": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Earliest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + "to": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Latest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + }, + name="AnoncredsPresentationReqAttrSpecNonRevokedSchema", + ), + allow_none=True, + required=False, + ) + + @validates_schema + def validate_fields(self, data, **kwargs): + """Validate schema fields. + + Data must have exactly one of name or names; if names then restrictions are + mandatory. + + Args: + data: The data to validate + kwargs: Additional keyword arguments + + Raises: + ValidationError: if data has both or neither of name and names + + """ + if ("name" in data) == ("names" in data): + raise ValidationError( + "Attribute specification must have either name or names but not both" + ) + restrictions = data.get("restrictions") + if ("names" in data) and (not restrictions or all(not r for r in restrictions)): + raise ValidationError( + "Attribute specification on 'names' must have non-empty restrictions" + ) + + +class AnoncredsPresentationRequest(BaseModel): + """anoncreds proof request.""" + + class Meta: + """Anoncreds proof request metadata.""" + + schema_class = "AnoncredsPresentationRequestSchema" + + def __init__( + self, + nonce: Optional[str] = None, + name: Optional[str] = None, + version: Optional[str] = None, + requested_attributes: Optional[Mapping] = None, + requested_predicates: Optional[Mapping] = None, + non_revoked: Optional[Mapping] = None, + **kwargs, + ): + """Initialize anoncreds cred abstract object. + + Args: + nonce (str): The nonce value. + name (str): The name of the proof request. + version (str): The version of the proof request. + requested_attributes (Mapping): A mapping of attribute names to attribute + constraints. + requested_predicates (Mapping): A mapping of predicate names to predicate + constraints. + non_revoked (Mapping): A mapping of non-revocation timestamps. + kwargs: Keyword arguments for BaseModel + + """ + super().__init__(**kwargs) + self.nonce = nonce + self.name = name + self.version = version + self.requested_attributes = requested_attributes + self.requested_predicates = requested_predicates + self.non_revoked = non_revoked + + +class AnoncredsPresentationRequestSchema(BaseModelSchema): + """Schema for anoncreds proof request.""" + + class Meta: + """Anoncreds proof request schema metadata.""" + + model_class = AnoncredsPresentationRequest + unknown = EXCLUDE + + nonce = fields.Str( + required=False, + validate=NUM_STR_NATURAL_VALIDATE, + metadata={"description": "Nonce", "example": NUM_STR_NATURAL_EXAMPLE}, + ) + name = fields.Str( + required=False, + dump_default="Proof request", + metadata={"description": "Proof request name", "example": "Proof request"}, + ) + version = fields.Str( + required=False, + dump_default="1.0", + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Proof request version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, + ) + requested_attributes = fields.Dict( + required=True, + keys=fields.Str( + metadata={"decription": "Attribute referent", "example": "0_legalname_uuid"} + ), + values=fields.Nested(AnoncredsPresentationReqAttrSpecSchema()), + metadata={"description": "Requested attribute specifications of proof request"}, + ) + requested_predicates = fields.Dict( + required=True, + keys=fields.Str( + metadata={"description": "Predicate referent", "example": "0_age_GE_uuid"} + ), + values=fields.Nested(AnoncredsPresentationReqPredSpecSchema()), + metadata={"description": "Requested predicate specifications of proof request"}, + ) + non_revoked = fields.Nested( + Schema.from_dict( + { + "from": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Earliest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + "to": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Latest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + }, + name="AnoncredPresentationRequestNonRevokedSchema", + ), + allow_none=True, + required=False, + ) diff --git a/acapy_agent/anoncreds/models/proof.py b/acapy_agent/anoncreds/models/proof.py new file mode 100644 index 0000000000..817b947cc5 --- /dev/null +++ b/acapy_agent/anoncreds/models/proof.py @@ -0,0 +1,749 @@ +"""Marshmallow bindings for anoncreds proofs.""" + +from typing import Mapping, Optional, Sequence + +from marshmallow import EXCLUDE, fields, validate + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ANONCREDS_REV_REG_ID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, + INT_EPOCH_EXAMPLE, + INT_EPOCH_VALIDATE, + NUM_STR_ANY_EXAMPLE, + NUM_STR_ANY_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, +) +from ...utils.tracing import AdminAPIMessageTracingSchema +from .predicate import Predicate +from .requested_credentials import ( + AnoncredsRequestedCredsRequestedAttrSchema, + AnoncredsRequestedCredsRequestedPredSchema, +) + + +class AnoncredsEQProof(BaseModel): + """Equality proof for anoncreds primary proof.""" + + class Meta: + """Equality proof metadata.""" + + schema_class = "AnoncredsEQProofMeta" + + def __init__( + self, + revealed_attrs: Mapping[str, str] = None, + a_prime: Optional[str] = None, + e: Optional[str] = None, + v: Optional[str] = None, + m: Mapping[str, str] = None, + m2: Optional[str] = None, + **kwargs, + ): + """Initialize equality proof object.""" + super().__init__(**kwargs) + self.revealed_attrs = revealed_attrs + self.a_prime = a_prime + self.e = e + self.v = v + self.m = m + self.m2 = m2 + + +class AnoncredsEQProofSchema(BaseModelSchema): + """Anoncreds equality proof schema.""" + + class Meta: + """Anoncreds equality proof metadata.""" + + model_class = AnoncredsEQProof + unknown = EXCLUDE + + revealed_attrs = fields.Dict( + keys=fields.Str(metadata={"example": "preference"}), + values=fields.Str( + validate=NUM_STR_ANY_VALIDATE, metadata={"example": NUM_STR_ANY_EXAMPLE} + ), + ) + a_prime = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + e = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + v = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + m = fields.Dict( + keys=fields.Str(metadata={"example": "master_secret"}), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + m2 = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + + +class AnoncredsGEProofPred(BaseModel): + """Anoncreds GE proof predicate.""" + + class Meta: + """Anoncreds GE proof predicate metadata.""" + + schema_class = "AnoncredsGEProofPredSchema" + + def __init__( + self, + attr_name: Optional[str] = None, + p_type: Optional[str] = None, + value: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds GE proof predicate.""" + super().__init__(**kwargs) + self.attr_name = attr_name + self.p_type = p_type + self.value = value + + +class AnoncredsGEProofPredSchema(BaseModelSchema): + """Anoncreds GE proof predicate schema.""" + + class Meta: + """Anoncreds GE proof predicate metadata.""" + + model_class = AnoncredsGEProofPred + unknown = EXCLUDE + + attr_name = fields.Str( + metadata={"description": "Attribute name, anoncreds-canonicalized"} + ) + p_type = fields.Str( + validate=validate.OneOf([p.fortran for p in Predicate]), + metadata={"description": "Predicate type"}, + ) + value = fields.Integer( + metadata={"strict": True, "description": "Predicate threshold value"} + ) + + +class AnoncredsGEProof(BaseModel): + """Greater-than-or-equal-to proof for anoncreds primary proof.""" + + class Meta: + """GE proof metadata.""" + + schema_class = "AnoncredsGEProofMeta" + + def __init__( + self, + u: Mapping[str, str] = None, + r: Mapping[str, str] = None, + mj: Optional[str] = None, + alpha: Optional[str] = None, + t: Mapping[str, str] = None, + predicate: Optional[AnoncredsGEProofPred] = None, + **kwargs, + ): + """Initialize GE proof object.""" + super().__init__(**kwargs) + self.u = u + self.r = r + self.mj = mj + self.alpha = alpha + self.t = t + self.predicate = predicate + + +class AnoncredsGEProofSchema(BaseModelSchema): + """Anoncreds GE proof schema.""" + + class Meta: + """Anoncreds GE proof schema metadata.""" + + model_class = AnoncredsGEProof + unknown = EXCLUDE + + u = fields.Dict( + keys=fields.Str(), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + r = fields.Dict( + keys=fields.Str(), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + mj = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + alpha = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + t = fields.Dict( + keys=fields.Str(), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + predicate = fields.Nested(AnoncredsGEProofPredSchema) + + +class AnoncredsPrimaryProof(BaseModel): + """Anoncreds primary proof.""" + + class Meta: + """Anoncreds primary proof metadata.""" + + schema_class = "AnoncredsPrimaryProofSchema" + + def __init__( + self, + eq_proof: Optional[AnoncredsEQProof] = None, + ge_proofs: Sequence[AnoncredsGEProof] = None, + **kwargs, + ): + """Initialize anoncreds primary proof.""" + super().__init__(**kwargs) + self.eq_proof = eq_proof + self.ge_proofs = ge_proofs + + +class AnoncredsPrimaryProofSchema(BaseModelSchema): + """Anoncreds primary proof schema.""" + + class Meta: + """Anoncreds primary proof schema metadata.""" + + model_class = AnoncredsPrimaryProof + unknown = EXCLUDE + + eq_proof = fields.Nested( + AnoncredsEQProofSchema, + allow_none=True, + metadata={"description": "Anoncreds equality proof"}, + ) + ge_proofs = fields.Nested( + AnoncredsGEProofSchema, + many=True, + allow_none=True, + metadata={"description": "Anoncreds GE proofs"}, + ) + + +class AnoncredsNonRevocProof(BaseModel): + """Anoncreds non-revocation proof.""" + + class Meta: + """Anoncreds non-revocation proof metadata.""" + + schema_class = "AnoncredsNonRevocProofSchema" + + def __init__( + self, + x_list: Optional[Mapping] = None, + c_list: Optional[Mapping] = None, + **kwargs, + ): + """Initialize anoncreds non-revocation proof.""" + super().__init__(**kwargs) + self.x_list = x_list + self.c_list = c_list + + +class AnoncredsNonRevocProofSchema(BaseModelSchema): + """Anoncreds non-revocation proof schema.""" + + class Meta: + """Anoncreds non-revocation proof schema metadata.""" + + model_class = AnoncredsNonRevocProof + unknown = EXCLUDE + + x_list = fields.Dict(keys=fields.Str(), values=fields.Str()) + c_list = fields.Dict(keys=fields.Str(), values=fields.Str()) + + +class AnoncredsProofProofProofsProof(BaseModel): + """Anoncreds proof.proof.proofs constituent proof.""" + + class Meta: + """Anoncreds proof.proof.proofs constituent proof schema.""" + + schema_class = "AnoncredsProofProofProofsProofSchema" + + def __init__( + self, + primary_proof: Optional[AnoncredsPrimaryProof] = None, + non_revoc_proof: Optional[AnoncredsNonRevocProof] = None, + **kwargs, + ): + """Initialize proof.proof.proofs constituent proof.""" + super().__init__(**kwargs) + self.primary_proof = primary_proof + self.non_revoc_proof = non_revoc_proof + + +class AnoncredsProofProofProofsProofSchema(BaseModelSchema): + """Anoncreds proof.proof.proofs constituent proof schema.""" + + class Meta: + """Anoncreds proof.proof.proofs constituent proof schema metadata.""" + + model_class = AnoncredsProofProofProofsProof + unknown = EXCLUDE + + primary_proof = fields.Nested( + AnoncredsPrimaryProofSchema, metadata={"description": "Anoncreds primary proof"} + ) + non_revoc_proof = fields.Nested( + AnoncredsNonRevocProofSchema, + allow_none=True, + metadata={"description": "Anoncreds non-revocation proof"}, + ) + + +class AnoncredsProofProofAggregatedProof(BaseModel): + """Anoncreds proof.proof aggregated proof.""" + + class Meta: + """Anoncreds proof.proof aggregated proof metadata.""" + + schema_class = "AnoncredsProofProofAggregatedProofSchema" + + def __init__( + self, + c_hash: Optional[str] = None, + c_list: Sequence[Sequence[int]] = None, + **kwargs, + ): + """Initialize anoncreds proof.proof agreggated proof.""" + super().__init__(**kwargs) + self.c_hash = c_hash + self.c_list = c_list + + +class AnoncredsProofProofAggregatedProofSchema(BaseModelSchema): + """Anoncreds proof.proof aggregated proof schema.""" + + class Meta: + """Anoncreds proof.proof aggregated proof schema metadata.""" + + model_class = AnoncredsProofProofAggregatedProof + unknown = EXCLUDE + + c_hash = fields.Str(metadata={"description": "c_hash value"}) + c_list = fields.List( + fields.List(fields.Int(metadata={"strict": True})), + metadata={"description": "c_list value"}, + ) + + +class AnoncredsProofProof(BaseModel): + """Anoncreds proof.proof content.""" + + class Meta: + """Anoncreds proof.proof content metadata.""" + + schema_class = "AnoncredsProofProofSchema" + + def __init__( + self, + proofs: Sequence[AnoncredsProofProofProofsProof] = None, + aggregated_proof: Optional[AnoncredsProofProofAggregatedProof] = None, + **kwargs, + ): + """Initialize anoncreds proof.proof content.""" + super().__init__(**kwargs) + self.proofs = proofs + self.aggregated_proof = aggregated_proof + + +class AnoncredsProofProofSchema(BaseModelSchema): + """Anoncreds proof.proof content schema.""" + + class Meta: + """Anoncreds proof.proof content schema metadata.""" + + model_class = AnoncredsProofProof + unknown = EXCLUDE + + proofs = fields.Nested( + AnoncredsProofProofProofsProofSchema, + many=True, + metadata={"description": "Anoncreds proof proofs"}, + ) + aggregated_proof = fields.Nested( + AnoncredsProofProofAggregatedProofSchema, + metadata={"description": "Anoncreds proof aggregated proof"}, + ) + + +class RawEncoded(BaseModel): + """Raw and encoded attribute values.""" + + class Meta: + """Raw and encoded attribute values metadata.""" + + schema_class = "RawEncodedSchema" + + def __init__( + self, + raw: Optional[str] = None, + encoded: Optional[str] = None, + **kwargs, + ): + """Initialize raw and encoded attribute values.""" + super().__init__(**kwargs) + self.raw = raw + self.encoded = encoded + + +class RawEncodedSchema(BaseModelSchema): + """Raw and encoded attribute values schema.""" + + class Meta: + """Raw and encoded attribute values schema metadata.""" + + model_class = RawEncoded + unknown = EXCLUDE + + raw = fields.Str(metadata={"description": "Raw value"}) + encoded = fields.Str( + validate=NUM_STR_ANY_VALIDATE, + metadata={"description": "Encoded value", "example": NUM_STR_ANY_EXAMPLE}, + ) + + +class AnoncredsProofRequestedProofRevealedAttr(RawEncoded): + """Anoncreds proof requested proof revealed attr.""" + + class Meta: + """Anoncreds proof requested proof revealed attr metadata.""" + + schema_class = "AnoncredsProofRequestedProofRevealedAttrSchema" + + def __init__( + self, + sub_proof_index: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof revealed attr.""" + super().__init__(**kwargs) + self.sub_proof_index = sub_proof_index + + +class AnoncredsProofRequestedProofRevealedAttrSchema(RawEncodedSchema): + """Anoncreds proof requested proof revealed attr schema.""" + + class Meta: + """Anoncreds proof requested proof revealed attr schema metadata.""" + + model_class = AnoncredsProofRequestedProofRevealedAttr + unknown = EXCLUDE + + sub_proof_index = fields.Int( + metadata={"strict": True, "description": "Sub-proof index"} + ) + + +class AnoncredsProofRequestedProofRevealedAttrGroup(BaseModel): + """Anoncreds proof requested proof revealed attr group.""" + + class Meta: + """Anoncreds proof requested proof revealed attr group metadata.""" + + schema_class = "AnoncredsProofRequestedProofRevealedAttrGroupSchema" + + def __init__( + self, + sub_proof_index: Optional[int] = None, + values: Mapping[str, RawEncoded] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof revealed attr.""" + super().__init__(**kwargs) + self.sub_proof_index = sub_proof_index + self.values = values + + +class AnoncredsProofRequestedProofRevealedAttrGroupSchema(BaseModelSchema): + """Anoncreds proof requested proof revealed attr group schema.""" + + class Meta: + """Anoncreds proof requested proof revealed attr group schema metadata.""" + + model_class = AnoncredsProofRequestedProofRevealedAttrGroup + unknown = EXCLUDE + + sub_proof_index = fields.Int( + metadata={"strict": True, "description": "Sub-proof index"} + ) + values = fields.Dict( + keys=fields.Str(), + values=fields.Nested(RawEncodedSchema), + metadata={ + "description": "Anoncreds proof requested proof revealed attr groups group value" # noqa: E501 + }, + ) + + +class AnoncredsProofRequestedProofPredicate(BaseModel): + """Anoncreds proof requested proof predicate.""" + + class Meta: + """Anoncreds proof requested proof requested proof predicate metadata.""" + + schema_class = "AnoncredsProofRequestedProofPredicateSchema" + + def __init__( + self, + sub_proof_index: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof predicate.""" + super().__init__(**kwargs) + self.sub_proof_index = sub_proof_index + + +class AnoncredsProofRequestedProofPredicateSchema(BaseModelSchema): + """Anoncreds proof requested prrof predicate schema.""" + + class Meta: + """Anoncreds proof requested proof requested proof predicate schema metadata.""" + + model_class = AnoncredsProofRequestedProofPredicate + unknown = EXCLUDE + + sub_proof_index = fields.Int( + metadata={"strict": True, "description": "Sub-proof index"} + ) + + +class AnoncredsProofRequestedProof(BaseModel): + """Anoncreds proof.requested_proof content.""" + + class Meta: + """Anoncreds proof.requested_proof content metadata.""" + + schema_class = "AnoncredsProofRequestedProofSchema" + + def __init__( + self, + revealed_attrs: Mapping[str, AnoncredsProofRequestedProofRevealedAttr] = None, + revealed_attr_groups: Mapping[ + str, + AnoncredsProofRequestedProofRevealedAttrGroup, + ] = None, + self_attested_attrs: Optional[Mapping] = None, + unrevealed_attrs: Optional[Mapping] = None, + predicates: Mapping[str, AnoncredsProofRequestedProofPredicate] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof.""" + super().__init__(**kwargs) + self.revealed_attrs = revealed_attrs + self.revealed_attr_groups = revealed_attr_groups + self.self_attested_attrs = self_attested_attrs + self.unrevealed_attrs = unrevealed_attrs + self.predicates = predicates + + +class AnoncredsProofRequestedProofSchema(BaseModelSchema): + """Anoncreds proof requested proof schema.""" + + class Meta: + """Anoncreds proof requested proof schema metadata.""" + + model_class = AnoncredsProofRequestedProof + unknown = EXCLUDE + + revealed_attrs = fields.Dict( + keys=fields.Str(), + values=fields.Nested(AnoncredsProofRequestedProofRevealedAttrSchema), + allow_none=True, + metadata={"description": "Proof requested proof revealed attributes"}, + ) + revealed_attr_groups = fields.Dict( + keys=fields.Str(), + values=fields.Nested(AnoncredsProofRequestedProofRevealedAttrGroupSchema), + allow_none=True, + metadata={"description": "Proof requested proof revealed attribute groups"}, + ) + self_attested_attrs = fields.Dict( + metadata={"description": "Proof requested proof self-attested attributes"} + ) + unrevealed_attrs = fields.Dict(metadata={"description": "Unrevealed attributes"}) + predicates = fields.Dict( + keys=fields.Str(), + values=fields.Nested(AnoncredsProofRequestedProofPredicateSchema), + metadata={"description": "Proof requested proof predicates."}, + ) + + +class AnoncredsProofIdentifier(BaseModel): + """Anoncreds proof identifier.""" + + class Meta: + """Anoncreds proof identifier metadata.""" + + schema_class = "AnoncredsProofIdentifierSchema" + + def __init__( + self, + schema_id: Optional[str] = None, + cred_def_id: Optional[str] = None, + rev_reg_id: Optional[str] = None, + timestamp: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds proof identifier.""" + super().__init__(**kwargs) + self.schema_id = schema_id + self.cred_def_id = cred_def_id + self.rev_reg_id = rev_reg_id + self.timestamp = timestamp + + +class AnoncredsProofIdentifierSchema(BaseModelSchema): + """Anoncreds proof identifier schema.""" + + class Meta: + """Anoncreds proof identifier schema metadata.""" + + model_class = AnoncredsProofIdentifier + unknown = EXCLUDE + + schema_id = fields.Str( + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + cred_def_id = fields.Str( + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + rev_reg_id = fields.Str( + allow_none=True, + validate=ANONCREDS_REV_REG_ID_VALIDATE, + metadata={ + "description": "Revocation registry identifier", + "example": ANONCREDS_REV_REG_ID_EXAMPLE, + }, + ) + timestamp = fields.Int( + allow_none=True, + validate=INT_EPOCH_VALIDATE, + metadata={ + "strict": True, + "description": "Timestamp epoch", + "example": INT_EPOCH_EXAMPLE, + }, + ) + + +class AnoncredsProof(BaseModel): + """Anoncreds proof.""" + + class Meta: + """Anoncreds proof metadata.""" + + schema_class = "AnoncredsProofSchema" + + def __init__( + self, + proof: Optional[AnoncredsProofProof] = None, + requested_proof: Optional[AnoncredsProofRequestedProof] = None, + identifiers: Sequence[AnoncredsProofIdentifier] = None, + **kwargs, + ): + """Initialize anoncreds proof.""" + super().__init__(**kwargs) + self.proof = proof + self.requested_proof = requested_proof + self.identifiers = identifiers + + +class AnoncredsProofSchema(BaseModelSchema): + """Anoncreds proof schema.""" + + class Meta: + """Anoncreds proof schema metadata.""" + + model_class = AnoncredsProof + unknown = EXCLUDE + + proof = fields.Nested( + AnoncredsProofProofSchema, + metadata={"description": "Anoncreds proof.proof content"}, + ) + requested_proof = fields.Nested( + AnoncredsProofRequestedProofSchema, + metadata={"description": "Anoncreds proof.requested_proof content"}, + ) + identifiers = fields.Nested( + AnoncredsProofIdentifierSchema, + many=True, + metadata={"description": "Anoncreds proof.identifiers content"}, + ) + + +class AnoncredsPresSpecSchema(AdminAPIMessageTracingSchema): + """Request schema for anoncreds proof specification to send as presentation.""" + + self_attested_attributes = fields.Dict( + required=True, + keys=fields.Str(metadata={"example": "attr_name"}), + values=fields.Str( + metadata={ + "example": "self_attested_value", + "description": ( + "Self-attested attribute values to use in requested-credentials" + " structure for proof construction" + ), + } + ), + metadata={"description": "Self-attested attributes to build into proof"}, + ) + requested_attributes = fields.Dict( + required=True, + keys=fields.Str(metadata={"example": "attr_referent"}), + values=fields.Nested(AnoncredsRequestedCredsRequestedAttrSchema), + metadata={ + "description": ( + "Nested object mapping proof request attribute referents to" + " requested-attribute specifiers" + ) + }, + ) + requested_predicates = fields.Dict( + required=True, + keys=fields.Str(metadata={"example": "pred_referent"}), + values=fields.Nested(AnoncredsRequestedCredsRequestedPredSchema), + metadata={ + "description": ( + "Nested object mapping proof request predicate referents to" + " requested-predicate specifiers" + ) + }, + ) + trace = fields.Bool( + required=False, + metadata={ + "description": "Whether to trace event (default false)", + "example": False, + }, + ) diff --git a/acapy_agent/anoncreds/models/requested_credentials.py b/acapy_agent/anoncreds/models/requested_credentials.py new file mode 100644 index 0000000000..ac0fcf3d33 --- /dev/null +++ b/acapy_agent/anoncreds/models/requested_credentials.py @@ -0,0 +1,47 @@ +"""Admin routes for presentations.""" + +from marshmallow import fields + +from ...messaging.models.openapi import OpenAPISchema +from ...messaging.valid import INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE + + +class AnoncredsRequestedCredsRequestedAttrSchema(OpenAPISchema): + """Schema for requested attributes within anoncreds requested creds structure.""" + + cred_id = fields.Str( + required=True, + metadata={ + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": ( + "Wallet credential identifier (typically but not necessarily a UUID)" + ), + }, + ) + revealed = fields.Bool( + dump_default=True, + metadata={"description": "Whether to reveal attribute in proof (default true)"}, + ) + + +class AnoncredsRequestedCredsRequestedPredSchema(OpenAPISchema): + """Schema for requested predicates within anoncreds requested creds structure.""" + + cred_id = fields.Str( + required=True, + metadata={ + "description": ( + "Wallet credential identifier (typically but not necessarily a UUID)" + ), + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + }, + ) + timestamp = fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": "Epoch timestamp of interest for non-revocation proof", + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ) diff --git a/acapy_agent/anoncreds/models/anoncreds_revocation.py b/acapy_agent/anoncreds/models/revocation.py similarity index 96% rename from acapy_agent/anoncreds/models/anoncreds_revocation.py rename to acapy_agent/anoncreds/models/revocation.py index cc90469eac..94c75a525a 100644 --- a/acapy_agent/anoncreds/models/anoncreds_revocation.py +++ b/acapy_agent/anoncreds/models/revocation.py @@ -7,15 +7,14 @@ from marshmallow.validate import OneOf from typing_extensions import Literal -from acapy_agent.messaging.valid import ( - INDY_CRED_DEF_ID_EXAMPLE, - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_OR_KEY_DID_EXAMPLE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_REV_REG_ID_EXAMPLE, -) - from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ISO8601_DATETIME_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, +) class RevRegDefValue(BaseModel): @@ -60,7 +59,7 @@ class Meta: unknown = EXCLUDE public_keys = fields.Dict( - data_key="publicKeys", metadata={"example": INDY_RAW_PUBLIC_KEY_EXAMPLE} + data_key="publicKeys", metadata={"example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE} ) max_cred_num = fields.Int(data_key="maxCredNum", metadata={"example": 777}) tails_location = fields.Str( @@ -131,7 +130,7 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) @@ -139,7 +138,7 @@ class Meta: cred_def_id = fields.Str( metadata={ "description": "Credential definition identifier", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, data_key="credDefId", ) @@ -209,7 +208,7 @@ class Meta: revocation_registry_definition_id = fields.Str( metadata={ "description": "revocation registry definition id", - "example": INDY_REV_REG_ID_EXAMPLE, + "example": ANONCREDS_REV_REG_ID_EXAMPLE, } ) revocation_registry_definition = fields.Nested( @@ -380,14 +379,14 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) rev_reg_def_id = fields.Str( metadata={ "description": "The ID of the revocation registry definition", - "example": INDY_REV_REG_ID_EXAMPLE, + "example": ANONCREDS_REV_REG_ID_EXAMPLE, }, data_key="revRegDefId", ) @@ -409,7 +408,7 @@ class Meta: timestamp = fields.Int( metadata={ "description": "Timestamp at which revocation list is applicable", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, required=False, ) diff --git a/acapy_agent/anoncreds/models/anoncreds_schema.py b/acapy_agent/anoncreds/models/schema.py similarity index 95% rename from acapy_agent/anoncreds/models/anoncreds_schema.py rename to acapy_agent/anoncreds/models/schema.py index b2383ff60f..6a3f56bc03 100644 --- a/acapy_agent/anoncreds/models/anoncreds_schema.py +++ b/acapy_agent/anoncreds/models/schema.py @@ -7,7 +7,10 @@ from marshmallow.validate import OneOf from ...messaging.models.base import BaseModel, BaseModelSchema -from ...messaging.valid import INDY_OR_KEY_DID_EXAMPLE, INDY_SCHEMA_ID_EXAMPLE +from ...messaging.valid import ( + ANONCREDS_DID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, +) class AnonCredsSchema(BaseModel): @@ -58,7 +61,7 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) @@ -129,7 +132,10 @@ class Meta: schema_value = fields.Nested(AnonCredsSchemaSchema(), data_key="schema") schema_id = fields.Str( - metadata={"description": "Schema identifier", "example": INDY_SCHEMA_ID_EXAMPLE} + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + } ) resolution_metadata = fields.Dict() schema_metadata = fields.Dict() @@ -185,7 +191,7 @@ class Meta: schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) schema_value = fields.Nested(AnonCredsSchemaSchema(), data_key="schema") diff --git a/acapy_agent/anoncreds/models/utils.py b/acapy_agent/anoncreds/models/utils.py new file mode 100644 index 0000000000..51f140844f --- /dev/null +++ b/acapy_agent/anoncreds/models/utils.py @@ -0,0 +1,99 @@ +"""Utilities to deal with anoncreds objects.""" + +from ..holder import AnonCredsHolder + + +def _get_value_error_msg(proof_request: dict, referent: str) -> str: + return ( + "Could not automatically construct presentation for " + + f"presentation request {proof_request['name']}" + + f":{proof_request['version']} because referent " + + f"{referent} did not produce any credentials." + ) + + +async def get_requested_creds_from_proof_request_preview( + proof_request: dict, + *, + holder: AnonCredsHolder, +): + """Build anoncreds requested-credentials structure. + + Given input proof request and presentation preview, use credentials in + holder's wallet to build anoncreds requested credentials structure for input + to proof creation. + + Args: + proof_request: anoncreds proof request + preview: preview from presentation proposal, if applicable + holder: holder injected into current context + + """ + req_creds = { + "self_attested_attributes": {}, + "requested_attributes": {}, + "requested_predicates": {}, + } + + for referent, _ in proof_request["requested_attributes"].items(): + credentials = await holder.get_credentials_for_presentation_request_by_referent( + presentation_request=proof_request, + referents=(referent,), + start=0, + count=100, + ) + if not credentials: + raise ValueError(_get_value_error_msg(proof_request, referent)) + + cred_match = credentials[0] # holder sorts + + if "restrictions" in proof_request["requested_attributes"][referent]: + req_creds["requested_attributes"][referent] = { + "cred_id": cred_match["cred_info"]["referent"], + "revealed": True, + } + else: + req_creds["self_attested_attributes"][referent] = cred_match["cred_info"][ + "attrs" + ][proof_request["requested_attributes"][referent]["name"]] + + for referent in proof_request["requested_predicates"]: + credentials = await holder.get_credentials_for_presentation_request_by_referent( + presentation_request=proof_request, + referents=(referent,), + start=0, + count=100, + ) + if not credentials: + raise ValueError(_get_value_error_msg(proof_request, referent)) + + cred_match = credentials[0] # holder sorts + if "restrictions" in proof_request["requested_predicates"][referent]: + req_creds["requested_predicates"][referent] = { + "cred_id": cred_match["cred_info"]["referent"], + "revealed": True, + } + else: + req_creds["self_attested_attributes"][referent] = cred_match["cred_info"][ + "attrs" + ][proof_request["requested_predicates"][referent]["name"]] + + return req_creds + + +def extract_non_revocation_intervals_from_proof_request(proof_req: dict): + """Return non-revocation intervals by requested item referent in proof request.""" + non_revoc_intervals = {} + for req_item_type in ("requested_attributes", "requested_predicates"): + for reft, req_item in proof_req[req_item_type].items(): + interval = req_item.get( + "non_revoked", + proof_req.get("non_revoked"), + ) + if interval: + timestamp_from = interval.get("from") + timestamp_to = interval.get("to") + if (timestamp_to is not None) and timestamp_from == timestamp_to: + interval["from"] = 0 # accommodate verify=False if from=to + non_revoc_intervals[reft] = interval + return non_revoc_intervals diff --git a/acapy_agent/anoncreds/registry.py b/acapy_agent/anoncreds/registry.py index 79aba036cc..c355b447cd 100644 --- a/acapy_agent/anoncreds/registry.py +++ b/acapy_agent/anoncreds/registry.py @@ -11,8 +11,8 @@ BaseAnonCredsRegistrar, BaseAnonCredsResolver, ) -from .models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from .models.anoncreds_revocation import ( +from .models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from .models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -20,7 +20,7 @@ RevRegDef, RevRegDefResult, ) -from .models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from .models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/revocation.py b/acapy_agent/anoncreds/revocation.py index 56b19d222d..e9cc88293f 100644 --- a/acapy_agent/anoncreds/revocation.py +++ b/acapy_agent/anoncreds/revocation.py @@ -26,12 +26,12 @@ from requests import RequestException, Session from uuid_utils import uuid4 -from acapy_agent.anoncreds.models.anoncreds_cred_def import CredDef - from ..askar.profile_anon import AskarAnoncredsProfile, AskarAnoncredsProfileSession from ..core.error import BaseError from ..core.event_bus import Event, EventBus from ..core.profile import Profile, ProfileSession +from ..multitenant.base import BaseMultitenantManager +from ..tails.anoncreds_tails_server import AnonCredsTailsServer from ..tails.base import BaseTailsServer from .error_messages import ANONCREDS_PROFILE_REQUIRED_MSG from .events import RevListFinishedEvent, RevRegDefFinishedEvent @@ -41,7 +41,8 @@ STATE_FINISHED, AnonCredsIssuer, ) -from .models.anoncreds_revocation import ( +from .models.credential_definition import CredDef +from .models.revocation import ( RevList, RevListResult, RevListState, @@ -694,7 +695,12 @@ def get_local_tails_path(self, rev_reg_def: RevRegDef) -> str: async def upload_tails_file(self, rev_reg_def: RevRegDef): """Upload the local tails file to the tails server.""" - tails_server = self.profile.inject_or(BaseTailsServer) + multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + tails_server = AnonCredsTailsServer() + else: + tails_server = self.profile.inject_or(BaseTailsServer) + if not tails_server: raise AnonCredsRevocationError("Tails server not configured") if not Path(self.get_local_tails_path(rev_reg_def)).is_file(): diff --git a/acapy_agent/anoncreds/routes.py b/acapy_agent/anoncreds/routes.py index 9cf1d6ad98..9a8fe04669 100644 --- a/acapy_agent/anoncreds/routes.py +++ b/acapy_agent/anoncreds/routes.py @@ -16,13 +16,12 @@ from ..admin.decorators.auth import tenant_authentication from ..admin.request_context import AdminRequestContext from ..core.event_bus import EventBus -from ..ledger.error import LedgerError from ..messaging.models.openapi import OpenAPISchema from ..messaging.valid import ( - INDY_CRED_DEF_ID_EXAMPLE, - INDY_OR_KEY_DID_EXAMPLE, - INDY_REV_REG_ID_EXAMPLE, - INDY_SCHEMA_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, UUIDFour, ) from ..revocation.error import RevocationNotSupportedError @@ -35,9 +34,9 @@ AnonCredsResolutionError, ) from .issuer import AnonCredsIssuer, AnonCredsIssuerError -from .models.anoncreds_cred_def import CredDefResultSchema, GetCredDefResultSchema -from .models.anoncreds_revocation import RevListResultSchema, RevRegDefResultSchema -from .models.anoncreds_schema import ( +from .models.credential_definition import CredDefResultSchema, GetCredDefResultSchema +from .models.revocation import RevListResultSchema, RevRegDefResultSchema +from .models.schema import ( AnonCredsSchemaSchema, GetSchemaResultSchema, SchemaResultSchema, @@ -69,7 +68,7 @@ class SchemaIdMatchInfo(OpenAPISchema): schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) @@ -112,7 +111,7 @@ class SchemasQueryStringSchema(OpenAPISchema): schema_issuer_id = fields.Str( metadata={ "description": "Schema issuer identifier", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, } ) @@ -124,7 +123,7 @@ class GetSchemasResponseSchema(OpenAPISchema): fields.Str( metadata={ "description": "Schema identifiers", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) ) @@ -137,7 +136,7 @@ class SchemaPostRequestSchema(OpenAPISchema): options = fields.Nested(SchemaPostOptionSchema()) -@docs(tags=["anoncreds - schemas"], summary="Create a schema on the connected ledger") +@docs(tags=["anoncreds - schemas"], summary="Create a schema on the connected datastore") @request_schema(SchemaPostRequestSchema()) @response_schema(SchemaResultSchema(), 200, description="") @tenant_authentication @@ -278,7 +277,7 @@ class CredIdMatchInfo(OpenAPISchema): cred_def_id = fields.Str( metadata={ "description": "Credential definition identifier", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, required=True, ) @@ -297,7 +296,7 @@ class InnerCredDefSchema(OpenAPISchema): schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, }, required=True, data_key="schemaId", @@ -305,7 +304,7 @@ class InnerCredDefSchema(OpenAPISchema): issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, required=True, data_key="issuerId", @@ -357,13 +356,13 @@ class CredDefsQueryStringSchema(OpenAPISchema): issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, } ) schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) schema_name = fields.Str( @@ -382,7 +381,7 @@ class CredDefsQueryStringSchema(OpenAPISchema): @docs( tags=["anoncreds - credential definitions"], - summary="Create a credential definition on the connected ledger", + summary="Create a credential definition on the connected datastore", ) @request_schema(CredDefPostRequestSchema()) @response_schema(CredDefResultSchema(), 200, description="") @@ -522,14 +521,14 @@ class InnerRevRegDefSchema(OpenAPISchema): issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) cred_def_id = fields.Str( metadata={ "description": "Credential definition identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, }, data_key="credDefId", ) @@ -573,7 +572,7 @@ class RevRegCreateRequestSchemaAnoncreds(OpenAPISchema): @docs( tags=["anoncreds - revocation"], - summary="Create and publish a registration revocation on the connected ledger", + summary="Create and publish a registration revocation on the connected datastore", ) @request_schema(RevRegCreateRequestSchemaAnoncreds()) @response_schema(RevRegDefResultSchema(), 200, description="") @@ -649,7 +648,7 @@ class RevListCreateRequestSchema(OpenAPISchema): rev_reg_def_id = fields.Str( metadata={ "description": "Revocation registry definition identifier", - "example": INDY_REV_REG_ID_EXAMPLE, + "example": ANONCREDS_REV_REG_ID_EXAMPLE, } ) options = fields.Nested(RevListOptionsSchema) @@ -657,7 +656,7 @@ class RevListCreateRequestSchema(OpenAPISchema): @docs( tags=["anoncreds - revocation"], - summary="Create and publish a revocation status list on the connected ledger", + summary="Create and publish a revocation status list on the connected datastore", ) @request_schema(RevListCreateRequestSchema()) @response_schema(RevListResultSchema(), 200, description="") @@ -687,7 +686,7 @@ async def rev_list_post(request: web.BaseRequest): handle_value_error(e) except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - except (AnonCredsRevocationError, LedgerError) as err: + except AnonCredsRevocationError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err diff --git a/acapy_agent/anoncreds/tests/test_holder.py b/acapy_agent/anoncreds/tests/test_holder.py index 6f8dae681d..c894b21e3f 100644 --- a/acapy_agent/anoncreds/tests/test_holder.py +++ b/acapy_agent/anoncreds/tests/test_holder.py @@ -45,8 +45,8 @@ from ...wallet.error import WalletNotFoundError from .. import holder as test_module from ..holder import CATEGORY_CREDENTIAL, AnonCredsHolder, AnonCredsHolderError -from ..models.anoncreds_cred_def import CredDef, CredDefValue, CredDefValuePrimary -from ..models.anoncreds_revocation import GetRevListResult, RevList +from ..models.credential_definition import CredDef, CredDefValue, CredDefValuePrimary +from ..models.revocation import GetRevListResult, RevList from ..registry import AnonCredsRegistry diff --git a/acapy_agent/anoncreds/tests/test_issuer.py b/acapy_agent/anoncreds/tests/test_issuer.py index f165f178d6..7442ffd2ae 100644 --- a/acapy_agent/anoncreds/tests/test_issuer.py +++ b/acapy_agent/anoncreds/tests/test_issuer.py @@ -10,7 +10,7 @@ AnonCredsObjectAlreadyExists, AnonCredsSchemaAlreadyExists, ) -from ...anoncreds.models.anoncreds_cred_def import ( +from ...anoncreds.models.credential_definition import ( CredDef, CredDefResult, CredDefState, @@ -19,7 +19,7 @@ CredDefValueRevocation, GetCredDefResult, ) -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, GetSchemaResult, SchemaResult, diff --git a/acapy_agent/anoncreds/tests/test_revocation.py b/acapy_agent/anoncreds/tests/test_revocation.py index 5de4ef368e..2d9bc62e15 100644 --- a/acapy_agent/anoncreds/tests/test_revocation.py +++ b/acapy_agent/anoncreds/tests/test_revocation.py @@ -16,8 +16,8 @@ from requests import RequestException, Session from ...anoncreds.issuer import AnonCredsIssuer -from ...anoncreds.models.anoncreds_cred_def import CredDef -from ...anoncreds.models.anoncreds_revocation import ( +from ...anoncreds.models.credential_definition import CredDef +from ...anoncreds.models.revocation import ( RevList, RevListResult, RevListState, @@ -26,7 +26,7 @@ RevRegDefState, RevRegDefValue, ) -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, GetSchemaResult, ) @@ -48,7 +48,7 @@ "accum_key": {"z": "1 0BB...386"}, }, tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", - tails_location="http://tails-server.com", + tails_location="https://tails-server.com", ), issuer_id="CsQY9MGeD3CQP4EyuVFo5m", type="CL_ACCUM", @@ -836,21 +836,40 @@ def test_generate_public_tails_uri(self): async def test_upload_tails_file(self): self.profile.inject_or = mock.Mock( - return_value=mock.MagicMock( - upload_tails_file=mock.CoroutineMock( - side_effect=[ - (True, "http://tails-server.com"), - (None, "http://tails-server.com"), - (True, "not-http://tails-server.com"), - ] - ) - ) + side_effect=[ + None, + mock.MagicMock( + upload_tails_file=mock.CoroutineMock( + return_value=(True, "https://tails-server.com") + ) + ), + ] ) # valid await self.revocation.upload_tails_file(rev_reg_def) # upload fails + self.profile.inject_or = mock.Mock( + side_effect=[ + None, + mock.MagicMock( + upload_tails_file=mock.CoroutineMock( + return_value=(None, "https://tails-server.com"), + ) + ), + ] + ) with self.assertRaises(test_module.AnonCredsRevocationError): await self.revocation.upload_tails_file(rev_reg_def) + self.profile.inject_or = mock.Mock( + side_effect=[ + None, + mock.MagicMock( + upload_tails_file=mock.CoroutineMock( + return_value=(True, "not-http://tails-server.com"), + ) + ), + ] + ) # tails location does not match with self.assertRaises(test_module.AnonCredsRevocationError): await self.revocation.upload_tails_file(rev_reg_def) diff --git a/acapy_agent/anoncreds/tests/test_revocation_setup.py b/acapy_agent/anoncreds/tests/test_revocation_setup.py index e56291efeb..357899f4c9 100644 --- a/acapy_agent/anoncreds/tests/test_revocation_setup.py +++ b/acapy_agent/anoncreds/tests/test_revocation_setup.py @@ -11,7 +11,7 @@ RevRegDefFinishedEvent, RevRegDefFinishedPayload, ) -from ..models.anoncreds_revocation import RevRegDef, RevRegDefValue +from ..models.revocation import RevRegDef, RevRegDefValue from ..revocation import AnonCredsRevocation diff --git a/acapy_agent/anoncreds/tests/test_routes.py b/acapy_agent/anoncreds/tests/test_routes.py index 17c4d15bee..607b81f4ae 100644 --- a/acapy_agent/anoncreds/tests/test_routes.py +++ b/acapy_agent/anoncreds/tests/test_routes.py @@ -7,7 +7,7 @@ from ...admin.request_context import AdminRequestContext from ...anoncreds.base import AnonCredsObjectNotFound from ...anoncreds.issuer import AnonCredsIssuer -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, SchemaResult, SchemaState, diff --git a/acapy_agent/anoncreds/tests/test_verifier.py b/acapy_agent/anoncreds/tests/test_verifier.py index 8f912a3f0f..0ff11fcb95 100644 --- a/acapy_agent/anoncreds/tests/test_verifier.py +++ b/acapy_agent/anoncreds/tests/test_verifier.py @@ -3,21 +3,21 @@ import pytest -from ...anoncreds.models.anoncreds_cred_def import ( +from ...anoncreds.models.credential_definition import ( CredDef, CredDefValue, CredDefValuePrimary, CredDefValueRevocation, GetCredDefResult, ) -from ...anoncreds.models.anoncreds_revocation import ( +from ...anoncreds.models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, RevRegDef, RevRegDefValue, ) -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, GetSchemaResult, ) diff --git a/acapy_agent/anoncreds/verifier.py b/acapy_agent/anoncreds/verifier.py index 4f7972371d..849c44ab5b 100644 --- a/acapy_agent/anoncreds/verifier.py +++ b/acapy_agent/anoncreds/verifier.py @@ -1,4 +1,4 @@ -"""Indy-Credx verifier implementation.""" +"""Anoncreds verifier implementation.""" import asyncio import logging @@ -9,10 +9,10 @@ from anoncreds import AnoncredsError, Presentation, W3cPresentation from ..core.profile import Profile -from ..indy.models.xform import indy_proof_req2non_revoc_intervals from ..messaging.util import canon, encode from ..vc.vc_ld.validation_result import PresentationVerificationResult -from .models.anoncreds_cred_def import GetCredDefResult +from .models.credential_definition import GetCredDefResult +from .models.utils import extract_non_revocation_intervals_from_proof_request from .registry import AnonCredsRegistry LOGGER = logging.getLogger(__name__) @@ -45,7 +45,7 @@ def non_revoc_intervals(self, pres_req: dict, pres: dict, cred_defs: dict) -> li """Remove superfluous non-revocation intervals in presentation request. Irrevocable credentials constitute proof of non-revocation, but - indy rejects proof requests with non-revocation intervals lining up + anoncreds rejects proof requests with non-revocation intervals lining up with non-revocable credentials in proof: seek and remove. Args: @@ -116,13 +116,15 @@ async def check_timestamps( Args: profile: relevant profile - pres_req: indy proof request - pres: indy proof request + pres_req: anoncreds proof request + pres: anoncreds proof request rev_reg_defs: rev reg defs by rev reg id, augmented with transaction times """ msgs = [] now = int(time()) - non_revoc_intervals = indy_proof_req2non_revoc_intervals(pres_req) + non_revoc_intervals = extract_non_revocation_intervals_from_proof_request( + pres_req + ) LOGGER.debug(f">>> got non-revoc intervals: {non_revoc_intervals}") # timestamp for irrevocable credential diff --git a/acapy_agent/askar/profile.py b/acapy_agent/askar/profile.py index e80bc569f1..1a5c24f8b3 100644 --- a/acapy_agent/askar/profile.py +++ b/acapy_agent/askar/profile.py @@ -41,13 +41,25 @@ def __init__( *, profile_id: Optional[str] = None, ): - """Create a new AskarProfile instance.""" + """Private constructor. Use 'create' to instantiate.""" super().__init__(context=context, name=opened.name, created=opened.created) self.opened = opened self.ledger_pool: Optional[IndyVdrLedgerPool] = None self.profile_id = profile_id - self.init_ledger_pool() - self.bind_providers() + + @classmethod + async def create( + cls, + opened: AskarOpenStore, + context: Optional[InjectionContext] = None, + *, + profile_id: Optional[str] = None, + ) -> "AskarProfile": + """Asynchronously create a new AskarProfile instance.""" + profile = cls(opened, context, profile_id=profile_id) + await profile.init_ledger_pool() + await profile.bind_providers() + return profile @property def name(self) -> str: @@ -64,7 +76,7 @@ async def remove(self): if self.profile_id: await self.store.remove_profile(self.profile_id) - def init_ledger_pool(self): + async def init_ledger_pool(self): """Initialize the ledger pool.""" if self.settings.get("ledger.disabled"): LOGGER.info("Ledger support is disabled") @@ -78,8 +90,8 @@ def init_ledger_pool(self): LOGGER.warning("Note: setting ledger to read-only mode") genesis_transactions = self.settings.get("ledger.genesis_transactions") cache = self.context.injector.inject_or(BaseCache) - self.ledger_pool = IndyVdrLedgerPool( - pool_name, + self.ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=pool_name, keepalive=keepalive, cache=cache, genesis_transactions=genesis_transactions, @@ -87,7 +99,7 @@ def init_ledger_pool(self): socks_proxy=socks_proxy, ) - def bind_providers(self): + async def bind_providers(self): """Initialize the profile-level instance providers.""" injector = self._context.injector @@ -134,23 +146,17 @@ def bind_providers(self): settings=self.settings ) cache = self.context.injector.inject_or(BaseCache) + ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=write_ledger_config.get("pool_name") + or write_ledger_config.get("id"), + keepalive=write_ledger_config.get("keepalive"), + cache=cache, + genesis_transactions=write_ledger_config.get("genesis_transactions"), + read_only=write_ledger_config.get("read_only"), + socks_proxy=write_ledger_config.get("socks_proxy"), + ) injector.bind_provider( - BaseLedger, - ClassProvider( - IndyVdrLedger, - IndyVdrLedgerPool( - write_ledger_config.get("pool_name") - or write_ledger_config.get("id"), - keepalive=write_ledger_config.get("keepalive"), - cache=cache, - genesis_transactions=write_ledger_config.get( - "genesis_transactions" - ), - read_only=write_ledger_config.get("read_only"), - socks_proxy=write_ledger_config.get("socks_proxy"), - ), - ref(self), - ), + BaseLedger, ClassProvider(IndyVdrLedger, ledger_pool, ref(self)) ) self.settings["ledger.write_ledger"] = write_ledger_config.get("id") if ( @@ -325,7 +331,7 @@ async def provision( """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=True) - return AskarProfile(opened, context) + return await AskarProfile.create(opened, context) async def open( self, context: InjectionContext, config: Mapping[str, Any] = None @@ -333,7 +339,7 @@ async def open( """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=False) - return AskarProfile(opened, context) + return await AskarProfile.create(opened, context) @classmethod async def generate_store_key(self, seed: Optional[str] = None) -> str: diff --git a/acapy_agent/askar/profile_anon.py b/acapy_agent/askar/profile_anon.py index eea73d876f..2698b30387 100644 --- a/acapy_agent/askar/profile_anon.py +++ b/acapy_agent/askar/profile_anon.py @@ -43,13 +43,25 @@ def __init__( *, profile_id: Optional[str] = None, ): - """Create a new AskarProfile instance.""" + """Create a new AskarAnoncredsProfile instance.""" super().__init__(context=context, name=opened.name, created=opened.created) self.opened = opened self.ledger_pool: Optional[IndyVdrLedgerPool] = None self.profile_id = profile_id - self.init_ledger_pool() - self.bind_providers() + + @classmethod + async def create( + cls, + opened: AskarOpenStore, + context: Optional[InjectionContext] = None, + *, + profile_id: Optional[str] = None, + ) -> "AskarAnoncredsProfile": + """Asynchronously create a new AskarAnoncredsProfile instance.""" + profile = cls(opened, context, profile_id=profile_id) + await profile.init_ledger_pool() + await profile.bind_providers() + return profile @property def name(self) -> str: @@ -66,7 +78,7 @@ async def remove(self): if self.profile_id: await self.store.remove_profile(self.profile_id) - def init_ledger_pool(self): + async def init_ledger_pool(self): """Initialize the ledger pool.""" if self.settings.get("ledger.disabled"): LOGGER.info("Ledger support is disabled") @@ -80,8 +92,8 @@ def init_ledger_pool(self): LOGGER.warning("Note: setting ledger to read-only mode") genesis_transactions = self.settings.get("ledger.genesis_transactions") cache = self.context.injector.inject_or(BaseCache) - self.ledger_pool = IndyVdrLedgerPool( - pool_name, + self.ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=pool_name, keepalive=keepalive, cache=cache, genesis_transactions=genesis_transactions, @@ -89,7 +101,7 @@ def init_ledger_pool(self): socks_proxy=socks_proxy, ) - def bind_providers(self): + async def bind_providers(self): """Initialize the profile-level instance providers.""" injector = self._context.injector @@ -123,23 +135,17 @@ def bind_providers(self): settings=self.settings ) cache = self.context.injector.inject_or(BaseCache) + ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=write_ledger_config.get("pool_name") + or write_ledger_config.get("id"), + keepalive=write_ledger_config.get("keepalive"), + cache=cache, + genesis_transactions=write_ledger_config.get("genesis_transactions"), + read_only=write_ledger_config.get("read_only"), + socks_proxy=write_ledger_config.get("socks_proxy"), + ) injector.bind_provider( - BaseLedger, - ClassProvider( - IndyVdrLedger, - IndyVdrLedgerPool( - write_ledger_config.get("pool_name") - or write_ledger_config.get("id"), - keepalive=write_ledger_config.get("keepalive"), - cache=cache, - genesis_transactions=write_ledger_config.get( - "genesis_transactions" - ), - read_only=write_ledger_config.get("read_only"), - socks_proxy=write_ledger_config.get("socks_proxy"), - ), - ref(self), - ), + BaseLedger, ClassProvider(IndyVdrLedger, ledger_pool, ref(self)) ) self.settings["ledger.write_ledger"] = write_ledger_config.get("id") if ( @@ -278,7 +284,7 @@ async def provision( """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=True) - return AskarAnoncredsProfile(opened, context) + return await AskarAnoncredsProfile.create(opened, context) async def open( self, context: InjectionContext, config: Mapping[str, Any] = None @@ -286,7 +292,7 @@ async def open( """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=False) - return AskarAnoncredsProfile(opened, context) + return await AskarAnoncredsProfile.create(opened, context) @classmethod async def generate_store_key(self, seed: Optional[str] = None) -> str: diff --git a/acapy_agent/askar/tests/test_profile.py b/acapy_agent/askar/tests/test_profile.py index 38a0326ded..211166b9e3 100644 --- a/acapy_agent/askar/tests/test_profile.py +++ b/acapy_agent/askar/tests/test_profile.py @@ -16,7 +16,7 @@ def open_store(): @pytest.mark.asyncio async def test_init_success(open_store): - askar_profile = AskarProfile( + askar_profile = await AskarProfile.create( open_store, ) @@ -44,7 +44,7 @@ async def test_init_multi_ledger(open_store): ] } ) - askar_profile = AskarProfile( + askar_profile = await AskarProfile.create( open_store, context=context, ) @@ -67,7 +67,7 @@ async def test_remove_success(open_store): "wallet.askar_profile": profile_id, "ledger.genesis_transactions": mock.MagicMock(), } - askar_profile = AskarProfile(openStore, context, profile_id=profile_id) + askar_profile = await AskarProfile.create(openStore, context, profile_id=profile_id) remove_profile_stub = asyncio.Future() remove_profile_stub.set_result(True) openStore.store.remove_profile.return_value = remove_profile_stub @@ -82,7 +82,7 @@ async def test_remove_profile_not_removed_if_wallet_type_not_askar_profile(open_ openStore = open_store context = InjectionContext() context.settings = {"multitenant.wallet_type": "basic"} - askar_profile = AskarProfile(openStore, context) + askar_profile = await AskarProfile.create(openStore, context) await askar_profile.remove() @@ -94,7 +94,7 @@ async def test_profile_manager_transaction(): profile = "profileId" with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, True, profile_id=profile) + askar_profile = await AskarProfile.create(None, True, profile_id=profile) askar_profile.profile_id = profile askar_profile_transaction = mock.MagicMock() askar_profile.store.transaction.return_value = askar_profile_transaction @@ -110,7 +110,7 @@ async def test_profile_manager_store(): profile = "profileId" with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, False, profile_id=profile) + askar_profile = await AskarProfile.create(None, False, profile_id=profile) askar_profile.profile_id = profile askar_profile_session = mock.MagicMock() askar_profile.store.session.return_value = askar_profile_session diff --git a/acapy_agent/commands/provision.py b/acapy_agent/commands/provision.py index 962b38dc8e..f0fb7cf561 100644 --- a/acapy_agent/commands/provision.py +++ b/acapy_agent/commands/provision.py @@ -1,6 +1,7 @@ """Provision command for setting up agent settings before starting.""" import asyncio +import logging from typing import Sequence from configargparse import ArgumentParser @@ -22,6 +23,8 @@ from ..storage.base import BaseStorage from . import PROG +LOGGER = logging.getLogger(__name__) + class ProvisionError(BaseError): """Base exception for provisioning errors.""" @@ -58,9 +61,9 @@ async def provision(settings: dict): ) if await ledger_config(root_profile, public_did and public_did.did, True): - print("Ledger configured") + LOGGER.info("Ledger configured") else: - print("Ledger not configured") + LOGGER.warning("Ledger not configured") await root_profile.close() except BaseError as e: diff --git a/acapy_agent/commands/start.py b/acapy_agent/commands/start.py index f30fc5c582..fb8652314c 100644 --- a/acapy_agent/commands/start.py +++ b/acapy_agent/commands/start.py @@ -31,7 +31,7 @@ async def start_app(conductor: Conductor): async def shutdown_app(conductor: Conductor): """Shut down.""" - print("\nShutting down") + LOGGER.info("Shutting down") await conductor.stop() @@ -59,7 +59,7 @@ def execute(argv: Sequence[str] = None): # Run the application if uvloop: uvloop.install() - print("uvloop installed") + LOGGER.info("uvloop installed") run_loop(start_app(conductor), shutdown_app(conductor)) diff --git a/acapy_agent/commands/tests/test_help.py b/acapy_agent/commands/tests/test_help.py index 562b371ee2..1e1360328f 100644 --- a/acapy_agent/commands/tests/test_help.py +++ b/acapy_agent/commands/tests/test_help.py @@ -5,11 +5,10 @@ class TestHelp(IsolatedAsyncioTestCase): def test_exec_help(self): - with mock.patch.object( - command.ArgumentParser, "print_help" - ) as mock_print_help, mock.patch( - "builtins.print", mock.MagicMock() - ) as mock_print: + with ( + mock.patch.object(command.ArgumentParser, "print_help") as mock_print_help, + mock.patch("builtins.print", mock.MagicMock()) as mock_print, + ): command.execute([]) mock_print_help.assert_called_once() @@ -17,10 +16,9 @@ def test_exec_help(self): mock_print.assert_called_once_with(command.__version__) def test_main(self): - with mock.patch.object( - command, "__name__", "__main__" - ) as mock_name, mock.patch.object( - command, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(command, "__name__", "__main__") as mock_name, + mock.patch.object(command, "execute", mock.MagicMock()) as mock_execute, + ): command.main() mock_execute.assert_called_once diff --git a/acapy_agent/commands/tests/test_provision.py b/acapy_agent/commands/tests/test_provision.py index 65d0d488bd..ed50bb9eb8 100644 --- a/acapy_agent/commands/tests/test_provision.py +++ b/acapy_agent/commands/tests/test_provision.py @@ -21,17 +21,20 @@ def test_bad_calls(self): async def test_provision_ledger_configured(self): profile = mock.MagicMock(close=mock.CoroutineMock()) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + test_module, "ledger_config", mock.CoroutineMock(return_value=True) ), - ), mock.patch.object( - test_module, "ledger_config", mock.CoroutineMock(return_value=True) ): await test_module.provision({}) @@ -44,9 +47,10 @@ async def test_provision_config_x(self): await test_module.provision({}) def test_main(self): - with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(test_module, "__name__", "__main__"), + mock.patch.object(test_module, "execute", mock.MagicMock()) as mock_execute, + ): test_module.main() mock_execute.assert_called_once @@ -55,12 +59,13 @@ async def test_provision_should_store_provided_mediation_invite(self): mediation_invite = "test-invite" test_profile = await create_test_profile() - with mock.patch.object( - test_module.MediationInviteStore, "store" - ) as invite_store, mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock(return_value=(test_profile, mock.MagicMock())), + with ( + mock.patch.object(test_module.MediationInviteStore, "store") as invite_store, + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock(return_value=(test_profile, mock.MagicMock())), + ), ): # when await test_module.provision({"mediation.invite": mediation_invite}) diff --git a/acapy_agent/commands/tests/test_start.py b/acapy_agent/commands/tests/test_start.py index 451ab584bb..cac10b8df6 100644 --- a/acapy_agent/commands/tests/test_start.py +++ b/acapy_agent/commands/tests/test_start.py @@ -25,22 +25,23 @@ async def test_start_shutdown_app(self): await test_module.shutdown_app(mock_conductor) def test_exec_start(self): - with mock.patch.object( - # Normally this would be a CoroutineMock. However, it is awaited by - # run_loop, which is mocked out. So we mock it as a MagicMock. - test_module, - "start_app", - mock.MagicMock(), - ) as start_app, mock.patch.object( - test_module, "run_loop" - ) as run_loop, mock.patch.object( - # Same here as note above - test_module, - "shutdown_app", - mock.MagicMock(), - ) as shutdown_app, mock.patch.object( - test_module, "uvloop", mock.MagicMock() - ) as mock_uvloop: + with ( + mock.patch.object( + # Normally this would be a CoroutineMock. However, it is awaited by + # run_loop, which is mocked out. So we mock it as a MagicMock. + test_module, + "start_app", + mock.MagicMock(), + ) as start_app, + mock.patch.object(test_module, "run_loop") as run_loop, + mock.patch.object( + # Same here as note above + test_module, + "shutdown_app", + mock.MagicMock(), + ) as shutdown_app, + mock.patch.object(test_module, "uvloop", mock.MagicMock()) as mock_uvloop, + ): mock_uvloop.install = mock.MagicMock() test_module.execute( [ @@ -102,11 +103,10 @@ async def test_run_loop_init_x(self): startup_call = startup() shutdown = mock.CoroutineMock() shutdown_call = shutdown() - with mock.patch.object( - test_module, "asyncio", autospec=True - ) as mock_asyncio, mock.patch.object( - test_module, "LOGGER", autospec=True - ) as mock_logger: + with ( + mock.patch.object(test_module, "asyncio", autospec=True) as mock_asyncio, + mock.patch.object(test_module, "LOGGER", autospec=True) as mock_logger, + ): test_module.run_loop(startup_call, shutdown_call) mock_add = mock_asyncio.get_event_loop.return_value.add_signal_handler mock_add.assert_called_once() @@ -135,10 +135,9 @@ async def test_run_loop_init_x(self): mock_logger.exception.assert_called_once() def test_main(self): - with mock.patch.object( - test_module, "__name__", "__main__" - ) as mock_name, mock.patch.object( - test_module, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(test_module, "__name__", "__main__") as mock_name, + mock.patch.object(test_module, "execute", mock.MagicMock()) as mock_execute, + ): test_module.main() mock_execute.assert_called_once diff --git a/acapy_agent/commands/tests/test_upgrade.py b/acapy_agent/commands/tests/test_upgrade.py index 51a33640a3..41728221c8 100644 --- a/acapy_agent/commands/tests/test_upgrade.py +++ b/acapy_agent/commands/tests/test_upgrade.py @@ -47,20 +47,24 @@ def test_bad_calls(self): test_module.execute(["bad"]) async def test_upgrade_storage_from_version_included(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( settings={ "upgrade.config_path": "./acapy_agent/commands/default_version_upgrade_config.yml", @@ -69,20 +73,24 @@ async def test_upgrade_storage_from_version_included(self): ) async def test_upgrade_storage_missing_from_version(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade(settings={}) async def test_upgrade_from_version(self): @@ -91,11 +99,14 @@ async def test_upgrade_from_version(self): "upgrade.from_version": "v0.7.2", } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -109,11 +120,14 @@ async def test_upgrade_all_subwallets(self): "upgrade.page_size": 1, } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -131,11 +145,14 @@ async def test_upgrade_specified_subwallets(self): "upgrade.force_upgrade": True, } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -148,11 +165,14 @@ async def test_upgrade_specified_subwallets(self): "upgrade.page_size": 1, } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -164,29 +184,32 @@ async def test_upgrade_callable(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ] + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ] + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - } + } + ), ), ): await test_module.upgrade( @@ -202,30 +225,33 @@ async def test_upgrade_callable_named_tag(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ] + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ] + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "fix_issue_rev_reg": {"fix_issue_rev_reg_records": True}, - } + "fix_issue_rev_reg": {"fix_issue_rev_reg_records": True}, + } + ), ), ): await test_module.upgrade( @@ -265,20 +291,24 @@ async def test_upgrade_missing_from_version(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): with self.assertRaises(UpgradeError) as ctx: await test_module.upgrade( settings={ @@ -296,30 +326,33 @@ async def test_upgrade_x_callable_not_set(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ] + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ] + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "v0.6.0": {"update_existing_records_b": True}, - } + "v0.6.0": {"update_existing_records_b": True}, + } + ), ), ): with self.assertRaises(UpgradeError) as ctx: @@ -331,28 +364,31 @@ async def test_upgrade_x_callable_not_set(self): assert "No function specified for" in str(ctx.exception) async def test_upgrade_x_class_not_found(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.Invalid" - ], - } - }, - } + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.Invalid" + ], + } + }, + } + ), ), ): with self.assertRaises(UpgradeError) as ctx: @@ -364,28 +400,34 @@ async def test_upgrade_x_class_not_found(self): assert "Unknown Record type" in str(ctx.exception) async def test_execute(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + mock.patch.object( + asyncio, "get_event_loop", mock.MagicMock() + ) as mock_get_event_loop, + mock.patch.object( + # Normally, this would be a CoroutingMock. However, the coroutine + # is awaited by run_until_complete, which is mocked out. + # Use MagicMock to prevent unawaited coroutine warnings. + test_module, + "upgrade", + mock.MagicMock(), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), mock.patch.object( - asyncio, "get_event_loop", mock.MagicMock() - ) as mock_get_event_loop, mock.patch.object( - # Normally, this would be a CoroutingMock. However, the coroutine - # is awaited by run_until_complete, which is mocked out. - # Use MagicMock to prevent unawaited coroutine warnings. - test_module, - "upgrade", - mock.MagicMock(), ): mock_get_event_loop.return_value = mock.MagicMock( run_until_complete=mock.MagicMock(), @@ -401,28 +443,31 @@ async def test_execute(self): ) async def test_upgrade_x_invalid_record_type(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_exch_record_path": [ - "acapy_agent.connections.models.connection_target.ConnectionTarget" - ], + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_exch_record_path": [ + "acapy_agent.connections.models.connection_target.ConnectionTarget" + ], + } } } - } + ), ), ): with self.assertRaises(UpgradeError) as ctx: @@ -434,35 +479,38 @@ async def test_upgrade_x_invalid_record_type(self): assert "Only BaseRecord can be resaved" in str(ctx.exception) async def test_upgrade_force(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ], + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ], + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "v0.7.3": { - "update_existing_records": True, - }, - "v0.7.1": { - "update_existing_records": False, - }, - } + "v0.7.3": { + "update_existing_records": True, + }, + "v0.7.1": { + "update_existing_records": False, + }, + } + ), ), ): await test_module.upgrade( @@ -511,9 +559,10 @@ async def test_upgrade_x_params(self): assert "upgrade requires either profile or settings" in str(ctx.exception) def test_main(self): - with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(test_module, "__name__", "__main__"), + mock.patch.object(test_module, "execute", mock.MagicMock()) as mock_execute, + ): test_module.main() mock_execute.assert_called_once @@ -711,30 +760,31 @@ async def test_upgrade_explicit_check(self): await test_module.upgrade(profile=self.profile) assert "Explicit upgrade flag with critical value found" in str(ctx.exception) - with mock.patch.object( - test_module, "LOGGER", mock.MagicMock() - ) as mock_logger, mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ], + with ( + mock.patch.object(test_module, "LOGGER", mock.MagicMock()) as mock_logger, + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ], + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "v0.7.3": { - "update_existing_records": True, - "explicit_upgrade": "warning", - }, - "v0.7.1": { - "update_existing_records": True, - "explicit_upgrade": "warning", - }, - } + "v0.7.3": { + "update_existing_records": True, + "explicit_upgrade": "warning", + }, + "v0.7.1": { + "update_existing_records": True, + "explicit_upgrade": "warning", + }, + } + ), ), ): await test_module.upgrade(profile=self.profile) diff --git a/acapy_agent/config/argparse.py b/acapy_agent/config/argparse.py index 0d231f2307..2f830fd69f 100644 --- a/acapy_agent/config/argparse.py +++ b/acapy_agent/config/argparse.py @@ -63,7 +63,7 @@ def get_registered(cls, category: Optional[str] = None): def create_argument_parser(*, prog: Optional[str] = None): - """Create am instance of an arg parser, force yaml format for external config.""" + """Create an instance of an arg parser, force yaml format for external config.""" return ArgumentParser(config_file_parser_class=YAMLConfigFileParser, prog=prog) diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index 136c79791d..8f28b0eaee 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -1,5 +1,7 @@ """Classes for configuring the default injection context.""" +import logging + from ..anoncreds.registry import AnonCredsRegistry from ..cache.base import BaseCache from ..cache.in_memory import InMemoryCache @@ -26,17 +28,22 @@ from .injection_context import InjectionContext from .provider import CachedProvider, ClassProvider +LOGGER = logging.getLogger(__name__) + class DefaultContextBuilder(ContextBuilder): """Default context builder.""" async def build_context(self) -> InjectionContext: """Build the base injection context; set DIDComm prefix to emit.""" + LOGGER.debug("Building new injection context") + context = InjectionContext(settings=self.settings) context.settings.set_default("default_label", "Aries Cloud Agent") if context.settings.get("timing.enabled"): timing_log = context.settings.get("timing.log_file") + LOGGER.debug("Enabling timing collector with log file: %s", timing_log) collector = Collector(log_path=timing_log) context.injector.bind_instance(Collector, collector) @@ -63,11 +70,8 @@ async def build_context(self) -> InjectionContext: # DIDComm Messaging if context.settings.get("experiment.didcomm_v2"): - from didcomm_messaging import ( - CryptoService, - PackagingService, - RoutingService, - ) + LOGGER.info("DIDComm v2 experimental mode enabled") + from didcomm_messaging import CryptoService, PackagingService, RoutingService from didcomm_messaging.crypto.backend.askar import AskarCryptoService context.injector.bind_instance(CryptoService, AskarCryptoService()) @@ -81,11 +85,13 @@ async def build_context(self) -> InjectionContext: async def bind_providers(self, context: InjectionContext): """Bind various class providers.""" + LOGGER.debug("Begin binding providers to context") context.injector.bind_provider(ProfileManager, ProfileManagerProvider()) wallet_type = self.settings.get("wallet.type") if wallet_type == "askar-anoncreds": + LOGGER.debug("Using AnonCreds tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -93,6 +99,7 @@ async def bind_providers(self, context: InjectionContext): ), ) else: + LOGGER.debug("Using Indy tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -104,12 +111,7 @@ async def bind_providers(self, context: InjectionContext): context.injector.bind_provider( BaseWireFormat, CachedProvider( - # StatsProvider( ClassProvider("acapy_agent.transport.pack_format.PackWireFormat"), - # ( - # "encode_message", "parse_message" - # ), - # ) ), ) @@ -120,6 +122,7 @@ async def bind_providers(self, context: InjectionContext): async def load_plugins(self, context: InjectionContext): """Set up plugin registry and load plugins.""" + LOGGER.debug("Initializing plugin registry") plugin_registry = PluginRegistry( blocklist=self.settings.get("blocked_plugins", []) ) @@ -130,18 +133,18 @@ async def load_plugins(self, context: InjectionContext): if not self.settings.get("transport.disabled"): plugin_registry.register_package("acapy_agent.protocols") - # Currently providing admin routes only - plugin_registry.register_plugin("acapy_agent.holder") - - plugin_registry.register_plugin("acapy_agent.ledger") - - plugin_registry.register_plugin("acapy_agent.messaging.jsonld") - plugin_registry.register_plugin("acapy_agent.resolver") - plugin_registry.register_plugin("acapy_agent.settings") - plugin_registry.register_plugin("acapy_agent.vc") - plugin_registry.register_plugin("acapy_agent.vc.data_integrity") - plugin_registry.register_plugin("acapy_agent.wallet") - plugin_registry.register_plugin("acapy_agent.wallet.keys") + # Define plugin groups + default_plugins = [ + "acapy_agent.holder", + "acapy_agent.ledger", + "acapy_agent.messaging.jsonld", + "acapy_agent.resolver", + "acapy_agent.settings", + "acapy_agent.vc", + "acapy_agent.vc.data_integrity", + "acapy_agent.wallet", + "acapy_agent.wallet.keys", + ] anoncreds_plugins = [ "acapy_agent.anoncreds", @@ -157,26 +160,34 @@ async def load_plugins(self, context: InjectionContext): "acapy_agent.revocation", ] - def register_askar_plugins(): - for plugin in askar_plugins: + def register_plugins(plugins: list[str], plugin_type: str): + """Register a group of plugins with logging.""" + LOGGER.debug("Registering %s plugins", plugin_type) + for plugin in plugins: plugin_registry.register_plugin(plugin) + def register_askar_plugins(): + register_plugins(askar_plugins, "askar") + def register_anoncreds_plugins(): - for plugin in anoncreds_plugins: - plugin_registry.register_plugin(plugin) + register_plugins(anoncreds_plugins, "anoncreds") - if wallet_type == "askar-anoncreds": - register_anoncreds_plugins() - else: - register_askar_plugins() + register_plugins(default_plugins, "default") if context.settings.get("multitenant.admin_enabled"): + LOGGER.debug("Multitenant admin enabled - registering additional plugins") plugin_registry.register_plugin("acapy_agent.multitenant.admin") register_askar_plugins() register_anoncreds_plugins() + else: + if wallet_type == "askar-anoncreds": + register_anoncreds_plugins() + else: + register_askar_plugins() # Register external plugins for plugin_path in self.settings.get("external_plugins", []): + LOGGER.debug("Registering external plugin: %s", plugin_path) plugin_registry.register_plugin(plugin_path) # Register message protocols diff --git a/acapy_agent/config/ledger.py b/acapy_agent/config/ledger.py index 7d7acb1e7e..ab335913b9 100644 --- a/acapy_agent/config/ledger.py +++ b/acapy_agent/config/ledger.py @@ -34,14 +34,18 @@ async def fetch_genesis_transactions(genesis_url: str) -> str: # https://github.com/openwallet-foundation/acapy/issues/1745 return await fetch(genesis_url, headers=headers, max_attempts=20) except FetchError as e: + LOGGER.error("Error retrieving genesis transactions from %s: %s", genesis_url, e) raise ConfigError("Error retrieving ledger genesis transactions") from e async def get_genesis_transactions(settings: Settings) -> str: """Fetch genesis transactions if necessary.""" + LOGGER.debug("Getting genesis transactions from settings") txns = settings.get("ledger.genesis_transactions") + LOGGER.debug("Genesis transactions from settings: %s", "found" if txns else "absent") if not txns: + LOGGER.debug("No genesis transactions found in settings") if settings.get("ledger.genesis_url"): txns = await fetch_genesis_transactions(settings["ledger.genesis_url"]) elif settings.get("ledger.genesis_file"): @@ -51,8 +55,10 @@ async def get_genesis_transactions(settings: Settings) -> str: with open(genesis_path, "r") as genesis_file: txns = genesis_file.read() except IOError as e: + LOGGER.error("Failed to read genesis file: %s", str(e)) raise ConfigError("Error reading ledger genesis transactions") from e if txns: + LOGGER.debug("Storing genesis transactions in settings") settings["ledger.genesis_transactions"] = txns return txns @@ -63,6 +69,8 @@ async def load_multiple_genesis_transactions_from_config(settings: Settings): ledger_config_list = settings.get("ledger.ledger_config_list") ledger_txns_list = [] write_ledger_set = False + LOGGER.debug("Processing %d ledger configs", len(ledger_config_list)) + for config in ledger_config_list: txns = None if "genesis_transactions" in config: @@ -74,11 +82,12 @@ async def load_multiple_genesis_transactions_from_config(settings: Settings): try: genesis_path = config.get("genesis_file") LOGGER.info( - "Reading ledger genesis transactions from: %s", genesis_path + "Reading ledger genesis transactions from file: %s", genesis_path ) with open(genesis_path, "r") as genesis_file: txns = genesis_file.read() except IOError as e: + LOGGER.error("Failed to read genesis file: %s", str(e)) raise ConfigError("Error reading ledger genesis transactions") from e is_write_ledger = ( False if config.get("is_write") is None else config.get("is_write") @@ -119,6 +128,7 @@ async def load_multiple_genesis_transactions_from_config(settings: Settings): " genesis_file and genesis_transactions provided." ) settings["ledger.ledger_config_list"] = ledger_txns_list + LOGGER.debug("Processed %d ledger configs successfully", len(ledger_txns_list)) async def ledger_config( @@ -126,6 +136,10 @@ async def ledger_config( ) -> bool: """Perform Indy ledger configuration.""" + LOGGER.debug( + "Configuring ledger for profile %s and public_did %s", profile.name, public_did + ) + session = await profile.session() ledger = session.inject_or(BaseLedger) @@ -136,32 +150,46 @@ async def ledger_config( async with ledger: # Check transaction author agreement acceptance if not ledger.read_only: + LOGGER.debug("Checking transaction author agreement") taa_info = await ledger.get_txn_author_agreement() if taa_info["taa_required"] and public_did: + LOGGER.debug("TAA acceptance required") taa_accepted = await ledger.get_latest_txn_author_acceptance() if ( not taa_accepted or taa_info["taa_record"]["digest"] != taa_accepted["digest"] ): + LOGGER.info("TAA acceptance needed - performing acceptance") if not await accept_taa(ledger, profile, taa_info, provision): + LOGGER.warning("TAA acceptance failed") return False + LOGGER.info("TAA acceptance completed") # Publish endpoints if necessary - skipped if TAA is required but not accepted endpoint = session.settings.get("default_endpoint") if public_did: wallet = session.inject(BaseWallet) try: + LOGGER.debug("Setting DID endpoint to: %s", endpoint) await wallet.set_did_endpoint(public_did, endpoint, ledger) except LedgerError as x_ledger: + LOGGER.error("Error setting DID endpoint: %s", x_ledger.message) raise ConfigError(x_ledger.message) from x_ledger # e.g., read-only # Publish profile endpoint if ledger is NOT read-only profile_endpoint = session.settings.get("profile_endpoint") if profile_endpoint and not ledger.read_only: + LOGGER.debug( + "Publishing profile endpoint: %s for DID: %s", + profile_endpoint, + public_did, + ) await ledger.update_endpoint_for_did( public_did, profile_endpoint, EndpointType.PROFILE ) + LOGGER.info("Profile endpoint published successfully") + LOGGER.info("Ledger configuration complete") return True diff --git a/acapy_agent/config/logging/configurator.py b/acapy_agent/config/logging/configurator.py index 11763dca08..128ccf5e49 100644 --- a/acapy_agent/config/logging/configurator.py +++ b/acapy_agent/config/logging/configurator.py @@ -32,6 +32,8 @@ TimedRotatingFileMultiProcessHandler, ) +LOGGER = logging.getLogger(__name__) + def load_resource(path: str, encoding: Optional[str] = None): """Open a resource file located in a python package or the local filesystem. @@ -57,7 +59,8 @@ def load_resource(path: str, encoding: Optional[str] = None): return io.TextIOWrapper(bstream, encoding=encoding) return bstream except IOError: - pass + LOGGER.warning("Resource not found: %s", path) + return None def dictConfig(config, new_file_path=None): @@ -95,18 +98,7 @@ def fileConfig( raise RuntimeError(f"{fname} is invalid: {e}") if new_file_path and cp.has_section("handler_timed_file_handler"): - cp.set( - "handler_timed_file_handler", - "args", - str( - ( - f"{new_file_path}", - "d", - 7, - 1, - ) - ), - ) + cp.set("handler_timed_file_handler", "args", str((new_file_path, "d", 7, 1))) formatters = _create_formatters(cp) with logging._lock: diff --git a/acapy_agent/config/tests/test_ledger.py b/acapy_agent/config/tests/test_ledger.py index 5c2940305b..813e9c5d88 100644 --- a/acapy_agent/config/tests/test_ledger.py +++ b/acapy_agent/config/tests/test_ledger.py @@ -317,11 +317,14 @@ async def test_load_multiple_genesis_transactions_from_config_a(self): }, ], } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -412,11 +415,14 @@ async def test_load_multiple_genesis_transactions_from_config_b(self): ], "ledger.genesis_url": "http://localhost:9000/genesis", } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -474,11 +480,14 @@ async def test_load_multiple_genesis_transactions_config_error_a(self): }, ], } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -537,11 +546,14 @@ async def test_load_multiple_genesis_transactions_multiple_write(self): }, ] } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -596,11 +608,14 @@ async def test_load_multiple_genesis_transactions_from_config_io_x(self): }, ], } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.side_effect = IOError("no read permission") with self.assertRaises(test_module.ConfigError): await test_module.load_multiple_genesis_transactions_from_config(settings) @@ -629,31 +644,38 @@ async def test_ledger_accept_taa_tty(self, mock_stdout): "aml_record": {"aml": ["wallet_agreement", "on_file"]}, } - with mock.patch.object( - test_module, "use_asyncio_event_loop", mock.MagicMock() - ), mock.patch.object( - test_module.prompt_toolkit, "prompt", mock.CoroutineMock() - ) as mock_prompt: + with ( + mock.patch.object(test_module, "use_asyncio_event_loop", mock.MagicMock()), + mock.patch.object( + test_module.prompt_toolkit, "prompt", mock.CoroutineMock() + ) as mock_prompt, + ): mock_prompt.side_effect = EOFError() assert not await test_module.accept_taa( None, self.profile, taa_info, provision=False ) - with mock.patch.object( - test_module, "use_asyncio_event_loop", mock.MagicMock() - ) as mock_use_aio_loop, mock.patch.object( - test_module.prompt_toolkit, "prompt", mock.CoroutineMock() - ) as mock_prompt: + with ( + mock.patch.object( + test_module, "use_asyncio_event_loop", mock.MagicMock() + ) as mock_use_aio_loop, + mock.patch.object( + test_module.prompt_toolkit, "prompt", mock.CoroutineMock() + ) as mock_prompt, + ): mock_prompt.return_value = "x" assert not await test_module.accept_taa( None, self.profile, taa_info, provision=False ) - with mock.patch.object( - test_module, "use_asyncio_event_loop", mock.MagicMock() - ) as mock_use_aio_loop, mock.patch.object( - test_module.prompt_toolkit, "prompt", mock.CoroutineMock() - ) as mock_prompt: + with ( + mock.patch.object( + test_module, "use_asyncio_event_loop", mock.MagicMock() + ) as mock_use_aio_loop, + mock.patch.object( + test_module.prompt_toolkit, "prompt", mock.CoroutineMock() + ) as mock_prompt, + ): mock_ledger = mock.MagicMock(accept_txn_author_agreement=mock.CoroutineMock()) mock_prompt.return_value = "" assert await test_module.accept_taa( diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index cf23074568..366cbd244d 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -4,6 +4,7 @@ from unittest import IsolatedAsyncioTestCase, mock from ..logging import configurator as test_module +from ..logging import utils class TestLoggingConfigurator(IsolatedAsyncioTestCase): @@ -126,9 +127,10 @@ def test_load_resource(self): assert result is None # Testing package resource access with encoding (text mode) - with mock.patch("importlib.resources.files") as mock_files, mock.patch( - "io.TextIOWrapper", mock.MagicMock() - ) as mock_text_io_wrapper: + with ( + mock.patch("importlib.resources.files") as mock_files, + mock.patch("io.TextIOWrapper", mock.MagicMock()) as mock_text_io_wrapper, + ): # Setup the mocks mock_resource_path = mock.MagicMock() mock_files.return_value.joinpath.return_value = mock_resource_path diff --git a/acapy_agent/config/tests/test_wallet.py b/acapy_agent/config/tests/test_wallet.py index 3fbcae8593..6f360dcf06 100644 --- a/acapy_agent/config/tests/test_wallet.py +++ b/acapy_agent/config/tests/test_wallet.py @@ -67,10 +67,13 @@ async def test_wallet_config_existing_replace(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -106,10 +109,13 @@ async def test_wallet_config_existing_open(self): self.context.injector.bind_instance(ProfileManager, MockManager(self.profile)) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -135,10 +141,11 @@ async def test_wallet_config_auto_provision(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - MockManager, "open", mock.CoroutineMock() - ) as mock_mgr_open, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object(MockManager, "open", mock.CoroutineMock()) as mock_mgr_open, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_mgr_open.side_effect = test_module.ProfileNotFoundError() @@ -180,12 +187,15 @@ async def test_wallet_config_bad_seed_x(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, - "seed_to_did", - mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), - ), mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, + "seed_to_did", + mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), + ), + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): with self.assertRaises(test_module.ConfigError): await test_module.wallet_config(self.context, provision=True) @@ -206,10 +216,13 @@ async def test_wallet_config_seed_local(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -230,12 +243,15 @@ async def test_wallet_config_seed_public(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, - "seed_to_did", - mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), - ), mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, + "seed_to_did", + mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), + ), + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): await test_module.wallet_config(self.context, provision=True) @@ -249,10 +265,13 @@ async def test_wallet_config_seed_no_public_did(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -275,10 +294,13 @@ async def test_wallet_config_for_key_derivation_method(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - MockManager, "provision", mock.CoroutineMock() - ) as mock_mgr_provision, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + MockManager, "provision", mock.CoroutineMock() + ) as mock_mgr_provision, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_mgr_provision.return_value = self.profile diff --git a/acapy_agent/config/wallet.py b/acapy_agent/config/wallet.py index f857b07847..b19e202aa2 100644 --- a/acapy_agent/config/wallet.py +++ b/acapy_agent/config/wallet.py @@ -61,11 +61,11 @@ async def wallet_config( if provision: if profile.created: - print("Created new profile") + LOGGER.info("Created new profile") else: - print("Opened existing profile") - print("Profile backend:", profile.backend) - print("Profile name:", profile.name) + LOGGER.info("Opened existing profile") + LOGGER.info("Profile backend: %s", profile.backend) + LOGGER.info("Profile name: %s", profile.name) wallet_seed = context.settings.get("wallet.seed") wallet_local_did = context.settings.get("wallet.local_did") @@ -84,8 +84,8 @@ async def wallet_config( ) public_did = replace_did_info.did await wallet.set_public_did(public_did) - print(f"Created new public DID: {public_did}") - print(f"Verkey: {replace_did_info.verkey}") + LOGGER.info(f"Created new public DID: {public_did}") + LOGGER.info(f"Verkey: {replace_did_info.verkey}") else: # If we already have a registered public did and it doesn't match # the one derived from `wallet_seed` then we error out. @@ -107,20 +107,20 @@ async def wallet_config( ) local_did = local_did_info.did if provision: - print(f"Created new local DID: {local_did}") - print(f"Verkey: {local_did_info.verkey}") + LOGGER.info(f"Created new local DID: {local_did}") + LOGGER.info(f"Verkey: {local_did_info.verkey}") else: public_did_info = await wallet.create_public_did( method=SOV, key_type=ED25519, seed=wallet_seed ) public_did = public_did_info.did if provision: - print(f"Created new public DID: {public_did}") - print(f"Verkey: {public_did_info.verkey}") + LOGGER.info(f"Created new public DID: {public_did}") + LOGGER.info(f"Verkey: {public_did_info.verkey}") # wait until ledger config to set public DID endpoint - wallet goes first if provision and not wallet_local_did and not public_did: - print("No public DID") + LOGGER.info("No public DID") # Debug settings test_seed = context.settings.get("debug.seed") diff --git a/acapy_agent/connections/models/conn_record.py b/acapy_agent/connections/models/conn_record.py index 874d8c3d7f..e27be92c4f 100644 --- a/acapy_agent/connections/models/conn_record.py +++ b/acapy_agent/connections/models/conn_record.py @@ -11,8 +11,8 @@ from ...messaging.valid import ( GENERIC_DID_EXAMPLE, GENERIC_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, UUID4_EXAMPLE, ) from ...protocols.connections.v1_0.message_types import ARIES_PROTOCOL as CONN_PROTO @@ -725,10 +725,10 @@ class Meta: ) invitation_key = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Public key for connection", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) invitation_msg_id = fields.Str( diff --git a/acapy_agent/connections/models/connection_target.py b/acapy_agent/connections/models/connection_target.py index ad7219db0a..bc81adc42e 100644 --- a/acapy_agent/connections/models/connection_target.py +++ b/acapy_agent/connections/models/connection_target.py @@ -8,8 +8,8 @@ from ...messaging.valid import ( GENERIC_DID_EXAMPLE, GENERIC_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, ) @@ -75,10 +75,10 @@ class Meta: ) recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), required=False, @@ -86,10 +86,10 @@ class Meta: ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="routingKeys", @@ -98,9 +98,9 @@ class Meta: ) sender_key = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Sender public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) diff --git a/acapy_agent/connections/tests/test_base_manager.py b/acapy_agent/connections/tests/test_base_manager.py index 84089929ca..12aa05d8a7 100644 --- a/acapy_agent/connections/tests/test_base_manager.py +++ b/acapy_agent/connections/tests/test_base_manager.py @@ -1190,11 +1190,14 @@ async def test_resolve_inbound_connection(self): mock_conn = mock.MagicMock() mock_conn.connection_id = "dummy" - with mock.patch.object( - AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() - ) as mock_wallet_get_local_did_for_verkey, mock.patch.object( - self.manager, "find_connection", mock.CoroutineMock() - ) as mock_mgr_find_conn: + with ( + mock.patch.object( + AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() + ) as mock_wallet_get_local_did_for_verkey, + mock.patch.object( + self.manager, "find_connection", mock.CoroutineMock() + ) as mock_mgr_find_conn, + ): mock_wallet_get_local_did_for_verkey.return_value = DIDInfo( self.test_did, self.test_verkey, @@ -1216,11 +1219,14 @@ async def test_resolve_inbound_connection_injector_error(self): mock_conn = mock.MagicMock() mock_conn.connection_id = "dummy" - with mock.patch.object( - AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() - ) as mock_wallet_get_local_did_for_verkey, mock.patch.object( - self.manager, "find_connection", mock.CoroutineMock() - ) as mock_mgr_find_conn: + with ( + mock.patch.object( + AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() + ) as mock_wallet_get_local_did_for_verkey, + mock.patch.object( + self.manager, "find_connection", mock.CoroutineMock() + ) as mock_mgr_find_conn, + ): mock_wallet_get_local_did_for_verkey.side_effect = InjectionError() mock_mgr_find_conn.return_value = mock_conn @@ -1236,11 +1242,14 @@ async def test_resolve_inbound_connection_wallet_not_found_error(self): mock_conn = mock.MagicMock() mock_conn.connection_id = "dummy" - with mock.patch.object( - AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() - ) as mock_wallet_get_local_did_for_verkey, mock.patch.object( - self.manager, "find_connection", mock.CoroutineMock() - ) as mock_mgr_find_conn: + with ( + mock.patch.object( + AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() + ) as mock_wallet_get_local_did_for_verkey, + mock.patch.object( + self.manager, "find_connection", mock.CoroutineMock() + ) as mock_mgr_find_conn, + ): mock_wallet_get_local_did_for_verkey.side_effect = WalletNotFoundError() mock_mgr_find_conn.return_value = mock_conn @@ -1339,11 +1348,14 @@ async def test_get_connection_targets_retrieve_connection(self): retrieve_invitation=mock.CoroutineMock(return_value=conn_invite), ) - with mock.patch.object( - ConnectionTarget, "serialize", autospec=True - ) as mock_conn_target_ser, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id: + with ( + mock.patch.object( + ConnectionTarget, "serialize", autospec=True + ) as mock_conn_target_ser, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn mock_conn_target_ser.return_value = {"serialized": "value"} targets = await self.manager.get_connection_targets( @@ -1383,13 +1395,17 @@ async def test_get_connection_targets_from_cache(self): state=ConnRecord.State.COMPLETED.rfc160, ) - with mock.patch.object( - ConnectionTarget, "serialize", autospec=True - ) as mock_conn_target_ser, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - self.manager, "fetch_connection_targets", mock.CoroutineMock() - ) as mock_fetch_connection_targets: + with ( + mock.patch.object( + ConnectionTarget, "serialize", autospec=True + ) as mock_conn_target_ser, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + self.manager, "fetch_connection_targets", mock.CoroutineMock() + ) as mock_fetch_connection_targets, + ): mock_fetch_connection_targets.return_value = [ConnectionTarget()] mock_conn_rec_retrieve_by_id.return_value = mock_conn mock_conn_target_ser.return_value = {"serialized": "value"} @@ -1428,13 +1444,17 @@ async def test_get_connection_targets_no_cache(self): state=ConnRecord.State.COMPLETED.rfc160, ) - with mock.patch.object( - ConnectionTarget, "serialize", autospec=True - ) as mock_conn_target_ser, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - self.manager, "fetch_connection_targets", mock.CoroutineMock() - ) as mock_fetch_connection_targets: + with ( + mock.patch.object( + ConnectionTarget, "serialize", autospec=True + ) as mock_conn_target_ser, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + self.manager, "fetch_connection_targets", mock.CoroutineMock() + ) as mock_fetch_connection_targets, + ): mock_fetch_connection_targets.return_value = [ConnectionTarget()] mock_conn_rec_retrieve_by_id.return_value = mock_conn mock_conn_target_ser.return_value = {"serialized": "value"} @@ -1522,9 +1542,12 @@ async def test_create_static_connection_multitenant(self): self.multitenant_mgr.get_default_mediator.return_value = None self.route_manager.route_static = mock.CoroutineMock() - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, self.test_verkey, @@ -1552,11 +1575,15 @@ async def test_create_static_connection_multitenant_auto_disclose_features(self) ) self.multitenant_mgr.get_default_mediator.return_value = None self.route_manager.route_static = mock.CoroutineMock() - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, self.test_verkey, @@ -1581,12 +1608,15 @@ async def test_create_static_connection_multitenant_mediator(self): default_mediator = mock.MagicMock() self.route_manager.route_static = mock.CoroutineMock() - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - BaseConnectionManager, "create_did_document" - ) as create_did_document, mock.patch.object( - BaseConnectionManager, "store_did_document" + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + BaseConnectionManager, "create_did_document" + ) as create_did_document, + mock.patch.object(BaseConnectionManager, "store_did_document"), ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, @@ -1675,11 +1705,14 @@ async def test_find_connection_retrieve_by_did(self): async def test_find_connection_retrieve_by_did_auto_disclose_features(self): self.context.update_settings({"auto_disclose_features": True}) - with mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + ): mock_conn_retrieve_by_did.return_value = mock.MagicMock( state=ConnRecord.State.RESPONSE.rfc23, save=mock.CoroutineMock(), @@ -1695,11 +1728,14 @@ async def test_find_connection_retrieve_by_did_auto_disclose_features(self): mock_proactive_disclose_features.assert_called_once() async def test_find_connection_retrieve_by_invitation_key(self): - with mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + ): mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() mock_conn_retrieve_by_invitation_msg_id.return_value = mock.MagicMock( state=ConnRecord.State.RESPONSE, @@ -1714,11 +1750,14 @@ async def test_find_connection_retrieve_by_invitation_key(self): assert conn_rec async def test_find_connection_retrieve_none_by_invitation_key(self): - with mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - ConnRecord, "retrieve_by_invitation_key", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + ConnRecord, "retrieve_by_invitation_key", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + ): mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() mock_conn_retrieve_by_invitation_msg_id.return_value = None @@ -1732,13 +1771,17 @@ async def test_find_connection_retrieve_none_by_invitation_key(self): async def test_get_endpoints(self): conn_id = "dummy" - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - AskarWallet, "get_local_did", autospec=True - ) as mock_wallet_get_local_did, mock.patch.object( - self.manager, "get_connection_targets", mock.CoroutineMock() - ) as mock_get_conn_targets: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object( + AskarWallet, "get_local_did", autospec=True + ) as mock_wallet_get_local_did, + mock.patch.object( + self.manager, "get_connection_targets", mock.CoroutineMock() + ) as mock_get_conn_targets, + ): mock_retrieve.return_value = mock.MagicMock() mock_wallet_get_local_did.return_value = mock.MagicMock( metadata={"endpoint": "localhost:8020"} diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index feffb04074..08d89c37e2 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -42,10 +42,7 @@ from ..messaging.responder import BaseResponder from ..multitenant.base import BaseMultitenantManager from ..multitenant.manager_provider import MultitenantManagerProvider -from ..protocols.connections.v1_0.manager import ( - ConnectionManager, - ConnectionManagerError, -) +from ..protocols.connections.v1_0.manager import ConnectionManager, ConnectionManagerError from ..protocols.connections.v1_0.messages.connection_invitation import ( ConnectionInvitation, ) @@ -124,41 +121,60 @@ def context(self) -> InjectionContext: async def setup(self): """Initialize the global request context.""" + LOGGER.debug("Starting setup of the Conductor") context = await self.context_builder.build_context() + LOGGER.debug("Context built successfully") if self.force_agent_anoncreds: + LOGGER.debug( + "Force agent anoncreds is enabled. " + "Setting wallet type to 'askar-anoncreds'." + ) context.settings.set_value("wallet.type", "askar-anoncreds") # Fetch genesis transactions if necessary if context.settings.get("ledger.ledger_config_list"): + LOGGER.debug( + "Ledger config list found. Loading multiple genesis transactions" + ) await load_multiple_genesis_transactions_from_config(context.settings) if ( context.settings.get("ledger.genesis_transactions") or context.settings.get("ledger.genesis_file") or context.settings.get("ledger.genesis_url") ): + LOGGER.debug( + "Genesis transactions/configurations found. Fetching genesis transactions" + ) await get_genesis_transactions(context.settings) # Configure the root profile + LOGGER.debug("Configuring the root profile and setting up public DID") self.root_profile, self.setup_public_did = await wallet_config(context) context = self.root_profile.context + LOGGER.debug("Root profile configured successfully") # Multiledger Setup - if ( - context.settings.get("ledger.ledger_config_list") - and len(context.settings.get("ledger.ledger_config_list")) > 0 - ): + ledger_config_list = context.settings.get("ledger.ledger_config_list") + if ledger_config_list and len(ledger_config_list) > 0: + LOGGER.debug("Setting up multiledger manager") context.injector.bind_provider( BaseMultipleLedgerManager, MultiIndyLedgerManagerProvider(self.root_profile), ) - if not (context.settings.get("ledger.genesis_transactions")): + if not context.settings.get("ledger.genesis_transactions"): ledger = context.injector.inject(BaseLedger) + LOGGER.debug( + "Ledger backend: %s, Profile backend: %s", + ledger.BACKEND_NAME, + self.root_profile.BACKEND_NAME, + ) if ( self.root_profile.BACKEND_NAME == "askar" and ledger.BACKEND_NAME == "indy-vdr" ): + LOGGER.debug("Binding IndyCredxVerifier for 'askar' backend.") context.injector.bind_provider( IndyVerifier, ClassProvider( @@ -170,6 +186,9 @@ async def setup(self): self.root_profile.BACKEND_NAME == "askar-anoncreds" and ledger.BACKEND_NAME == "indy-vdr" ): + LOGGER.debug( + "Binding IndyCredxVerifier for 'askar-anoncreds' backend." + ) context.injector.bind_provider( IndyVerifier, ClassProvider( @@ -178,6 +197,7 @@ async def setup(self): ), ) else: + LOGGER.error("Unsupported ledger backend for multiledger setup.") raise MultipleLedgerManagerError( "Multiledger is supported only for Indy SDK or Askar " "[Indy VDR] profile" @@ -187,13 +207,17 @@ async def setup(self): ) # Configure the ledger - if not await ledger_config( + ledger_configured = await ledger_config( self.root_profile, self.setup_public_did and self.setup_public_did.did - ): - LOGGER.warning("No ledger configured") + ) + if not ledger_configured: + LOGGER.warning("No ledger configured.") + else: + LOGGER.debug("Ledger configured successfully.") if not context.settings.get("transport.disabled"): # Register all inbound transports if enabled + LOGGER.debug("Transport not disabled. Setting up inbound transports.") self.inbound_transport_manager = InboundTransportManager( self.root_profile, self.inbound_message_router, self.handle_not_returned ) @@ -201,45 +225,54 @@ async def setup(self): context.injector.bind_instance( InboundTransportManager, self.inbound_transport_manager ) + LOGGER.debug("Inbound transports registered successfully.") - if not context.settings.get("transport.disabled"): # Register all outbound transports + LOGGER.debug("Setting up outbound transports.") self.outbound_transport_manager = OutboundTransportManager( self.root_profile, self.handle_not_delivered ) await self.outbound_transport_manager.setup() + LOGGER.debug("Outbound transports registered successfully.") # Initialize dispatcher + LOGGER.debug("Initializing dispatcher.") self.dispatcher = Dispatcher(self.root_profile) await self.dispatcher.setup() + LOGGER.debug("Dispatcher initialized successfully.") wire_format = context.inject_or(BaseWireFormat) if wire_format and hasattr(wire_format, "task_queue"): wire_format.task_queue = self.dispatcher.task_queue + LOGGER.debug("Wire format task queue bound to dispatcher.") # Bind manager for multitenancy related tasks if context.settings.get("multitenant.enabled"): + LOGGER.debug("Multitenant is enabled. Binding MultitenantManagerProvider.") context.injector.bind_provider( BaseMultitenantManager, MultitenantManagerProvider(self.root_profile) ) # Bind route manager provider + LOGGER.debug("Binding RouteManagerProvider.") context.injector.bind_provider( RouteManager, RouteManagerProvider(self.root_profile) ) - # Bind oob message processor to be able to receive and process un-encrypted - # messages + # Bind OobMessageProcessor to be able to receive and process unencrypted messages + LOGGER.debug("Binding OobMessageProcessor.") context.injector.bind_instance( OobMessageProcessor, OobMessageProcessor(inbound_message_router=self.inbound_message_router), ) # Bind default PyLD document loader + LOGGER.debug("Binding default DocumentLoader.") context.injector.bind_instance(DocumentLoader, DocumentLoader(self.root_profile)) # Admin API if context.settings.get("admin.enabled"): + LOGGER.debug("Admin API is enabled. Attempting to register admin server.") try: admin_host = context.settings.get("admin.host", "0.0.0.0") admin_port = context.settings.get("admin.port", "80") @@ -255,13 +288,15 @@ async def setup(self): self.get_stats, ) context.injector.bind_instance(BaseAdminServer, self.admin_server) + LOGGER.debug("Admin server registered on %s:%s", admin_host, admin_port) except Exception: - LOGGER.exception("Unable to register admin server") + LOGGER.exception("Unable to register admin server.") raise # Fetch stats collector, if any collector = context.inject_or(Collector) if collector: + LOGGER.debug("Stats collector found. Wrapping methods for collection.") # add stats to our own methods collector.wrap( self, @@ -280,32 +315,40 @@ async def setup(self): "find_inbound_connection", ), ) + LOGGER.debug("Methods wrapped with stats collector.") async def start(self) -> None: """Start the agent.""" - + LOGGER.debug("Starting the Conductor agent.") context = self.root_profile.context await self.check_for_valid_wallet_type(self.root_profile) + LOGGER.debug("Wallet type validated.") if not context.settings.get("transport.disabled"): # Start up transports if enabled try: + LOGGER.debug("Transport not disabled. Starting inbound transports.") await self.inbound_transport_manager.start() + LOGGER.debug("Inbound transports started successfully.") except Exception: - LOGGER.exception("Unable to start inbound transports") + LOGGER.exception("Unable to start inbound transports.") raise try: + LOGGER.debug("Starting outbound transports.") await self.outbound_transport_manager.start() + LOGGER.debug("Outbound transports started successfully.") except Exception: - LOGGER.exception("Unable to start outbound transports") + LOGGER.exception("Unable to start outbound transports.") raise # Start up Admin server if self.admin_server: + LOGGER.debug("Admin server present. Starting admin server.") try: await self.admin_server.start() + LOGGER.debug("Admin server started successfully.") except Exception: - LOGGER.exception("Unable to start administration API") + LOGGER.exception("Unable to start administration API.") # Make admin responder available during message parsing # This allows webhooks to be called when a connection is marked active, # for example @@ -314,10 +357,12 @@ async def start(self) -> None: self.admin_server.outbound_message_router, ) context.injector.bind_instance(BaseResponder, responder) + LOGGER.debug("Admin responder bound to injector.") # Get agent label default_label = context.settings.get("default_label") public_did = self.setup_public_did and self.setup_public_did.did + LOGGER.debug("Agent label: %s", default_label) if context.settings.get("log.banner", True): if context.settings.get("transport.disabled"): @@ -352,6 +397,7 @@ async def start(self) -> None: from_version_storage = None from_version = None agent_version = f"v{__version__}" + LOGGER.debug("Recording ACA-Py version in wallet if needed.") async with self.root_profile.session() as session: storage: BaseStorage = session.context.inject(BaseStorage) try: @@ -366,10 +412,16 @@ async def start(self) -> None: ) except StorageNotFoundError: LOGGER.warning("Wallet version storage record not found.") + from_version_config = self.root_profile.settings.get("upgrade.from_version") force_upgrade_flag = ( self.root_profile.settings.get("upgrade.force_upgrade") or False ) + LOGGER.debug( + "Force upgrade flag: %s, From version config: %s", + force_upgrade_flag, + from_version_config, + ) if force_upgrade_flag and from_version_config: if from_version_storage: @@ -381,8 +433,13 @@ async def start(self) -> None: from_version = from_version_storage else: from_version = from_version_config + LOGGER.debug( + "Determined from_version based on force_upgrade: %s", from_version + ) else: from_version = from_version_storage or from_version_config + LOGGER.debug("Determined from_version: %s", from_version) + if not from_version: LOGGER.warning( ( @@ -393,17 +450,27 @@ async def start(self) -> None: ) from_version = DEFAULT_ACAPY_VERSION self.root_profile.settings.set_value("upgrade.from_version", from_version) + LOGGER.debug("Set upgrade.from_version to default: %s", from_version) + config_available_list = get_upgrade_version_list( config_path=self.root_profile.settings.get("upgrade.config_path"), from_version=from_version, ) + LOGGER.debug("Available upgrade versions: %s", config_available_list) + if len(config_available_list) >= 1: + LOGGER.info("Upgrade configurations available. Initiating upgrade.") await upgrade(profile=self.root_profile) elif not (from_version_storage and from_version_storage == agent_version): + LOGGER.debug("No upgrades needed. Adding version record.") await add_version_record(profile=self.root_profile, version=agent_version) # Create a static connection for use by the test-suite if context.settings.get("debug.test_suite_endpoint"): + LOGGER.debug( + "Test suite endpoint configured. " + "Creating static connection for test suite." + ) mgr = ConnectionManager(self.root_profile) their_endpoint = context.settings["debug.test_suite_endpoint"] test_conn = await mgr.create_static_connection( @@ -412,32 +479,38 @@ async def start(self) -> None: their_endpoint=their_endpoint, alias="test-suite", ) - print("Created static connection for test suite") - print(" - My DID:", test_conn.my_did) - print(" - Their DID:", test_conn.their_did) - print(" - Their endpoint:", their_endpoint) - print() + LOGGER.info( + "Created static connection for test suite\n" + f" - My DID: {test_conn.my_did}\n" + f" - Their DID: {test_conn.their_did}\n" + f" - Their endpoint: {their_endpoint}\n" + ) del mgr + LOGGER.debug("Static connection for test suite created and manager deleted.") # Clear default mediator if context.settings.get("mediation.clear"): + LOGGER.debug("Mediation clear flag set. Clearing default mediator.") mediation_mgr = MediationManager(self.root_profile) await mediation_mgr.clear_default_mediator() - print("Default mediator cleared.") + LOGGER.info("Default mediator cleared.") - # Clear default mediator # Set default mediator by id default_mediator_id = context.settings.get("mediation.default_id") if default_mediator_id: + LOGGER.debug("Setting default mediator to ID: %s", default_mediator_id) mediation_mgr = MediationManager(self.root_profile) try: await mediation_mgr.set_default_mediator_by_id(default_mediator_id) - print(f"Default mediator set to {default_mediator_id}") + LOGGER.info(f"Default mediator set to {default_mediator_id}") except Exception: - LOGGER.exception("Error updating default mediator") + LOGGER.exception("Error updating default mediator.") # Print an invitation to the terminal if context.settings.get("debug.print_invitation"): + LOGGER.debug( + "Debug flag for printing invitation is set. Creating invitation." + ) try: mgr = OutOfBandManager(self.root_profile) invi_rec = await mgr.create_invitation( @@ -451,17 +524,20 @@ async def start(self) -> None: ) base_url = context.settings.get("invite_base_url") invite_url = invi_rec.invitation.to_url(base_url) - print("Invitation URL:") - print(invite_url, flush=True) + LOGGER.info(f"Invitation URL:\n{invite_url}") qr = QRCode(border=1) qr.add_data(invite_url) qr.print_ascii(invert=True) del mgr except Exception: - LOGGER.exception("Error creating invitation") + LOGGER.exception("Error creating invitation.") # Print connections protocol invitation to the terminal if context.settings.get("debug.print_connections_invitation"): + LOGGER.debug( + "Debug flag for printing connections invitation is set. " + "Creating connections invitation." + ) try: mgr = ConnectionManager(self.root_profile) _record, invite = await mgr.create_invitation( @@ -474,17 +550,17 @@ async def start(self) -> None: ) base_url = context.settings.get("invite_base_url") invite_url = invite.to_url(base_url) - print("Invitation URL (Connections protocol):") - print(invite_url, flush=True) + LOGGER.info(f"Invitation URL (Connections protocol):\n{invite_url}") qr = QRCode(border=1) qr.add_data(invite_url) qr.print_ascii(invert=True) del mgr except Exception: - LOGGER.exception("Error creating invitation") + LOGGER.exception("Error creating connections protocol invitation.") # mediation connection establishment provided_invite: str = context.settings.get("mediation.invite") + LOGGER.debug("Mediation invite provided: %s", provided_invite) try: async with self.root_profile.session() as session: @@ -492,16 +568,24 @@ async def start(self) -> None: mediation_invite_record = await invite_store.get_mediation_invite_record( provided_invite ) + LOGGER.debug("Mediation invite record retrieved successfully.") except Exception: - LOGGER.exception("Error retrieving mediator invitation") + LOGGER.exception("Error retrieving mediator invitation.") mediation_invite_record = None # Accept mediation invitation if one was specified or stored if mediation_invite_record is not None: + LOGGER.debug( + "Mediation invite record found. " + "Attempting to accept mediation invitation." + ) try: mediation_connections_invite = context.settings.get( "mediation.connections_invite", False ) + LOGGER.debug( + "Mediation connections invite flag: %s", mediation_connections_invite + ) invitation_handler = ( ConnectionInvitation if mediation_connections_invite @@ -509,8 +593,11 @@ async def start(self) -> None: ) if not mediation_invite_record.used: - # clear previous mediator configuration before establishing a - # new one + # clear previous mediator configuration before establishing a new one + LOGGER.debug( + "Mediation invite not used. " + "Clearing default mediator before accepting new invite." + ) await MediationManager(self.root_profile).clear_default_mediator() mgr = ( @@ -518,6 +605,7 @@ async def start(self) -> None: if mediation_connections_invite else OutOfBandManager(self.root_profile) ) + LOGGER.debug("Receiving mediation invitation.") record = await mgr.receive_invitation( invitation=invitation_handler.from_url( mediation_invite_record.invite @@ -528,6 +616,7 @@ async def start(self) -> None: await MediationInviteStore( session.context.inject(BaseStorage) ).mark_default_invite_as_used() + LOGGER.debug("Marked mediation invite as used.") await record.metadata_set( session, MediationManager.SEND_REQ_AFTER_CONNECTION, True @@ -535,48 +624,65 @@ async def start(self) -> None: await record.metadata_set( session, MediationManager.SET_TO_DEFAULT_ON_GRANTED, True ) + LOGGER.debug("Set mediation metadata after connection.") - print("Attempting to connect to mediator...") + LOGGER.info("Attempting to connect to mediator...") del mgr + LOGGER.debug("Mediation manager deleted after setting up mediator.") except Exception: - LOGGER.exception("Error accepting mediation invitation") + LOGGER.exception("Error accepting mediation invitation.") try: + LOGGER.debug("Checking for wallet upgrades in progress.") await self.check_for_wallet_upgrades_in_progress() + LOGGER.debug("Wallet upgrades check completed.") except Exception: LOGGER.exception( - "An exception was caught while checking for wallet upgrades in progress" + "An exception was caught while checking for wallet upgrades in progress." ) # notify protocols of startup status + LOGGER.debug("Notifying protocols of startup status.") await self.root_profile.notify(STARTUP_EVENT_TOPIC, {}) + LOGGER.debug("Startup notification sent.") async def stop(self, timeout=1.0): """Stop the agent.""" + LOGGER.info("Stopping the Conductor agent.") # notify protocols that we are shutting down if self.root_profile: + LOGGER.debug("Notifying protocols of shutdown.") await self.root_profile.notify(SHUTDOWN_EVENT_TOPIC, {}) + LOGGER.debug("Shutdown notification sent.") shutdown = TaskQueue() if self.dispatcher: + LOGGER.debug("Initiating shutdown of dispatcher.") shutdown.run(self.dispatcher.complete()) if self.admin_server: + LOGGER.debug("Initiating shutdown of admin server.") shutdown.run(self.admin_server.stop()) if self.inbound_transport_manager: + LOGGER.debug("Initiating shutdown of inbound transport manager.") shutdown.run(self.inbound_transport_manager.stop()) if self.outbound_transport_manager: + LOGGER.debug("Initiating shutdown of outbound transport manager.") shutdown.run(self.outbound_transport_manager.stop()) if self.root_profile: # close multitenant profiles multitenant_mgr = self.context.inject_or(BaseMultitenantManager) if multitenant_mgr: + LOGGER.debug("Closing multitenant profiles.") for profile in multitenant_mgr.open_profiles: + LOGGER.debug("Closing profile: %s", profile.name) shutdown.run(profile.close()) - + LOGGER.debug("Closing root profile.") shutdown.run(self.root_profile.close()) + LOGGER.debug("Waiting for shutdown tasks to complete with timeout=%f.", timeout) await shutdown.complete(timeout) + LOGGER.info("Conductor agent stopped successfully.") def inbound_message_router( self, @@ -867,19 +973,7 @@ async def check_for_valid_wallet_type(self, profile): async def check_for_wallet_upgrades_in_progress(self): """Check for upgrade and upgrade if needed.""" - - # We need to use the correct multitenant manager for single vs multiple wallets - # here because the multitenant provider hasn't been initialized yet. - manager_type = self.context.settings.get_value( - "multitenant.wallet_type", default="basic" - ).lower() - - manager_class = MultitenantManagerProvider.MANAGER_TYPES.get( - manager_type, manager_type - ) - - multitenant_mgr = self.context.inject_or(manager_class) - if multitenant_mgr: + if self.context.settings.get_value("multitenant.enabled"): subwallet_profiles = await get_subwallet_profiles_from_storage( self.root_profile ) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index b3fa709386..55bf1d08a1 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -3,7 +3,7 @@ import logging from collections import OrderedDict from types import ModuleType -from typing import Iterable, Optional, Sequence +from typing import Optional, Sequence, Set from ..config.injection_context import InjectionContext from ..core.event_bus import EventBus @@ -18,10 +18,10 @@ class PluginRegistry: """Plugin registry for indexing application plugins.""" - def __init__(self, blocklist: Iterable[str] = []): + def __init__(self, blocklist: Optional[Set[str]] = None): """Initialize a `PluginRegistry` instance.""" - self._plugins = OrderedDict() - self._blocklist = set(blocklist) + self._plugins: OrderedDict[str, ModuleType] = OrderedDict() + self._blocklist: Set[str] = set(blocklist) if blocklist else set() @property def plugin_names(self) -> Sequence[str]: @@ -57,7 +57,6 @@ def validate_version(self, version_list, module_name): for version_dict in version_list: # Dicts must have correct format - try: if not ( isinstance(version_dict["major_version"], int) @@ -89,8 +88,8 @@ def validate_version(self, version_list, module_name): > version_dict["current_minor_version"] ): raise ProtocolDefinitionValidationError( - "Minimum supported minor version cannot" - + " be greater than current minor version" + "Minimum supported minor version cannot " + "be greater than current minor version" ) # There can only be one definition per major version @@ -102,7 +101,7 @@ def validate_version(self, version_list, module_name): if count > 1: raise ProtocolDefinitionValidationError( "There can only be one definition per major version. " - + f"Found {count} for major version {major_version}." + f"Found {count} for major version {major_version}." ) # Specified module must be loadable @@ -111,97 +110,126 @@ def validate_version(self, version_list, module_name): if not mod: raise ProtocolDefinitionValidationError( - "Version module path is not " - + f"loadable: {module_name}, {version_path}" + f"Version module path is not loadable: {module_name}, {version_path}" ) return True - def register_plugin(self, module_name: str) -> ModuleType: + def register_plugin(self, module_name: str) -> Optional[ModuleType]: """Register a plugin module.""" - if module_name in self._plugins: - mod = self._plugins[module_name] - elif module_name in self._blocklist: - LOGGER.debug(f"Blocked {module_name} from loading due to blocklist") + if self._is_already_registered(module_name): + return self._plugins.get(module_name) + + if self._is_blocked(module_name): return None - else: - try: - mod = ClassLoader.load_module(module_name) - LOGGER.debug(f"Loaded module: {module_name}") - except ModuleLoadError as e: - LOGGER.error(f"Error loading plugin module: {e}") - return None - # Module must exist - if not mod: - LOGGER.error(f"Module doesn't exist: {module_name}") - return None - - # Any plugin with a setup method is considered valid. - if hasattr(mod, "setup"): - self._plugins[module_name] = mod - return mod - - # Make an exception for non-protocol modules - # that contain admin routes and for old-style protocol - # modules without version support - routes = ClassLoader.load_module("routes", module_name) - message_types = ClassLoader.load_module("message_types", module_name) - if routes or message_types: - self._plugins[module_name] = mod - return mod - - definition = ClassLoader.load_module("definition", module_name) - - # definition.py must exist in protocol - if not definition: - LOGGER.error(f"Protocol does not include definition.py: {module_name}") - return None - - # definition.py must include versions attribute - if not hasattr(definition, "versions"): - LOGGER.error( - "Protocol definition does not include " - f"versions attribute: {module_name}" - ) - return None + mod = self._load_module(module_name) + if not mod: + LOGGER.error("Module doesn't exist: %s", module_name) + return None - # Definition list must not be malformed - try: - self.validate_version(definition.versions, module_name) - except ProtocolDefinitionValidationError as e: - LOGGER.error(f"Protocol versions definition is malformed. {e}") - return None + if self._is_valid_plugin(mod, module_name): + self._plugins[module_name] = mod + LOGGER.debug("Registered plugin: %s", module_name) + return mod - self._plugins[module_name] = mod - return mod + LOGGER.warning("Failed to register plugin: %s", module_name) + return None - # # Load each version as a separate plugin - # for version in definition.versions: - # mod = ClassLoader.load_module(f"{module_name}.{version['path']}") - # self._plugins[module_name] = mod - # return mod + def _is_already_registered(self, module_name: str) -> bool: + """Check if the plugin is already registered.""" + if module_name in self._plugins: + LOGGER.debug("Plugin %s is already registered.", module_name) + return True + return False + + def _is_blocked(self, module_name: str) -> bool: + """Check if the plugin is in the blocklist.""" + if module_name in self._blocklist: + LOGGER.debug("Blocked %s from loading due to blocklist.", module_name) + return True + return False + + def _load_module(self, module_name: str) -> Optional[ModuleType]: + """Load the plugin module using ClassLoader.""" + try: + mod = ClassLoader.load_module(module_name) + return mod + except ModuleLoadError as e: + LOGGER.error("Error loading plugin module '%s': %s", module_name, e) + return None + + def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: + """Validate the plugin based on various criteria.""" + # Check if the plugin has a 'setup' method + if hasattr(mod, "setup"): + return True + + # Check for 'routes' or 'message_types' modules + # This makes an exception for non-protocol modules that contain admin routes + # and for old-style protocol modules without version support + routes = ClassLoader.load_module("routes", module_name) + message_types = ClassLoader.load_module("message_types", module_name) + if routes or message_types: + return True + + # Check for 'definition' module with 'versions' attribute + definition = ClassLoader.load_module("definition", module_name) + if not definition: + LOGGER.error( + "Protocol does not include 'definition.py' for module: %s", + module_name, + ) + return False + + if not hasattr(definition, "versions"): + LOGGER.error( + "Protocol definition does not include versions attribute for module: %s", + module_name, + ) + return False + + # Validate the 'versions' attribute + try: + self.validate_version(definition.versions, module_name) + return True + except ProtocolDefinitionValidationError as e: + LOGGER.error( + "Protocol versions definition is malformed for module '%s': %s", + module_name, + e, + ) + return False def register_package(self, package_name: str) -> Sequence[ModuleType]: """Register all modules (sub-packages) under a given package name.""" + LOGGER.debug("Registering package: %s", package_name) try: module_names = ClassLoader.scan_subpackages(package_name) except ModuleLoadError: LOGGER.error("Plugin module package not found: %s", package_name) module_names = [] - return list( - filter( - None, - ( - self.register_plugin(module_name) - for module_name in module_names - if module_name.split(".")[-1] != "tests" - ), - ) - ) - async def init_context(self, context: InjectionContext): + registered_plugins = [] + for module_name in module_names: + # Skip any module whose last segment is 'tests' + if module_name.split(".")[-1] == "tests": + continue + + plugin = self.register_plugin(module_name) + if plugin: + registered_plugins.append(plugin) + else: + LOGGER.warning( + "Failed to register %s under %s", module_name, package_name + ) + + return registered_plugins + + async def init_context(self, context: InjectionContext) -> None: """Call plugin setup methods on the current context.""" + LOGGER.debug("Initializing plugin context for %d plugins", len(self._plugins)) + for plugin in self._plugins.values(): if hasattr(plugin, "setup"): await plugin.setup(context) @@ -216,25 +244,29 @@ async def load_protocol_version( context: InjectionContext, mod: ModuleType, version_definition: Optional[dict] = None, - ): + ) -> None: """Load a particular protocol version.""" protocol_registry = context.inject(ProtocolRegistry) goal_code_registry = context.inject(GoalCodeRegistry) + if hasattr(mod, "MESSAGE_TYPES"): protocol_registry.register_message_types( mod.MESSAGE_TYPES, version_definition=version_definition ) + if hasattr(mod, "CONTROLLERS"): protocol_registry.register_controllers(mod.CONTROLLERS) goal_code_registry.register_controllers(mod.CONTROLLERS) - async def load_protocols(self, context: InjectionContext, plugin: ModuleType): + async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> None: """For modules that don't implement setup, register protocols manually.""" + plugin_name = plugin.__name__ # If this module contains message_types, then assume that # this is a valid module of the old style (not versioned) try: - mod = ClassLoader.load_module(plugin.__name__ + ".message_types") + message_types_path = f"{plugin_name}.message_types" + mod = ClassLoader.load_module(message_types_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin module message types: %s", e) return @@ -242,106 +274,134 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType): if mod: await self.load_protocol_version(context, mod) else: - # Otherwise, try check for definition.py for versioned - # protocol packages + # Otherwise, try check for definition.py for versioned protocol packages try: - definition = ClassLoader.load_module(plugin.__name__ + ".definition") + definition_path = f"{plugin_name}.definition" + definition = ClassLoader.load_module(definition_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin definition module: %s", e) return if definition: for protocol_version in definition.versions: + version_path = ( + f"{plugin_name}.{protocol_version['path']}.message_types" + ) try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{protocol_version['path']}" - + ".message_types" - ) - await self.load_protocol_version(context, mod, protocol_version) - + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading plugin module message types: %s", e) + LOGGER.error( + "Error loading plugin module message types from %s: %s", + version_path, + e, + ) return - async def register_admin_routes(self, app): + if mod: + await self.load_protocol_version(context, mod, protocol_version) + else: + LOGGER.debug("Failed to load %s", version_path) + + async def register_admin_routes(self, app) -> None: """Call route registration methods on the current context.""" + LOGGER.debug("Registering admin routes for %d plugins", len(self._plugins)) + for plugin in self._plugins.values(): - definition = ClassLoader.load_module("definition", plugin.__name__) + plugin_name = plugin.__name__ + mod = None + definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. for plugin_version in definition.versions: + version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{plugin_version['path']}.routes" - ) + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error( + "Error loading admin routes from %s: %s", version_path, e + ) continue + if mod and hasattr(mod, "register"): await mod.register(app) else: # Load plugin routes that aren't in a versioned package. + routes_path = f"{plugin_name}.routes" try: - mod = ClassLoader.load_module(f"{plugin.__name__}.routes") + mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading admin routes from %s: %s", routes_path, e) continue + if mod and hasattr(mod, "register"): await mod.register(app) - def register_protocol_events(self, context: InjectionContext): + def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" + LOGGER.debug("Registering protocol events for %d plugins", len(self._plugins)) + event_bus = context.inject_or(EventBus) if not event_bus: LOGGER.error("No event bus in context") return + for plugin in self._plugins.values(): - definition = ClassLoader.load_module("definition", plugin.__name__) + plugin_name = plugin.__name__ + mod = None + definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. for plugin_version in definition.versions: + version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{plugin_version['path']}.routes" - ) + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading events from %s: %s", version_path, e) continue + if mod and hasattr(mod, "register_events"): mod.register_events(event_bus) else: # Load plugin routes that aren't in a versioned package. + routes_path = f"{plugin_name}.routes" try: - mod = ClassLoader.load_module(f"{plugin.__name__}.routes") + mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading events from %s: %s", routes_path, e) continue + if mod and hasattr(mod, "register_events"): mod.register_events(event_bus) - def post_process_routes(self, app): + def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" + LOGGER.debug("Post-processing routes for %d plugins", len(self._plugins)) + for plugin in self._plugins.values(): - definition = ClassLoader.load_module("definition", plugin.__name__) + plugin_name = plugin.__name__ + mod = None + definition = ClassLoader.load_module("definition", plugin_name) if definition: # Set binary file responses for routes that are in a versioned package. for plugin_version in definition.versions: + version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{plugin_version['path']}.routes" - ) + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading routes from %s: %s", version_path, e) continue + if mod and hasattr(mod, "post_process_routes"): mod.post_process_routes(app) else: # Set binary file responses for routes not in a versioned package. + routes_path = f"{plugin_name}.routes" try: - mod = ClassLoader.load_module(f"{plugin.__name__}.routes") + mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading routes from %s: %s", routes_path, e) continue + if mod and hasattr(mod, "post_process_routes"): mod.post_process_routes(app) diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 875623deee..6d8530a4e5 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -1,5 +1,5 @@ -from io import StringIO from unittest import IsolatedAsyncioTestCase +from unittest.mock import call import pytest @@ -120,26 +120,32 @@ async def test_startup_version_record_exists(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] - ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger: + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + ): await conductor.setup() mock_inbound_mgr.return_value.setup.assert_awaited_once() @@ -178,24 +184,29 @@ async def test_startup_version_no_upgrade_add_record(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] - ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -218,26 +229,34 @@ async def test_startup_version_force_upgrade(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] - ), - ), mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -255,27 +274,36 @@ async def test_startup_version_force_upgrade(self): await conductor.stop() test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), - ), mock.patch.object(test_module, "ledger_config"), mock.patch.object( - test_module.Conductor, "check_for_valid_wallet_type" + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, + ), + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), + ), + mock.patch.object(test_module, "ledger_config"), + mock.patch.object(test_module.Conductor, "check_for_valid_wallet_type"), ): await conductor.setup() mock_inbound_mgr.return_value.registered_transports = {} @@ -290,35 +318,46 @@ async def test_startup_version_record_not_exists(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, + ), + mock.patch.object( + BaseStorage, + "find_record", + mock.CoroutineMock( + side_effect=[mock.MagicMock(value="askar"), StorageNotFoundError()] + ), + ), + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), + ), + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False - ), mock.patch.object( - BaseStorage, - "find_record", - mock.CoroutineMock( - side_effect=[mock.MagicMock(value="askar"), StorageNotFoundError()] - ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), - ), mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) @@ -348,20 +387,23 @@ async def test_startup_admin_server_x(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ), mock.patch.object( - test_module, "AdminServer", mock.MagicMock() - ) as mock_admin_server: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "LoggingConfigurator", autospec=True), + mock.patch.object( + test_module, "AdminServer", mock.MagicMock() + ) as mock_admin_server, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -375,21 +417,29 @@ async def test_startup_no_public_did(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): mock_outbound_mgr.return_value.registered_transports = {} mock_outbound_mgr.return_value.enqueue_message = mock.CoroutineMock() @@ -422,19 +472,26 @@ async def test_stats(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): mock_inbound_mgr.return_value.sessions = ["dummy"] mock_outbound_mgr.return_value.outbound_buffer = [ @@ -466,16 +523,19 @@ async def test_inbound_message_handler(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -504,26 +564,32 @@ async def test_inbound_message_handler_ledger_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - conductor.dispatcher, "queue_message", autospec=True - ) as mock_dispatch_q, mock.patch.object( - conductor.admin_server, "notify_fatal_error", mock.MagicMock() - ) as mock_notify: + with ( + mock.patch.object( + conductor.dispatcher, "queue_message", autospec=True + ) as mock_dispatch_q, + mock.patch.object( + conductor.admin_server, "notify_fatal_error", mock.MagicMock() + ) as mock_notify, + ): mock_dispatch_q.side_effect = test_module.LedgerConfigError("ledger down") message_body = "{}" @@ -583,16 +649,19 @@ async def test_outbound_message_handler_with_target(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -623,18 +692,22 @@ async def test_outbound_message_handler_with_connection(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as conn_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as conn_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -672,16 +745,19 @@ async def test_outbound_message_handler_with_verkey_no_target(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -717,16 +793,19 @@ async def test_handle_nots(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", mock.MagicMock() - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", mock.MagicMock() + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), enqueue_message=mock.CoroutineMock(), @@ -743,11 +822,12 @@ async def test_handle_nots(self): conductor.handle_not_returned(conductor.root_profile, message) - with mock.patch.object( - test_module, "ConnectionManager" - ) as mock_conn_mgr, mock.patch.object( - conductor.dispatcher, "run_task", mock.MagicMock() - ) as mock_run_task: + with ( + mock.patch.object(test_module, "ConnectionManager") as mock_conn_mgr, + mock.patch.object( + conductor.dispatcher, "run_task", mock.MagicMock() + ) as mock_run_task, + ): # Normally this should be a coroutine mock; however, the coroutine # is awaited by dispatcher.run_task, which is mocked here. MagicMock # to prevent unawaited coroutine warning. @@ -795,25 +875,31 @@ async def test_handle_not_returned_ledger_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - conductor.dispatcher, "run_task", mock.MagicMock() - ) as mock_dispatch_run, mock.patch.object( - conductor.admin_server, "notify_fatal_error", mock.MagicMock() - ) as mock_notify: + with ( + mock.patch.object( + conductor.dispatcher, "run_task", mock.MagicMock() + ) as mock_dispatch_run, + mock.patch.object( + conductor.admin_server, "notify_fatal_error", mock.MagicMock() + ) as mock_notify, + ): mock_dispatch_run.side_effect = test_module.LedgerConfigError( "No such ledger" ) @@ -837,28 +923,35 @@ async def test_queue_outbound_ledger_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as conn_mgr, mock.patch.object( - conductor.dispatcher, "run_task", mock.MagicMock() - ) as mock_dispatch_run, mock.patch.object( - conductor.admin_server, "notify_fatal_error", mock.MagicMock() - ) as mock_notify: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as conn_mgr, + mock.patch.object( + conductor.dispatcher, "run_task", mock.MagicMock() + ) as mock_dispatch_run, + mock.patch.object( + conductor.admin_server, "notify_fatal_error", mock.MagicMock() + ) as mock_notify, + ): # Normally this should be a coroutine mock; however, the coroutine # is awaited by dispatcher.run_task, which is mocked here. MagicMock # to prevent unawaited coroutine warning. @@ -886,16 +979,19 @@ async def test_admin(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -903,9 +999,10 @@ async def test_admin(self): admin = conductor.context.inject(BaseAdminServer) assert admin is conductor.admin_server - with mock.patch.object( - admin, "start", autospec=True - ) as admin_start, mock.patch.object(admin, "stop", autospec=True) as admin_stop: + with ( + mock.patch.object(admin, "start", autospec=True) as admin_start, + mock.patch.object(admin, "stop", autospec=True) as admin_stop, + ): await conductor.start() admin_start.assert_awaited_once_with() @@ -925,16 +1022,19 @@ async def test_admin_startx(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -942,13 +1042,12 @@ async def test_admin_startx(self): admin = conductor.context.inject(BaseAdminServer) assert admin is conductor.admin_server - with mock.patch.object( - admin, "start", autospec=True - ) as admin_start, mock.patch.object( - admin, "stop", autospec=True - ) as admin_stop, mock.patch.object( - test_module, "OutOfBandManager" - ) as oob_mgr, mock.patch.object(test_module, "ConnectionManager") as conn_mgr: + with ( + mock.patch.object(admin, "start", autospec=True) as admin_start, + mock.patch.object(admin, "stop", autospec=True) as admin_stop, + mock.patch.object(test_module, "OutOfBandManager") as oob_mgr, + mock.patch.object(test_module, "ConnectionManager") as conn_mgr, + ): admin_start.side_effect = KeyError("trouble") oob_mgr.return_value.create_invitation = mock.CoroutineMock( side_effect=KeyError("double trouble") @@ -967,16 +1066,19 @@ async def test_setup_collector(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -989,18 +1091,20 @@ async def test_start_static(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1017,20 +1121,21 @@ async def test_start_x_in(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "InboundTransportManager" - ) as mock_intx_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object(test_module, "InboundTransportManager") as mock_intx_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_intx_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), start=mock.CoroutineMock(side_effect=KeyError("trouble")), @@ -1050,18 +1155,18 @@ async def test_start_x_out_a(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "OutboundTransportManager" - ) as mock_outx_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object(test_module, "OutboundTransportManager") as mock_outx_mgr, + ): mock_outx_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), start=mock.CoroutineMock(side_effect=KeyError("trouble")), @@ -1078,18 +1183,18 @@ async def test_start_x_out_b(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "OutboundTransportManager" - ) as mock_outx_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object(test_module, "OutboundTransportManager") as mock_outx_mgr, + ): mock_outx_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), start=mock.CoroutineMock(side_effect=KeyError("trouble")), @@ -1123,16 +1228,19 @@ async def test_dispatch_complete_non_fatal_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1165,16 +1273,19 @@ async def test_dispatch_complete_fatal_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1203,26 +1314,58 @@ async def test_print_invite_connection(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + # Define expected invitation URLs + expected_oob_url = "http://localhost?oob=test_oob_invite" + expected_ci_url = "http://localhost?c_i=test_ci_invite" + + # Mock the InvitationRecord returned by create_invitation for OOB + mock_oob_invitation = mock.MagicMock() + mock_oob_invitation.invitation.to_url.return_value = expected_oob_url + + # Mock the InvitationRecord returned by create_invitation for Connections Protocol + mock_ci_invitation = mock.MagicMock() + mock_ci_invitation.to_url.return_value = expected_ci_url + + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch("sys.stdout", new=StringIO()) as captured, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "OutOfBandManager") as oob_mgr, + mock.patch.object(test_module, "ConnectionManager") as conn_mgr, + mock.patch.object(test_module.LOGGER, "info") as mock_logger_info, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } + + # Configure create_invitation to return the mocked invitations + oob_mgr.return_value.create_invitation = mock.CoroutineMock( + return_value=mock_oob_invitation + ) + conn_mgr.return_value.create_invitation = mock.CoroutineMock( + return_value=(None, mock_ci_invitation) + ) + + # Execute the conductor lifecycle await conductor.setup() await conductor.start() await conductor.stop() - value = captured.getvalue() - assert "http://localhost?oob=" in value - assert "http://localhost?c_i=" in value + + # Assert that LOGGER.info was called twice with the expected URLs + expected_calls = [ + call(f"Invitation URL:\n{expected_oob_url}"), + call(f"Invitation URL (Connections protocol):\n{expected_ci_url}"), + ] + mock_logger_info.assert_has_calls(expected_calls, any_order=True) async def test_clear_default_mediator(self): builder: ContextBuilder = StubContextBuilder(self.test_settings) @@ -1231,16 +1374,19 @@ async def test_clear_default_mediator(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1262,34 +1408,41 @@ async def test_set_default_mediator(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - test_module, - "MediationManager", - return_value=mock.MagicMock(set_default_mediator_by_id=mock.CoroutineMock()), - ) as mock_mgr, mock.patch.object( - MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, - "LOGGER", - mock.MagicMock( - exception=mock.MagicMock( - side_effect=Exception("This method should not have been called") - ) + with ( + mock.patch.object( + test_module, + "MediationManager", + return_value=mock.MagicMock( + set_default_mediator_by_id=mock.CoroutineMock() + ), + ) as mock_mgr, + mock.patch.object(MediationRecord, "retrieve_by_id", mock.CoroutineMock()), + mock.patch.object( + test_module, + "LOGGER", + mock.MagicMock( + exception=mock.MagicMock( + side_effect=Exception("This method should not have been called") + ) + ), ), ): await conductor.start() @@ -1303,26 +1456,32 @@ async def test_set_default_mediator_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=Exception()), - ), mock.patch.object(test_module, "LOGGER") as mock_logger: + with ( + mock.patch.object( + MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=Exception()), + ), + mock.patch.object(test_module, "LOGGER") as mock_logger, + ): await conductor.start() await conductor.stop() mock_logger.exception.assert_called_once() @@ -1341,16 +1500,19 @@ async def test_webhook_router(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1386,16 +1548,19 @@ async def test_shutdown_multitenant_profiles(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1456,16 +1621,19 @@ async def test_mediator_invitation_0160(self, mock_from_url, _): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1473,18 +1641,24 @@ async def test_mediator_invitation_0160(self, mock_from_url, _): mock_conn_record = mock.MagicMock() - with mock.patch.object( - test_module, - "ConnectionManager", - mock.MagicMock( - return_value=mock.MagicMock( - receive_invitation=mock.CoroutineMock(return_value=mock_conn_record) - ) + with ( + mock.patch.object( + test_module, + "ConnectionManager", + mock.MagicMock( + return_value=mock.MagicMock( + receive_invitation=mock.CoroutineMock( + return_value=mock_conn_record + ) + ) + ), + ) as mock_mgr, + mock.patch.object(mock_conn_record, "metadata_set", mock.CoroutineMock()), + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ) as mock_mgr, mock.patch.object( - mock_conn_record, "metadata_set", mock.CoroutineMock() - ), mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): await conductor.start() await conductor.stop() @@ -1502,16 +1676,19 @@ async def test_mediator_invitation_0434(self, mock_from_url, _): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1537,16 +1714,21 @@ async def test_mediator_invitation_0434(self, mock_from_url, _): state=OobRecord.STATE_INITIAL, ) - with mock.patch.object( - test_module, - "OutOfBandManager", - mock.MagicMock( - return_value=mock.MagicMock( - receive_invitation=mock.CoroutineMock(return_value=oob_record) - ) + with ( + mock.patch.object( + test_module, + "OutOfBandManager", + mock.MagicMock( + return_value=mock.MagicMock( + receive_invitation=mock.CoroutineMock(return_value=oob_record) + ) + ), + ) as mock_mgr, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ) as mock_mgr, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): assert not conductor.root_profile.settings["mediation.connections_invite"] await conductor.start() @@ -1572,16 +1754,19 @@ async def test_mediation_invitation_should_use_stored_invitation( conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1598,12 +1783,14 @@ async def test_mediation_invitation_should_use_stored_invitation( ) # when - with mock.patch.object( - test_module, "ConnectionManager", return_value=connection_manager_mock - ), mock.patch.object( - mock_conn_record, "metadata_set", mock.CoroutineMock() - ), mock.patch.object( - test_module, "MediationManager", return_value=mock_mediation_manager + with ( + mock.patch.object( + test_module, "ConnectionManager", return_value=connection_manager_mock + ), + mock.patch.object(mock_conn_record, "metadata_set", mock.CoroutineMock()), + mock.patch.object( + test_module, "MediationManager", return_value=mock_mediation_manager + ), ): await conductor.start() await conductor.stop() @@ -1627,16 +1814,19 @@ async def test_mediation_invitation_should_not_create_connection_for_old_invitat conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1665,26 +1855,32 @@ async def test_mediator_invitation_x(self, _): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - test_module.ConnectionInvitation, - "from_url", - mock.MagicMock(side_effect=Exception()), - ) as mock_from_url, mock.patch.object(test_module, "LOGGER") as mock_logger: + with ( + mock.patch.object( + test_module.ConnectionInvitation, + "from_url", + mock.MagicMock(side_effect=Exception()), + ) as mock_from_url, + mock.patch.object(test_module, "LOGGER") as mock_logger, + ): await conductor.start() await conductor.stop() mock_from_url.assert_called_once_with("test-invite") @@ -1711,22 +1907,28 @@ async def test_setup_ledger_both_multiple_and_base(self): BaseLedger, mock.MagicMock(BaseLedger, autospec=True) ) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "load_multiple_genesis_transactions_from_config", - mock.CoroutineMock(), - ) as mock_multiple_genesis_load, mock.patch.object( - test_module, "get_genesis_transactions", mock.CoroutineMock() - ) as mock_genesis_load, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object(test_module, "ledger_config"): + mock.patch.object( + test_module, + "load_multiple_genesis_transactions_from_config", + mock.CoroutineMock(), + ) as mock_multiple_genesis_load, + mock.patch.object( + test_module, "get_genesis_transactions", mock.CoroutineMock() + ) as mock_genesis_load, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "ledger_config"), + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1741,18 +1943,23 @@ async def test_setup_ledger_only_base(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "get_genesis_transactions", mock.CoroutineMock() - ) as mock_genesis_load, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object(test_module, "ledger_config"): + mock.patch.object( + test_module, "get_genesis_transactions", mock.CoroutineMock() + ) as mock_genesis_load, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "ledger_config"), + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1765,21 +1972,26 @@ async def test_startup_storage_type_anoncreds_and_config_askar_re_calls_setup(se test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) @@ -1811,27 +2023,33 @@ async def test_startup_storage_type_does_not_exist_and_existing_agent_then_set_t test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) @@ -1866,27 +2084,33 @@ async def test_startup_storage_type_does_not_exist_and_new_anoncreds_agent( test_settings, await builder.build_context() ) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) diff --git a/acapy_agent/core/tests/test_dispatcher.py b/acapy_agent/core/tests/test_dispatcher.py index c352192f19..b941e584e3 100644 --- a/acapy_agent/core/tests/test_dispatcher.py +++ b/acapy_agent/core/tests/test_dispatcher.py @@ -105,11 +105,14 @@ async def test_dispatch(self): "@type": DIDCommPrefix.qualify_current(StubAgentMessage.Meta.message_type) } - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ) as handler_mock, mock.patch.object( - test_module, "BaseConnectionManager", autospec=True - ) as conn_mgr_mock: + with ( + mock.patch.object( + StubAgentMessageHandler, "handle", autospec=True + ) as handler_mock, + mock.patch.object( + test_module, "BaseConnectionManager", autospec=True + ) as conn_mgr_mock, + ): conn_mgr_mock.return_value = mock.MagicMock( find_inbound_connection=mock.CoroutineMock( return_value=mock.MagicMock(connection_id="dummy") @@ -148,10 +151,11 @@ async def test_dispatch_versioned_message(self): "@type": DIDCommPrefix.qualify_current(StubAgentMessage.Meta.message_type) } - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ) as handler_mock, mock.patch.object( - test_module, "BaseConnectionManager", autospec=True + with ( + mock.patch.object( + StubAgentMessageHandler, "handle", autospec=True + ) as handler_mock, + mock.patch.object(test_module, "BaseConnectionManager", autospec=True), ): await dispatcher.queue_message( dispatcher.profile, make_inbound(message), rcv.send @@ -217,11 +221,12 @@ async def test_dispatch_versioned_message_message_class_deserialize_x(self): rcv = Receiver() message = {"@type": "doc/proto-name/1.1/no-such-message-type"} - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ), mock.patch.object( - registry, "resolve_message_class", mock.MagicMock() - ) as mock_resolve: + with ( + mock.patch.object(StubAgentMessageHandler, "handle", autospec=True), + mock.patch.object( + registry, "resolve_message_class", mock.MagicMock() + ) as mock_resolve, + ): mock_resolve.return_value = mock.MagicMock( deserialize=mock.MagicMock(side_effect=test_module.BaseModelError()) ) @@ -258,10 +263,11 @@ async def test_dispatch_versioned_message_handle_greater_succeeds(self): "@type": DIDCommPrefix.qualify_current(StubV1_2AgentMessage.Meta.message_type) } - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ) as handler_mock, mock.patch.object( - test_module, "BaseConnectionManager", autospec=True + with ( + mock.patch.object( + StubAgentMessageHandler, "handle", autospec=True + ) as handler_mock, + mock.patch.object(test_module, "BaseConnectionManager", autospec=True), ): await dispatcher.queue_message( dispatcher.profile, make_inbound(message), rcv.send @@ -393,12 +399,13 @@ async def test_create_send_outbound(self): outbound_message = await responder.create_outbound( json.dumps(message.serialize()) ) - with mock.patch.object( - responder, "_send", mock.CoroutineMock() - ), mock.patch.object( - test_module.BaseResponder, - "conn_rec_active_state_check", - mock.CoroutineMock(return_value=True), + with ( + mock.patch.object(responder, "_send", mock.CoroutineMock()), + mock.patch.object( + test_module.BaseResponder, + "conn_rec_active_state_check", + mock.CoroutineMock(return_value=True), + ), ): await responder.send_outbound(outbound_message) @@ -418,12 +425,13 @@ async def test_create_send_outbound_with_msg_attrs(self): message = StubAgentMessage() responder = test_module.DispatcherResponder(context, message, None) outbound_message = await responder.create_outbound(message) - with mock.patch.object( - responder, "_send", mock.CoroutineMock() - ), mock.patch.object( - test_module.BaseResponder, - "conn_rec_active_state_check", - mock.CoroutineMock(return_value=True), + with ( + mock.patch.object(responder, "_send", mock.CoroutineMock()), + mock.patch.object( + test_module.BaseResponder, + "conn_rec_active_state_check", + mock.CoroutineMock(return_value=True), + ), ): await responder.send_outbound( message=outbound_message, diff --git a/acapy_agent/core/tests/test_oob_processor.py b/acapy_agent/core/tests/test_oob_processor.py index f3a9541f78..4b3e85bedb 100644 --- a/acapy_agent/core/tests/test_oob_processor.py +++ b/acapy_agent/core/tests/test_oob_processor.py @@ -426,17 +426,20 @@ async def test_find_oob_record_for_inbound_message_sender_connection_id_no_match mock_retrieve.assert_called_once_with(ANY, {"invi_msg_id": "the-pthid"}) # Connection id is not the same, state is AWAIT_RESPONSE. oob has connection_id - with mock.patch.object( - OobRecord, - "retrieve_by_tag_filter", - mock.CoroutineMock(return_value=self.oob_record), - ) as mock_retrieve, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock( - return_value=mock.MagicMock(delete_record=mock.CoroutineMock()) - ), - ) as mock_retrieve_conn: + with ( + mock.patch.object( + OobRecord, + "retrieve_by_tag_filter", + mock.CoroutineMock(return_value=self.oob_record), + ) as mock_retrieve, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock( + return_value=mock.MagicMock(delete_record=mock.CoroutineMock()) + ), + ) as mock_retrieve_conn, + ): self.oob_record.role = OobRecord.ROLE_SENDER self.oob_record.state = OobRecord.STATE_AWAIT_RESPONSE self.context.connection_record = mock.MagicMock( diff --git a/acapy_agent/core/tests/test_plugin_registry.py b/acapy_agent/core/tests/test_plugin_registry.py index b5727a4546..4e870fbdfb 100644 --- a/acapy_agent/core/tests/test_plugin_registry.py +++ b/acapy_agent/core/tests/test_plugin_registry.py @@ -537,6 +537,7 @@ async def test_load_protocols_load_mod(self): mock_mod = mock.MagicMock() mock_mod.MESSAGE_TYPES = mock.MagicMock() mock_mod.CONTROLLERS = mock.MagicMock() + mock_mod.__name__ = "test_mod" with mock.patch.object( ClassLoader, "load_module", mock.MagicMock() @@ -595,6 +596,7 @@ async def test_load_protocols_no_mod_def_message_types(self): mock_mod = mock.MagicMock() mock_mod.MESSAGE_TYPES = mock.MagicMock() mock_mod.CONTROLLERS = mock.MagicMock() + mock_mod.__name__ = "test_mod" with mock.patch.object( ClassLoader, "load_module", mock.MagicMock() diff --git a/acapy_agent/didcomm_v2/tests/test_adapters.py b/acapy_agent/didcomm_v2/tests/test_adapters.py index 56d861bfcb..747d52a1b6 100644 --- a/acapy_agent/didcomm_v2/tests/test_adapters.py +++ b/acapy_agent/didcomm_v2/tests/test_adapters.py @@ -70,7 +70,7 @@ async def test_secrets_adapter_errors(self): ) store = MagicMock() - askar_profile = AskarProfile(opened=store) + askar_profile = await AskarProfile.create(opened=store) session: AskarProfileSession = askar_profile.session() sec_adapter = SecretsAdapter(session) @@ -84,7 +84,7 @@ async def test_secrets_adapter_errors(self): async def test_secrets_adapter_empty(self): store = MagicMock() - askar_profile = AskarProfile(opened=store) + askar_profile = await AskarProfile.create(opened=store) session: AskarProfileSession = askar_profile.session() sec_adapter = SecretsAdapter(session) @@ -95,7 +95,7 @@ async def test_secrets_adapter_empty(self): async def test_secrets_adapter_valid_return(self): store = MagicMock() - askar_profile = AskarProfile(opened=store) + askar_profile = await AskarProfile.create(opened=store) session: AskarProfileSession = askar_profile.session() sec_adapter = SecretsAdapter(session) diff --git a/acapy_agent/indy/models/cred_def.py b/acapy_agent/indy/models/cred_def.py index dbdaea2b2d..4c5547f96e 100644 --- a/acapy_agent/indy/models/cred_def.py +++ b/acapy_agent/indy/models/cred_def.py @@ -6,8 +6,8 @@ from ...messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NUM_STR_WHOLE_EXAMPLE, NUM_STR_WHOLE_VALIDATE, ) @@ -92,10 +92,10 @@ class CredentialDefinitionSchema(OpenAPISchema): """Marshmallow schema for indy cred def.""" ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Node protocol version", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) ident = fields.Str( diff --git a/acapy_agent/indy/models/pres_preview.py b/acapy_agent/indy/models/pres_preview.py index 496c1e93cd..d9e740193e 100644 --- a/acapy_agent/indy/models/pres_preview.py +++ b/acapy_agent/indy/models/pres_preview.py @@ -16,8 +16,8 @@ from ...messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, - INDY_PREDICATE_EXAMPLE, - INDY_PREDICATE_VALIDATE, + PREDICATE_EXAMPLE, + PREDICATE_VALIDATE, ) from ...multitenant.base import BaseMultitenantManager from ...protocols.didcomm_prefix import DIDCommPrefix @@ -100,10 +100,10 @@ class Meta: ) predicate = fields.Str( required=True, - validate=INDY_PREDICATE_VALIDATE, + validate=PREDICATE_VALIDATE, metadata={ "description": "Predicate type ('<', '<=', '>=', or '>')", - "example": INDY_PREDICATE_EXAMPLE, + "example": PREDICATE_EXAMPLE, }, ) threshold = fields.Int( diff --git a/acapy_agent/indy/models/proof_request.py b/acapy_agent/indy/models/proof_request.py index 1c87ecf454..f27ac5a8f6 100644 --- a/acapy_agent/indy/models/proof_request.py +++ b/acapy_agent/indy/models/proof_request.py @@ -15,14 +15,14 @@ from ...messaging.models.openapi import OpenAPISchema from ...messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, - INDY_PREDICATE_EXAMPLE, - INDY_PREDICATE_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NUM_STR_NATURAL_EXAMPLE, NUM_STR_NATURAL_VALIDATE, + PREDICATE_EXAMPLE, + PREDICATE_VALIDATE, ) @@ -125,10 +125,10 @@ class IndyProofReqPredSpecSchema(OpenAPISchema): ) p_type = fields.Str( required=True, - validate=INDY_PREDICATE_VALIDATE, + validate=PREDICATE_VALIDATE, metadata={ "description": "Predicate type ('<', '<=', '>=', or '>')", - "example": INDY_PREDICATE_EXAMPLE, + "example": PREDICATE_EXAMPLE, }, ) p_value = fields.Int( @@ -251,10 +251,10 @@ class Meta: version = fields.Str( required=False, dump_default="1.0", - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Proof request version", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) requested_attributes = fields.Dict( diff --git a/acapy_agent/indy/models/revocation.py b/acapy_agent/indy/models/revocation.py index a7a2795fbd..14c5617709 100644 --- a/acapy_agent/indy/models/revocation.py +++ b/acapy_agent/indy/models/revocation.py @@ -12,8 +12,8 @@ INDY_CRED_DEF_ID_VALIDATE, INDY_REV_REG_ID_EXAMPLE, INDY_REV_REG_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NATURAL_NUM_EXAMPLE, NATURAL_NUM_VALIDATE, ) @@ -180,10 +180,10 @@ class Meta: unknown = EXCLUDE ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Version of revocation registry definition", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) id_ = fields.Str( @@ -294,10 +294,10 @@ class Meta: unknown = EXCLUDE ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Version of revocation registry entry", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) value = fields.Nested( diff --git a/acapy_agent/indy/models/schema.py b/acapy_agent/indy/models/schema.py index 5dff944356..df91802bc7 100644 --- a/acapy_agent/indy/models/schema.py +++ b/acapy_agent/indy/models/schema.py @@ -6,8 +6,8 @@ from ...messaging.valid import ( INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NATURAL_NUM_EXAMPLE, NATURAL_NUM_VALIDATE, ) @@ -17,10 +17,10 @@ class SchemaSchema(OpenAPISchema): """Marshmallow schema for indy schema.""" ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Node protocol version", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) ident = fields.Str( @@ -38,8 +38,11 @@ class SchemaSchema(OpenAPISchema): } ) version = fields.Str( - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) attr_names = fields.List( fields.Str(metadata={"description": "Attribute name", "example": "score"}), diff --git a/acapy_agent/indy/tests/test_verifier.py b/acapy_agent/indy/tests/test_verifier.py index c038daa3d3..54762cb636 100644 --- a/acapy_agent/indy/tests/test_verifier.py +++ b/acapy_agent/indy/tests/test_verifier.py @@ -436,11 +436,12 @@ async def test_check_timestamps(self): proof_req_x = deepcopy(INDY_PROOF_REQ_NAME) proof_req_x["non_revoked"] = {"from": 1600000000, "to": 1600001000} proof_x["identifiers"][0]["timestamp"] = 1579890000 - with mock.patch.object( - test_module, "LOGGER", mock.MagicMock() - ) as mock_logger, mock.patch.object( - IndyLedgerRequestsExecutor, "get_ledger_for_identifier" - ) as mock_get_ledger: + with ( + mock.patch.object(test_module, "LOGGER", mock.MagicMock()) as mock_logger, + mock.patch.object( + IndyLedgerRequestsExecutor, "get_ledger_for_identifier" + ) as mock_get_ledger, + ): mock_get_ledger.return_value = (None, self.ledger) pre_logger_calls = mock_logger.info.call_count await self.verifier.check_timestamps( diff --git a/acapy_agent/ledger/indy_vdr.py b/acapy_agent/ledger/indy_vdr.py index d26734ec6f..61733c912c 100644 --- a/acapy_agent/ledger/indy_vdr.py +++ b/acapy_agent/ledger/indy_vdr.py @@ -11,7 +11,7 @@ from io import StringIO from pathlib import Path from time import time -from typing import List, Optional, Tuple, Union +from typing import Dict, List, Optional, Tuple, Union from indy_vdr import Pool, Request, VdrError, ledger, open_pool @@ -40,36 +40,48 @@ def _normalize_txns(txns: str) -> str: """Normalize a set of genesis transactions.""" + LOGGER.debug("Normalizing genesis transactions") lines = StringIO() for line in txns.splitlines(): line = line.strip() if line: lines.write(line) lines.write("\n") + LOGGER.debug("Finished normalizing genesis transactions") return lines.getvalue() def _write_safe(path: Path, content: str): """Atomically write to a file path.""" + LOGGER.debug("Writing content safely to path: %s", path) dir_path = path.parent with tempfile.NamedTemporaryFile(dir=dir_path, delete=False) as tmp: + LOGGER.debug("Created temporary file: %s", tmp.name) tmp.write(content.encode("utf-8")) tmp_name = tmp.name + LOGGER.debug("Renaming temporary file to target path") os.rename(tmp_name, path) + LOGGER.debug("Successfully wrote content to: %s", path) def _hash_txns(txns: str) -> str: """Obtain a hash of a set of genesis transactions.""" - return hashlib.sha256(txns.encode("utf-8")).hexdigest()[-16:] + LOGGER.debug("Calculating hash of genesis transactions") + hash_value = hashlib.sha256(txns.encode("utf-8")).hexdigest()[-16:] + LOGGER.debug("Generated transaction hash: %s", hash_value) + return hash_value class IndyVdrLedgerPool: - """Indy-VDR ledger pool manager.""" + """Indy-VDR ledger pool manager with singleton behavior based on configuration.""" + + _instances: Dict[tuple, "IndyVdrLedgerPool"] = {} + _lock = asyncio.Lock() def __init__( self, - name: str, *, + name: str, keepalive: int = 0, cache: Optional[BaseCache] = None, cache_duration: int = 600, @@ -77,69 +89,230 @@ def __init__( read_only: bool = False, socks_proxy: Optional[str] = None, ): - """Initialize an IndyLedger instance. + """Private constructor. Use 'create_instance' to instantiate.""" + LOGGER.debug( + "Initializing IndyVdrLedgerPool with name: %s, keepalive: %s, cache_duration: %s, read_only: %s", + name, + keepalive, + cache_duration, + read_only, + ) - Args: - name: The pool ledger configuration name - keepalive: How many seconds to keep the ledger open - cache: The cache instance to use - cache_duration: The TTL for ledger cache entries - genesis_transactions: The ledger genesis transaction as a string - read_only: Prevent any ledger write operations - socks_proxy: Specifies socks proxy for ZMQ to connect to ledger pool - """ - self.ref_count = 0 - self.ref_lock = asyncio.Lock() + # Instance attributes + self.name = name self.keepalive = keepalive - self.close_task: asyncio.Future = None self.cache = cache - self.cache_duration: int = cache_duration + self.cache_duration = cache_duration + self.genesis_transactions = genesis_transactions + self.read_only = read_only + self.socks_proxy = socks_proxy + + self.ref_count = 0 + self.ref_lock = asyncio.Lock() + self.close_task: Optional[asyncio.Task] = None self.handle: Optional[Pool] = None - self.name = name self.cfg_path_cache: Optional[Path] = None self.genesis_hash_cache: Optional[str] = None self.genesis_txns_cache = genesis_transactions self.init_config = bool(genesis_transactions) self.taa_cache: Optional[str] = None - self.read_only: bool = read_only - self.socks_proxy: str = socks_proxy + + LOGGER.debug("Pool %s initialization staged", name) + + @classmethod + async def get_or_create( + cls, + *, + name: str, + keepalive: int = 0, + cache: Optional[BaseCache] = None, + cache_duration: int = 600, + genesis_transactions: Optional[str] = None, + read_only: bool = False, + socks_proxy: Optional[str] = None, + ) -> "IndyVdrLedgerPool": + """Asynchronously create or retrieve the singleton instance based on configuration. + + Args: + name: The pool ledger configuration name. + keepalive: How many seconds to keep the ledger open. + cache: The cache instance to use. + cache_duration: The TTL for ledger cache entries. + genesis_transactions: The ledger genesis transaction as a string. + read_only: Prevent any ledger write operations. + socks_proxy: Specifies socks proxy for ZMQ to connect to ledger pool. + + Returns: + An initialized instance of IndyVdrLedgerPool. + """ + LOGGER.debug( + "Creating or retrieving IndyVdrLedgerPool instance with params: name=%s, keepalive=%s, cache_duration=%s, read_only=%s, socks_proxy=%s", + name, + keepalive, + cache_duration, + read_only, + socks_proxy, + ) + + config_key = ( + name, + keepalive, + cache_duration, + genesis_transactions, + read_only, + socks_proxy, + ) + LOGGER.debug("Generated config key: %s", config_key) + + async with cls._lock: + if config_key not in cls._instances: + LOGGER.debug( + "No existing instance found for config key, creating new instance" + ) + instance = cls( + name=name, + keepalive=keepalive, + cache=cache, + cache_duration=cache_duration, + genesis_transactions=genesis_transactions, + read_only=read_only, + socks_proxy=socks_proxy, + ) + try: + LOGGER.debug("Initializing new IndyVdrLedgerPool instance") + await instance.initialize() + except Exception as e: + LOGGER.exception( + "Initialization failed for IndyVdrLedgerPool with config: %s", + config_key, + exc_info=e, + ) + raise + cls._instances[config_key] = instance + LOGGER.debug( + "Successfully created and stored new IndyVdrLedgerPool instance: %s", + config_key, + ) + else: + LOGGER.debug( + "Found existing IndyVdrLedgerPool instance for config: %s", config_key + ) + instance = cls._instances[config_key] + + async with instance.ref_lock: + instance.ref_count += 1 + LOGGER.debug( + "Incremented reference count to %s for instance %s", + instance.ref_count, + config_key, + ) + + LOGGER.debug( + "Returning IndyVdrLedgerPool instance with ref_count: %s", + instance.ref_count, + ) + return instance + + async def initialize(self): + """Initialize the ledger pool.""" + LOGGER.debug("Beginning pool initialization") + if self.init_config: + LOGGER.debug("Creating pool config with genesis transactions") + await self.create_pool_config(self.genesis_txns_cache, recreate=True) + self.init_config = False + LOGGER.debug("Opening pool connection") + await self.open() + LOGGER.debug("Pool initialization complete") + + @classmethod + async def release_instance(cls, instance: "IndyVdrLedgerPool"): + """Release a reference to the instance and possibly remove it from the registry. + + Args: + instance: The IndyVdrLedgerPool instance to release. + """ + LOGGER.debug("Beginning instance release process for pool: %s", instance.name) + config_key = ( + instance.name, + instance.keepalive, + instance.cache_duration, + instance.genesis_transactions, + instance.read_only, + instance.socks_proxy, + ) + LOGGER.debug("Generated config key for release: %s", config_key) + + async with cls._lock: + async with instance.ref_lock: + instance.ref_count -= 1 + LOGGER.debug( + "Decremented reference count to %s for instance %s", + instance.ref_count, + config_key, + ) + if instance.ref_count <= 0: + LOGGER.debug( + "Reference count is zero or negative, cleaning up instance" + ) + await instance.close() + del cls._instances[config_key] + LOGGER.debug( + "Successfully removed IndyVdrLedgerPool instance: %s", config_key + ) + else: + LOGGER.debug( + "Instance still has active references: %s", instance.ref_count + ) @property def cfg_path(self) -> Path: """Get the path to the configuration file, ensuring it's created.""" if not self.cfg_path_cache: + LOGGER.debug("Creating configuration path cache") self.cfg_path_cache = storage_path("vdr", create=True) + LOGGER.debug("Configuration path set to: %s", self.cfg_path_cache) return self.cfg_path_cache @property def genesis_hash(self) -> str: """Get the hash of the configured genesis transactions.""" if not self.genesis_hash_cache: + LOGGER.debug("Calculating genesis transactions hash") self.genesis_hash_cache = _hash_txns(self.genesis_txns) + LOGGER.debug("Genesis hash calculated: %s", self.genesis_hash_cache) return self.genesis_hash_cache @property def genesis_txns(self) -> str: """Get the configured genesis transactions.""" if not self.genesis_txns_cache: + LOGGER.debug("Loading genesis transactions from file") try: path = self.cfg_path.joinpath(self.name, "genesis") + LOGGER.debug("Reading genesis file from: %s", path) self.genesis_txns_cache = _normalize_txns(open(path).read()) + LOGGER.debug("Successfully loaded genesis transactions") except FileNotFoundError: + LOGGER.error("Pool config '%s' not found", self.name) raise LedgerConfigError("Pool config '%s' not found", self.name) from None return self.genesis_txns_cache async def create_pool_config(self, genesis_transactions: str, recreate: bool = False): """Create the pool ledger configuration.""" + LOGGER.debug("Creating pool config for '%s', recreate=%s", self.name, recreate) cfg_pool = self.cfg_path.joinpath(self.name) cfg_pool.mkdir(exist_ok=True) + LOGGER.debug("Created pool configuration directory: %s", cfg_pool) + genesis = _normalize_txns(genesis_transactions) if not genesis: + LOGGER.error("Empty genesis transactions provided") raise LedgerConfigError("Empty genesis transactions") genesis_path = cfg_pool.joinpath("genesis") try: + LOGGER.debug("Checking existing genesis file: %s", genesis_path) cmp_genesis = open(genesis_path).read() if _normalize_txns(cmp_genesis) == genesis: LOGGER.debug( @@ -148,66 +321,94 @@ async def create_pool_config(self, genesis_transactions: str, recreate: bool = F ) return elif not recreate: + LOGGER.error( + "Pool ledger '%s' exists with different genesis transactions", + self.name, + ) raise LedgerConfigError( f"Pool ledger '{self.name}' exists with " "different genesis transactions" ) except FileNotFoundError: + LOGGER.debug("No existing genesis file found") pass try: + LOGGER.debug("Writing genesis transactions to: %s", genesis_path) _write_safe(genesis_path, genesis) except OSError as err: + LOGGER.exception("Error writing genesis transactions", exc_info=err) raise LedgerConfigError("Error writing genesis transactions") from err - LOGGER.debug("Wrote pool ledger config '%s'", self.name) + LOGGER.debug("Successfully wrote pool ledger config '%s'", self.name) self.genesis_txns_cache = genesis async def open(self): """Open the pool ledger, creating it if necessary.""" + LOGGER.debug("Opening pool ledger: %s", self.name) if self.init_config: + LOGGER.debug("Initializing pool config with genesis transactions") await self.create_pool_config(self.genesis_txns_cache, recreate=True) self.init_config = False genesis_hash = self.genesis_hash + LOGGER.debug("Using genesis hash: %s", genesis_hash) cfg_pool = self.cfg_path.joinpath(self.name) cfg_pool.mkdir(exist_ok=True) cache_path = cfg_pool.joinpath(f"cache-{genesis_hash}") try: + LOGGER.debug("Attempting to read cached transactions from: %s", cache_path) txns = open(cache_path).read() cached = True + LOGGER.debug("Successfully read cached transactions") except FileNotFoundError: + LOGGER.debug("No cached transactions found, using genesis transactions") txns = self.genesis_txns cached = False + LOGGER.debug("Opening pool with transactions, socks_proxy=%s", self.socks_proxy) self.handle = await open_pool(transactions=txns, socks_proxy=self.socks_proxy) + LOGGER.debug("Pool opened successfully") + upd_txns = _normalize_txns(await self.handle.get_transactions()) if not cached or upd_txns != txns: + LOGGER.debug("Updating cached transactions") try: _write_safe(cache_path, upd_txns) + LOGGER.debug("Successfully wrote updated cached transactions") except OSError: LOGGER.exception("Error writing cached genesis transactions") async def close(self): """Close the pool ledger.""" if self.handle: + LOGGER.debug("Attempting to close pool ledger") exc = None for attempt in range(3): try: + LOGGER.debug("Close attempt %s/3", attempt + 1) self.handle.close() except VdrError as err: + LOGGER.warning( + "Error closing pool ledger (attempt %s/3): %s", + attempt + 1, + str(err), + ) await asyncio.sleep(0.01) exc = err continue self.handle = None exc = None + LOGGER.debug("Successfully closed pool ledger") break if exc: - LOGGER.exception("Exception when closing pool ledger", exc_info=exc) + LOGGER.exception( + "Failed to close pool ledger after 3 attempts", exc_info=exc + ) self.ref_count += 1 # if we are here, we should have self.ref_lock self.close_task = None raise LedgerError("Exception when closing pool ledger") from exc @@ -227,18 +428,43 @@ async def context_close(self): async def closer(timeout: int): """Close the pool ledger after a timeout.""" - await asyncio.sleep(timeout) - async with self.ref_lock: - if not self.ref_count: - LOGGER.debug("Closing pool ledger after timeout") - await self.close() + try: + LOGGER.debug( + "Coroutine will sleep for %d seconds before closing the pool.", + timeout, + ) + await asyncio.sleep(timeout) + async with self.ref_lock: + if not self.ref_count: + LOGGER.debug( + "No more references. Proceeding to close the pool ledger." + ) + await self.close() + else: + LOGGER.debug( + "Reference count is %d. Not closing the pool yet.", + self.ref_count, + ) + except Exception as e: + LOGGER.exception( + "Exception occurred in closer coroutine during pool closure.", + exc_info=e, + ) async with self.ref_lock: self.ref_count -= 1 + LOGGER.debug("Decremented ref_count to %d.", self.ref_count) if not self.ref_count: if self.keepalive: - self.close_task = asyncio.ensure_future(closer(self.keepalive)) + LOGGER.debug( + "Scheduling closer coroutine with keepalive=%s", + self.keepalive, + ) + self.close_task = asyncio.create_task(closer(self.keepalive)) else: + LOGGER.debug( + "No keepalive set. Proceeding to close the pool immediately." + ) await self.close() diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py b/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py index 4feb805b31..917a48e923 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py @@ -24,7 +24,8 @@ async def asyncSetUp(self): "genesis_transactions": "genesis_transactions", } ] - self.ledger = IndyVdrLedger(IndyVdrLedgerPool("test_prod_1"), self.profile) + pool = await IndyVdrLedgerPool.get_or_create(name="test_prod_1") + self.ledger = IndyVdrLedger(pool, self.profile) mock_ledger_manger = mock.MagicMock(BaseMultipleLedgerManager, autospec=True) mock_ledger_manger.extract_did_from_identifier = mock.MagicMock( return_value="WgWxqztrNooG92RXvxSTWv" diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py b/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py index a64f20a8b7..1451a5fabb 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py @@ -63,17 +63,19 @@ async def asyncSetUp(self): self.context.injector.bind_instance(BaseResponder, self.responder) self.production_ledger = OrderedDict() self.non_production_ledger = OrderedDict() - test_prod_ledger = IndyVdrLedger(IndyVdrLedgerPool("test_prod_1"), self.profile) + test_prod_ledger = IndyVdrLedger( + await IndyVdrLedgerPool.get_or_create(name="test_prod_1"), self.profile + ) writable_ledgers = set() self.production_ledger["test_prod_1"] = test_prod_ledger self.production_ledger["test_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_prod_2"), self.profile ) self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) writable_ledgers.add("test_prod_1") writable_ledgers.add("test_prod_2") @@ -195,10 +197,10 @@ async def test_get_ledger_by_did_self_cert_b( ): self.non_production_ledger = OrderedDict() self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) self.manager = MultiIndyVDRLedgerManager( self.profile, @@ -239,11 +241,14 @@ async def test_get_ledger_by_did_not_self_cert( "verkey": "ABUF7uxYTxZ6qYdZ4G9e1Gi", } ) - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = get_nym_reply mock_wait.return_value = mock_submit.return_value @@ -354,11 +359,14 @@ async def test_get_ledger_by_did_not_self_cert_not_self_cert_prod( ): get_nym_reply = deepcopy(GET_NYM_INDY_VDR_REPLY) get_nym_reply["data"]["verkey"] = "ABUF7uxYTxZ6qYdZ4G9e1Gi" - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = get_nym_reply mock_wait.return_value = mock_submit.return_value @@ -381,10 +389,10 @@ async def test_lookup_did_in_configured_ledgers_self_cert_non_prod( ): self.non_production_ledger = OrderedDict() self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) self.manager = MultiIndyVDRLedgerManager( self.profile, @@ -414,10 +422,10 @@ async def test_get_ledger_by_did_not_self_cert_non_prod( ): self.non_production_ledger = OrderedDict() self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) self.manager = MultiIndyVDRLedgerManager( self.profile, @@ -425,11 +433,14 @@ async def test_get_ledger_by_did_not_self_cert_non_prod( ) get_nym_reply = deepcopy(GET_NYM_REPLY) get_nym_reply["result"]["data"]["verkey"] = "ABUF7uxYTxZ6qYdZ4G9e1Gi" - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = get_nym_reply mock_wait.return_value = mock_submit.return_value @@ -450,11 +461,14 @@ async def test_get_ledger_by_did_not_self_cert_non_prod( async def test_lookup_did_in_configured_ledgers_x( self, mock_submit, mock_build_get_nym_req, mock_close, mock_open ): - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = GET_NYM_INDY_VDR_REPLY mock_wait.return_value = mock_submit.return_value diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py b/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py index ce9cc002a6..639c46c37f 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py @@ -57,7 +57,8 @@ async def test_provide_askar_manager(self): context = InjectionContext() profile = await create_test_profile() context.injector.bind_instance( - BaseLedger, IndyVdrLedger(IndyVdrLedgerPool("name"), profile) + BaseLedger, + IndyVdrLedger(await IndyVdrLedgerPool.get_or_create(name="name"), profile), ) provider = MultiIndyLedgerManagerProvider(profile) context.settings["ledger.ledger_config_list"] = LEDGER_CONFIG diff --git a/acapy_agent/ledger/routes.py b/acapy_agent/ledger/routes.py index 4d63eb5af3..fee5e15261 100644 --- a/acapy_agent/ledger/routes.py +++ b/acapy_agent/ledger/routes.py @@ -25,10 +25,10 @@ ENDPOINT_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, UUID4_EXAMPLE, ) from ..multitenant.base import BaseMultitenantManager @@ -133,10 +133,10 @@ class RegisterLedgerNymQueryStringSchema(OpenAPISchema): ) verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) alias = fields.Str( @@ -230,10 +230,10 @@ class GetDIDVerkeyResponseSchema(OpenAPISchema): verkey = fields.Str( allow_none=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Full verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) diff --git a/acapy_agent/ledger/tests/test_indy_vdr.py b/acapy_agent/ledger/tests/test_indy_vdr.py index 927498c707..079c444a39 100644 --- a/acapy_agent/ledger/tests/test_indy_vdr.py +++ b/acapy_agent/ledger/tests/test_indy_vdr.py @@ -43,7 +43,9 @@ async def ledger(): profile.context.injector.bind_instance(BaseCache, InMemoryCache()) profile.context.injector.bind_instance(KeyTypes, KeyTypes()) - ledger = IndyVdrLedger(IndyVdrLedgerPool("test-ledger"), profile) + ledger = IndyVdrLedger( + await IndyVdrLedgerPool.get_or_create(name="test-ledger"), profile + ) async def open(): ledger.pool.handle = mock.MagicMock(indy_vdr.Pool) @@ -51,10 +53,12 @@ async def open(): async def close(): ledger.pool.handle = None - with mock.patch.object(ledger.pool, "open", open), mock.patch.object( - ledger.pool, "close", close - ), mock.patch.object( - ledger, "is_ledger_read_only", mock.CoroutineMock(return_value=False) + with ( + mock.patch.object(ledger.pool, "open", open), + mock.patch.object(ledger.pool, "close", close), + mock.patch.object( + ledger, "is_ledger_read_only", mock.CoroutineMock(return_value=False) + ), ): yield ledger @@ -338,14 +342,17 @@ async def test_send_schema_ledger_read_only( async with ledger: ledger.pool.read_only = True - with mock.patch.object( - ledger, - "check_existing_schema", - mock.CoroutineMock(return_value=False), - ), mock.patch.object( - ledger, - "is_ledger_read_only", - mock.CoroutineMock(return_value=True), + with ( + mock.patch.object( + ledger, + "check_existing_schema", + mock.CoroutineMock(return_value=False), + ), + mock.patch.object( + ledger, + "is_ledger_read_only", + mock.CoroutineMock(return_value=True), + ), ): with pytest.raises(LedgerError): await ledger.create_and_send_schema( @@ -768,25 +775,28 @@ async def test_update_endpoint_for_did_calls_attr_json(self, ledger: IndyVdrLedg test_did = await wallet.create_public_did(SOV, ED25519) async with ledger: - with mock.patch.object( - ledger, - "_construct_attr_json", - mock.CoroutineMock( - return_value=json.dumps( - { - "endpoint": { + with ( + mock.patch.object( + ledger, + "_construct_attr_json", + mock.CoroutineMock( + return_value=json.dumps( + { "endpoint": { - "endpoint": "https://url", - "routingKeys": [], + "endpoint": { + "endpoint": "https://url", + "routingKeys": [], + } } } - } - ) + ) + ), + ) as mock_construct_attr_json, + mock.patch.object( + ledger, + "get_all_endpoints_for_did", + mock.CoroutineMock(return_value={}), ), - ) as mock_construct_attr_json, mock.patch.object( - ledger, - "get_all_endpoints_for_did", - mock.CoroutineMock(return_value={}), ): await ledger.update_endpoint_for_did( test_did.did, diff --git a/acapy_agent/ledger/tests/test_routes.py b/acapy_agent/ledger/tests/test_routes.py index 00adc0952b..70e1092b56 100644 --- a/acapy_agent/ledger/tests/test_routes.py +++ b/acapy_agent/ledger/tests/test_routes.py @@ -134,13 +134,16 @@ async def test_get_verkey_multitenant(self): IndyLedgerRequestsExecutor, self.mock_ledger_requests_executor, ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as json_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as json_response, + ): self.ledger.get_key_for_did.return_value = self.test_verkey result = await test_module.get_did_verkey(self.request) json_response.assert_called_once_with( @@ -208,13 +211,16 @@ async def test_get_endpoint_multitenant(self): mock.MagicMock(MultitenantManager, autospec=True), ) self.request.query = {"did": self.test_did} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as json_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as json_response, + ): self.ledger.get_endpoint_for_did.return_value = self.test_endpoint result = await test_module.get_did_endpoint(self.request) json_response.assert_called_once_with( @@ -327,13 +333,17 @@ async def test_register_nym_create_transaction_for_endorser(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -371,13 +381,17 @@ async def test_register_nym_create_transaction_for_endorser_no_public_did(self): } self.profile.context.settings["endorser.author"] = True - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -414,11 +428,14 @@ async def test_register_nym_create_transaction_for_endorser_storage_x(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock(side_effect=test_module.StorageError()) ) @@ -583,13 +600,16 @@ async def test_get_nym_role_multitenant(self): ) self.request.query = {"did": self.test_did} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as json_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as json_response, + ): self.ledger.get_nym_role.return_value = Role.USER result = await test_module.get_nym_role(self.request) json_response.assert_called_once_with( diff --git a/acapy_agent/messaging/base_message.py b/acapy_agent/messaging/base_message.py index 91df02cb1f..766aa47898 100644 --- a/acapy_agent/messaging/base_message.py +++ b/acapy_agent/messaging/base_message.py @@ -1,6 +1,6 @@ """Base message.""" -from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty +from abc import ABC, abstractmethod from enum import Enum, auto from typing import TYPE_CHECKING, Optional, Type @@ -23,15 +23,18 @@ class BaseMessage(ABC): the context of the plugin. """ - @abstractproperty + @property + @abstractmethod def _type(self) -> str: """Return message type.""" - @abstractproperty + @property + @abstractmethod def _id(self) -> str: """Return message id.""" - @abstractproperty + @property + @abstractmethod def _thread_id(self) -> Optional[str]: """Return message thread id.""" @@ -39,10 +42,12 @@ def _thread_id(self) -> Optional[str]: def serialize(self, msg_format: DIDCommVersion = DIDCommVersion.v1) -> dict: """Return serialized message in format specified.""" - @abstractclassmethod + @classmethod + @abstractmethod def deserialize(cls, value: dict, msg_format: DIDCommVersion = DIDCommVersion.v1): """Return message object deserialized from value in format specified.""" - @abstractproperty + @property + @abstractmethod def Handler(self) -> Type["BaseHandler"]: """Return reference to handler class.""" diff --git a/acapy_agent/messaging/credential_definitions/tests/test_routes.py b/acapy_agent/messaging/credential_definitions/tests/test_routes.py index 93ad921c48..65fb61e0b1 100644 --- a/acapy_agent/messaging/credential_definitions/tests/test_routes.py +++ b/acapy_agent/messaging/credential_definitions/tests/test_routes.py @@ -103,13 +103,17 @@ async def test_send_credential_definition_create_transaction_for_endorser(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -152,11 +156,14 @@ async def test_send_credential_definition_create_transaction_for_endorser_storag "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -356,11 +363,14 @@ async def test_get_credential_definition_multitenant(self): mock.MagicMock(MultitenantManager, autospec=True), ) self.request.match_info = {"cred_def_id": CRED_DEF_ID} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): result = await test_module.credential_definitions_get_credential_definition( self.request ) diff --git a/acapy_agent/messaging/credential_definitions/util.py b/acapy_agent/messaging/credential_definitions/util.py index fb732ecd44..1cca544747 100644 --- a/acapy_agent/messaging/credential_definitions/util.py +++ b/acapy_agent/messaging/credential_definitions/util.py @@ -13,8 +13,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, ) CRED_DEF_SENT_RECORD_TYPE = "cred_def_sent" @@ -41,8 +41,11 @@ class CredDefQueryStringSchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, diff --git a/acapy_agent/messaging/decorators/attach_decorator.py b/acapy_agent/messaging/decorators/attach_decorator.py index 98fc177996..7b17c6f670 100644 --- a/acapy_agent/messaging/decorators/attach_decorator.py +++ b/acapy_agent/messaging/decorators/attach_decorator.py @@ -29,8 +29,8 @@ BASE64_VALIDATE, BASE64URL_NO_PAD_EXAMPLE, BASE64URL_NO_PAD_VALIDATE, - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, JWS_HEADER_KID_EXAMPLE, JWS_HEADER_KID_VALIDATE, SHA256_EXAMPLE, @@ -778,12 +778,12 @@ class Meta: ) lastmod_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "Hint regarding last modification datetime, in ISO-8601 format" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) description = fields.Str( diff --git a/acapy_agent/messaging/decorators/service_decorator.py b/acapy_agent/messaging/decorators/service_decorator.py index 0a4695a01c..e4f94b90e3 100644 --- a/acapy_agent/messaging/decorators/service_decorator.py +++ b/acapy_agent/messaging/decorators/service_decorator.py @@ -9,7 +9,10 @@ from marshmallow import EXCLUDE, fields from ..models.base import BaseModel, BaseModelSchema -from ..valid import INDY_RAW_PUBLIC_KEY_EXAMPLE, INDY_RAW_PUBLIC_KEY_VALIDATE +from ..valid import ( + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, +) class ServiceDecorator(BaseModel): @@ -82,10 +85,10 @@ class Meta: recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="recipientKeys", @@ -102,10 +105,10 @@ class Meta: ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="routingKeys", diff --git a/acapy_agent/messaging/decorators/signature_decorator.py b/acapy_agent/messaging/decorators/signature_decorator.py index 22ec1b38c1..ed7a217611 100644 --- a/acapy_agent/messaging/decorators/signature_decorator.py +++ b/acapy_agent/messaging/decorators/signature_decorator.py @@ -3,7 +3,7 @@ import json import struct import time -from typing import Optional +from typing import Optional, Tuple from marshmallow import EXCLUDE, fields @@ -15,8 +15,8 @@ from ..valid import ( BASE64URL_EXAMPLE, BASE64URL_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, ) @@ -86,7 +86,7 @@ async def create( signer=signer, ) - def decode(self) -> (object, int): + def decode(self) -> Tuple[object, int]: """Decode the signature to its timestamp and value. Returns: @@ -164,9 +164,9 @@ class Meta: ) signer = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Signer verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/decorators/timing_decorator.py b/acapy_agent/messaging/decorators/timing_decorator.py index 7ad8fc8c86..cd8dd829d7 100644 --- a/acapy_agent/messaging/decorators/timing_decorator.py +++ b/acapy_agent/messaging/decorators/timing_decorator.py @@ -11,7 +11,7 @@ from ..models.base import BaseModel, BaseModelSchema from ..util import datetime_to_str -from ..valid import INDY_ISO8601_DATETIME_EXAMPLE, INDY_ISO8601_DATETIME_VALIDATE +from ..valid import ISO8601_DATETIME_EXAMPLE, ISO8601_DATETIME_VALIDATE class TimingDecorator(BaseModel): @@ -62,34 +62,34 @@ class Meta: in_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of message receipt", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) out_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of message dispatch", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) stale_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time when message should be considered stale", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) expires_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time when message should be considered expired", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) delay_milli = fields.Int( @@ -102,9 +102,9 @@ class Meta: ) wait_until_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Earliest time at which to perform processing", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/jsonld/tests/test_routes.py b/acapy_agent/messaging/jsonld/tests/test_routes.py index 992b907a49..a98d0818f2 100644 --- a/acapy_agent/messaging/jsonld/tests/test_routes.py +++ b/acapy_agent/messaging/jsonld/tests/test_routes.py @@ -353,13 +353,13 @@ async def test_verify_credential(self): mock_response.assert_called_once_with({"valid": True}) # expected response # compact, expand take a LONG TIME: do them once above, mock for error cases - with mock.patch.object( - jsonld, "compact", mock.MagicMock() - ) as mock_compact, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_expand, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(jsonld, "compact", mock.MagicMock()) as mock_compact, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_expand, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_expand.return_value = [mock.MagicMock()] mock_compact.return_value = { "@context": "...", @@ -388,13 +388,13 @@ async def test_verify_credential(self): result = await test_module.verify(self.request) assert "error" in json.loads(result) - with mock.patch.object( - jsonld, "compact", mock.MagicMock() - ) as mock_compact, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_expand, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(jsonld, "compact", mock.MagicMock()) as mock_compact, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_expand, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_expand.return_value = [mock.MagicMock()] mock_compact.return_value = { "@context": "...", @@ -503,13 +503,13 @@ async def test_sign_credential(self): # compact, expand take a LONG TIME: do them once above, mock for error cases posted_request = deepcopy(POSTED_REQUEST) self.request.json = mock.CoroutineMock(return_value=posted_request) - with mock.patch.object( - jsonld, "compact", mock.MagicMock() - ) as mock_compact, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_expand, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(jsonld, "compact", mock.MagicMock()) as mock_compact, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_expand, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_expand.return_value = [mock.MagicMock()] mock_compact.return_value = {} # drop all attributes mock_response.side_effect = lambda x: json.dumps(x) diff --git a/acapy_agent/messaging/models/base_record.py b/acapy_agent/messaging/models/base_record.py index 100135486c..f32a8e0c4e 100644 --- a/acapy_agent/messaging/models/base_record.py +++ b/acapy_agent/messaging/models/base_record.py @@ -20,7 +20,7 @@ ) from ...storage.record import StorageRecord from ..util import datetime_to_str, time_now -from ..valid import INDY_ISO8601_DATETIME_EXAMPLE, INDY_ISO8601_DATETIME_VALIDATE +from ..valid import ISO8601_DATETIME_EXAMPLE, ISO8601_DATETIME_VALIDATE from .base import BaseModel, BaseModelError, BaseModelSchema LOGGER = logging.getLogger(__name__) @@ -591,18 +591,18 @@ class Meta: ) created_at = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of record creation", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) updated_at = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of last record update", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/schemas/routes.py b/acapy_agent/messaging/schemas/routes.py index d8128a5398..c31983d264 100644 --- a/acapy_agent/messaging/schemas/routes.py +++ b/acapy_agent/messaging/schemas/routes.py @@ -49,8 +49,8 @@ B58, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, UUID4_EXAMPLE, ) from .util import ( @@ -70,8 +70,11 @@ class SchemaSendRequestSchema(OpenAPISchema): ) schema_version = fields.Str( required=True, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) attributes = fields.List( fields.Str(metadata={"description": "attribute name", "example": "score"}), diff --git a/acapy_agent/messaging/schemas/tests/test_routes.py b/acapy_agent/messaging/schemas/tests/test_routes.py index eb29c9cf31..a84a05171d 100644 --- a/acapy_agent/messaging/schemas/tests/test_routes.py +++ b/acapy_agent/messaging/schemas/tests/test_routes.py @@ -104,13 +104,17 @@ async def test_send_schema_create_transaction_for_endorser(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -155,11 +159,14 @@ async def test_send_schema_create_transaction_for_endorser_storage_x(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock(side_effect=test_module.StorageError()) ) @@ -339,11 +346,14 @@ async def test_get_schema_multitenant(self): mock.MagicMock(MultitenantManager, autospec=True), ) self.request.match_info = {"schema_id": SCHEMA_ID} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): result = await test_module.schemas_get_schema(self.request) assert result == mock_response.return_value mock_response.assert_called_once_with( diff --git a/acapy_agent/messaging/schemas/util.py b/acapy_agent/messaging/schemas/util.py index 35f8ce5bae..9a3e0cf989 100644 --- a/acapy_agent/messaging/schemas/util.py +++ b/acapy_agent/messaging/schemas/util.py @@ -11,8 +11,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, ) @@ -37,8 +37,11 @@ class SchemaQueryStringSchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) diff --git a/acapy_agent/messaging/tests/test_valid.py b/acapy_agent/messaging/tests/test_valid.py index 8983d27964..b99737c4a8 100644 --- a/acapy_agent/messaging/tests/test_valid.py +++ b/acapy_agent/messaging/tests/test_valid.py @@ -12,26 +12,27 @@ CREDENTIAL_TYPE_VALIDATE, DID_KEY_VALIDATE, DID_POSTURE_VALIDATE, + DID_TDW_VALIDATE, ENDPOINT_TYPE_VALIDATE, ENDPOINT_VALIDATE, INDY_CRED_DEF_ID_VALIDATE, INDY_CRED_REV_ID_VALIDATE, INDY_DID_VALIDATE, INDY_EXTRA_WQL_VALIDATE, - INDY_ISO8601_DATETIME_VALIDATE, - INDY_PREDICATE_VALIDATE, - INDY_RAW_PUBLIC_KEY_VALIDATE, INDY_REV_REG_ID_VALIDATE, INDY_REV_REG_SIZE_VALIDATE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_VALIDATE, INDY_WQL_VALIDATE, INT_EPOCH_VALIDATE, + ISO8601_DATETIME_VALIDATE, JWS_HEADER_KID_VALIDATE, JWT_VALIDATE, + MAJOR_MINOR_VERSION_VALIDATE, NATURAL_NUM_VALIDATE, NUM_STR_NATURAL_VALIDATE, NUM_STR_WHOLE_VALIDATE, + PREDICATE_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, SHA256_VALIDATE, UUID4_VALIDATE, WHOLE_NUM_VALIDATE, @@ -114,6 +115,24 @@ def test_indy_did(self): INDY_DID_VALIDATE("Q4zqM7aXqm7gDQkUVLng9h") INDY_DID_VALIDATE("did:sov:Q4zqM7aXqm7gDQkUVLng9h") + def test_tdw_did(self): + valid_tdw_dids = [ + "did:tdw:QmUchSB5f5DJQks9CeyLJjhAy4iKJcYzRyiuYq3sjV13px:example.com", + "did:tdw:QmZiKXwQVfyZVuvCsuHpQh4arSUpEmeVVRvSfv3uiEycSr:example.com%3A5000", + ] + for valid_tdw_did in valid_tdw_dids: + DID_TDW_VALIDATE(valid_tdw_did) + + non_valid_tdw_dids = [ + "did:web:QmUchSB5f5DJQks9CeyLJjhAy4iKJcYzRyiuYq3sjV13px", + # Did urls are not allowed + "did:tdw:QmP9VWaTCHcyztDpRj9XSHvZbmYe3m9HZ61KoDtZgWaXVU:example.com%3A5000#z6MkkzY9skorPaoEbCJFKUo7thD8Yb8MBs28aJRopf1TUo9V", + "did:tdw:QmZiKXwQVfyZVuvCsuHpQh4arSUpEmeVVRvSfv3uiEycSr:example.com%3A5000/whois", + ] + for non_valid_tdw_did in non_valid_tdw_dids: + with self.assertRaises(ValidationError): + DID_TDW_VALIDATE(non_valid_tdw_did) + def test_indy_raw_public_key(self): non_indy_raw_public_keys = [ "Q4zqM7aXqm7gDQkUVLng9JQ4zqM7aXqm7gDQkUVLng9I", # 'I' not a base58 char @@ -122,9 +141,11 @@ def test_indy_raw_public_key(self): ] for non_indy_raw_public_key in non_indy_raw_public_keys: with self.assertRaises(ValidationError): - INDY_RAW_PUBLIC_KEY_VALIDATE(non_indy_raw_public_key) + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE(non_indy_raw_public_key) - INDY_RAW_PUBLIC_KEY_VALIDATE("Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h") + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE( + "Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h" + ) def test_jws_header_kid(self): non_kids = [ @@ -264,12 +285,12 @@ def test_version(self): non_versions = ["-1", "", "3_5", "3.5a"] for non_version in non_versions: with self.assertRaises(ValidationError): - INDY_VERSION_VALIDATE(non_version) + MAJOR_MINOR_VERSION_VALIDATE(non_version) - INDY_VERSION_VALIDATE("1.0") - INDY_VERSION_VALIDATE(".05") - INDY_VERSION_VALIDATE("1.2.3") - INDY_VERSION_VALIDATE("..") # perverse but technically OK + MAJOR_MINOR_VERSION_VALIDATE("1.0") + MAJOR_MINOR_VERSION_VALIDATE(".05") + MAJOR_MINOR_VERSION_VALIDATE("1.2.3") + MAJOR_MINOR_VERSION_VALIDATE("..") # perverse but technically OK def test_schema_id(self): non_schema_ids = [ @@ -292,12 +313,12 @@ def test_predicate(self): non_predicates = [">>", "", " >= ", "<<<=", "==", "=", "!="] for non_predicate in non_predicates: with self.assertRaises(ValidationError): - INDY_PREDICATE_VALIDATE(non_predicate) + PREDICATE_VALIDATE(non_predicate) - INDY_PREDICATE_VALIDATE("<") - INDY_PREDICATE_VALIDATE("<=") - INDY_PREDICATE_VALIDATE(">=") - INDY_PREDICATE_VALIDATE(">") + PREDICATE_VALIDATE("<") + PREDICATE_VALIDATE("<=") + PREDICATE_VALIDATE(">=") + PREDICATE_VALIDATE(">") def test_indy_date(self): non_datetimes = [ @@ -310,17 +331,17 @@ def test_indy_date(self): ] for non_datetime in non_datetimes: with self.assertRaises(ValidationError): - INDY_ISO8601_DATETIME_VALIDATE(non_datetime) - - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00Z") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00Z") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00+00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00-00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00-00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.1-00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.123456-00:00") + ISO8601_DATETIME_VALIDATE(non_datetime) + + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00Z") + ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00Z") + ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00+00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00-00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00-00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.1-00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.123456-00:00") def test_indy_wql(self): non_wqls = [ diff --git a/acapy_agent/messaging/valid.py b/acapy_agent/messaging/valid.py index 894c1a819b..c5026ca382 100644 --- a/acapy_agent/messaging/valid.py +++ b/acapy_agent/messaging/valid.py @@ -319,6 +319,20 @@ def __init__(self): ) +class DIDTdw(Regexp): + """Validate value against did:tdw specification.""" + + EXAMPLE = "did:tdw:QmP9VWaTCHcyztDpRj9XSHvZbmYe3m9HZ61KoDtZgWaXVU:example.com%3A5000" + PATTERN = re.compile(r"^(did:tdw:)([a-zA-Z0-9%._-]*:)*[a-zA-Z0-9%._-]+$") + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + DIDTdw.PATTERN, error="Value {input} is not in W3C did:tdw format" + ) + + class DIDPosture(OneOf): """Validate value against defined DID postures.""" @@ -348,6 +362,21 @@ def __init__(self): ) +class AnoncredsDID(Regexp): + """Validate value against indy DID.""" + + EXAMPLE = "did:(method):WgWxqztrNooG92RXvxSTWv" + PATTERN = re.compile("^(did:[a-z]:.+$)?$") + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + IndyDID.PATTERN, + error="Value {input} is not an decentralized identifier (DID)", + ) + + class DIDValidation(Regexp): """Validate value against any valid DID spec.""" @@ -386,8 +415,8 @@ def __init__(self): ) -class IndyRawPublicKey(Regexp): - """Validate value against indy (Ed25519VerificationKey2018) raw public key.""" +class RawPublicEd25519VerificationKey2018(Regexp): + """Validate value against (Ed25519VerificationKey2018) raw public key.""" EXAMPLE = "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV" PATTERN = rf"^[{B58}]{{43,44}}$" @@ -396,7 +425,7 @@ def __init__(self): """Initialize the instance.""" super().__init__( - IndyRawPublicKey.PATTERN, + RawPublicEd25519VerificationKey2018.PATTERN, error="Value {input} is not a raw Ed25519VerificationKey2018 key", ) @@ -409,7 +438,9 @@ class RoutingKey(Regexp): """ EXAMPLE = DIDKey.EXAMPLE - PATTERN = re.compile(DIDKey.PATTERN.pattern + "|" + IndyRawPublicKey.PATTERN) + PATTERN = re.compile( + DIDKey.PATTERN.pattern + "|" + RawPublicEd25519VerificationKey2018.PATTERN + ) def __init__(self): """Initialize the instance.""" @@ -444,8 +475,23 @@ def __init__(self): ) -class IndyVersion(Regexp): - """Validate value against indy version specification.""" +class AnoncredsCredDefId(Regexp): + """Validate value against anoncreds credential definition identifier specification.""" + + EXAMPLE = "did:(method):3:CL:20:tag" + PATTERN = r"^(.+$)" + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + IndyCredDefId.PATTERN, + error="Value {input} is not an anoncreds credential definition identifier", + ) + + +class MajorMinorVersion(Regexp): + """Validate value against major minor version specification.""" EXAMPLE = "1.0" PATTERN = r"^[0-9.]+$" @@ -454,8 +500,8 @@ def __init__(self): """Initialize the instance.""" super().__init__( - IndyVersion.PATTERN, - error="Value {input} is not an indy version (use only digits and '.')", + MajorMinorVersion.PATTERN, + error="Value {input} is not a valid version major minor version (use only digits and '.')", # noqa: E501 ) @@ -474,6 +520,21 @@ def __init__(self): ) +class AnoncredsSchemaId(Regexp): + """Validate value against indy schema identifier specification.""" + + EXAMPLE = "did:(method):2:schema_name:1.0" + PATTERN = r"^(.+$)" + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + IndySchemaId.PATTERN, + error="Value {input} is not an anoncreds schema identifier", + ) + + class IndyRevRegId(Regexp): """Validate value against indy revocation registry identifier specification.""" @@ -494,6 +555,21 @@ def __init__(self): ) +class AnoncredsRevRegId(Regexp): + """Validate value against anoncreds revocation registry identifier specification.""" + + EXAMPLE = "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0" + PATTERN = r"^(.+$)" + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + AnoncredsRevRegId.PATTERN, + error="Value {input} is not an anoncreds revocation registry identifier", + ) + + class IndyCredRevId(Regexp): """Validate value against indy credential revocation identifier specification.""" @@ -509,8 +585,8 @@ def __init__(self): ) -class IndyPredicate(OneOf): - """Validate value against indy predicate.""" +class Predicate(OneOf): + """Validate value against predicate.""" EXAMPLE = ">=" @@ -523,8 +599,8 @@ def __init__(self): ) -class IndyISO8601DateTime(Regexp): - """Validate value against ISO 8601 datetime format, indy profile.""" +class ISO8601DateTime(Regexp): + """Validate value against ISO 8601 datetime format.""" EXAMPLE = epoch_to_str(EXAMPLE_TIMESTAMP) PATTERN = ( @@ -536,7 +612,7 @@ def __init__(self): """Initialize the instance.""" super().__init__( - IndyISO8601DateTime.PATTERN, + ISO8601DateTime.PATTERN, error="Value {input} is not a date in valid format", ) @@ -934,6 +1010,9 @@ def __init__( DID_WEB_VALIDATE = DIDWeb() DID_WEB_EXAMPLE = DIDWeb.EXAMPLE +DID_TDW_VALIDATE = DIDTdw() +DID_TDW_EXAMPLE = DIDTdw.EXAMPLE + ROUTING_KEY_VALIDATE = RoutingKey() ROUTING_KEY_EXAMPLE = RoutingKey.EXAMPLE @@ -943,29 +1022,38 @@ def __init__( GENERIC_DID_VALIDATE = MaybeIndyDID() GENERIC_DID_EXAMPLE = MaybeIndyDID.EXAMPLE -INDY_RAW_PUBLIC_KEY_VALIDATE = IndyRawPublicKey() -INDY_RAW_PUBLIC_KEY_EXAMPLE = IndyRawPublicKey.EXAMPLE +RAW_ED25519_2018_PUBLIC_KEY_VALIDATE = RawPublicEd25519VerificationKey2018() +RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE = RawPublicEd25519VerificationKey2018.EXAMPLE INDY_SCHEMA_ID_VALIDATE = IndySchemaId() INDY_SCHEMA_ID_EXAMPLE = IndySchemaId.EXAMPLE +ANONCREDS_SCHEMA_ID_VALIDATE = AnoncredsSchemaId() +ANONCREDS_SCHEMA_ID_EXAMPLE = AnoncredsSchemaId.EXAMPLE + INDY_CRED_DEF_ID_VALIDATE = IndyCredDefId() INDY_CRED_DEF_ID_EXAMPLE = IndyCredDefId.EXAMPLE +ANONCREDS_CRED_DEF_ID_VALIDATE = AnoncredsCredDefId() +ANONCREDS_CRED_DEF_ID_EXAMPLE = AnoncredsCredDefId.EXAMPLE + INDY_REV_REG_ID_VALIDATE = IndyRevRegId() INDY_REV_REG_ID_EXAMPLE = IndyRevRegId.EXAMPLE +ANONCREDS_REV_REG_ID_VALIDATE = AnoncredsRevRegId() +ANONCREDS_REV_REG_ID_EXAMPLE = AnoncredsRevRegId.EXAMPLE + INDY_CRED_REV_ID_VALIDATE = IndyCredRevId() INDY_CRED_REV_ID_EXAMPLE = IndyCredRevId.EXAMPLE -INDY_VERSION_VALIDATE = IndyVersion() -INDY_VERSION_EXAMPLE = IndyVersion.EXAMPLE +MAJOR_MINOR_VERSION_VALIDATE = MajorMinorVersion() +MAJOR_MINOR_VERSION_EXAMPLE = MajorMinorVersion.EXAMPLE -INDY_PREDICATE_VALIDATE = IndyPredicate() -INDY_PREDICATE_EXAMPLE = IndyPredicate.EXAMPLE +PREDICATE_VALIDATE = Predicate() +PREDICATE_EXAMPLE = Predicate.EXAMPLE -INDY_ISO8601_DATETIME_VALIDATE = IndyISO8601DateTime() -INDY_ISO8601_DATETIME_EXAMPLE = IndyISO8601DateTime.EXAMPLE +ISO8601_DATETIME_VALIDATE = ISO8601DateTime() +ISO8601_DATETIME_EXAMPLE = ISO8601DateTime.EXAMPLE RFC3339_DATETIME_VALIDATE = RFC3339DateTime() RFC3339_DATETIME_EXAMPLE = RFC3339DateTime.EXAMPLE @@ -1020,3 +1108,6 @@ def __init__( INDY_OR_KEY_DID_VALIDATE = IndyOrKeyDID() INDY_OR_KEY_DID_EXAMPLE = IndyOrKeyDID.EXAMPLE + +ANONCREDS_DID_VALIDATE = AnoncredsDID() +ANONCREDS_DID_EXAMPLE = AnoncredsDID.EXAMPLE diff --git a/acapy_agent/multitenant/admin/tests/test_routes.py b/acapy_agent/multitenant/admin/tests/test_routes.py index 0dc4101267..6f24c863de 100644 --- a/acapy_agent/multitenant/admin/tests/test_routes.py +++ b/acapy_agent/multitenant/admin/tests/test_routes.py @@ -51,11 +51,12 @@ async def test_format_wallet_record_removes_wallet_key(self): assert "wallet.key" not in formatted["settings"] async def test_wallets_list(self): - with mock.patch.object( - test_module, "WalletRecord", autospec=True - ) as mock_wallet_record, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "WalletRecord", autospec=True + ) as mock_wallet_record, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): wallets = [ mock.MagicMock( serialize=mock.MagicMock( @@ -110,11 +111,12 @@ async def test_wallets_list_x(self): async def test_wallets_list_query(self): self.request.query = {"wallet_name": "test"} - with mock.patch.object( - test_module, "WalletRecord", autospec=True - ) as mock_wallet_record, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "WalletRecord", autospec=True + ) as mock_wallet_record, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): wallets = [ mock.MagicMock( serialize=mock.MagicMock( @@ -654,11 +656,12 @@ async def test_wallet_get(self): return_value={"settings": {}, "wallet_id": "dummy"} ) - with mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_wallet_record_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_wallet_record_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_wallet_record_retrieve_by_id.return_value = mock_wallet_record await test_module.wallet_get(self.request) @@ -698,11 +701,12 @@ async def test_wallet_create_token_managed(self): return_value={"settings": {}, "wallet_id": "dummy"} ) - with mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_wallet_record_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_wallet_record_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_wallet_record_retrieve_by_id.return_value = mock_wallet_record mock_multitenant_mgr = mock.AsyncMock(BaseMultitenantManager, autospec=True) mock_multitenant_mgr.create_auth_token = mock.CoroutineMock( @@ -727,11 +731,12 @@ async def test_wallet_create_token_unmanaged(self): return_value={"settings": {}, "wallet_id": "dummy"} ) - with mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_wallet_record_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_wallet_record_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_wallet_record_retrieve_by_id.return_value = mock_wallet_record mock_multitenant_mgr = mock.AsyncMock(BaseMultitenantManager, autospec=True) mock_multitenant_mgr.create_auth_token = mock.CoroutineMock( @@ -803,10 +808,11 @@ async def test_wallet_remove_managed(self): BaseMultitenantManager, mock_multitenant_mgr ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ), ): result = await test_module.wallet_remove(self.request) @@ -822,10 +828,11 @@ async def test_wallet_remove_unmanaged(self): self.profile.context.injector.bind_instance( BaseMultitenantManager, mock_multitenant_mgr ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ), ): result = await test_module.wallet_remove(self.request) diff --git a/acapy_agent/multitenant/manager.py b/acapy_agent/multitenant/manager.py index 1a6bda9030..8137e9dbe9 100644 --- a/acapy_agent/multitenant/manager.py +++ b/acapy_agent/multitenant/manager.py @@ -88,7 +88,7 @@ async def get_wallet_profile( # return anoncreds profile if explicitly set as wallet type if profile.context.settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( profile.opened, profile.context, ) diff --git a/acapy_agent/multitenant/single_wallet_askar_manager.py b/acapy_agent/multitenant/single_wallet_askar_manager.py index 157bd287e0..417bdfb572 100644 --- a/acapy_agent/multitenant/single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/single_wallet_askar_manager.py @@ -107,13 +107,13 @@ async def get_wallet_profile( # return anoncreds profile if explicitly set as wallet type if profile_context.settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( self._multitenant_profile.opened, profile_context, profile_id=wallet_record.wallet_id, ) - return AskarProfile( + return await AskarProfile.create( self._multitenant_profile.opened, profile_context, profile_id=wallet_record.wallet_id, diff --git a/acapy_agent/multitenant/tests/test_base.py b/acapy_agent/multitenant/tests/test_base.py index 88834434f0..dbfb40a85c 100644 --- a/acapy_agent/multitenant/tests/test_base.py +++ b/acapy_agent/multitenant/tests/test_base.py @@ -210,11 +210,10 @@ async def test_create_wallet_saves_wallet_record_creates_profile(self): mock_route_manager.route_verkey = mock.CoroutineMock() self.context.injector.bind_instance(RouteManager, mock_route_manager) - with mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save, mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile: + with ( + mock.patch.object(WalletRecord, "save") as wallet_record_save, + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + ): get_wallet_profile.return_value = await create_test_profile() wallet_record = await self.manager.create_wallet( @@ -247,13 +246,11 @@ async def test_create_wallet_adds_wallet_route(self): mock_route_manager = mock.MagicMock() mock_route_manager.route_verkey = mock.CoroutineMock() - with mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save, mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile, mock.patch.object( - BaseWallet, "get_public_did" - ) as get_public_did: + with ( + mock.patch.object(WalletRecord, "save") as wallet_record_save, + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + mock.patch.object(BaseWallet, "get_public_did") as get_public_did, + ): mock_profile = await create_test_profile() mock_profile.context.injector.bind_instance(RouteManager, mock_route_manager) get_wallet_profile.return_value = mock_profile @@ -277,11 +274,10 @@ async def test_create_wallet_adds_wallet_route(self): assert wallet_record.wallet_key == "test_key" async def test_update_wallet(self): - with mock.patch.object( - WalletRecord, "retrieve_by_id" - ) as retrieve_by_id, mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save: + with ( + mock.patch.object(WalletRecord, "retrieve_by_id") as retrieve_by_id, + mock.patch.object(WalletRecord, "save") as wallet_record_save, + ): wallet_id = "test-wallet-id" retrieve_by_id.return_value = WalletRecord( wallet_id=wallet_id, @@ -315,17 +311,15 @@ async def test_remove_wallet_fails_no_wallet_key_but_required(self): await self.manager.remove_wallet("test") async def test_remove_wallet_removes_profile_wallet_storage_records(self): - with mock.patch.object( - WalletRecord, "retrieve_by_id" - ) as retrieve_by_id, mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile, mock.patch.object( - self.manager, "remove_wallet_profile" - ) as remove_wallet_profile, mock.patch.object( - WalletRecord, "delete_record" - ) as wallet_delete_record, mock.patch.object( - AskarStorage, "delete_all_records" - ) as delete_all_records: + with ( + mock.patch.object(WalletRecord, "retrieve_by_id") as retrieve_by_id, + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + mock.patch.object( + self.manager, "remove_wallet_profile" + ) as remove_wallet_profile, + mock.patch.object(WalletRecord, "delete_record") as wallet_delete_record, + mock.patch.object(AskarStorage, "delete_all_records") as delete_all_records, + ): wallet_record = WalletRecord( wallet_id="test", key_management_mode=WalletRecord.MODE_UNMANAGED, @@ -555,10 +549,9 @@ async def test_get_profile_for_token_managed_wallet_x_iat_no_match(self): algorithm="HS256", ) - with mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile, self.assertRaises( - MultitenantManagerError, msg="Token not valid" + with ( + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + self.assertRaises(MultitenantManagerError, msg="Token not valid"), ): await self.manager.get_profile_for_token(self.profile.context, token) @@ -632,12 +625,15 @@ async def test_get_wallets_by_message(self): async def test_get_profile_for_key(self): mock_wallet = mock.MagicMock() mock_wallet.requires_external_key = False - with mock.patch.object( - self.manager, - "_get_wallet_by_key", - mock.CoroutineMock(return_value=mock_wallet), - ), mock.patch.object( - self.manager, "get_wallet_profile", mock.CoroutineMock() - ) as mock_get_wallet_profile: + with ( + mock.patch.object( + self.manager, + "_get_wallet_by_key", + mock.CoroutineMock(return_value=mock_wallet), + ), + mock.patch.object( + self.manager, "get_wallet_profile", mock.CoroutineMock() + ) as mock_get_wallet_profile, + ): profile = await self.manager.get_profile_for_key(self.context, "test-verkey") assert profile == mock_get_wallet_profile.return_value diff --git a/acapy_agent/multitenant/tests/test_manager.py b/acapy_agent/multitenant/tests/test_manager.py index 7cd92e5bc7..cc633d2e09 100644 --- a/acapy_agent/multitenant/tests/test_manager.py +++ b/acapy_agent/multitenant/tests/test_manager.py @@ -169,11 +169,10 @@ async def side_effect(context, provision): assert profile.settings.get("mediation.clear") is True async def test_update_wallet_update_wallet_profile(self): - with mock.patch.object( - WalletRecord, "retrieve_by_id" - ) as retrieve_by_id, mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save: + with ( + mock.patch.object(WalletRecord, "retrieve_by_id") as retrieve_by_id, + mock.patch.object(WalletRecord, "save") as wallet_record_save, + ): wallet_id = "test-wallet-id" wallet_profile = await create_test_profile() self.manager._profiles.put("test-wallet-id", wallet_profile) diff --git a/acapy_agent/multitenant/tests/test_route_manager.py b/acapy_agent/multitenant/tests/test_route_manager.py index 3a3218199d..4dad3d9dce 100644 --- a/acapy_agent/multitenant/tests/test_route_manager.py +++ b/acapy_agent/multitenant/tests/test_route_manager.py @@ -61,11 +61,16 @@ async def test_route_for_key_sub_mediator_no_base_mediator( mediation_id="test-mediation-id", connection_id="test-mediator-conn-id" ) - with mock.patch.object( - route_manager, "get_base_wallet_mediator", mock.CoroutineMock(return_value=None) - ), mock.patch.object( - RoutingManager, "create_route_record", mock.CoroutineMock() - ) as mock_create_route_record: + with ( + mock.patch.object( + route_manager, + "get_base_wallet_mediator", + mock.CoroutineMock(return_value=None), + ), + mock.patch.object( + RoutingManager, "create_route_record", mock.CoroutineMock() + ) as mock_create_route_record, + ): keylist_update = await route_manager._route_for_key( sub_profile, TEST_VERKEY, @@ -102,13 +107,16 @@ async def test_route_for_key_sub_mediator_and_base_mediator( connection_id="test-base-mediator-conn-id", ) - with mock.patch.object( - route_manager, - "get_base_wallet_mediator", - mock.CoroutineMock(return_value=base_mediation_record), - ), mock.patch.object( - RoutingManager, "create_route_record", mock.CoroutineMock() - ) as mock_create_route_record: + with ( + mock.patch.object( + route_manager, + "get_base_wallet_mediator", + mock.CoroutineMock(return_value=base_mediation_record), + ), + mock.patch.object( + RoutingManager, "create_route_record", mock.CoroutineMock() + ) as mock_create_route_record, + ): keylist_update = await route_manager._route_for_key( sub_profile, TEST_VERKEY, @@ -142,13 +150,16 @@ async def test_route_for_key_base_mediator_no_sub_mediator( connection_id="test-base-mediator-conn-id", ) - with mock.patch.object( - route_manager, - "get_base_wallet_mediator", - mock.CoroutineMock(return_value=base_mediation_record), - ), mock.patch.object( - RoutingManager, "create_route_record", mock.CoroutineMock() - ) as mock_create_route_record: + with ( + mock.patch.object( + route_manager, + "get_base_wallet_mediator", + mock.CoroutineMock(return_value=base_mediation_record), + ), + mock.patch.object( + RoutingManager, "create_route_record", mock.CoroutineMock() + ) as mock_create_route_record, + ): keylist_update = await route_manager._route_for_key( sub_profile, TEST_VERKEY, diff --git a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py index 6ac3cbb77f..c59f098f18 100644 --- a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py @@ -43,13 +43,16 @@ async def test_get_wallet_profile_should_open_store_and_return_profile_with_wall }, ) - with mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" - ) as wallet_config, mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile", - ) as AskarProfile: + with ( + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" + ) as wallet_config, + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile", + ) as AskarProfile, + ): sub_wallet_profile_context = InjectionContext() - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context def side_effect(context, provision): @@ -115,13 +118,16 @@ async def test_get_anoncreds_wallet_profile_should_open_store_and_return_anoncre }, ) - with mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" - ) as wallet_config, mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.AskarAnoncredsProfile", - ) as AskarAnoncredsProfile: + with ( + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" + ) as wallet_config, + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.AskarAnoncredsProfile", + ) as AskarAnoncredsProfile, + ): sub_wallet_profile_context = InjectionContext() - sub_wallet_profile = AskarAnoncredsProfile(None, None) + sub_wallet_profile = await AskarAnoncredsProfile.create(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context def side_effect(context, provision): @@ -144,7 +150,7 @@ async def test_get_wallet_profile_should_create_profile(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() sub_wallet_profile.store.create_profile.return_value = create_profile_stub self.manager._multitenant_profile = sub_wallet_profile @@ -170,7 +176,7 @@ async def test_get_wallet_profile_should_use_custom_subwallet_name(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() def side_effect(context, provision): @@ -201,7 +207,7 @@ async def test_open_profiles(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() sub_wallet_profile.store.create_profile.return_value = create_profile_stub self.manager._multitenant_profile = sub_wallet_profile diff --git a/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py b/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py index 1b76449de6..268a252711 100644 --- a/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py @@ -73,13 +73,13 @@ async def test_actionmenu_perform(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Perform", autospec=True - ) as mock_perform, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True) as mock_perform, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() await test_module.actionmenu_perform(self.request) @@ -93,9 +93,12 @@ async def test_actionmenu_perform_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate storage not found (bad connection id) mock_conn_record.retrieve_by_id = mock.CoroutineMock( side_effect=StorageNotFoundError @@ -108,9 +111,12 @@ async def test_actionmenu_perform_conn_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate connection not ready mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_conn_record.retrieve_by_id.return_value.is_ready = False @@ -122,13 +128,13 @@ async def test_actionmenu_request(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "MenuRequest", autospec=True - ) as menu_request, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "MenuRequest", autospec=True) as menu_request, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() await test_module.actionmenu_request(self.request) @@ -142,9 +148,12 @@ async def test_actionmenu_request_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate storage not found (bad connection id) mock_conn_record.retrieve_by_id = mock.CoroutineMock( side_effect=StorageNotFoundError @@ -157,9 +166,12 @@ async def test_actionmenu_request_conn_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate connection not ready mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_conn_record.retrieve_by_id.return_value.is_ready = False @@ -171,13 +183,13 @@ async def test_actionmenu_send(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_menu.deserialize = mock.MagicMock() @@ -192,11 +204,12 @@ async def test_actionmenu_send_deserialize_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_menu.deserialize = mock.MagicMock( side_effect=test_module.BaseModelError("cannot deserialize") @@ -209,11 +222,12 @@ async def test_actionmenu_send_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + ): mock_menu.deserialize = mock.MagicMock() # Emulate storage not found (bad connection id) @@ -228,11 +242,12 @@ async def test_actionmenu_send_conn_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + ): mock_menu.deserialize = mock.MagicMock() # Emulate connection not ready diff --git a/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py b/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py index 840be506b9..1a8940a904 100644 --- a/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py +++ b/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py @@ -8,8 +8,8 @@ from .....messaging.agent_message import AgentMessage, AgentMessageSchema from .....messaging.util import datetime_now, datetime_to_str from .....messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, ) from ..message_types import BASIC_MESSAGE, PROTOCOL_PACKAGE @@ -63,12 +63,12 @@ class Meta: sent_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "Time message was sent, ISO8601 with space date/time separator" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) content = fields.Str( diff --git a/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py b/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py index cd15506fd4..736ae633d7 100644 --- a/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py @@ -33,13 +33,15 @@ async def test_connections_send_message(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": self.test_conn_id} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_connection_record, mock.patch.object( - test_module, "BasicMessage", autospec=True - ) as mock_basic_message, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_connection_record, + mock.patch.object( + test_module, "BasicMessage", autospec=True + ) as mock_basic_message, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_connection_record.retrieve_by_id = mock.CoroutineMock() await test_module.connections_send_message(self.request) @@ -50,10 +52,11 @@ async def test_connections_send_message_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": self.test_conn_id} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_connection_record, mock.patch.object( - test_module, "BasicMessage", autospec=True + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_connection_record, + mock.patch.object(test_module, "BasicMessage", autospec=True), ): # Emulate storage not found (bad connection id) mock_connection_record.retrieve_by_id = mock.CoroutineMock( @@ -67,11 +70,14 @@ async def test_connections_send_message_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": self.test_conn_id} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_connection_record, mock.patch.object( - test_module, "BasicMessage", autospec=True - ) as mock_basic_message: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_connection_record, + mock.patch.object( + test_module, "BasicMessage", autospec=True + ) as mock_basic_message, + ): # Emulate connection not ready mock_connection_record.retrieve_by_id = mock.CoroutineMock() mock_connection_record.retrieve_by_id.return_value.is_ready = False diff --git a/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py b/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py index d983eb0ede..51e9f5f3c2 100644 --- a/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py +++ b/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py @@ -10,8 +10,8 @@ from .....messaging.valid import ( GENERIC_DID_EXAMPLE, GENERIC_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, ) from .....wallet.util import b64_to_bytes, bytes_to_b64 from ..message_types import CONNECTION_INVITATION, PROTOCOL_PACKAGE @@ -131,10 +131,10 @@ class Meta: ) recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="recipientKeys", @@ -151,10 +151,10 @@ class Meta: ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="routingKeys", diff --git a/acapy_agent/protocols/connections/v1_0/routes.py b/acapy_agent/protocols/connections/v1_0/routes.py index 8277484e40..0e415ceabc 100644 --- a/acapy_agent/protocols/connections/v1_0/routes.py +++ b/acapy_agent/protocols/connections/v1_0/routes.py @@ -29,8 +29,8 @@ GENERIC_DID_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, ) @@ -94,10 +94,10 @@ class CreateInvitationRequestSchema(OpenAPISchema): recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), required=False, @@ -112,10 +112,10 @@ class CreateInvitationRequestSchema(OpenAPISchema): ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), required=False, @@ -213,10 +213,10 @@ class ConnectionStaticResultSchema(OpenAPISchema): ) my_verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "My verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) my_endpoint = fields.Str( @@ -231,10 +231,10 @@ class ConnectionStaticResultSchema(OpenAPISchema): ) their_verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Remote verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) record = fields.Nested(ConnRecordSchema(), required=True) @@ -248,10 +248,10 @@ class ConnectionsListQueryStringSchema(PaginatedQuerySchema): ) invitation_key = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "invitation key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) my_did = fields.Str( diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_manager.py b/acapy_agent/protocols/connections/v1_0/tests/test_manager.py index a96363dc00..eb2c5b7f6d 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_manager.py @@ -412,14 +412,18 @@ async def test_create_request_multitenant(self): endpoint=self.test_mediator_endpoint, ) - with mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, @@ -465,14 +469,16 @@ async def test_create_request_mediation_id(self): # Ensure the path with new did creation is hit record.my_did = None - with mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - AskarWallet, "create_local_did" - ) as create_local_did, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object(AskarWallet, "create_local_did") as create_local_did, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): did_info = DIDInfo( did=self.test_did, @@ -516,14 +522,16 @@ async def test_create_request_default_mediator(self): # Ensure the path with new did creation is hit record.my_did = None - with mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - AskarWallet, "create_local_did" - ) as create_local_did, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object(AskarWallet, "create_local_did") as create_local_did, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): did_info = DIDInfo( did=self.test_did, @@ -565,18 +573,18 @@ async def test_receive_request_public_did_oob_invite(self): ) self.context.update_settings({"public_invites": True}) - with mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = ConnRecord() conn_rec = await self.manager.receive_request(mock_request, receipt) @@ -606,18 +614,19 @@ async def test_receive_request_public_did_unsolicited_fails(self): ) self.context.update_settings({"public_invites": True}) - with self.assertRaises(ConnectionManagerError), mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + self.assertRaises(ConnectionManagerError), + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = None await self.manager.receive_request(mock_request, receipt) @@ -646,20 +655,20 @@ async def test_receive_request_public_did_conn_invite(self): mock_connection_record.attach_request = mock.CoroutineMock() self.context.update_settings({"public_invites": True}) - with mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, - "retrieve_by_invitation_msg_id", - mock.CoroutineMock(return_value=mock_connection_record), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, + "retrieve_by_invitation_msg_id", + mock.CoroutineMock(return_value=mock_connection_record), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): conn_rec = await self.manager.receive_request(mock_request, receipt) assert conn_rec @@ -685,18 +694,18 @@ async def test_receive_request_public_did_unsolicited(self): self.context.update_settings({"public_invites": True}) self.context.update_settings({"requests_through_public_did": True}) - with mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = None conn_rec = await self.manager.receive_request(mock_request, receipt) @@ -721,11 +730,12 @@ async def test_receive_request_public_did_no_did_doc(self): ) self.context.update_settings({"public_invites": True}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object(ConnRecord, "retrieve_request", autospec=True): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + ): with self.assertRaises(ConnectionManagerError): await self.manager.receive_request(mock_request, receipt) @@ -749,11 +759,12 @@ async def test_receive_request_public_did_wrong_did(self): ) self.context.update_settings({"public_invites": True}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object(ConnRecord, "retrieve_request", autospec=True): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + ): with self.assertRaises(ConnectionManagerError): await self.manager.receive_request(mock_request, receipt) @@ -775,13 +786,13 @@ async def test_receive_request_public_did_no_public_invites(self): ) self.context.update_settings({"public_invites": False}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): with self.assertRaises(ConnectionManagerError): await self.manager.receive_request(mock_request, receipt) @@ -807,16 +818,17 @@ async def test_receive_request_public_did_no_auto_accept(self): self.context.update_settings( {"public_invites": True, "debug.auto_accept_requests": False} ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = ConnRecord() conn_rec = await self.manager.receive_request(mock_request, receipt) @@ -828,11 +840,13 @@ async def test_receive_request_public_did_no_auto_accept(self): async def test_create_response(self): conn_rec = ConnRecord(state=ConnRecord.State.REQUEST.rfc160) - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnectionResponse, "sign_field", autospec=True - ), mock.patch.object(conn_rec, "metadata_get", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + mock.patch.object(conn_rec, "metadata_get", mock.CoroutineMock()), + ): await self.manager.create_response(conn_rec, "http://10.20.30.40:5060/") async def test_create_response_multitenant(self): @@ -849,22 +863,25 @@ async def test_create_response_multitenant(self): endpoint=self.test_mediator_endpoint, ) - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "save", autospec=True - ), mock.patch.object( - ConnRecord, "metadata_get", mock.CoroutineMock(return_value=False) - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnectionResponse, "sign_field", autospec=True - ), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "metadata_get", mock.CoroutineMock(return_value=False) + ), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, @@ -921,21 +938,24 @@ async def test_create_response_mediation(self): # Ensure the path with new did creation is hit record.my_did = None - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "save", autospec=True - ), mock.patch.object( - record, "metadata_get", mock.CoroutineMock(return_value=False) - ), mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - AskarWallet, "create_local_did" - ) as create_local_did, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), - ), mock.patch.object( - record, "retrieve_request", autospec=True - ), mock.patch.object(ConnectionResponse, "sign_field", autospec=True): + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + record, "metadata_get", mock.CoroutineMock(return_value=False) + ), + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object(AskarWallet, "create_local_did") as create_local_did, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), + mock.patch.object(record, "retrieve_request", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + ): did_info = DIDInfo( did=self.test_did, verkey=self.test_verkey, @@ -964,12 +984,14 @@ async def test_create_response_auto_send_mediation_request(self): ) conn_rec.my_did = None - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnectionResponse, "sign_field", autospec=True - ), mock.patch.object( - conn_rec, "metadata_get", mock.CoroutineMock(return_value=True) + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + mock.patch.object( + conn_rec, "metadata_get", mock.CoroutineMock(return_value=True) + ), ): await self.manager.create_response(conn_rec) @@ -988,11 +1010,16 @@ async def test_accept_response_find_by_thread_id(self): mock_response.verify_signed_field = mock.CoroutineMock(return_value="sig_verkey") receipt = MessageReceipt(recipient_did=self.test_did, recipient_did_public=True) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), @@ -1017,13 +1044,19 @@ async def test_accept_response_not_found_by_thread_id_receipt_has_sender_did(sel receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.return_value = mock.MagicMock( did=self.test_target_did, @@ -1051,11 +1084,15 @@ async def test_accept_response_not_found_by_thread_id_nor_receipt_sender_did(sel receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() @@ -1072,9 +1109,12 @@ async def test_accept_response_find_by_thread_id_bad_state(self): receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( state=ConnRecord.State.ABANDONED.rfc23 ) @@ -1091,9 +1131,12 @@ async def test_accept_response_find_by_thread_id_no_connection_did_doc(self): receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), @@ -1113,9 +1156,12 @@ async def test_accept_response_find_by_thread_id_did_mismatch(self): receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), @@ -1135,10 +1181,14 @@ async def test_accept_response_verify_invitation_key_sign_failure(self): mock_response.verify_signed_field = mock.CoroutineMock(side_effect=ValueError) receipt = MessageReceipt(recipient_did=self.test_did, recipient_did_public=True) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, @@ -1162,11 +1212,16 @@ async def test_accept_response_auto_send_mediation_request(self): mock_response.verify_signed_field = mock.CoroutineMock(return_value="sig_verkey") receipt = MessageReceipt(recipient_did=self.test_did, recipient_did_public=True) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py index 05e279e75b..002ad67263 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py @@ -148,11 +148,12 @@ async def test_connections_retrieve(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock(return_value={"hello": "world"}) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec await test_module.connections_retrieve(self.request) @@ -161,11 +162,12 @@ async def test_connections_retrieve(self): async def test_connections_endpoints(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr_cls.return_value = mock.MagicMock( get_endpoints=mock.CoroutineMock( return_value=("localhost:8080", "1.2.3.4:8081") @@ -182,9 +184,12 @@ async def test_connections_endpoints(self): async def test_connections_endpoints_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_mgr_cls.return_value = mock.MagicMock( get_endpoints=mock.CoroutineMock(side_effect=StorageNotFoundError()) ) @@ -203,13 +208,15 @@ async def test_connections_metadata(self): self.request.match_info = {"conn_id": "dummy"} mock_conn_rec = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ) as mock_metadata_get_all, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + mock_conn_rec, "metadata_get_all", mock.CoroutineMock() + ) as mock_metadata_get_all, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get_all.return_value = {"hello": "world"} @@ -222,15 +229,16 @@ async def test_connections_metadata_get_single(self): mock_conn_rec = mock.MagicMock() self.request.query = {"key": "test"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ), mock.patch.object( - mock_conn_rec, "metadata_get", mock.CoroutineMock() - ) as mock_metadata_get, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(mock_conn_rec, "metadata_get_all", mock.CoroutineMock()), + mock.patch.object( + mock_conn_rec, "metadata_get", mock.CoroutineMock() + ) as mock_metadata_get, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get.return_value = {"test": "value"} @@ -242,11 +250,15 @@ async def test_connections_metadata_x(self): self.request.match_info = {"conn_id": "dummy"} mock_conn_rec = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ) as mock_metadata_get_all, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + mock_conn_rec, "metadata_get_all", mock.CoroutineMock() + ) as mock_metadata_get_all, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get_all.side_effect = StorageNotFoundError() @@ -264,15 +276,18 @@ async def test_connections_metadata_set(self): return_value={"metadata": {"hello": "world"}} ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ) as mock_metadata_get_all, mock.patch.object( - mock_conn_rec, "metadata_set", mock.CoroutineMock() - ) as mock_metadata_set, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + mock_conn_rec, "metadata_get_all", mock.CoroutineMock() + ) as mock_metadata_get_all, + mock.patch.object( + mock_conn_rec, "metadata_set", mock.CoroutineMock() + ) as mock_metadata_set, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get_all.return_value = {"hello": "world"} @@ -287,13 +302,16 @@ async def test_connections_metadata_set_x(self): return_value={"metadata": {"hello": "world"}} ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ), mock.patch.object( - mock_conn_rec, "metadata_set", mock.CoroutineMock() - ) as mock_metadata_set, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(mock_conn_rec, "metadata_get_all", mock.CoroutineMock()), + mock.patch.object( + mock_conn_rec, "metadata_set", mock.CoroutineMock() + ) as mock_metadata_set, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_set.side_effect = StorageNotFoundError() @@ -345,11 +363,12 @@ async def test_connections_create_invitation(self): "multi_use": "true", } - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr.return_value.create_invitation = mock.CoroutineMock( return_value=( mock.MagicMock( # connection record @@ -452,13 +471,15 @@ async def test_connections_receive_invitation(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnectionInvitation, "deserialize", autospec=True - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnectionInvitation, "deserialize", autospec=True + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr.return_value.receive_invitation = mock.CoroutineMock( return_value=mock_conn_rec ) @@ -476,10 +497,11 @@ async def test_connections_receive_invitation_bad(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnectionInvitation, "deserialize", autospec=True - ) as mock_inv_deser, mock.patch.object( - test_module, "ConnectionManager", autospec=True + with ( + mock.patch.object( + test_module.ConnectionInvitation, "deserialize", autospec=True + ) as mock_inv_deser, + mock.patch.object(test_module, "ConnectionManager", autospec=True), ): mock_inv_deser.side_effect = test_module.BaseModelError() @@ -503,11 +525,14 @@ async def test_connections_receive_invitation_x_bad_mediation_id(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnectionInvitation, "deserialize", autospec=True - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr: + with ( + mock.patch.object( + test_module.ConnectionInvitation, "deserialize", autospec=True + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + ): mock_conn_mgr.return_value.receive_invitation = mock.CoroutineMock( side_effect=StorageNotFoundError() ) @@ -525,13 +550,15 @@ async def test_connections_accept_invitation(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_conn_mgr.return_value.create_request = mock.CoroutineMock() @@ -552,11 +579,14 @@ async def test_connections_accept_invitation_not_found(self): async def test_connections_accept_invitation_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + ): mock_conn_mgr.return_value.create_request = mock.CoroutineMock( side_effect=test_module.ConnectionManagerError() ) @@ -568,11 +598,14 @@ async def test_connections_accept_invitation_x_bad_mediation_id(self): self.request.match_info = {"conn_id": "dummy"} self.request.query["mediation_id"] = "some-id" - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + ): mock_conn_mgr.return_value.create_request = mock.CoroutineMock( side_effect=StorageNotFoundError() ) @@ -589,13 +622,15 @@ async def test_connections_accept_request(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_conn_mgr.return_value.create_response = mock.CoroutineMock() @@ -616,11 +651,15 @@ async def test_connections_accept_request_not_found(self): async def test_connections_accept_request_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_mgr.return_value.create_response = mock.CoroutineMock( side_effect=test_module.ConnectionManagerError() ) @@ -633,11 +672,12 @@ async def test_connections_remove(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.delete_record = mock.CoroutineMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec await test_module.connections_remove(self.request) @@ -652,11 +692,12 @@ async def test_connections_remove_cache_key(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.delete_record = mock.CoroutineMock() assert (await cache.get("conn_rec_state::dummy")) == "active" - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec await test_module.connections_remove(self.request) @@ -716,11 +757,12 @@ async def test_connections_create_static(self): mock_their_info.did = "their_did" mock_their_info.verkey = "their_verkey" - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr.return_value.create_static_connection = mock.CoroutineMock( return_value=(mock_my_info, mock_their_info, mock_conn_rec) ) diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py index 8f7dbcc25d..4d32ebc819 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py @@ -57,11 +57,10 @@ async def test_handler_no_active_connection(self): async def test_handler(self): handler, responder = KeylistUpdateResponseHandler(), MockResponder() - with mock.patch.object( - MediationManager, "store_update_results" - ) as mock_store, mock.patch.object( - handler, "notify_keylist_updated" - ) as mock_notify: + with ( + mock.patch.object(MediationManager, "store_update_results") as mock_store, + mock.patch.object(handler, "notify_keylist_updated") as mock_notify, + ): await handler.handle(self.context, responder) mock_store.assert_called_once_with(TEST_CONN_ID, self.updated) mock_notify.assert_called_once_with( diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py index 79b2ab6ae2..e494e4c83a 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py @@ -78,13 +78,16 @@ async def test_handler_connection_has_set_to_default_meta( handler, responder = MediationGrantHandler(), MockResponder() record = MediationRecord(connection_id=TEST_CONN_ID) await record.save(session) - with mock.patch.object( - context.connection_record, - "metadata_get", - mock.CoroutineMock(return_value=True), - ), mock.patch.object( - test_module, "MediationManager", autospec=True - ) as mock_mediation_manager: + with ( + mock.patch.object( + context.connection_record, + "metadata_get", + mock.CoroutineMock(return_value=True), + ), + mock.patch.object( + test_module, "MediationManager", autospec=True + ) as mock_mediation_manager, + ): await handler.handle(context, responder) mock_mediation_manager.return_value.set_default_mediator.assert_called_once_with( record @@ -127,12 +130,15 @@ async def test_handler_connection_no_set_to_default( handler, responder = MediationGrantHandler(), MockResponder() record = MediationRecord(connection_id=TEST_CONN_ID) await record.save(session) - with mock.patch.object( - context.connection_record, - "metadata_get", - mock.CoroutineMock(return_value=False), - ), mock.patch.object( - test_module, "MediationManager", autospec=True - ) as mock_mediation_manager: + with ( + mock.patch.object( + context.connection_record, + "metadata_get", + mock.CoroutineMock(return_value=False), + ), + mock.patch.object( + test_module, "MediationManager", autospec=True + ) as mock_mediation_manager, + ): await handler.handle(context, responder) mock_mediation_manager.return_value.set_default_mediator.assert_not_called() diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py index 9bd237c9c0..c0ef5c6855 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py @@ -397,21 +397,27 @@ async def test_store_update_results( ), ] - with mock.patch.object( - RouteRecord, "query", mock.CoroutineMock() - ) as mock_route_rec_query, mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ) as mock_logger_error: + with ( + mock.patch.object( + RouteRecord, "query", mock.CoroutineMock() + ) as mock_route_rec_query, + mock.patch.object( + test_module.LOGGER, "error", mock.MagicMock() + ) as mock_logger_error, + ): mock_route_rec_query.side_effect = StorageNotFoundError("no record") await manager.store_update_results(TEST_CONN_ID, results) mock_logger_error.assert_called_once() - with mock.patch.object( - RouteRecord, "query", mock.CoroutineMock() - ) as mock_route_rec_query, mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ) as mock_logger_error: + with ( + mock.patch.object( + RouteRecord, "query", mock.CoroutineMock() + ) as mock_route_rec_query, + mock.patch.object( + test_module.LOGGER, "error", mock.MagicMock() + ) as mock_logger_error, + ): mock_route_rec_query.return_value = [ mock.MagicMock(delete_record=mock.CoroutineMock()) ] * 2 diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py index 5ff5b4ac5b..86d9cc6bff 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py @@ -78,13 +78,14 @@ async def test_get_or_create_my_did_no_did( ): conn_record.my_did = None mock_did_info = mock.MagicMock() - with mock.patch.object( - AskarWallet, - "create_local_did", - mock.CoroutineMock(return_value=mock_did_info), - ) as mock_create_local_did, mock.patch.object( - conn_record, "save", mock.CoroutineMock() - ) as mock_save: + with ( + mock.patch.object( + AskarWallet, + "create_local_did", + mock.CoroutineMock(return_value=mock_did_info), + ) as mock_create_local_did, + mock.patch.object(conn_record, "save", mock.CoroutineMock()) as mock_save, + ): info = await route_manager.get_or_create_my_did(profile, conn_record) assert mock_did_info == info mock_create_local_did.assert_called_once() @@ -110,12 +111,15 @@ async def test_mediation_record_for_connection_mediation_id( profile: Profile, route_manager: RouteManager, conn_record: ConnRecord ): mediation_record = MediationRecord(mediation_id="test-mediation-id") - with mock.patch.object( - route_manager, - "mediation_record_if_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_mediation_record_if_id, mock.patch.object( - route_manager, "save_mediator_for_connection", mock.CoroutineMock() + with ( + mock.patch.object( + route_manager, + "mediation_record_if_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_mediation_record_if_id, + mock.patch.object( + route_manager, "save_mediator_for_connection", mock.CoroutineMock() + ), ): assert await route_manager.mediation_records_for_connection( profile, conn_record, mediation_record.mediation_id @@ -133,12 +137,15 @@ async def test_mediation_record_for_connection_mediation_metadata( conn_record.metadata_get.return_value = { MediationManager.METADATA_ID: mediation_record.mediation_id } - with mock.patch.object( - route_manager, - "mediation_record_if_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_mediation_record_if_id, mock.patch.object( - route_manager, "save_mediator_for_connection", mock.CoroutineMock() + with ( + mock.patch.object( + route_manager, + "mediation_record_if_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_mediation_record_if_id, + mock.patch.object( + route_manager, "save_mediator_for_connection", mock.CoroutineMock() + ), ): assert await route_manager.mediation_records_for_connection( profile, conn_record, "another-mediation-id" @@ -153,12 +160,15 @@ async def test_mediation_record_for_connection_default( profile: Profile, route_manager: RouteManager, conn_record: ConnRecord ): mediation_record = MediationRecord(mediation_id="test-mediation-id") - with mock.patch.object( - route_manager, - "mediation_record_if_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_mediation_record_if_id, mock.patch.object( - route_manager, "save_mediator_for_connection", mock.CoroutineMock() + with ( + mock.patch.object( + route_manager, + "mediation_record_if_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_mediation_record_if_id, + mock.patch.object( + route_manager, "save_mediator_for_connection", mock.CoroutineMock() + ), ): assert await route_manager.mediation_records_for_connection( profile, conn_record, None, or_default=True @@ -210,13 +220,16 @@ async def test_mediation_record_if_id_with_id_and_default( mediation_record = MediationRecord( mediation_id="test-mediation-id", state=MediationRecord.STATE_GRANTED ) - with mock.patch.object( - MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_retrieve_by_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ) as mock_get_default_mediator: + with ( + mock.patch.object( + MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_retrieve_by_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ) as mock_get_default_mediator, + ): actual = await route_manager.mediation_record_if_id( profile, mediation_id=mediation_record.mediation_id, or_default=True ) @@ -233,13 +246,16 @@ async def test_mediation_record_if_id_without_id_and_default( mediation_record = MediationRecord( mediation_id="test-mediation-id", state=MediationRecord.STATE_GRANTED ) - with mock.patch.object( - MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id, mock.patch.object( - MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_get_default_mediator: + with ( + mock.patch.object( + MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + mock.patch.object( + MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_get_default_mediator, + ): actual = await route_manager.mediation_record_if_id( profile, mediation_id=None, or_default=True ) @@ -253,11 +269,16 @@ async def test_mediation_record_if_id_without_id_and_no_default( profile: Profile, route_manager: RouteManager, ): - with mock.patch.object( - MediationRecord, "retrieve_by_id", mock.CoroutineMock(return_value=None) - ) as mock_retrieve_by_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock(return_value=None) - ) as mock_get_default_mediator: + with ( + mock.patch.object( + MediationRecord, "retrieve_by_id", mock.CoroutineMock(return_value=None) + ) as mock_retrieve_by_id, + mock.patch.object( + MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=None), + ) as mock_get_default_mediator, + ): assert ( await route_manager.mediation_record_if_id( profile, mediation_id=None, or_default=True @@ -319,21 +340,24 @@ async def test_route_connection_state_inviter_replace_key_none( mock_did_info = mock.MagicMock(DIDInfo) conn_record.invitation_key = TEST_RECORD_VERKEY - with mock.patch.object( - route_manager, - "get_or_create_my_did", - mock.CoroutineMock(return_value=mock_did_info), - ), mock.patch.object( - AskarWallet, - "get_public_did", - mock.CoroutineMock( - return_value=DIDInfo( - TEST_RECORD_DID, - TEST_RECORD_VERKEY, - None, - method=SOV, - key_type=ED25519, - ) + with ( + mock.patch.object( + route_manager, + "get_or_create_my_did", + mock.CoroutineMock(return_value=mock_did_info), + ), + mock.patch.object( + AskarWallet, + "get_public_did", + mock.CoroutineMock( + return_value=DIDInfo( + TEST_RECORD_DID, + TEST_RECORD_VERKEY, + None, + method=SOV, + key_type=ED25519, + ) + ), ), ): await route_manager.route_connection_as_inviter( @@ -355,11 +379,14 @@ async def test_route_connection_state_invitee( mediation_record = MediationRecord(mediation_id="test-mediation-id") conn_record.state = "invitation" conn_record.their_role = "responder" - with mock.patch.object( - route_manager, "route_connection_as_invitee", mock.CoroutineMock() - ) as mock_route_connection_as_invitee, mock.patch.object( - route_manager, "route_connection_as_inviter", mock.CoroutineMock() - ) as mock_route_connection_as_inviter: + with ( + mock.patch.object( + route_manager, "route_connection_as_invitee", mock.CoroutineMock() + ) as mock_route_connection_as_invitee, + mock.patch.object( + route_manager, "route_connection_as_inviter", mock.CoroutineMock() + ) as mock_route_connection_as_inviter, + ): await route_manager.route_connection(profile, conn_record, [mediation_record]) mock_route_connection_as_invitee.assert_called_once() mock_route_connection_as_inviter.assert_not_called() @@ -372,11 +399,14 @@ async def test_route_connection_state_inviter( mediation_record = MediationRecord(mediation_id="test-mediation-id") conn_record.state = "request" conn_record.their_role = "requester" - with mock.patch.object( - route_manager, "route_connection_as_invitee", mock.CoroutineMock() - ) as mock_route_connection_as_invitee, mock.patch.object( - route_manager, "route_connection_as_inviter", mock.CoroutineMock() - ) as mock_route_connection_as_inviter: + with ( + mock.patch.object( + route_manager, "route_connection_as_invitee", mock.CoroutineMock() + ) as mock_route_connection_as_invitee, + mock.patch.object( + route_manager, "route_connection_as_inviter", mock.CoroutineMock() + ) as mock_route_connection_as_inviter, + ): await route_manager.route_connection(profile, conn_record, [mediation_record]) mock_route_connection_as_inviter.assert_called_once() mock_route_connection_as_invitee.assert_not_called() diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py index 773f31fbc6..cf0eda45ab 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py @@ -71,13 +71,14 @@ def test_mediation_sort_key(self): async def test_list_mediation_requests(self): self.request.query = {} - with mock.patch.object( - test_module.MediationRecord, - "query", - mock.CoroutineMock(return_value=[self.mock_record]), - ) as mock_query, mock.patch.object( - test_module.web, "json_response" - ) as json_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "query", + mock.CoroutineMock(return_value=[self.mock_record]), + ) as mock_query, + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.list_mediation_requests(self.request) json_response.assert_called_once_with( {"results": [self.mock_record.serialize.return_value]} @@ -89,13 +90,14 @@ async def test_list_mediation_requests_filters(self): "state": MediationRecord.STATE_GRANTED, "conn_id": "test-conn-id", } - with mock.patch.object( - test_module.MediationRecord, - "query", - mock.CoroutineMock(return_value=[self.mock_record]), - ) as mock_query, mock.patch.object( - test_module.web, "json_response" - ) as json_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "query", + mock.CoroutineMock(return_value=[self.mock_record]), + ) as mock_query, + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.list_mediation_requests(self.request) json_response.assert_called_once_with( {"results": [self.mock_record.serialize.return_value]} @@ -114,53 +116,63 @@ async def test_list_mediation_requests_x(self): await test_module.list_mediation_requests(self.request) async def test_list_mediation_requests_no_records(self): - with mock.patch.object( - test_module, - "MediationRecord", - mock.MagicMock(query=mock.CoroutineMock(return_value=[])), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + test_module, + "MediationRecord", + mock.MagicMock(query=mock.CoroutineMock(return_value=[])), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.list_mediation_requests(self.request) mock_response.assert_called_once_with({"results": []}) async def test_retrieve_mediation_request(self): - with mock.patch.object( - test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_mediation_record_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_mediation_record_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mediation_record_retrieve.return_value = self.mock_record await test_module.retrieve_mediation_request(self.request) mock_response.assert_called_once_with(self.mock_record.serialize.return_value) mock_mediation_record_retrieve.assert_called() async def test_retrieve_mediation_request_x_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPNotFound + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPNotFound), ): await test_module.retrieve_mediation_request(self.request) async def test_retrieve_mediation_request_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPBadRequest + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPBadRequest), ): await test_module.retrieve_mediation_request(self.request) async def test_delete_mediation_request(self): - with mock.patch.object( - test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_mediation_record_retrieve, mock.patch.object( - self.mock_record, "delete_record", mock.CoroutineMock() - ) as mock_delete_record, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_mediation_record_retrieve, + mock.patch.object( + self.mock_record, "delete_record", mock.CoroutineMock() + ) as mock_delete_record, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mediation_record_retrieve.return_value = self.mock_record await test_module.delete_mediation_request(self.request) mock_response.assert_called_once_with(self.mock_record.serialize.return_value) @@ -168,38 +180,45 @@ async def test_delete_mediation_request(self): mock_delete_record.assert_called() async def test_delete_mediation_request_x_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPNotFound + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPNotFound), ): await test_module.delete_mediation_request(self.request) async def test_delete_mediation_request_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPBadRequest + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPBadRequest), ): await test_module.delete_mediation_request(self.request) async def test_request_mediation(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module, "MediationManager", autospec=True - ) as mock_med_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module.MediationRecord, - "exists_for_connection_id", - mock.CoroutineMock(return_value=False), - ), mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "MediationManager", autospec=True + ) as mock_med_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module.MediationRecord, + "exists_for_connection_id", + mock.CoroutineMock(return_value=False), + ), + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), ): mock_med_mgr.return_value.prepare_request = mock.CoroutineMock( return_value=( @@ -218,52 +237,68 @@ async def test_request_mediation(self): async def test_request_mediation_x_conn_not_ready(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock.MagicMock(is_ready=False)), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock.MagicMock(is_ready=False)), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.request_mediation(self.request) async def test_request_mediation_x_already_exists(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module.MediationRecord, - "exists_for_connection_id", - mock.CoroutineMock(return_value=True), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module.MediationRecord, + "exists_for_connection_id", + mock.CoroutineMock(return_value=True), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.request_mediation(self.request) async def test_request_mediation_x_conn_not_found(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.request_mediation(self.request) async def test_request_mediation_x_storage_error(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.request_mediation(self.request) async def test_mediation_request_grant_role_server(self): self.mock_record.role = MediationRecord.ROLE_SERVER - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.mediation_request_grant(self.request) mock_response.assert_called_once_with( self.mock_record.serialize.return_value, status=201 @@ -272,36 +307,48 @@ async def test_mediation_request_grant_role_server(self): async def test_mediation_request_grant_role_client_x(self): self.mock_record.role = MediationRecord.ROLE_CLIENT - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.mediation_request_grant(self.request) async def test_mediation_request_grant_x_rec_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.mediation_request_grant(self.request) async def test_mediation_request_grant_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.mediation_request_grant(self.request) async def test_mediation_request_deny_role_server(self): self.mock_record.role = MediationRecord.ROLE_SERVER - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.mediation_request_deny(self.request) mock_response.assert_called_once_with( self.mock_record.serialize.return_value, status=201 @@ -310,10 +357,11 @@ async def test_mediation_request_deny_role_server(self): async def test_mediation_request_deny_role_client_x(self): self.mock_record.role = MediationRecord.ROLE_CLIENT - with mock.patch.object( - test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_mediation_record_retrieve, mock.patch.object( - test_module.web, "json_response" + with ( + mock.patch.object( + test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_mediation_record_retrieve, + mock.patch.object(test_module.web, "json_response"), ): mock_mediation_record_retrieve.return_value = mock.MagicMock( role=MediationRecord.ROLE_CLIENT @@ -322,19 +370,25 @@ async def test_mediation_request_deny_role_client_x(self): await test_module.mediation_request_deny(self.request) async def test_mediation_request_deny_x_rec_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.mediation_request_deny(self.request) async def test_mediation_request_deny_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.mediation_request_deny(self.request) async def test_get_keylist(self): @@ -348,17 +402,19 @@ async def test_get_keylist(self): ) ] - with mock.patch.object( - test_module.RouteRecord, - "query", - mock.CoroutineMock(return_value=query_results), - ) as mock_query, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=session), - ) as mock_session, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.RouteRecord, + "query", + mock.CoroutineMock(return_value=query_results), + ) as mock_query, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=session), + ) as mock_session, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.get_keylist(self.request) mock_response.assert_called_once_with( {"results": [{"serialized": "route record"}]}, status=200 @@ -370,27 +426,32 @@ async def test_get_keylist(self): async def test_get_keylist_no_matching_records(self): session = await self.profile.session() - with mock.patch.object( - test_module.RouteRecord, - "query", - mock.CoroutineMock(return_value=[]), - ) as mock_query, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=session), - ) as mock_session, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.RouteRecord, + "query", + mock.CoroutineMock(return_value=[]), + ) as mock_query, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=session), + ) as mock_session, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.get_keylist(self.request) mock_query.assert_called_once_with(mock_session.return_value, {}) mock_response.assert_called_once_with({"results": []}, status=200) async def test_get_keylist_storage_error(self): - with mock.patch.object( - test_module.RouteRecord, - "query", - mock.CoroutineMock(side_effect=test_module.StorageError), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.RouteRecord, + "query", + mock.CoroutineMock(side_effect=test_module.StorageError), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.get_keylist(self.request) async def test_send_keylist_update(self): @@ -421,18 +482,23 @@ async def test_send_keylist_update(self): self.request.json.return_value = body - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock( - return_value=mock.MagicMock( - state=MediationRecord.STATE_GRANTED, connection_id="test-conn-id" - ) + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock( + return_value=mock.MagicMock( + state=MediationRecord.STATE_GRANTED, connection_id="test-conn-id" + ) + ), + ), + mock.patch.object( + test_module.web, + "json_response", + mock.MagicMock( + side_effect=lambda *args, **kwargs: [*args, *kwargs.values()] + ), ), - ), mock.patch.object( - test_module.web, - "json_response", - mock.MagicMock(side_effect=lambda *args, **kwargs: [*args, *kwargs.values()]), ): results, status = await test_module.send_keylist_update(self.request) assert results["updates"] == body_with_didkey["updates"] @@ -461,15 +527,18 @@ async def test_send_keylist_update_bad_mediation_state(self): ] } - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock( - return_value=mock.MagicMock( - state=MediationRecord.STATE_DENIED, connection_id="test-conn-id" - ) + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock( + return_value=mock.MagicMock( + state=MediationRecord.STATE_DENIED, connection_id="test-conn-id" + ) + ), ), - ), self.assertRaises(test_module.web.HTTPBadRequest): + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.send_keylist_update(self.request) async def test_send_keylist_update_bad_updates(self): @@ -486,11 +555,14 @@ async def test_send_keylist_update_x_no_mediation_rec(self): }, ] } - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.send_keylist_update(self.request) async def test_send_keylist_update_x_storage_error(self): @@ -503,28 +575,33 @@ async def test_send_keylist_update_x_storage_error(self): ] } - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.send_keylist_update(self.request) @mock.patch.object(test_module, "MediationManager", autospec=True) async def test_send_keylist_query(self, mock_manager): self.request.json.return_value = {"filter": {"test": "filter"}} self.request.query = {"paginate_limit": 10, "paginate_offset": 20} - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object( - mock_manager.return_value, - "prepare_keylist_query", - mock.CoroutineMock(), - ) as mock_prepare_keylist_query, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object( + mock_manager.return_value, + "prepare_keylist_query", + mock.CoroutineMock(), + ) as mock_prepare_keylist_query, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.send_keylist_query(self.request) mock_prepare_keylist_query.assert_called_once_with( filter_={"test": "filter"}, paginate_limit=10, paginate_offset=20 @@ -536,29 +613,36 @@ async def test_send_keylist_query(self, mock_manager): ) async def test_send_keylist_query_x_no_mediation_record(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.send_keylist_query(self.request) async def test_send_keylist_query_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.send_keylist_query(self.request) async def test_get_default_mediator(self): self.request.query = {} - with mock.patch.object( - test_module.web, "json_response" - ) as json_response, mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=self.mock_record), + with ( + mock.patch.object(test_module.web, "json_response") as json_response, + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=self.mock_record), + ), ): await test_module.get_default_mediator(self.request) json_response.assert_called_once_with( @@ -568,12 +652,13 @@ async def test_get_default_mediator(self): async def test_get_empty_default_mediator(self): self.request.query = {} - with mock.patch.object( - test_module.web, "json_response" - ) as json_response, mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=None), + with ( + mock.patch.object(test_module.web, "json_response") as json_response, + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=None), + ), ): await test_module.get_default_mediator(self.request) json_response.assert_called_once_with( @@ -583,10 +668,13 @@ async def test_get_empty_default_mediator(self): async def test_get_default_mediator_storage_error(self): self.request.query = {} - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), ): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.get_default_mediator(self.request) @@ -596,15 +684,19 @@ async def test_set_default_mediator(self): "mediation_id": "fake_id", } self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object( - test_module.MediationManager, - "set_default_mediator_by_id", - mock.CoroutineMock(), - ), mock.patch.object(test_module.web, "json_response") as json_response: + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object( + test_module.MediationManager, + "set_default_mediator_by_id", + mock.CoroutineMock(), + ), + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.set_default_mediator(self.request) json_response.assert_called_once_with( self.mock_record.serialize.return_value, @@ -616,29 +708,37 @@ async def test_set_default_mediator_storage_error(self): "mediation_id": "bad_id", } self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object( - test_module.MediationManager, - "set_default_mediator_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object( + test_module.MediationManager, + "set_default_mediator_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object(test_module.web, "json_response"), + ): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.set_default_mediator(self.request) async def test_clear_default_mediator(self): self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object( - test_module.MediationManager, - "clear_default_mediator", - mock.CoroutineMock(), - ), mock.patch.object(test_module.web, "json_response") as json_response: + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object( + test_module.MediationManager, + "clear_default_mediator", + mock.CoroutineMock(), + ), + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.clear_default_mediator(self.request) json_response.assert_called_once_with( self.mock_record.serialize.return_value, @@ -647,15 +747,19 @@ async def test_clear_default_mediator(self): async def test_clear_default_mediator_storage_error(self): self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object( - test_module.MediationManager, - "clear_default_mediator", - mock.CoroutineMock(), - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object( + test_module.MediationManager, + "clear_default_mediator", + mock.CoroutineMock(), + ), + mock.patch.object(test_module.web, "json_response"), + ): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.clear_default_mediator(self.request) @@ -673,9 +777,12 @@ async def test_update_keylist_for_connection(self): ) mock_route_manager.mediation_record_for_connection = mock.CoroutineMock() self.context.injector.bind_instance(RouteManager, mock_route_manager) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object(test_module.web, "json_response") as json_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.update_keylist_for_connection(self.request) json_response.assert_called_once_with({"mock": "serialized"}, status=200) diff --git a/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py b/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py index b4bc7cd6d5..cf72da930e 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py @@ -92,9 +92,12 @@ async def test_receive_rotate_x(self): RotateProblemReport(problem_items=[{"did": test_to_did}]) ) - with mock.patch.object( - self.manager, "_ensure_supported_did", side_effect=test_problem_report - ), mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send: + with ( + mock.patch.object( + self.manager, "_ensure_supported_did", side_effect=test_problem_report + ), + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): await self.manager.receive_rotate( mock_conn_record, Rotate(to_did=test_to_did) ) diff --git a/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py b/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py index 57c8752e23..5dae863727 100644 --- a/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py @@ -174,13 +174,15 @@ async def test_receive_invitation(self): ) await mediation_record.save(session) - with mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator, mock.patch.object( - AdminResponder, "send_reply" - ) as mock_send_reply: + with ( + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + mock.patch.object(AdminResponder, "send_reply") as mock_send_reply, + ): mock_get_default_mediator.return_value = mediation_record invi_rec = await self.oob_manager.create_invitation( my_endpoint="testendpoint", @@ -206,15 +208,18 @@ async def test_receive_invitation_oob_public_did(self): ED25519, ) public_did_info = await wallet.get_public_did() - with mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator, mock.patch.object( - self.manager, "resolve_connection_targets", mock.CoroutineMock() - ) as mock_resolve_targets, mock.patch.object( - AdminResponder, "send_reply" - ) as mock_send_reply: + with ( + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + mock.patch.object( + self.manager, "resolve_connection_targets", mock.CoroutineMock() + ) as mock_resolve_targets, + mock.patch.object(AdminResponder, "send_reply") as mock_send_reply, + ): mock_resolve_targets.return_value = [ mock.MagicMock(recipient_keys=["test"]) ] @@ -289,11 +294,14 @@ async def test_create_request_implicit(self): ) await mediation_record.save(session) - with mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator: + with ( + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + ): mock_get_default_mediator.return_value = mediation_record mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) @@ -370,8 +378,11 @@ async def test_create_request_implicit_x_public_already_connected(self): SOV, ED25519, ) - with self.assertRaises(DIDXManagerError) as context, mock.patch.object( - test_module.ConnRecord, "retrieve_by_did", mock.CoroutineMock() + with ( + self.assertRaises(DIDXManagerError) as context, + mock.patch.object( + test_module.ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ), ): await self.manager.create_request_implicit( their_public_did=TestConfig.test_target_did, @@ -414,13 +425,17 @@ async def test_create_request_multitenant(self): {"multitenant.enabled": True, "wallet.id": "test_wallet"} ) - with mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco: + with ( + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + ): mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) ) @@ -625,24 +640,35 @@ async def test_receive_request_explicit_public_did(self): STATE_REQUEST = ConnRecord.State.REQUEST self.profile.context.update_settings({"public_invites": True}) ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ) as mock_response, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - MediationManager, "prepare_request", autospec=True - ) as mock_mediation_mgr_prep_req, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + test_module, "DIDXResponse", autospec=True + ) as mock_response, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + MediationManager, "prepare_request", autospec=True + ) as mock_mediation_mgr_prep_req, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) @@ -760,27 +786,36 @@ async def test_receive_request_public_did_no_did_doc_attachment(self): STATE_REQUEST = ConnRecord.State.REQUEST self.profile.context.update_settings({"public_invites": True}) ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ) as mock_response, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value=DIDDoc(TestConfig.test_did)), - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - self.manager, - "record_keys_for_resolvable_did", - mock.CoroutineMock(), - ), mock.patch.object( - MediationManager, "prepare_request", autospec=True - ) as mock_mediation_mgr_prep_req: + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + test_module, "DIDXResponse", autospec=True + ) as mock_response, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock(return_value=DIDDoc(TestConfig.test_did)), + ), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + self.manager, + "record_keys_for_resolvable_did", + mock.CoroutineMock(), + ), + mock.patch.object( + MediationManager, "prepare_request", autospec=True + ) as mock_mediation_mgr_prep_req, + ): mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) ) @@ -856,11 +891,14 @@ async def test_receive_request_public_did_no_did_doc_attachment_no_did(self): STATE_REQUEST = ConnRecord.State.REQUEST self.profile.context.update_settings({"public_invites": True}) ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture: + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + ): mock_conn_record = mock.MagicMock( accept=ACCEPT_AUTO, my_did=None, @@ -964,16 +1002,21 @@ async def test_receive_request_public_did_x_wrong_did(self): self.profile.context.update_settings({"public_invites": True}) mock_conn_rec_state_request = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "LjgpST2rjsoxYegQDRm7EL"}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock(return_value={"id": "LjgpST2rjsoxYegQDRm7EL"}), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_record = mock.MagicMock( accept=ConnRecord.ACCEPT_MANUAL, @@ -1028,14 +1071,18 @@ async def test_receive_request_public_did_x_did_doc_attach_bad_sig(self): self.profile.context.update_settings({"public_invites": True}) mock_conn_rec_state_request = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(side_effect=DIDXManagerError), + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock(side_effect=DIDXManagerError), + ), ): mock_conn_record = mock.MagicMock( accept=ConnRecord.ACCEPT_MANUAL, @@ -1088,14 +1135,13 @@ async def test_receive_request_public_did_no_public_invites(self): ) self.profile.context.update_settings({"public_invites": False}) - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ), mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() + with ( + mock.patch.object(test_module, "ConnRecord", mock.MagicMock()), + mock.patch.object(test_module, "AttachDecorator", autospec=True), + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ), ): with self.assertRaises(DIDXManagerError) as context: await self.manager.receive_request( @@ -1133,22 +1179,28 @@ async def test_receive_request_public_did_no_auto_accept(self): {"public_invites": True, "debug.auto_accept_requests": False} ) mock_conn_rec_state_request = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ), mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ), mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object(test_module, "AttachDecorator", autospec=True), + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ), + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_record = mock.MagicMock( accept=ConnRecord.ACCEPT_MANUAL, @@ -1213,16 +1265,23 @@ async def test_receive_request_implicit_public_did_not_enabled(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_did_posture.get = mock.MagicMock( return_value=test_module.DIDPosture.PUBLIC @@ -1279,16 +1338,23 @@ async def test_receive_request_implicit_public_did(self): ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO STATE_REQUEST = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_did_posture.get = mock.MagicMock( return_value=test_module.DIDPosture.PUBLIC @@ -1363,18 +1429,26 @@ async def test_receive_request_peer_did(self): ) self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ) as mock_response, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + test_module, "DIDXResponse", autospec=True + ) as mock_response, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_rec_cls.retrieve_by_invitation_msg_id = mock.CoroutineMock( return_value=mock_conn @@ -1451,15 +1525,19 @@ async def test_receive_request_peer_did_not_found_x(self): async def test_create_response(self): conn_rec = ConnRecord(connection_id="dummy", state=ConnRecord.State.REQUEST.rfc23) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + ): mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( @@ -1499,15 +1577,17 @@ async def test_create_response_mediation_id(self): await record.save(session) await record.attach_invitation(session, invi) - with mock.patch.object( - ConnRecord, "log_state", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - record, "metadata_get", mock.CoroutineMock(return_value=False) - ), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco: + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + record, "metadata_get", mock.CoroutineMock(return_value=False) + ), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + ): mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( data=mock.MagicMock(sign=mock.CoroutineMock()) @@ -1548,12 +1628,13 @@ async def test_create_response_mediation_id_invalid_conn_state(self): await record.save(session) await record.attach_invitation(session, invi) - with mock.patch.object( - ConnRecord, "log_state", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - record, "metadata_get", mock.CoroutineMock(return_value=False) + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + record, "metadata_get", mock.CoroutineMock(return_value=False) + ), ): with self.assertRaises(DIDXManagerError) as context: await self.manager.create_response( @@ -1571,15 +1652,19 @@ async def test_create_response_multitenant(self): } ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request" - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did: + with ( + mock.patch.object(test_module.ConnRecord, "retrieve_request"), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + ): mock_wallet_create_local_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -1604,17 +1689,22 @@ async def test_create_response_conn_rec_my_did(self): state=ConnRecord.State.REQUEST.rfc23, ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - AskarWallet, "get_local_did", mock.CoroutineMock() - ) as mock_get_loc_did: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + AskarWallet, "get_local_did", mock.CoroutineMock() + ) as mock_get_loc_did, + ): mock_get_loc_did.return_value = self.did_info mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( @@ -1635,11 +1725,15 @@ async def test_create_response_inkind_peer_did_2(self): self.profile.context.update_settings({"emit_did_peer_2": False}) - with mock.patch.object( - self.manager, "create_did_peer_2", mock.CoroutineMock() - ) as mock_create_did_peer_2, mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + self.manager, "create_did_peer_2", mock.CoroutineMock() + ) as mock_create_did_peer_2, + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + ): mock_create_did_peer_2.return_value = DIDInfo( TestConfig.test_did_peer_2, TestConfig.test_verkey, @@ -1663,11 +1757,15 @@ async def test_create_response_inkind_peer_did_4(self): self.profile.context.update_settings({"emit_did_peer_4": False}) - with mock.patch.object( - self.manager, "create_did_peer_4", mock.CoroutineMock() - ) as mock_create_did_peer_4, mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + self.manager, "create_did_peer_4", mock.CoroutineMock() + ) as mock_create_did_peer_4, + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + ): mock_create_did_peer_4.return_value = DIDInfo( TestConfig.test_did_peer_4, TestConfig.test_verkey, @@ -1691,11 +1789,15 @@ async def test_create_response_peer_1_gets_peer_4(self): self.profile.context.update_settings({"emit_did_peer_4": False}) - with mock.patch.object( - self.manager, "create_did_peer_4", mock.CoroutineMock() - ) as mock_create_did_peer_4, mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + self.manager, "create_did_peer_4", mock.CoroutineMock() + ) as mock_create_did_peer_4, + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + ): mock_create_did_peer_4.return_value = DIDInfo( TestConfig.test_did_peer_4, TestConfig.test_verkey, @@ -1731,15 +1833,19 @@ async def test_create_response_use_public_did(self): conn_rec = ConnRecord(connection_id="dummy", state=ConnRecord.State.REQUEST.rfc23) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + ): mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( @@ -1754,15 +1860,19 @@ async def test_create_response_use_public_did(self): async def test_create_response_use_public_did_x_no_public_did(self): conn_rec = ConnRecord(connection_id="dummy", state=ConnRecord.State.REQUEST.rfc23) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + ): mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( @@ -1798,12 +1908,15 @@ async def test_accept_response_find_by_thread_id(self): recipient_did_public=True, ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=TestConfig.test_target_did, @@ -1856,14 +1969,18 @@ async def test_accept_response_find_by_thread_id_auto_disclose_features(self): ) self.context.update_settings({"auto_disclose_features": True}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=TestConfig.test_target_did, @@ -1912,12 +2029,15 @@ async def test_accept_response_not_found_by_thread_id_receipt_has_sender_did(sel receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.return_value = mock.MagicMock( @@ -1958,11 +2078,15 @@ async def test_accept_response_not_found_by_thread_id_nor_receipt_sender_did(sel receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() @@ -1984,9 +2108,12 @@ async def test_accept_response_find_by_thread_id_bad_state(self): receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( state=ConnRecord.State.ABANDONED.rfc23 ) @@ -2007,14 +2134,20 @@ async def test_accept_response_find_by_thread_id_no_did_doc_attached(self): recipient_did_public=True, ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - DIDDoc, "deserialize", mock.MagicMock() - ) as mock_did_doc_deser, mock.patch.object( - self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object( + DIDDoc, "deserialize", mock.MagicMock() + ) as mock_did_doc_deser, + mock.patch.object( + self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + ), ): mock_did_doc_deser.return_value = mock.MagicMock( did=TestConfig.test_target_did @@ -2047,14 +2180,20 @@ async def test_accept_response_find_by_thread_id_no_did_doc_attached_no_did(self recipient_did_public=True, ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - DIDDoc, "deserialize", mock.MagicMock() - ) as mock_did_doc_deser, mock.patch.object( - self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object( + DIDDoc, "deserialize", mock.MagicMock() + ) as mock_did_doc_deser, + mock.patch.object( + self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + ), ): mock_did_doc_deser.return_value = mock.MagicMock( did=TestConfig.test_target_did @@ -2092,12 +2231,15 @@ async def test_accept_response_find_by_thread_id_did_mismatch(self): receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=TestConfig.test_target_did, @@ -2139,11 +2281,14 @@ async def test_accept_complete_with_disclose(self): mock_complete = mock.MagicMock() receipt = MessageReceipt(sender_did=TestConfig.test_target_did) self.context.update_settings({"auto_disclose_features": True}) - with mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + ): mock_conn_retrieve_by_req_id.return_value.save = mock.CoroutineMock() mock_conn_retrieve_by_req_id.return_value.my_did = None mock_conn_retrieve_by_req_id.return_value.their_did = None diff --git a/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py b/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py index 20b0eace36..81be5fda3d 100644 --- a/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py @@ -43,13 +43,13 @@ async def test_didx_accept_invitation(self): mock_conn_rec = mock.MagicMock(save=mock.CoroutineMock()) mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_class, mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_class, + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_class.retrieve_by_id.return_value = mock_conn_rec mock_didx_mgr.return_value.create_request = mock.CoroutineMock() @@ -70,9 +70,12 @@ async def test_didx_accept_invitation_not_found(self): async def test_didx_accept_invitation_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + ): mock_didx_mgr.return_value.create_request = mock.CoroutineMock( side_effect=test_module.DIDXManagerError() ) @@ -88,11 +91,10 @@ async def test_didx_create_request_implicit(self): "mediator_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", } - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_didx_mgr.return_value.create_request_implicit = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(return_value="mock serialization") @@ -111,9 +113,10 @@ async def test_didx_create_request_implicit_not_found_x(self): "auto_accept": "true", } - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.create_request_implicit = mock.CoroutineMock( side_effect=StorageNotFoundError("not found") ) @@ -130,9 +133,10 @@ async def test_didx_create_request_implicit_wallet_x(self): "auto_accept": "true", } - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.create_request_implicit = mock.CoroutineMock( side_effect=test_module.WalletError("wallet error") ) @@ -152,13 +156,11 @@ async def test_didx_receive_request_implicit(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.DIDXRequest, "deserialize", mock.MagicMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module.DIDXRequest, "deserialize", mock.MagicMock()), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_didx_mgr.return_value.receive_request = mock.CoroutineMock( return_value=mock_conn_rec ) @@ -174,11 +176,11 @@ async def test_didx_receive_request_implicit_not_found_x(self): self.request._thread.pthid = "did:sov:0000000000000000000000" self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module.DIDXRequest, "deserialize", mock.MagicMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module.DIDXRequest, "deserialize", mock.MagicMock()), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.receive_request = mock.CoroutineMock( side_effect=StorageNotFoundError("tricorder must be broken") ) @@ -195,11 +197,13 @@ async def test_didx_receive_request_implicit_bad_request_x(self): self.request._thread.pthid = "did:sov:0000000000000000000000" self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module.DIDXRequest, "deserialize", mock.MagicMock() - ) as mock_didx_req_deser, mock.patch.object( - test_module, "DIDXManager", autospec=True - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.DIDXRequest, "deserialize", mock.MagicMock() + ) as mock_didx_req_deser, + mock.patch.object(test_module, "DIDXManager", autospec=True), + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_req_deser.side_effect = test_module.BaseModelError("bad bits") with self.assertRaises(test_module.web.HTTPBadRequest) as context: await test_module.didx_receive_request_implicit(self.request) @@ -214,13 +218,13 @@ async def test_didx_accept_request(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_didx_mgr.return_value.create_response = mock.CoroutineMock() @@ -241,11 +245,13 @@ async def test_didx_accept_request_not_found(self): async def test_didx_accept_request_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.create_response = mock.CoroutineMock( side_effect=test_module.DIDXManagerError() ) @@ -257,11 +263,13 @@ async def test_didx_reject(self): self.request.match_info = {"conn_id": "dummy"} self.request.json = mock.CoroutineMock(return_value={"reason": "asdf"}) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.reject = mock.CoroutineMock() await test_module.didx_reject(self.request) @@ -282,11 +290,13 @@ async def test_didx_reject_x_bad_conn_state(self): self.request.match_info = {"conn_id": "dummy"} self.request.json = mock.CoroutineMock(return_value={"reason": "asdf"}) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.reject = mock.CoroutineMock( side_effect=test_module.DIDXManagerError() ) diff --git a/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py b/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py index efb99110cb..9e428c958a 100644 --- a/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py +++ b/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py @@ -69,11 +69,14 @@ async def test_receive_query_process_disclosed(self, request_context): request_context.connection_ready = True handler = QueryHandler() responder = MockResponder() - with mock.patch.object( - ProtocolRegistry, "protocols_matching_query", mock.MagicMock() - ), mock.patch.object( - ProtocolRegistry, "prepare_disclosed", mock.CoroutineMock() - ) as mock_prepare_disclosed: + with ( + mock.patch.object( + ProtocolRegistry, "protocols_matching_query", mock.MagicMock() + ), + mock.patch.object( + ProtocolRegistry, "prepare_disclosed", mock.CoroutineMock() + ) as mock_prepare_disclosed, + ): mock_prepare_disclosed.return_value = [ {"test": "test"}, { diff --git a/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py b/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py index 88ccfcecde..134b7a736b 100644 --- a/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py @@ -43,11 +43,14 @@ async def asyncSetUp(self): async def test_receive_disclosure(self): test_conn_id = "test123" self.disclose.assign_thread_id("test123") - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + ): mock_retrieve.return_value = TEST_DISCOVERY_EX_REC ex_rec = await self.manager.receive_disclose( disclose_msg=self.disclose, connection_id=test_conn_id @@ -62,19 +65,24 @@ async def test_receive_disclosure(self): async def test_receive_disclosure_retrieve_by_conn(self): test_conn_id = "test123" self.disclose.assign_thread_id("test123") - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = TEST_DISCOVERY_EX_REC @@ -91,15 +99,19 @@ async def test_receive_disclosure_retrieve_by_conn(self): async def test_receive_disclosure_retrieve_by_conn_not_found(self): test_conn_id = "test123" self.disclose.assign_thread_id("test123") - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -114,15 +126,19 @@ async def test_receive_disclosure_retrieve_by_conn_not_found(self): async def test_receive_disclosure_retrieve_new_ex_rec(self): test_conn_id = "test123" - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -148,23 +164,27 @@ async def test_check_if_disclosure_received(self): async def test_create_and_send_query_with_connection(self): return_ex_rec = V10DiscoveryExchangeRecord(query_msg=Query(query="*")) - with mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, - "save", - mock.CoroutineMock(), - ), mock.patch.object( - V10DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() - ) as mock_disclosure_received, mock.patch.object( - self.responder, "send", mock.CoroutineMock() - ) as mock_send: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, + "save", + mock.CoroutineMock(), + ), + mock.patch.object( + V10DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() + ) as mock_disclosure_received, + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = V10DiscoveryExchangeRecord() mock_disclosure_received.return_value = return_ex_rec diff --git a/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py b/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py index d644c0bfce..3269bbafe2 100644 --- a/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py @@ -40,11 +40,12 @@ async def test_query_features(self): discovery_exchange_id="3fa85f64-5717-4562-b3fc-2c963f66afa6", query_msg=Query(query="*"), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V10DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V10DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -59,11 +60,12 @@ async def test_query_features_with_connection(self): query_msg=Query(query="*"), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V10DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V10DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -78,11 +80,12 @@ async def test_query_records(self): query_msg=Query(query="*"), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.return_value = test_rec await test_module.query_records(self.request) mock_response.assert_called_once_with({"results": [test_rec.serialize()]}) @@ -92,9 +95,12 @@ async def test_query_records_x(self): self.request.query = {"connection_id": "test"} - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) @@ -113,11 +119,12 @@ async def test_query_records_all(self): ), ] - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.return_value = test_recs await test_module.query_records(self.request) mock_response.assert_called_once_with( @@ -127,9 +134,12 @@ async def test_query_records_all(self): async def test_query_records_connection_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) diff --git a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py index 0405014557..11bf227dae 100644 --- a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py +++ b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py @@ -94,14 +94,17 @@ async def test_disclosures_connection_id_no_thid(self, request_context): handler = DisclosuresHandler() mock_responder = MockResponder() - with mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=StorageNotFoundError), - ), mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(return_value=discovery_record), + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(return_value=discovery_record), + ), ): await handler.handle(request_context, mock_responder) assert not mock_responder.messages @@ -127,14 +130,17 @@ async def test_disclosures_no_conn_id_no_thid(self, request_context): handler = DisclosuresHandler() mock_responder = MockResponder() - with mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=StorageNotFoundError), - ), mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(side_effect=StorageNotFoundError), + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), ): await handler.handle(request_context, mock_responder) assert not mock_responder.messages diff --git a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py index adf63001da..b988702070 100644 --- a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py +++ b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py @@ -134,11 +134,14 @@ async def test_receive_query_process_disclosed(self, request_context): request_context.connection_ready = True handler = QueriesHandler() responder = MockResponder() - with mock.patch.object( - V20DiscoveryMgr, "execute_protocol_query", mock.CoroutineMock() - ) as mock_exec_protocol_query, mock.patch.object( - V20DiscoveryMgr, "execute_goal_code_query", mock.CoroutineMock() - ) as mock_goal_code_protocol_query: + with ( + mock.patch.object( + V20DiscoveryMgr, "execute_protocol_query", mock.CoroutineMock() + ) as mock_exec_protocol_query, + mock.patch.object( + V20DiscoveryMgr, "execute_goal_code_query", mock.CoroutineMock() + ) as mock_goal_code_protocol_query, + ): mock_exec_protocol_query.return_value = [ {"test": "test"}, { diff --git a/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py b/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py index 3778d0784e..0473161c73 100644 --- a/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py +++ b/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py @@ -52,11 +52,14 @@ async def asyncSetUp(self): async def test_receive_disclosure(self): test_conn_id = "test123" self.queries.assign_thread_id("test123") - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + ): mock_retrieve.return_value = TEST_DISCOVERY_EX_REC ex_rec = await self.manager.receive_disclose( disclose_msg=self.disclosures, connection_id=test_conn_id @@ -71,19 +74,24 @@ async def test_receive_disclosure(self): async def test_receive_disclosure_retrieve_by_conn(self): test_conn_id = "test123" self.queries.assign_thread_id("test123") - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = TEST_DISCOVERY_EX_REC @@ -100,15 +108,19 @@ async def test_receive_disclosure_retrieve_by_conn(self): async def test_receive_disclosure_retrieve_by_conn_not_found(self): test_conn_id = "test123" self.queries.assign_thread_id("test123") - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -123,15 +135,19 @@ async def test_receive_disclosure_retrieve_by_conn_not_found(self): async def test_receive_disclosure_retrieve_new_ex_rec(self): test_conn_id = "test123" - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -144,25 +160,27 @@ async def test_receive_disclosure_retrieve_new_ex_rec(self): ) async def test_proactive_disclosure(self): - with mock.patch.object( - V20DiscoveryMgr, - "receive_query", - mock.CoroutineMock(), - ) as mock_receive_query, mock.patch.object( - self.responder, "send", mock.CoroutineMock() - ) as mock_send: + with ( + mock.patch.object( + V20DiscoveryMgr, + "receive_query", + mock.CoroutineMock(), + ) as mock_receive_query, + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): mock_receive_query.return_value = Disclosures() await self.manager.proactive_disclose_features("test123") mock_send.assert_called_once() async def test_proactive_disclosure_no_responder(self): self.profile.context.injector.clear_binding(BaseResponder) - with mock.patch.object( - V20DiscoveryMgr, - "receive_query", - mock.CoroutineMock(), - ) as mock_receive_query, mock.patch.object( - self.responder, "send", mock.CoroutineMock() + with ( + mock.patch.object( + V20DiscoveryMgr, + "receive_query", + mock.CoroutineMock(), + ) as mock_receive_query, + mock.patch.object(self.responder, "send", mock.CoroutineMock()), ): self._caplog.set_level(logging.WARNING) mock_receive_query.return_value = Disclosures() @@ -195,23 +213,27 @@ async def test_create_and_send_query_with_connection(self): ] ) ) - with mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "save", - mock.CoroutineMock(), - ), mock.patch.object( - V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() - ) as mock_disclosure_received, mock.patch.object( - self.responder, "send", mock.CoroutineMock() - ) as mock_send: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "save", + mock.CoroutineMock(), + ), + mock.patch.object( + V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() + ) as mock_disclosure_received, + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = V20DiscoveryExchangeRecord() mock_disclosure_received.return_value = return_ex_rec @@ -223,17 +245,21 @@ async def test_create_and_send_query_with_connection(self): async def test_create_and_send_query_with_connection_no_responder(self): self.profile.context.injector.clear_binding(BaseResponder) - with mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "save", - mock.CoroutineMock(), - ), mock.patch.object( - V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() - ) as mock_disclosure_received: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "save", + mock.CoroutineMock(), + ), + mock.patch.object( + V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() + ) as mock_disclosure_received, + ): self._caplog.set_level(logging.WARNING) mock_exists_for_connection_id.return_value = False mock_disclosure_received.side_effect = asyncio.TimeoutError diff --git a/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py b/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py index 464916b963..dc06abcb00 100644 --- a/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py @@ -46,11 +46,12 @@ async def test_query_features(self): ), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V20DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -74,11 +75,12 @@ async def test_query_features_with_connection(self): ), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V20DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -98,11 +100,12 @@ async def test_query_records(self): ), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.return_value = test_rec await test_module.query_records(self.request) mock_response.assert_called_once_with({"results": [test_rec.serialize()]}) @@ -112,9 +115,12 @@ async def test_query_records_x(self): self.request.query = {"connection_id": "test"} - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) @@ -143,11 +149,12 @@ async def test_query_records_all(self): ), ] - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.return_value = test_recs await test_module.query_records(self.request) mock_response.assert_called_once_with( @@ -157,9 +164,12 @@ async def test_query_records_all(self): async def test_query_records_connection_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) diff --git a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py index 6519e9b27e..d333948eda 100644 --- a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py @@ -476,11 +476,10 @@ async def test_complete_transaction(self): ) ) - with mock.patch.object( - TransactionRecord, "save", autospec=True - ) as save_record, mock.patch.object( - ConnRecord, "retrieve_by_id" - ) as mock_conn_rec_retrieve: + with ( + mock.patch.object(TransactionRecord, "save", autospec=True) as save_record, + mock.patch.object(ConnRecord, "retrieve_by_id") as mock_conn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -534,11 +533,10 @@ async def test_complete_transaction_anoncreds( ) self.ledger.get_indy_storage = future - with mock.patch.object( - TransactionRecord, "save", autospec=True - ) as save_record, mock.patch.object( - ConnRecord, "retrieve_by_id" - ) as mock_conn_rec_retrieve: + with ( + mock.patch.object(TransactionRecord, "save", autospec=True) as save_record, + mock.patch.object(ConnRecord, "retrieve_by_id") as mock_conn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ diff --git a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py index 66bf109838..65dd81e8c7 100644 --- a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py @@ -62,11 +62,12 @@ async def asyncSetUp(self): self.test_did = "sample-did" async def test_transactions_list(self): - with mock.patch.object( - TransactionRecord, "query", mock.CoroutineMock() - ) as mock_query, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + TransactionRecord, "query", mock.CoroutineMock() + ) as mock_query, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_query.return_value = [ mock.MagicMock(serialize=mock.MagicMock(return_value={"...": "..."})) ] @@ -75,9 +76,12 @@ async def test_transactions_list(self): mock_response.assert_called_once_with({"results": [{"...": "..."}]}) async def test_transactions_list_x(self): - with mock.patch.object( - TransactionRecord, "query", mock.CoroutineMock() - ) as mock_query, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + TransactionRecord, "query", mock.CoroutineMock() + ) as mock_query, + mock.patch.object(test_module.web, "json_response"), + ): mock_query.side_effect = test_module.StorageError() with self.assertRaises(test_module.web.HTTPBadRequest): @@ -86,11 +90,12 @@ async def test_transactions_list_x(self): async def test_transactions_retrieve(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) ) @@ -129,15 +134,18 @@ async def test_transaction_create_request(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -193,11 +201,14 @@ async def test_transaction_create_request_base_model_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -224,13 +235,17 @@ async def test_transaction_create_request_no_jobs_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -260,13 +275,17 @@ async def test_transaction_create_request_no_my_job_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -302,13 +321,17 @@ async def test_transaction_create_request_no_their_job_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -344,11 +367,14 @@ async def test_transaction_create_request_my_wrong_job_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -375,13 +401,17 @@ async def test_transaction_create_request_mgr_create_request_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -423,15 +453,18 @@ async def test_endorse_transaction_response(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( return_value=( @@ -523,11 +556,14 @@ async def test_endorse_transaction_response_base_model_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -554,11 +590,14 @@ async def test_endorse_transaction_response_no_jobs_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -588,13 +627,17 @@ async def test_endorse_transaction_response_no_ledger_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( return_value=( @@ -639,11 +682,14 @@ async def test_endorse_transaction_response_wrong_my_job_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -682,13 +728,17 @@ async def test_endorse_transaction_response_ledger_x(self): side_effect=test_module.LedgerError() ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( return_value=( @@ -733,13 +783,18 @@ async def test_endorse_transaction_response_txn_mgr_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -779,15 +834,18 @@ async def test_refuse_transaction_response(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_refuse_response=mock.CoroutineMock( return_value=( @@ -859,11 +917,14 @@ async def test_refuse_transaction_response_conn_base_model_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -890,11 +951,14 @@ async def test_refuse_transaction_response_no_jobs_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -923,11 +987,14 @@ async def test_refuse_transaction_response_wrong_my_job_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -962,13 +1029,18 @@ async def test_refuse_transaction_response_txn_mgr_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( create_refuse_response=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -993,15 +1065,18 @@ async def test_refuse_transaction_response_txn_mgr_x(self): async def test_cancel_transaction(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( cancel_transaction=mock.CoroutineMock( return_value=( @@ -1043,11 +1118,14 @@ async def test_cancel_transaction_not_found_x(self): async def test_cancel_transaction_conn_rec_base_model_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -1059,11 +1137,14 @@ async def test_cancel_transaction_conn_rec_base_model_x(self): async def test_cancel_transaction_no_jobs_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -1077,11 +1158,14 @@ async def test_cancel_transaction_no_jobs_x(self): async def test_cancel_transaction_wrong_my_job_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -1101,13 +1185,18 @@ async def test_cancel_transaction_wrong_my_job_x(self): async def test_cancel_transaction_txn_mgr_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( cancel_transaction=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -1132,15 +1221,18 @@ async def test_cancel_transaction_txn_mgr_x(self): async def test_transaction_resend(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( transaction_resend=mock.CoroutineMock( return_value=( @@ -1182,11 +1274,14 @@ async def test_transaction_resend_not_found_x(self): async def test_transaction_resend_conn_rec_base_model_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -1198,11 +1293,14 @@ async def test_transaction_resend_conn_rec_base_model_x(self): async def test_transaction_resend_no_jobs_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -1216,11 +1314,14 @@ async def test_transaction_resend_no_jobs_x(self): async def test_transaction_resend_my_wrong_job_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -1241,13 +1342,18 @@ async def test_transaction_resend_my_wrong_job_x(self): async def test_transaction_resend_txn_mgr_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( transaction_resend=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -1272,13 +1378,15 @@ async def test_transaction_resend_txn_mgr_x(self): async def test_set_endorser_role(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( set_transaction_my_job=mock.CoroutineMock() ) @@ -1322,11 +1430,12 @@ async def test_set_endorser_role_base_model_x(self): async def test_set_endorser_info(self): self.request.match_info = {"conn_id": "dummy"} self.request.query = {"endorser_did": "did", "endorser_name": "name"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -1354,11 +1463,12 @@ async def test_set_endorser_info(self): async def test_set_endorser_info_no_prior_value(self): self.request.match_info = {"conn_id": "dummy"} self.request.query = {"endorser_did": "did", "endorser_name": "name"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( side_effect=[ @@ -1466,13 +1576,15 @@ async def test_set_endorser_info_my_wrong_job_x(self): async def test_transaction_write_schema_txn(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value.complete_transaction = mock.CoroutineMock() mock_txn_mgr.return_value.complete_transaction.return_value = ( @@ -1526,11 +1638,14 @@ async def test_transaction_write_wrong_state_x(self): async def test_transaction_write_schema_txn_complete_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( complete_transaction=mock.CoroutineMock( side_effect=test_module.StorageError() diff --git a/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py b/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py index 656b3db249..c8a0e94d52 100644 --- a/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py +++ b/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py @@ -70,11 +70,12 @@ async def test_introduction_start(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - self.context, "inject_or", mock.MagicMock() - ) as mock_ctx_inject, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + self.context, "inject_or", mock.MagicMock() + ) as mock_ctx_inject, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_ctx_inject.return_value = mock.MagicMock( start_introduction=mock.CoroutineMock() ) diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py index 32aa553b2e..43eeb5e1ff 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py @@ -117,11 +117,12 @@ async def test_called_auto_store_x(self): handler = test_module.CredentialIssueHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py index 4b3982431d..c6fe03eafc 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py @@ -109,11 +109,12 @@ async def test_called_auto_request_x(self): handler = test_module.CredentialOfferHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py index 94b0ee83e3..905b7c2e46 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py @@ -86,11 +86,12 @@ async def test_called_auto_offer_x(self): handler = test_module.CredentialProposalHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py index 7050d754e6..740a3f759c 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py @@ -128,10 +128,11 @@ async def test_called_auto_issue_x(self): }, ) - with mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - cred_ex_rec, "save_error_state", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(cred_ex_rec, "save_error_state", mock.CoroutineMock()), ): mock_cred_mgr.return_value.receive_request = mock.CoroutineMock( return_value=cred_ex_rec @@ -146,11 +147,12 @@ async def test_called_auto_issue_x(self): handler = test_module.CredentialRequestHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py b/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py index 05416c54b1..d53ce0e549 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py +++ b/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py @@ -12,8 +12,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, ) from ..message_types import CREDENTIAL_PROPOSAL, PROTOCOL_PACKAGE from .inner.credential_preview import CredentialPreview, CredentialPreviewSchema @@ -104,8 +104,8 @@ class Meta: schema_version = fields.Str( required=False, allow_none=False, - validate=INDY_VERSION_VALIDATE, - metadata={"example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={"example": MAJOR_MINOR_VERSION_EXAMPLE}, ) cred_def_id = fields.Str( required=False, diff --git a/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py b/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py index dabca65888..661504d4c2 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py +++ b/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py @@ -77,11 +77,12 @@ async def test_save_error_state(self): record.state = V10CredentialExchange.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="test") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/routes.py b/acapy_agent/protocols/issue_credential/v1_0/routes.py index 898f335b01..95bb4eeedc 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v1_0/routes.py @@ -34,8 +34,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, ) @@ -142,8 +142,11 @@ class V10CredentialCreateSchema(AdminAPIMessageTracingSchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, @@ -201,8 +204,11 @@ class V10CredentialProposalRequestSchemaBase(AdminAPIMessageTracingSchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, diff --git a/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py b/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py index a8bed3b72b..af7a358fec 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py @@ -402,12 +402,12 @@ async def test_create_bound_offer(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "get_cached_key", autospec=True - ) as get_cached_key, mock.patch.object( - V10CredentialExchange, "set_cached_key", autospec=True + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, "get_cached_key", autospec=True + ) as get_cached_key, + mock.patch.object(V10CredentialExchange, "set_cached_key", autospec=True), ): get_cached_key.return_value = None issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -473,12 +473,12 @@ async def test_create_bound_offer_no_cred_def(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, "get_cached_key", autospec=True - ) as get_cached_key, mock.patch.object( - V10CredentialExchange, "set_cached_key", autospec=True + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, "get_cached_key", autospec=True + ) as get_cached_key, + mock.patch.object(V10CredentialExchange, "set_cached_key", autospec=True), ): get_cached_key.return_value = None issuer = mock.MagicMock() @@ -526,12 +526,13 @@ async def test_receive_offer_proposed(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(return_value=stored_exchange), + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(return_value=stored_exchange), + ), ): exchange = await self.manager.receive_offer(offer, connection_id) @@ -565,12 +566,13 @@ async def test_receive_free_offer(self): self.profile.context.connection_record = mock.MagicMock() self.profile.context.connection_record.connection_id = connection_id - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(side_effect=StorageNotFoundError), + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), ): exchange = await self.manager.receive_offer(offer, connection_id) @@ -752,13 +754,16 @@ async def test_receive_request(self): requests_attach=[CredentialRequest.wrap_indy_cred_req(INDY_CRED_REQ)] ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(return_value=stored_exchange), - ) as retrieve_ex: + with ( + mock.patch.object( + V10CredentialExchange, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(return_value=stored_exchange), + ) as retrieve_ex, + ): exchange = await self.manager.receive_request(request, mock_conn, None) retrieve_ex.assert_called() @@ -787,13 +792,14 @@ async def test_receive_request_no_connection_cred_request(self): ) mock_oob = mock.MagicMock() - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as mock_save, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as mock_retrieve: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as mock_save, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as mock_retrieve, + ): mock_retrieve.return_value = stored_exchange cx_rec = await self.manager.receive_request(request, mock_conn, mock_oob) @@ -822,13 +828,14 @@ async def test_receive_request_no_cred_ex_with_offer_found(self): connection_id="test_conn_id", ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as mock_retrieve: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as mock_retrieve, + ): mock_retrieve.side_effect = (StorageNotFoundError(),) with self.assertRaises(StorageNotFoundError): await self.manager.receive_request(request, mock_conn, None) @@ -870,11 +877,10 @@ async def test_issue_credential_revocable(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex: + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + ): revoc.return_value.get_or_create_active_registry = mock.CoroutineMock( return_value=( mock.MagicMock( # active_rev_reg_rec @@ -959,12 +965,13 @@ async def test_issue_credential_non_revocable(self): self.ledger.__aenter__ = mock.CoroutineMock(return_value=self.ledger) self.profile.context.injector.clear_binding(BaseLedger) self.profile.context.injector.bind_instance(BaseLedger, self.ledger) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), ): (ret_exchange, ret_cred_issue) = await self.manager.issue_credential( stored_exchange, comment=comment, retries=0 @@ -1022,11 +1029,10 @@ async def test_issue_credential_fills_rr(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex: + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + ): revoc.return_value = mock.MagicMock( get_or_create_active_registry=( mock.CoroutineMock( @@ -1216,13 +1222,14 @@ async def test_receive_credential(self): credentials_attach=[CredentialIssue.wrap_indy_credential(INDY_CRED)] ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(return_value=stored_exchange), - ) as retrieve_ex: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(return_value=stored_exchange), + ) as retrieve_ex, + ): exchange = await self.manager.receive_credential(issue, connection_id) assert retrieve_ex.call_args.args[1] == connection_id @@ -1283,12 +1290,12 @@ async def test_store_credential(self): return_value=("test_ledger_id", self.ledger) ) self.profile.context.injector.bind_instance(IndyLedgerRequestsExecutor, executor) - with mock.patch.object( - test_module, "RevocationRegistry", autospec=True - ) as mock_rev_reg, mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True + with ( + mock.patch.object( + test_module, "RevocationRegistry", autospec=True + ) as mock_rev_reg, + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object(V10CredentialExchange, "delete_record", autospec=True), ): mock_rev_reg.from_definition = mock.MagicMock( return_value=mock.MagicMock( @@ -1389,10 +1396,9 @@ async def test_store_credential_no_preview(self): return_value=("test_ledger_id", self.ledger) ) self.profile.context.injector.bind_instance(IndyLedgerRequestsExecutor, executor) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object(V10CredentialExchange, "delete_record", autospec=True), ): ret_exchange = await self.manager.store_credential(stored_exchange) @@ -1480,15 +1486,18 @@ async def test_send_credential_ack(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True - ) as mock_delete_ex, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exception, mock.patch.object( - test_module.LOGGER, "warning", mock.MagicMock() - ) as mock_log_warning: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, "delete_record", autospec=True + ) as mock_delete_ex, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exception, + mock.patch.object( + test_module.LOGGER, "warning", mock.MagicMock() + ) as mock_log_warning, + ): mock_delete_ex.side_effect = test_module.StorageError() (exch, ack) = await self.manager.send_credential_ack(stored_exchange) assert ack._thread @@ -1516,15 +1525,17 @@ async def test_receive_credential_ack(self): ack = CredentialAck() - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True - ) as delete_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as retrieve_ex: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, "delete_record", autospec=True + ) as delete_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as retrieve_ex, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_credential_ack(ack, connection_id) @@ -1557,13 +1568,14 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as retrieve_ex: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as retrieve_ex, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_problem_report( diff --git a/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py b/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py index a5fe618496..dddac2e214 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py @@ -120,13 +120,16 @@ async def test_credential_exchange_retrieve_x(self): async def test_credential_exchange_create(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -151,13 +154,16 @@ async def test_credential_exchange_create(self): async def test_credential_exchange_create_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), + mock.patch.object(test_module.web, "json_response"), + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -184,13 +190,16 @@ async def test_credential_exchange_create_no_proposal(self): async def test_credential_exchange_send(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -229,11 +238,12 @@ async def test_credential_exchange_send_no_conn_record(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -255,11 +265,12 @@ async def test_credential_exchange_send_not_ready(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -274,12 +285,14 @@ async def test_credential_exchange_send_not_ready(self): async def test_credential_exchange_send_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -313,13 +326,13 @@ async def test_credential_exchange_send_proposal(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex_record = mock.MagicMock() mock_credential_manager.return_value.create_proposal.return_value = ( mock_cred_ex_record @@ -336,12 +349,14 @@ async def test_credential_exchange_send_proposal(self): async def test_credential_exchange_send_proposal_no_conn_record(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( @@ -373,12 +388,14 @@ async def test_credential_exchange_send_proposal_deser_x(self): async def test_credential_exchange_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() @@ -399,11 +416,12 @@ async def test_credential_exchange_send_proposal_x(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -428,13 +446,13 @@ async def test_credential_exchange_create_free_offer(self): self.context.update_settings({"debug.auto_respond_credential_offer": True}) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_cred_ex_record = mock.MagicMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -498,11 +516,12 @@ async def test_credential_exchange_create_free_offer_deser_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.side_effect = ( test_module.BaseModelError() @@ -522,11 +541,12 @@ async def test_credential_exchange_create_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock( side_effect=test_module.BaseModelError(), @@ -555,13 +575,13 @@ async def test_credential_exchange_send_free_offer(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_cred_ex_record = mock.MagicMock() @@ -606,11 +626,12 @@ async def test_credential_exchange_send_free_offer_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -629,11 +650,12 @@ async def test_credential_exchange_send_free_offer_not_ready(self): self.request.json = mock.CoroutineMock() self.request.json.return_value["auto_issue"] = True - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -658,11 +680,13 @@ async def test_credential_exchange_send_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -684,15 +708,16 @@ async def test_credential_exchange_send_bound_offer(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_PROPOSAL_RECEIVED @@ -732,13 +757,15 @@ async def test_credential_exchange_send_bound_offer_no_conn_record(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock( @@ -785,13 +812,15 @@ async def test_credential_exchange_send_bound_offer_not_ready(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -816,15 +845,16 @@ async def test_credential_exchange_send_request(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_OFFER_RECEIVED @@ -847,17 +877,19 @@ async def test_credential_exchange_send_request_no_conn(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "OobRecord", autospec=True - ) as mock_oob_rec, mock.patch.object( - test_module, "default_did_from_verkey", autospec=True - ) as mock_default_did_from_verkey, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "OobRecord", autospec=True) as mock_oob_rec, + mock.patch.object( + test_module, "default_did_from_verkey", autospec=True + ) as mock_default_did_from_verkey, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_oob_rec.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock.MagicMock(our_recipient_key="our-recipient_key") ) @@ -905,13 +937,15 @@ async def test_credential_exchange_send_request_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -938,13 +972,15 @@ async def test_credential_exchange_send_request_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -969,15 +1005,16 @@ async def test_credential_exchange_issue(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_REQUEST_RECEIVED @@ -1020,13 +1057,15 @@ async def test_credential_exchange_issue_no_conn_record(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + ): mock_cred_ex_rec.state = mock_cred_ex_cls.STATE_REQUEST_RECEIVED mock_cred_ex_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_cred_ex_rec @@ -1050,13 +1089,15 @@ async def test_credential_exchange_issue_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_REQUEST_RECEIVED @@ -1084,13 +1125,15 @@ async def test_credential_exchange_issue_rev_reg_full(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + ): mock_cred_ex_cls.state = mock_cred_ex_cls.STATE_REQUEST_RECEIVED mock_cred_ex_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_cred_ex_rec @@ -1116,13 +1159,15 @@ async def test_credential_exchange_issue_deser_x(self): serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + ): mock_cred_ex_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_cred_ex_rec ) @@ -1141,15 +1186,16 @@ async def test_credential_exchange_store(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_CREDENTIAL_RECEIVED @@ -1177,15 +1223,16 @@ async def test_credential_exchange_store_bad_cred_id_json(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_CREDENTIAL_RECEIVED @@ -1226,13 +1273,15 @@ async def test_credential_exchange_store_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock( @@ -1262,13 +1311,13 @@ async def test_credential_exchange_store_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ), mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object(test_module, "CredentialManager", autospec=True), + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -1287,13 +1336,16 @@ async def test_credential_exchange_store_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_ex_record = mock.MagicMock( state=mock_cred_ex_cls.STATE_CREDENTIAL_RECEIVED, serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -1316,11 +1368,12 @@ async def test_credential_exchange_store_x(self): async def test_credential_exchange_remove(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value = mock_cred_ex @@ -1366,15 +1419,17 @@ async def test_credential_exchange_problem_report(self): self.request.match_info = {"cred_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "CredentialManager", autospec=True - ), mock.patch.object(test_module, "ConnRecord", autospec=True), mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "CredentialManager", autospec=True), + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -1410,13 +1465,13 @@ async def test_credential_exchange_problem_report_x(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "CredentialManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "CredentialManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( save_error_state=mock.CoroutineMock( diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py index e72614437a..a25e4bb62c 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py @@ -1,30 +1,28 @@ -"""V2.0 issue-credential indy credential format handler.""" +"""V2.0 issue-credential anoncreds credential format handler.""" import json import logging from typing import Mapping, Optional, Tuple +from anoncreds import CredentialDefinition, Schema from marshmallow import RAISE +from ......anoncreds.base import AnonCredsResolutionError from ......anoncreds.holder import AnonCredsHolder, AnonCredsHolderError -from ......anoncreds.issuer import AnonCredsIssuer +from ......anoncreds.issuer import CATEGORY_CRED_DEF, CATEGORY_SCHEMA, AnonCredsIssuer +from ......anoncreds.models.credential import AnoncredsCredentialSchema +from ......anoncreds.models.credential_offer import AnoncredsCredentialOfferSchema +from ......anoncreds.models.credential_proposal import ( + AnoncredsCredentialDefinitionProposal, +) +from ......anoncreds.models.credential_request import AnoncredsCredRequestSchema from ......anoncreds.registry import AnonCredsRegistry from ......anoncreds.revocation import AnonCredsRevocation from ......cache.base import BaseCache -from ......indy.models.cred import IndyCredentialSchema -from ......indy.models.cred_abstract import IndyCredAbstractSchema -from ......indy.models.cred_request import IndyCredRequestSchema -from ......ledger.base import BaseLedger -from ......ledger.multiple_ledger.ledger_requests_executor import ( - GET_CRED_DEF, - IndyLedgerRequestsExecutor, -) from ......messaging.credential_definitions.util import ( CRED_DEF_SENT_RECORD_TYPE, - CredDefQueryStringSchema, ) from ......messaging.decorators.attach_decorator import AttachDecorator -from ......multitenant.base import BaseMultitenantManager from ......revocation_anoncreds.models.issuer_cred_rev_record import IssuerCredRevRecord from ......storage.base import BaseStorage from ...message_types import ( @@ -40,16 +38,16 @@ from ...messages.cred_proposal import V20CredProposal from ...messages.cred_request import V20CredRequest from ...models.cred_ex_record import V20CredExRecord -from ...models.detail.indy import V20CredExRecordIndy +from ...models.detail.anoncreds import V20CredExRecordAnoncreds from ..handler import CredFormatAttachment, V20CredFormatError, V20CredFormatHandler LOGGER = logging.getLogger(__name__) class AnonCredsCredFormatHandler(V20CredFormatHandler): - """Indy credential format handler.""" + """Anoncreds credential format handler.""" - format = V20CredFormat.Format.INDY + format = V20CredFormat.Format.ANONCREDS @classmethod def validate_fields(cls, message_type: str, attachment_data: Mapping): @@ -71,10 +69,10 @@ def validate_fields(cls, message_type: str, attachment_data: Mapping): """ mapping = { - CRED_20_PROPOSAL: CredDefQueryStringSchema, - CRED_20_OFFER: IndyCredAbstractSchema, - CRED_20_REQUEST: IndyCredRequestSchema, - CRED_20_ISSUE: IndyCredentialSchema, + CRED_20_PROPOSAL: AnoncredsCredentialDefinitionProposal, + CRED_20_OFFER: AnoncredsCredentialOfferSchema, + CRED_20_REQUEST: AnoncredsCredRequestSchema, + CRED_20_ISSUE: AnoncredsCredentialSchema, } # Get schema class @@ -83,7 +81,7 @@ def validate_fields(cls, message_type: str, attachment_data: Mapping): # Validate, throw if not valid Schema(unknown=RAISE).load(attachment_data) - async def get_detail_record(self, cred_ex_id: str) -> V20CredExRecordIndy: + async def get_detail_record(self, cred_ex_id: str) -> V20CredExRecordAnoncreds: """Retrieve credential exchange detail record by cred_ex_id.""" async with self.profile.session() as session: @@ -167,7 +165,7 @@ async def _match_sent_cred_def_id(self, tag_query: Mapping[str, str]) -> str: async def create_proposal( self, cred_ex_record: V20CredExRecord, proposal_data: Mapping[str, str] ) -> Tuple[V20CredFormat, AttachDecorator]: - """Create indy credential proposal.""" + """Create anoncreds credential proposal.""" if proposal_data is None: proposal_data = {} @@ -176,7 +174,7 @@ async def create_proposal( async def receive_proposal( self, cred_ex_record: V20CredExRecord, cred_proposal_message: V20CredProposal ) -> None: - """Receive indy credential proposal. + """Receive anoncreds credential proposal. No custom handling is required for this step. """ @@ -184,35 +182,37 @@ async def receive_proposal( async def create_offer( self, cred_proposal_message: V20CredProposal ) -> CredFormatAttachment: - """Create indy credential offer.""" + """Create anoncreds credential offer.""" issuer = AnonCredsIssuer(self.profile) - ledger = self.profile.inject(BaseLedger) cache = self.profile.inject_or(BaseCache) + anoncreds_attachment = cred_proposal_message.attachment( + AnonCredsCredFormatHandler.format + ) + + if not anoncreds_attachment: + anoncreds_attachment = cred_proposal_message.attachment( + V20CredFormat.Format.INDY.api + ) + cred_def_id = await issuer.match_created_credential_definitions( - **cred_proposal_message.attachment(AnonCredsCredFormatHandler.format) + **anoncreds_attachment ) async def _create(): offer_json = await issuer.create_credential_offer(cred_def_id) return json.loads(offer_json) - multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) - if multitenant_mgr: - ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) - else: - ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) - ledger = ( - await ledger_exec_inst.get_ledger_for_identifier( - cred_def_id, - txn_record_type=GET_CRED_DEF, + async with self.profile.session() as session: + cred_def_entry = await session.handle.fetch(CATEGORY_CRED_DEF, cred_def_id) + cred_def_dict = CredentialDefinition.load(cred_def_entry.value).to_dict() + schema_entry = await session.handle.fetch( + CATEGORY_SCHEMA, cred_def_dict["schemaId"] ) - )[1] - async with ledger: - schema_id = await ledger.credential_definition_id2schema_id(cred_def_id) - schema = await ledger.get_schema(schema_id) - schema_attrs = set(schema["attrNames"]) + schema_dict = Schema.load(schema_entry.value).to_dict() + + schema_attrs = set(schema_dict["attrNames"]) preview_attrs = set(cred_proposal_message.credential_preview.attr_dict()) if preview_attrs != schema_attrs: raise V20CredFormatError( @@ -238,23 +238,26 @@ async def _create(): async def receive_offer( self, cred_ex_record: V20CredExRecord, cred_offer_message: V20CredOffer ) -> None: - """Receive indy credential offer.""" + """Receive anoncreds credential offer.""" async def create_request( self, cred_ex_record: V20CredExRecord, request_data: Optional[Mapping] = None ) -> CredFormatAttachment: - """Create indy credential request.""" + """Create anoncreds credential request.""" if cred_ex_record.state != V20CredExRecord.STATE_OFFER_RECEIVED: raise V20CredFormatError( - "Indy issue credential format cannot start from credential request" + "Anoncreds issue credential format cannot start from credential request" ) await self._check_uniqueness(cred_ex_record.cred_ex_id) - holder_did = request_data.get("holder_did") if request_data else None + + # For backwards compatibility, remove indy backup when indy format is retired + from ..indy.handler import IndyCredFormatHandler + cred_offer = cred_ex_record.cred_offer.attachment( AnonCredsCredFormatHandler.format - ) + ) or cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format) if "nonce" not in cred_offer: raise V20CredFormatError("Missing nonce in credential offer") @@ -265,19 +268,24 @@ async def create_request( async def _create(): anoncreds_registry = self.profile.inject(AnonCredsRegistry) - cred_def_result = await anoncreds_registry.get_credential_definition( - self.profile, cred_def_id - ) - - holder = AnonCredsHolder(self.profile) - request_json, metadata_json = await holder.create_credential_request( - cred_offer, cred_def_result.credential_definition, holder_did - ) + try: + cred_def_result = await anoncreds_registry.get_credential_definition( + self.profile, cred_def_id + ) + holder = AnonCredsHolder(self.profile) + request_json, metadata_json = await holder.create_credential_request( + cred_offer, cred_def_result.credential_definition, holder_did + ) - return { - "request": json.loads(request_json), - "metadata": json.loads(metadata_json), - } + return { + "request": json.loads(request_json), + "metadata": json.loads(metadata_json), + } + # This is for compatability with a holder that isn't anoncreds capable + except AnonCredsResolutionError: + return await IndyCredFormatHandler.create_cred_request_result( + self, cred_offer, holder_did, cred_def_id + ) cache_key = f"credential_request::{cred_def_id}::{holder_did}::{nonce}" cred_req_result = None @@ -292,7 +300,7 @@ async def _create(): if not cred_req_result: cred_req_result = await _create() - detail_record = V20CredExRecordIndy( + detail_record = V20CredExRecordAnoncreds( cred_ex_id=cred_ex_record.cred_ex_id, cred_request_metadata=cred_req_result["metadata"], ) @@ -305,18 +313,25 @@ async def _create(): async def receive_request( self, cred_ex_record: V20CredExRecord, cred_request_message: V20CredRequest ) -> None: - """Receive indy credential request.""" + """Receive anoncreds credential request.""" if not cred_ex_record.cred_offer: raise V20CredFormatError( - "Indy issue credential format cannot start from credential request" + "Anoncreds issue credential format cannot start from credential request" ) async def issue_credential( self, cred_ex_record: V20CredExRecord, retries: int = 5 ) -> CredFormatAttachment: - """Issue indy credential.""" + """Issue anoncreds credential.""" await self._check_uniqueness(cred_ex_record.cred_ex_id) + # For backwards compatibility, remove indy backup when indy format is retired + from ..indy.handler import IndyCredFormatHandler + + if cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format): + indy_handler = IndyCredFormatHandler(self.profile) + return await indy_handler.issue_credential(cred_ex_record, retries) + cred_offer = cred_ex_record.cred_offer.attachment( AnonCredsCredFormatHandler.format ) @@ -342,7 +357,7 @@ async def issue_credential( result = self.get_format_data(CRED_20_ISSUE, json.loads(cred_json)) async with self._profile.transaction() as txn: - detail_record = V20CredExRecordIndy( + detail_record = V20CredExRecordAnoncreds( cred_ex_id=cred_ex_record.cred_ex_id, rev_reg_id=rev_reg_def_id, cred_rev_id=cred_rev_id, @@ -371,7 +386,7 @@ async def issue_credential( async def receive_credential( self, cred_ex_record: V20CredExRecord, cred_issue_message: V20CredIssue ) -> None: - """Receive indy credential. + """Receive anoncreds credential. Validation is done in the store credential step. """ @@ -379,21 +394,33 @@ async def receive_credential( async def store_credential( self, cred_ex_record: V20CredExRecord, cred_id: Optional[str] = None ) -> None: - """Store indy credential.""" - cred = cred_ex_record.cred_issue.attachment(AnonCredsCredFormatHandler.format) + """Store anoncreds credential.""" + + # For backwards compatibility, remove indy backup when indy format is retired + from ..indy.handler import IndyCredFormatHandler + + cred = cred_ex_record.cred_issue.attachment( + AnonCredsCredFormatHandler.format + ) or cred_ex_record.cred_issue.attachment(IndyCredFormatHandler.format) rev_reg_def = None anoncreds_registry = self.profile.inject(AnonCredsRegistry) - cred_def_result = await anoncreds_registry.get_credential_definition( - self.profile, cred["cred_def_id"] - ) - if cred.get("rev_reg_id"): - rev_reg_def_result = ( - await anoncreds_registry.get_revocation_registry_definition( - self.profile, cred["rev_reg_id"] + try: + cred_def_result = await anoncreds_registry.get_credential_definition( + self.profile, cred["cred_def_id"] + ) + if cred.get("rev_reg_id"): + rev_reg_def_result = ( + await anoncreds_registry.get_revocation_registry_definition( + self.profile, cred["rev_reg_id"] + ) ) + rev_reg_def = rev_reg_def_result.revocation_registry + + except AnonCredsResolutionError: + return await IndyCredFormatHandler.store_credential( + self, cred_ex_record, cred_id ) - rev_reg_def = rev_reg_def_result.revocation_registry holder = AnonCredsHolder(self.profile) cred_offer_message = cred_ex_record.cred_offer diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py index 46606417fb..f795929e8b 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py @@ -36,10 +36,10 @@ from ....messages.cred_request import V20CredRequest from ....messages.inner.cred_preview import V20CredAttrSpec, V20CredPreview from ....models.cred_ex_record import V20CredExRecord -from ....models.detail.indy import V20CredExRecordIndy +from ....models.detail.anoncreds import V20CredExRecordAnoncreds from ...handler import V20CredFormatError from .. import handler as test_module -from ..handler import LOGGER as INDY_LOGGER +from ..handler import LOGGER as ANONCREDS_LOGGER from ..handler import AnonCredsCredFormatHandler TEST_DID = "LjgpST2rjsoxYegQDRm7EL" @@ -108,7 +108,7 @@ "tailsLocation": TAILS_LOCAL, }, } -INDY_OFFER = { +ANONCREDS_OFFER = { "schema_id": SCHEMA_ID, "cred_def_id": CRED_DEF_ID, "key_correctness_proof": { @@ -131,7 +131,7 @@ }, "nonce": "1234567890", } -INDY_CRED_REQ = { +ANONCREDS_CRED_REQ = { "prover_did": TEST_DID, "cred_def_id": CRED_DEF_ID, "blinded_ms": { @@ -148,7 +148,7 @@ }, "nonce": "9876543210", } -INDY_CRED = { +ANONCREDS_CRED = { "schema_id": SCHEMA_ID, "cred_def_id": CRED_DEF_ID, "rev_reg_id": REV_REG_ID, @@ -232,9 +232,9 @@ async def asyncSetUp(self): async def test_validate_fields(self): # Test correct data self.handler.validate_fields(CRED_20_PROPOSAL, {"cred_def_id": CRED_DEF_ID}) - self.handler.validate_fields(CRED_20_OFFER, INDY_OFFER) - self.handler.validate_fields(CRED_20_REQUEST, INDY_CRED_REQ) - self.handler.validate_fields(CRED_20_ISSUE, INDY_CRED) + self.handler.validate_fields(CRED_20_OFFER, ANONCREDS_OFFER) + self.handler.validate_fields(CRED_20_REQUEST, ANONCREDS_CRED_REQ) + self.handler.validate_fields(CRED_20_ISSUE, ANONCREDS_CRED) # test incorrect proposal with self.assertRaises(ValidationError): @@ -244,31 +244,31 @@ async def test_validate_fields(self): # test incorrect offer with self.assertRaises(ValidationError): - offer = INDY_OFFER.copy() + offer = ANONCREDS_OFFER.copy() offer.pop("nonce") self.handler.validate_fields(CRED_20_OFFER, offer) # test incorrect request with self.assertRaises(ValidationError): - req = INDY_CRED_REQ.copy() + req = ANONCREDS_CRED_REQ.copy() req.pop("nonce") self.handler.validate_fields(CRED_20_REQUEST, req) # test incorrect cred with self.assertRaises(ValidationError): - cred = INDY_CRED.copy() + cred = ANONCREDS_CRED.copy() cred.pop("schema_id") self.handler.validate_fields(CRED_20_ISSUE, cred) async def test_get_indy_detail_record(self): cred_ex_id = "dummy" details_indy = [ - V20CredExRecordIndy( + V20CredExRecordAnoncreds( cred_ex_id=cred_ex_id, rev_reg_id="rr-id", cred_rev_id="0", ), - V20CredExRecordIndy( + V20CredExRecordAnoncreds( cred_ex_id=cred_ex_id, rev_reg_id="rr-id", cred_rev_id="1", @@ -278,7 +278,9 @@ async def test_get_indy_detail_record(self): await details_indy[0].save(session) await details_indy[1].save(session) # exercise logger warning on get() - with mock.patch.object(INDY_LOGGER, "warning", mock.MagicMock()) as mock_warning: + with mock.patch.object( + ANONCREDS_LOGGER, "warning", mock.MagicMock() + ) as mock_warning: assert await self.handler.get_detail_record(cred_ex_id) in details_indy mock_warning.assert_called_once() @@ -354,7 +356,7 @@ async def test_create_offer(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -379,7 +381,7 @@ async def test_create_offer(self): await self.session.storage.add_record(cred_def_record) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) (cred_format, attachment) = await self.handler.create_offer(cred_proposal) @@ -390,7 +392,7 @@ async def test_create_offer(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_OFFER + assert attachment.content == ANONCREDS_OFFER # assert data is encoded as base64 assert attachment.data.base64 @@ -417,7 +419,7 @@ async def test_create_offer_no_cache(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -446,7 +448,7 @@ async def test_create_offer_no_cache(self): await self.session.storage.add_record(cred_def_record) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) (cred_format, attachment) = await self.handler.create_offer(cred_proposal) @@ -457,7 +459,7 @@ async def test_create_offer_no_cache(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_OFFER + assert attachment.content == ANONCREDS_OFFER # assert data is encoded as base64 assert attachment.data.base64 @@ -480,7 +482,7 @@ async def test_create_offer_attr_mismatch(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -509,7 +511,7 @@ async def test_create_offer_attr_mismatch(self): await self.session.storage.add_record(cred_def_record) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) with mock.patch.object( IndyLedgerRequestsExecutor, @@ -526,7 +528,7 @@ async def test_create_offer_no_matching_sent_cred_def(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -534,7 +536,7 @@ async def test_create_offer_no_matching_sent_cred_def(self): ) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) with self.assertRaises(V20CredFormatError) as context: @@ -557,11 +559,11 @@ async def test_create_request(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_ex_record = V20CredExRecord( cred_ex_id="dummy-id", @@ -574,7 +576,7 @@ async def test_create_request(self): cred_req_meta = {} self.holder.create_credential_request = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED_REQ), json.dumps(cred_req_meta)) + return_value=(json.dumps(ANONCREDS_CRED_REQ), json.dumps(cred_req_meta)) ) (cred_format, attachment) = await self.handler.create_request( @@ -582,14 +584,14 @@ async def test_create_request(self): ) self.holder.create_credential_request.assert_called_once_with( - INDY_OFFER, cred_def, holder_did + ANONCREDS_OFFER, cred_def, holder_did ) # assert identifier match assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_CRED_REQ + assert attachment.content == ANONCREDS_CRED_REQ # assert data is encoded as base64 assert attachment.data.base64 @@ -617,16 +619,18 @@ async def test_create_request_bad_state(self): with self.assertRaises(V20CredFormatError) as context: await self.handler.create_request(cred_ex_record) - assert "Indy issue credential format cannot start from credential request" in str( - context.exception + assert ( + "Anoncreds issue credential format cannot start from credential request" + in str(context.exception) ) cred_ex_record.state = None with self.assertRaises(V20CredFormatError) as context: await self.handler.create_request(cred_ex_record) - assert "Indy issue credential format cannot start from credential request" in str( - context.exception + assert ( + "Anoncreds issue credential format cannot start from credential request" + in str(context.exception) ) async def test_create_request_not_unique_x(self): @@ -658,8 +662,9 @@ async def test_receive_request_no_offer(self): with self.assertRaises(V20CredFormatError) as context: await self.handler.receive_request(cred_ex_record, cred_request_message) - assert "Indy issue credential format cannot start from credential request" in str( - context.exception + assert ( + "Anoncreds issue credential format cannot start from credential request" + in str(context.exception) ) @pytest.mark.skip(reason="Anoncreds-break") @@ -680,22 +685,22 @@ async def test_issue_credential_revocable(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -709,7 +714,7 @@ async def test_issue_credential_revocable(self): cred_rev_id = "1000" self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), cred_rev_id) + return_value=(json.dumps(ANONCREDS_CRED), cred_rev_id) ) with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc: @@ -732,8 +737,8 @@ async def test_issue_credential_revocable(self): self.issuer.create_credential.assert_called_once_with( SCHEMA, - INDY_OFFER, - INDY_CRED_REQ, + ANONCREDS_OFFER, + ANONCREDS_CRED_REQ, attr_values, REV_REG_ID, "dummy-path", @@ -743,7 +748,7 @@ async def test_issue_credential_revocable(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_CRED + assert attachment.content == ANONCREDS_CRED # assert data is encoded as base64 assert attachment.data.base64 @@ -768,22 +773,22 @@ async def test_issue_credential_non_revocable(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -796,7 +801,7 @@ async def test_issue_credential_non_revocable(self): ) self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), None) + return_value=(json.dumps(ANONCREDS_CRED), None) ) self.ledger.get_credential_definition = mock.CoroutineMock( return_value=CRED_DEF_NR @@ -816,8 +821,8 @@ async def test_issue_credential_non_revocable(self): self.issuer.create_credential.assert_called_once_with( SCHEMA, - INDY_OFFER, - INDY_CRED_REQ, + ANONCREDS_OFFER, + ANONCREDS_CRED_REQ, attr_values, None, None, @@ -827,7 +832,7 @@ async def test_issue_credential_non_revocable(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_CRED + assert attachment.content == ANONCREDS_CRED # assert data is encoded as base64 assert attachment.data.base64 @@ -867,22 +872,22 @@ async def test_issue_credential_no_active_rr_no_retries(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -895,7 +900,7 @@ async def test_issue_credential_no_active_rr_no_retries(self): ) self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), cred_rev_id) + return_value=(json.dumps(ANONCREDS_CRED), cred_rev_id) ) with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc: @@ -926,22 +931,22 @@ async def test_issue_credential_no_active_rr_retry(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -954,7 +959,7 @@ async def test_issue_credential_no_active_rr_retry(self): ) self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), cred_rev_id) + return_value=(json.dumps(ANONCREDS_CRED), cred_rev_id) ) with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc: @@ -996,22 +1001,22 @@ async def test_issue_credential_rr_full(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -1075,11 +1080,11 @@ async def test_store_credential(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_offer.assign_thread_id(thread_id) cred_request = V20CredRequest( @@ -1087,22 +1092,22 @@ async def test_store_credential(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_issue = V20CredIssue( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_ISSUE][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - credentials_attach=[AttachDecorator.data_base64(INDY_CRED, ident="0")], + credentials_attach=[AttachDecorator.data_base64(ANONCREDS_CRED, ident="0")], ) stored_cx_rec = V20CredExRecord( @@ -1141,15 +1146,19 @@ async def test_store_credential(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module, "RevocationRegistry", autospec=True - ) as mock_rev_reg, mock.patch.object( - test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module, "RevocationRegistry", autospec=True + ) as mock_rev_reg, + mock.patch.object( + test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + ): mock_rev_reg.from_definition = mock.MagicMock( return_value=mock.MagicMock( get_or_fetch_local_tails_path=mock.CoroutineMock() @@ -1167,7 +1176,7 @@ async def test_store_credential(self): self.holder.store_credential.assert_called_once_with( CRED_DEF, - INDY_CRED, + ANONCREDS_CRED, cred_req_meta, {"pic": "image/jpeg"}, credential_id=cred_id, @@ -1198,11 +1207,11 @@ async def test_store_credential_holder_store_indy_error(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_offer.assign_thread_id(thread_id) cred_request = V20CredRequest( @@ -1210,22 +1219,22 @@ async def test_store_credential_holder_store_indy_error(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_issue = V20CredIssue( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_ISSUE][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - credentials_attach=[AttachDecorator.data_base64(INDY_CRED, ident="0")], + credentials_attach=[AttachDecorator.data_base64(ANONCREDS_CRED, ident="0")], ) stored_cx_rec = V20CredExRecord( @@ -1246,11 +1255,14 @@ async def test_store_credential_holder_store_indy_error(self): side_effect=test_module.AnonCredsHolderError("Problem", {"message": "Nope"}) ) - with mock.patch.object( - test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record, mock.patch.object( - test_module.RevocationRegistry, "from_definition", mock.MagicMock() - ) as mock_rev_reg: + with ( + mock.patch.object( + test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + mock.patch.object( + test_module.RevocationRegistry, "from_definition", mock.MagicMock() + ) as mock_rev_reg, + ): mock_get_detail_record.return_value = mock.MagicMock( cred_request_metadata=cred_req_meta, save=mock.CoroutineMock(), diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py index cc5cc15f7e..a001b11d86 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py @@ -1,7 +1,7 @@ """V2.0 issue-credential base credential format handler.""" import logging -from abc import ABC, abstractclassmethod, abstractmethod +from abc import ABC, abstractmethod from typing import Mapping, Optional, Tuple from .....core.error import BaseError @@ -60,7 +60,8 @@ def get_format_identifier(self, message_type: str) -> str: def get_format_data(self, message_type: str, data: dict) -> CredFormatAttachment: """Get credential format and attachment objects for use in cred ex messages.""" - @abstractclassmethod + @classmethod + @abstractmethod def validate_fields(cls, message_type: str, attachment_data: dict) -> None: """Validate attachment data for specific message type and format.""" diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py index ecadd98539..19a2857cf3 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py @@ -7,6 +7,7 @@ from marshmallow import RAISE +from ......askar.profile_anon import AskarAnoncredsProfile from ......cache.base import BaseCache from ......core.profile import Profile from ......indy.holder import IndyHolder, IndyHolderError @@ -14,7 +15,6 @@ from ......indy.models.cred import IndyCredentialSchema from ......indy.models.cred_abstract import IndyCredAbstractSchema from ......indy.models.cred_request import IndyCredRequestSchema -from ......ledger.base import BaseLedger from ......ledger.multiple_ledger.ledger_requests_executor import ( GET_CRED_DEF, GET_SCHEMA, @@ -105,10 +105,6 @@ async def get_detail_record(self, cred_ex_id: str) -> V20CredExRecordIndy: session, cred_ex_id ) - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return await self.anoncreds_handler.get_detail_record(cred_ex_id) - if len(records) > 1: LOGGER.warning( "Cred ex id %s has %d %s detail records: should be 1", @@ -140,9 +136,6 @@ def get_format_identifier(self, message_type: str) -> str: str: Issue credential attachment format identifier """ - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_identifier(message_type) return ATTACHMENT_FORMAT[message_type][IndyCredFormatHandler.format.api] @@ -162,9 +155,6 @@ def get_format_data(self, message_type: str, data: dict) -> CredFormatAttachment CredFormatAttachment: Credential format and attachment data objects """ - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_data(message_type, data) return ( V20CredFormat( @@ -192,7 +182,7 @@ async def create_proposal( self, cred_ex_record: V20CredExRecord, proposal_data: Mapping[str, str] ) -> Tuple[V20CredFormat, AttachDecorator]: """Create indy credential proposal.""" - # Temporary shim while the new anoncreds library integration is in progress + # Create the proposal with the anoncreds handler if agent is anoncreds capable if self.anoncreds_handler: return await self.anoncreds_handler.create_proposal( cred_ex_record, @@ -217,12 +207,12 @@ async def create_offer( ) -> CredFormatAttachment: """Create indy credential offer.""" - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return await self.anoncreds_handler.create_offer(cred_proposal_message) + if isinstance(self.profile, AskarAnoncredsProfile): + raise V20CredFormatError( + "This issuer is anoncreds capable. Please use the anonreds format." + ) issuer = self.profile.inject(IndyIssuer) - ledger = self.profile.inject(BaseLedger) cache = self.profile.inject_or(BaseCache) cred_def_id = await self._match_sent_cred_def_id( @@ -275,11 +265,38 @@ async def receive_offer( ) -> None: """Receive indy credential offer.""" + async def create_cred_request_result(self, cred_offer, holder_did, cred_def_id): + """Create credential request result.""" + multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) + else: + ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) + ledger = ( + await ledger_exec_inst.get_ledger_for_identifier( + cred_def_id, + txn_record_type=GET_CRED_DEF, + ) + )[1] + async with ledger: + cred_def = await ledger.get_credential_definition(cred_def_id) + + holder = self.profile.inject(IndyHolder) + request_json, metadata_json = await holder.create_credential_request( + cred_offer, cred_def, holder_did + ) + + return { + "request": json.loads(request_json), + "metadata": json.loads(metadata_json), + } + async def create_request( self, cred_ex_record: V20CredExRecord, request_data: Optional[Mapping] = None ) -> CredFormatAttachment: """Create indy credential request.""" - # Temporary shim while the new anoncreds library integration is in progress + + # Create the request with the anoncreds handler if agent is anoncreds capable if self.anoncreds_handler: return await self.anoncreds_handler.create_request( cred_ex_record, @@ -302,31 +319,6 @@ async def create_request( nonce = cred_offer["nonce"] cred_def_id = cred_offer["cred_def_id"] - async def _create(): - multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) - if multitenant_mgr: - ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) - else: - ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) - ledger = ( - await ledger_exec_inst.get_ledger_for_identifier( - cred_def_id, - txn_record_type=GET_CRED_DEF, - ) - )[1] - async with ledger: - cred_def = await ledger.get_credential_definition(cred_def_id) - - holder = self.profile.inject(IndyHolder) - request_json, metadata_json = await holder.create_credential_request( - cred_offer, cred_def, holder_did - ) - - return { - "request": json.loads(request_json), - "metadata": json.loads(metadata_json), - } - cache_key = f"credential_request::{cred_def_id}::{holder_did}::{nonce}" cred_req_result = None cache = self.profile.inject_or(BaseCache) @@ -335,10 +327,14 @@ async def _create(): if entry.result: cred_req_result = entry.result else: - cred_req_result = await _create() + cred_req_result = await self.create_cred_request_result( + cred_offer, holder_did, cred_def_id + ) await entry.set_result(cred_req_result, 3600) if not cred_req_result: - cred_req_result = await _create() + cred_req_result = await self.create_cred_request_result( + cred_offer, holder_did, cred_def_id + ) detail_record = V20CredExRecordIndy( cred_ex_id=cred_ex_record.cred_ex_id, @@ -354,7 +350,7 @@ async def receive_request( self, cred_ex_record: V20CredExRecord, cred_request_message: V20CredRequest ) -> None: """Receive indy credential request.""" - # Temporary shim while the new anoncreds library integration is in progress + # Receive the request with the anoncreds handler if agent is anoncreds capable if self.anoncreds_handler: return await self.anoncreds_handler.receive_request( cred_ex_record, @@ -445,9 +441,11 @@ async def issue_credential( await self._check_uniqueness(cred_ex_record.cred_ex_id) cred_offer = cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format) + from ..anoncreds.handler import AnonCredsCredFormatHandler + cred_request = cred_ex_record.cred_request.attachment( IndyCredFormatHandler.format - ) + ) or cred_ex_record.cred_request.attachment(AnonCredsCredFormatHandler.format) cred_values = cred_ex_record.cred_offer.credential_preview.attr_dict(decode=False) schema_id = cred_offer["schema_id"] cred_def_id = cred_offer["cred_def_id"] @@ -517,10 +515,14 @@ async def store_credential( ) -> None: """Store indy credential.""" # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: + if hasattr(self, "anoncreds_handler") and self.anoncreds_handler: return await self.anoncreds_handler.store_credential(cred_ex_record, cred_id) - cred = cred_ex_record.cred_issue.attachment(IndyCredFormatHandler.format) + from ..anoncreds.handler import AnonCredsCredFormatHandler + + cred = cred_ex_record.cred_issue.attachment( + IndyCredFormatHandler.format + ) or cred_ex_record.cred_issue.attachment(AnonCredsCredFormatHandler.format) rev_reg_def = None multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py index 91c80e2b7a..78bd346d02 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py @@ -1132,15 +1132,19 @@ async def test_store_credential(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module, "RevocationRegistry", autospec=True - ) as mock_rev_reg, mock.patch.object( - test_module.IndyCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module, "RevocationRegistry", autospec=True + ) as mock_rev_reg, + mock.patch.object( + test_module.IndyCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + ): mock_rev_reg.from_definition = mock.MagicMock( return_value=mock.MagicMock( get_or_fetch_local_tails_path=mock.CoroutineMock() @@ -1236,11 +1240,14 @@ async def test_store_credential_holder_store_indy_error(self): side_effect=test_module.IndyHolderError("Problem", {"message": "Nope"}) ) - with mock.patch.object( - test_module.IndyCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record, mock.patch.object( - test_module.RevocationRegistry, "from_definition", mock.MagicMock() - ) as mock_rev_reg: + with ( + mock.patch.object( + test_module.IndyCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + mock.patch.object( + test_module.RevocationRegistry, "from_definition", mock.MagicMock() + ) as mock_rev_reg, + ): mock_get_detail_record.return_value = mock.MagicMock( cred_request_metadata=cred_req_meta, save=mock.CoroutineMock(), diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py index 9d74382d8d..7a9b1ca549 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py @@ -6,8 +6,8 @@ from .......messaging.models.base import BaseModel, BaseModelSchema from .......messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, UUID4_EXAMPLE, ) @@ -109,13 +109,13 @@ class Meta: created = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "The date and time of the proof (with a maximum accuracy in seconds)." " Defaults to current system time" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py index 2b2e948adb..33a92abbc9 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py @@ -255,12 +255,13 @@ async def test_receive_proposal(self): await self.handler.receive_proposal(cred_ex_record, cred_proposal_message) async def test_create_offer(self): - with mock.patch.object( - VcLdpManager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ) as mock_can_issue, patch.object( - test_module, "get_properties_without_context", return_value=[] + with ( + mock.patch.object( + VcLdpManager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ) as mock_can_issue, + patch.object(test_module, "get_properties_without_context", return_value=[]), ): (cred_format, attachment) = await self.handler.create_offer( self.cred_proposal @@ -295,11 +296,14 @@ async def test_create_offer_adds_bbs_context(self): ], ) - with mock.patch.object( - VcLdpManager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ), patch.object(test_module, "get_properties_without_context", return_value=[]): + with ( + mock.patch.object( + VcLdpManager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ), + patch.object(test_module, "get_properties_without_context", return_value=[]), + ): (cred_format, attachment) = await self.handler.create_offer(cred_proposal) # assert BBS url added to context @@ -320,11 +324,14 @@ async def test_create_offer_adds_ed25519_2020_context(self): ], ) - with mock.patch.object( - VcLdpManager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ), patch.object(test_module, "get_properties_without_context", return_value=[]): + with ( + mock.patch.object( + VcLdpManager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ), + patch.object(test_module, "get_properties_without_context", return_value=[]), + ): (cred_format, attachment) = await self.handler.create_offer(cred_proposal) # assert BBS url added to context @@ -342,15 +349,19 @@ async def test_create_offer_x_no_proposal(self): async def test_create_offer_x_wrong_attributes(self): missing_properties = ["foo"] - with mock.patch.object( - self.manager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ), patch.object( - test_module, - "get_properties_without_context", - return_value=missing_properties, - ), self.assertRaises(LinkedDataProofException) as context: + with ( + mock.patch.object( + self.manager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ), + patch.object( + test_module, + "get_properties_without_context", + return_value=missing_properties, + ), + self.assertRaises(LinkedDataProofException) as context, + ): await self.handler.create_offer(self.cred_proposal) assert ( @@ -885,17 +896,24 @@ async def test_store_credential_x_not_verified(self): cred_id = "cred_id" self.holder.store_credential = mock.CoroutineMock() - with mock.patch.object( - self.manager, - "_get_suite", - mock.CoroutineMock(), - ), mock.patch.object( - self.manager, - "verify_credential", - mock.CoroutineMock(return_value=DocumentVerificationResult(verified=False)), - ), mock.patch.object( - self.manager, - "_get_proof_purpose", - ), self.assertRaises(V20CredFormatError) as context: + with ( + mock.patch.object( + self.manager, + "_get_suite", + mock.CoroutineMock(), + ), + mock.patch.object( + self.manager, + "verify_credential", + mock.CoroutineMock( + return_value=DocumentVerificationResult(verified=False) + ), + ), + mock.patch.object( + self.manager, + "_get_proof_purpose", + ), + self.assertRaises(V20CredFormatError) as context, + ): await self.handler.store_credential(cred_ex_record, cred_id) assert "Received invalid credential: " in str(context.exception) diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py index ae8f23fa69..3ff75a5119 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py @@ -9,11 +9,11 @@ from .......anoncreds.holder import AnonCredsHolder, AnonCredsHolderError from .......anoncreds.issuer import AnonCredsIssuer -from .......anoncreds.models.anoncreds_cred_def import ( +from .......anoncreds.models.credential_definition import ( CredDef, GetCredDefResult, ) -from .......anoncreds.models.anoncreds_revocation import ( +from .......anoncreds.models.revocation import ( GetRevRegDefResult, RevRegDef, ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py index b87034e70c..ccd1a854e2 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py @@ -109,11 +109,14 @@ async def test_called_auto_request_x_indy(self): handler = test_module.V20CredOfferHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() @@ -145,11 +148,14 @@ async def test_called_auto_request_x_anoncreds(self): handler = test_module.V20CredOfferHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py index 8ece39bf7b..a901018d08 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py @@ -86,11 +86,14 @@ async def test_called_auto_offer_x_indy(self): handler = test_module.V20CredProposalHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() @@ -115,11 +118,14 @@ async def test_called_auto_offer_x_anoncreds(self): handler = test_module.V20CredProposalHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py index 3fc7571b62..f2d9763e0f 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py @@ -102,10 +102,11 @@ async def test_called_auto_issue_x_indy(self): ) request_context.injector.bind_instance(OobMessageProcessor, mock_oob_processor) - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - cred_ex_rec, "save_error_state", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(cred_ex_rec, "save_error_state", mock.CoroutineMock()), ): mock_cred_mgr.return_value.receive_request = mock.CoroutineMock( return_value=cred_ex_rec @@ -120,11 +121,14 @@ async def test_called_auto_issue_x_indy(self): handler = test_module.V20CredRequestHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() @@ -142,10 +146,11 @@ async def test_called_auto_issue_x_anoncreds(self): ) request_context.injector.bind_instance(OobMessageProcessor, mock_oob_processor) - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - cred_ex_rec, "save_error_state", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(cred_ex_rec, "save_error_state", mock.CoroutineMock()), ): mock_cred_mgr.return_value.receive_request = mock.CoroutineMock( return_value=cred_ex_rec @@ -160,11 +165,14 @@ async def test_called_auto_issue_x_anoncreds(self): handler = test_module.V20CredRequestHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/manager.py b/acapy_agent/protocols/issue_credential/v2_0/manager.py index 068f94a4bd..124e832c47 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/manager.py +++ b/acapy_agent/protocols/issue_credential/v2_0/manager.py @@ -591,8 +591,14 @@ async def receive_credential( ] handled_formats = [] - # check that we didn't receive any formats not present in the request - if set(issue_formats) - set(req_formats): + def _check_formats(): + """Allow indy issue fomat and anoncreds req format or matching formats.""" + return ( + issue_formats == [V20CredFormat.Format.INDY] + and req_formats == [V20CredFormat.Format.ANONCREDS] + ) or len(set(issue_formats) - set(req_formats)) == 0 + + if not _check_formats(): raise V20CredManagerError( "Received issue credential format(s) not present in credential " f"request: {set(issue_formats) - set(req_formats)}" diff --git a/acapy_agent/protocols/issue_credential/v2_0/message_types.py b/acapy_agent/protocols/issue_credential/v2_0/message_types.py index 668d2b7332..e34ce0385d 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/message_types.py +++ b/acapy_agent/protocols/issue_credential/v2_0/message_types.py @@ -37,21 +37,25 @@ # Format specifications ATTACHMENT_FORMAT = { CRED_20_PROPOSAL: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-filter@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred-filter@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc@v0.1", }, CRED_20_OFFER: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-abstract@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred-abstract@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc-offer@v0.1", }, CRED_20_REQUEST: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-req@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred-req@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc-request@v0.1", }, CRED_20_ISSUE: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc@v0.1", diff --git a/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py b/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py index 0574d4736d..589dfcf579 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py +++ b/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py @@ -11,6 +11,7 @@ from .....messaging.models.base import BaseModel, BaseModelSchema from .....messaging.valid import UUID4_EXAMPLE from .....utils.classloader import DeferLoad +from ..models.detail.anoncreds import V20CredExRecordAnoncreds from ..models.detail.indy import V20CredExRecordIndy from ..models.detail.ld_proof import V20CredExRecordLDProof @@ -31,6 +32,14 @@ class Meta: class Format(Enum): """Attachment format.""" + ANONCREDS = FormatSpec( + "anoncreds/", + V20CredExRecordAnoncreds, + DeferLoad( + "acapy_agent.protocols.issue_credential.v2_0" + ".formats.anoncreds.handler.AnonCredsCredFormatHandler" + ), + ) INDY = FormatSpec( "hlindy/", V20CredExRecordIndy, @@ -39,23 +48,6 @@ class Format(Enum): ".formats.indy.handler.IndyCredFormatHandler" ), ) - """ - Once we switch to anoncreds this will replace the above INDY definition. - - In the meantime there are some hardcoded references in the - "...formats.indy.handler.IndyCredFormatHandler" class. - - :: - - INDY = FormatSpec( - "hlindy/", - V20CredExRecordIndy, - DeferLoad( - "acapy_agent.protocols.issue_credential.v2_0" - ".formats.anoncreds.handler.AnonCredsCredFormatHandler" - ), - ) - """ LD_PROOF = FormatSpec( "aries/", V20CredExRecordLDProof, @@ -97,7 +89,9 @@ def aries(self) -> str: return self.value.aries @property - def detail(self) -> Union[V20CredExRecordIndy, V20CredExRecordLDProof]: + def detail( + self, + ) -> Union[V20CredExRecordIndy, V20CredExRecordLDProof, V20CredExRecordAnoncreds]: """Accessor for credential exchange detail class.""" return self.value.detail diff --git a/acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py b/acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py new file mode 100644 index 0000000000..f683ff68ca --- /dev/null +++ b/acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py @@ -0,0 +1,131 @@ +"""Anoncreds specific credential exchange information with non-secrets storage.""" + +from typing import Any, Mapping, Optional, Sequence + +from marshmallow import EXCLUDE, fields + +from ......core.profile import ProfileSession +from ......messaging.models.base_record import BaseRecord, BaseRecordSchema +from ......messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_REV_REG_ID_EXAMPLE, + UUID4_EXAMPLE, +) +from .. import UNENCRYPTED_TAGS + + +class V20CredExRecordAnoncreds(BaseRecord): + """Credential exchange anoncreds detail record.""" + + class Meta: + """V20CredExRecordAnoncreds metadata.""" + + schema_class = "V20CredExRecordAnoncredsSchema" + + RECORD_ID_NAME = "cred_ex_anoncreds_id" + RECORD_TYPE = "anoncreds_cred_ex_v20" + TAG_NAMES = {"~cred_ex_id"} if UNENCRYPTED_TAGS else {"cred_ex_id"} + RECORD_TOPIC = "issue_credential_v2_0_anoncreds" + + def __init__( + self, + cred_ex_anoncreds_id: Optional[str] = None, + *, + cred_ex_id: Optional[str] = None, + cred_id_stored: Optional[str] = None, + cred_request_metadata: Optional[Mapping] = None, + rev_reg_id: Optional[str] = None, + cred_rev_id: Optional[str] = None, + **kwargs, + ): + """Initialize anoncreds credential exchange record details.""" + super().__init__(cred_ex_anoncreds_id, **kwargs) + + self.cred_ex_id = cred_ex_id + self.cred_id_stored = cred_id_stored + self.cred_request_metadata = cred_request_metadata + self.rev_reg_id = rev_reg_id + self.cred_rev_id = cred_rev_id + + @property + def cred_ex_anoncreds_id(self) -> str: + """Accessor for the ID associated with this exchange.""" + return self._id + + @property + def record_value(self) -> dict: + """Accessor for the JSON record value generated for this credential exchange.""" + return { + prop: getattr(self, prop) + for prop in ( + "cred_id_stored", + "cred_request_metadata", + "rev_reg_id", + "cred_rev_id", + ) + } + + @classmethod + async def query_by_cred_ex_id( + cls, + session: ProfileSession, + cred_ex_id: str, + ) -> Sequence["V20CredExRecordAnoncreds"]: + """Retrieve credential exchange anoncreds detail record(s) by its cred ex id.""" + return await cls.query( + session=session, + tag_filter={"cred_ex_id": cred_ex_id}, + ) + + def __eq__(self, other: Any) -> bool: + """Comparison between records.""" + return super().__eq__(other) + + +class V20CredExRecordAnoncredsSchema(BaseRecordSchema): + """Credential exchange anoncreds detail record detail schema.""" + + class Meta: + """Credential exchange anoncreds detail record schema metadata.""" + + model_class = V20CredExRecordAnoncreds + unknown = EXCLUDE + + cred_ex_anoncreds_id = fields.Str( + required=False, + metadata={"description": "Record identifier", "example": UUID4_EXAMPLE}, + ) + cred_ex_id = fields.Str( + required=False, + metadata={ + "description": "Corresponding v2.0 credential exchange record identifier", + "example": UUID4_EXAMPLE, + }, + ) + cred_id_stored = fields.Str( + required=False, + metadata={ + "description": "Credential identifier stored in wallet", + "example": UUID4_EXAMPLE, + }, + ) + cred_request_metadata = fields.Dict( + required=False, + metadata={"description": "Credential request metadata for anoncreds holder"}, + ) + rev_reg_id = fields.Str( + required=False, + metadata={ + "description": "Revocation registry identifier", + "example": ANONCREDS_REV_REG_ID_EXAMPLE, + }, + ) + cred_rev_id = fields.Str( + required=False, + metadata={ + "description": ( + "Credential revocation identifier within revocation registry" + ), + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py b/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py index a3ef8a756d..b7fdaa2e7b 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py +++ b/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py @@ -125,11 +125,12 @@ async def test_save_error_state(self): record.state = V20CredExRecord.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="test") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/routes.py b/acapy_agent/protocols/issue_credential/v2_0/routes.py index 7e3c2f20fb..1c06a4e572 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/routes.py @@ -31,14 +31,16 @@ get_paginated_query_params, ) from ....messaging.valid import ( + ANONCREDS_DID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, ) @@ -135,6 +137,36 @@ class V20CredStoreRequestSchema(OpenAPISchema): credential_id = fields.Str(required=False) +class V20CredFilterAnoncredsSchema(OpenAPISchema): + """Anoncreds credential filtration criteria.""" + + cred_def_id = fields.Str( + required=False, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_DID_EXAMPLE, + }, + ) + schema_id = fields.Str( + required=False, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + issuer_id = fields.Str( + required=False, + metadata={ + "description": "Credential issuer DID", + "example": ANONCREDS_DID_EXAMPLE, + }, + ) + epoch = fields.Str( + required=False, + metadata={"description": "Credential epoch time", "example": "2021-08-24"}, + ) + + class V20CredFilterIndySchema(OpenAPISchema): """Indy credential filtration criteria.""" @@ -165,8 +197,11 @@ class V20CredFilterIndySchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, @@ -205,8 +240,11 @@ class V20CredFilterVCDISchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, @@ -218,6 +256,11 @@ class V20CredFilterVCDISchema(OpenAPISchema): class V20CredFilterSchema(OpenAPISchema): """Credential filtration criteria.""" + anoncreds = fields.Nested( + V20CredFilterAnoncredsSchema, + required=False, + metadata={"description": "Credential filter for anoncreds"}, + ) indy = fields.Nested( V20CredFilterIndySchema, required=False, @@ -951,11 +994,17 @@ async def _create_free_offer( ) cred_manager = V20CredManager(profile) - (cred_ex_record, cred_offer_message) = await cred_manager.create_offer( - cred_ex_record, - comment=comment, - replacement_id=replacement_id, - ) + try: + (cred_ex_record, cred_offer_message) = await cred_manager.create_offer( + cred_ex_record, + comment=comment, + replacement_id=replacement_id, + ) + except ValueError as err: + LOGGER.exception(f"Error creating credential offer: {err}") + async with profile.session() as session: + await cred_ex_record.save_error_state(session, reason=err) + raise web.HTTPBadRequest(reason=err) return (cred_ex_record, cred_offer_message) diff --git a/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py b/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py index 65062ad5ea..015033925e 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py +++ b/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py @@ -145,11 +145,10 @@ async def test_create_proposal(self): ) ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_proposal = mock.CoroutineMock( return_value=( V20CredFormat( @@ -186,11 +185,10 @@ async def test_create_proposal_no_preview(self): connection_id = "test_conn_id" comment = "comment" - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_proposal = mock.CoroutineMock( return_value=( V20CredFormat( @@ -236,11 +234,10 @@ async def test_receive_proposal(self): ) ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_proposal = mock.CoroutineMock() cred_proposal = V20CredProposal( @@ -308,11 +305,10 @@ async def test_create_free_offer(self): cred_proposal=cred_proposal, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_offer = mock.CoroutineMock( return_value=( V20CredFormat( @@ -384,11 +380,10 @@ async def test_create_bound_offer(self): cred_proposal=cred_proposal, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_offer = mock.CoroutineMock( return_value=( V20CredFormat( @@ -492,15 +487,15 @@ async def test_receive_offer_proposed(self): thread_id=thread_id, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, - "retrieve_by_conn_and_thread", - mock.CoroutineMock(return_value=stored_cx_rec), - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, + "retrieve_by_conn_and_thread", + mock.CoroutineMock(return_value=stored_cx_rec), + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_offer = mock.CoroutineMock() cx_rec = await self.manager.receive_offer(cred_offer, connection_id) @@ -549,13 +544,13 @@ async def test_receive_free_offer(self): self.context.conn_record = mock.MagicMock() self.context.conn_record.connection_id = connection_id - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_offer = mock.CoroutineMock() mock_retrieve.side_effect = (StorageNotFoundError(),) cx_rec = await self.manager.receive_offer(cred_offer, connection_id) @@ -602,11 +597,10 @@ async def test_create_bound_request(self): self.cache = InMemoryCache() self.context.injector.bind_instance(BaseCache, self.cache) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_request = mock.CoroutineMock( return_value=( V20CredFormat( @@ -689,11 +683,10 @@ async def test_create_free_request(self): self.cache = InMemoryCache() self.context.injector.bind_instance(BaseCache, self.cache) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_request = mock.CoroutineMock( return_value=( V20CredFormat( @@ -754,13 +747,13 @@ async def test_receive_request(self): requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_retrieve.side_effect = (StorageNotFoundError(),) mock_handler.return_value.receive_request = mock.CoroutineMock() @@ -799,13 +792,13 @@ async def test_receive_request_no_connection_cred_request(self): mock_conn = mock.MagicMock(connection_id="test_conn_id") mock_oob = mock.MagicMock() - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_retrieve.return_value = stored_cx_rec mock_handler.return_value.receive_request = mock.CoroutineMock() @@ -834,11 +827,13 @@ async def test_receive_request_no_cred_ex_with_offer_found(self): requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], ) - with mock.patch.object(V20CredExRecord, "save", autospec=True), mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True), + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_retrieve.side_effect = (StorageNotFoundError(),) mock_handler.return_value.receive_request = mock.CoroutineMock() @@ -926,11 +921,10 @@ async def test_issue_credential_indy(self): ) self.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.issue_credential = mock.CoroutineMock( return_value=( V20CredFormat( @@ -1033,11 +1027,10 @@ async def test_issue_credential_anoncreds(self): ) self.context.injector.bind_instance(AnonCredsIssuer, issuer) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.issue_credential = mock.CoroutineMock( return_value=( V20CredFormat( @@ -1139,15 +1132,15 @@ async def test_receive_cred(self): credentials_attach=[AttachDecorator.data_base64(INDY_CRED, ident="0")], ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, - "retrieve_by_conn_and_thread", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, + "retrieve_by_conn_and_thread", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_credential = mock.CoroutineMock() mock_retrieve.return_value = stored_cx_rec ret_cx_rec = await self.manager.receive_credential( @@ -1282,13 +1275,13 @@ async def test_store_credential(self): thread_id=thread_id, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - test_module.V20CredManager, "delete_cred_ex_record", autospec=True - ) as mock_delete, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + test_module.V20CredManager, "delete_cred_ex_record", autospec=True + ) as mock_delete, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.store_credential = mock.CoroutineMock() ret_cx_rec = await self.manager.store_credential( @@ -1329,15 +1322,18 @@ async def test_send_cred_ack(self): auto_remove=True, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save_ex, mock.patch.object( - V20CredExRecord, "delete_record", autospec=True - ) as mock_delete_ex, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exception, mock.patch.object( - test_module.LOGGER, "warning", mock.MagicMock() - ) as mock_log_warning: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save_ex, + mock.patch.object( + V20CredExRecord, "delete_record", autospec=True + ) as mock_delete_ex, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exception, + mock.patch.object( + test_module.LOGGER, "warning", mock.MagicMock() + ) as mock_log_warning, + ): mock_delete_ex.side_effect = test_module.StorageError() (_, ack) = await self.manager.send_cred_ack(stored_exchange) assert ack._thread @@ -1361,15 +1357,18 @@ async def test_receive_cred_ack(self): ack = V20CredAck() - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "delete_record", autospec=True - ) as mock_delete, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.V20CredManager, "delete_cred_ex_record", autospec=True - ) as mock_delete: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "delete_record", autospec=True + ) as mock_delete, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object( + test_module.V20CredManager, "delete_cred_ex_record", autospec=True + ) as mock_delete, + ): mock_retrieve.return_value = stored_cx_rec ret_cx_rec = await self.manager.receive_credential_ack( ack, @@ -1386,13 +1385,15 @@ async def test_delete_cred_ex_record(self): stored_cx_rec = mock.MagicMock(delete_record=mock.CoroutineMock()) stored_indy = mock.MagicMock(delete_record=mock.CoroutineMock()) - with mock.patch.object( - V20CredExRecord, "delete_record", autospec=True - ), mock.patch.object( - V20CredExRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module, "V20CredFormat", mock.MagicMock() - ) as mock_cred_format: + with ( + mock.patch.object(V20CredExRecord, "delete_record", autospec=True), + mock.patch.object( + V20CredExRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object( + test_module, "V20CredFormat", mock.MagicMock() + ) as mock_cred_format, + ): mock_retrieve.return_value = stored_cx_rec mock_cred_format.Format = [ mock.MagicMock( @@ -1428,13 +1429,14 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20CredExRecord, - "retrieve_by_conn_and_thread", - mock.CoroutineMock(), - ) as retrieve_ex: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20CredExRecord, + "retrieve_by_conn_and_thread", + mock.CoroutineMock(), + ) as retrieve_ex, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_problem_report( diff --git a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py index 5ca0854086..9e3663d5ed 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py @@ -135,11 +135,12 @@ async def test_credential_exchange_list_x(self): async def test_credential_exchange_retrieve(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -149,9 +150,10 @@ async def test_credential_exchange_retrieve(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ - mock.MagicMock( # indy + mock.MagicMock( # anoncreds serialize=mock.MagicMock(return_value={"...": "..."}) ), + None, # indy None, # ld_proof None, # vc_di ] @@ -162,7 +164,8 @@ async def test_credential_exchange_retrieve(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, - "indy": {"...": "..."}, + "anoncreds": {"...": "..."}, + "indy": None, "ld_proof": None, "vc_di": None, } @@ -171,11 +174,12 @@ async def test_credential_exchange_retrieve(self): async def test_credential_exchange_retrieve_indy_ld_proof(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -185,6 +189,9 @@ async def test_credential_exchange_retrieve_indy_ld_proof(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ + mock.MagicMock( # anoncreds + serialize=mock.MagicMock(return_value={"anon": "creds"}) + ), mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"in": "dy"}) ), @@ -202,6 +209,7 @@ async def test_credential_exchange_retrieve_indy_ld_proof(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": {"anon": "creds"}, "indy": {"in": "dy"}, "ld_proof": {"ld": "proof"}, "vc_di": {"vc": "di"}, @@ -225,11 +233,12 @@ async def test_credential_exchange_retrieve_not_found(self): async def test_credential_exchange_retrieve_x(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -248,13 +257,14 @@ async def test_credential_exchange_retrieve_x(self): async def test_credential_exchange_create(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -277,13 +287,14 @@ async def test_credential_exchange_create(self): async def test_credential_exchange_create_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -317,13 +328,14 @@ async def test_credential_exchange_create_no_filter(self): async def test_credential_exchange_send(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -347,17 +359,19 @@ async def test_credential_exchange_send_request_no_conn_no_holder_did(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "OobRecord", autospec=True - ) as mock_oob_rec, mock.patch.object( - test_module, "default_did_from_verkey", autospec=True - ) as mock_default_did_from_verkey, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "OobRecord", autospec=True) as mock_oob_rec, + mock.patch.object( + test_module, "default_did_from_verkey", autospec=True + ) as mock_default_did_from_verkey, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_oob_rec.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock.MagicMock(our_recipient_key="our-recipient_key") ) @@ -397,11 +411,12 @@ async def test_credential_exchange_send_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -427,11 +442,12 @@ async def test_credential_exchange_send_not_ready(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): mock_conn_rec.retrieve_by_id.return_value.is_ready = False mock_cred_mgr.return_value.create_offer.return_value = ( @@ -445,12 +461,12 @@ async def test_credential_exchange_send_not_ready(self): async def test_credential_exchange_send_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -487,13 +503,13 @@ async def test_credential_exchange_send_proposal(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cx_rec = mock.MagicMock() mock_cred_mgr.return_value.create_proposal.return_value = mock_cx_rec @@ -519,12 +535,12 @@ async def test_credential_exchange_send_proposal_no_filter(self): async def test_credential_exchange_send_proposal_no_conn_record(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( @@ -548,11 +564,12 @@ async def test_credential_exchange_send_proposal_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): mock_cx_rec = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -565,12 +582,12 @@ async def test_credential_exchange_send_proposal_x(self): async def test_credential_exchange_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() @@ -593,13 +610,13 @@ async def test_credential_exchange_create_free_offer(self): ) self.context.update_settings({"debug.auto_respond_credential_offer": True}) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -636,11 +653,12 @@ async def test_credential_exchange_create_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): mock_cx_rec = mock.MagicMock( serialize=mock.MagicMock( side_effect=test_module.BaseModelError(), @@ -669,13 +687,13 @@ async def test_credential_exchange_send_free_offer(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -707,13 +725,13 @@ async def test_credential_exchange_send_free_offer_vcdi(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): # Mock the creation of a credential offer, especially for handling VC-DI mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() @@ -753,11 +771,12 @@ async def test_credential_exchange_send_free_offer_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -783,11 +802,12 @@ async def test_credential_exchange_send_free_offer_not_ready(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -812,11 +832,13 @@ async def test_credential_exchange_send_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_cx_rec = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -837,15 +859,16 @@ async def test_credential_exchange_send_bound_offer(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_PROPOSAL_RECEIVED @@ -868,13 +891,16 @@ async def test_credential_exchange_send_bound_offer_linked_data_error(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_PROPOSAL_RECEIVED @@ -910,13 +936,15 @@ async def test_credential_exchange_send_bound_offer_no_conn_record(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock( @@ -963,13 +991,15 @@ async def test_credential_exchange_send_bound_offer_not_ready(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -994,15 +1024,16 @@ async def test_credential_exchange_send_request(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_OFFER_RECEIVED @@ -1038,13 +1069,15 @@ async def test_credential_exchange_send_request_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1071,13 +1104,15 @@ async def test_credential_exchange_send_request_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1105,13 +1140,13 @@ async def test_credential_exchange_send_free_request(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_request = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() @@ -1139,11 +1174,12 @@ async def test_credential_exchange_send_free_request_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -1165,11 +1201,12 @@ async def test_credential_exchange_send_free_request_not_ready(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -1190,11 +1227,13 @@ async def test_credential_exchange_send_free_request_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_mgr.return_value.create_request = mock.CoroutineMock( side_effect=[ test_module.LedgerError(), @@ -1211,17 +1250,17 @@ async def test_credential_exchange_issue(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_REQUEST_RECEIVED @@ -1230,9 +1269,10 @@ async def test_credential_exchange_issue(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ - mock.MagicMock( # indy + mock.MagicMock( # anoncreds serialize=mock.MagicMock(return_value={"...": "..."}) ), + None, None, # ld_proof None, # vc_di ] @@ -1248,7 +1288,8 @@ async def test_credential_exchange_issue(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, - "indy": {"...": "..."}, + "anoncreds": {"...": "..."}, + "indy": None, "ld_proof": None, "vc_di": None, } @@ -1258,17 +1299,17 @@ async def test_credential_exchange_issue_vcdi(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_REQUEST_RECEIVED @@ -1277,7 +1318,8 @@ async def test_credential_exchange_issue_vcdi(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ - None, + None, # anoncreds + None, # indy None, # ld_proof mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"...": "..."}) @@ -1295,6 +1337,7 @@ async def test_credential_exchange_issue_vcdi(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": None, "indy": None, "ld_proof": None, "vc_di": {"...": "..."}, @@ -1325,13 +1368,15 @@ async def test_credential_exchange_issue_no_conn_record(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec.state = mock_cx_rec_cls.STATE_REQUEST_RECEIVED mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) @@ -1353,13 +1398,15 @@ async def test_credential_exchange_issue_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.retrieve_by_id = mock.CoroutineMock() mock_cx_rec.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_REQUEST_RECEIVED @@ -1387,13 +1434,15 @@ async def test_credential_exchange_issue_rev_reg_full_indy(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec.state = mock_cx_rec_cls.STATE_REQUEST_RECEIVED mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) @@ -1417,13 +1466,15 @@ async def test_credential_exchange_issue_rev_reg_full_anoncreds(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec.state = mock_cx_rec_cls.STATE_REQUEST_RECEIVED mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) @@ -1449,13 +1500,15 @@ async def test_credential_exchange_issue_deser_x(self): mock_conn_rec = mock.MagicMock(ConnRecord, autospec=True) mock_conn_rec.retrieve_by_id = mock.CoroutineMock(return_value=ConnRecord()) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) mock_cred_mgr.return_value = mock.MagicMock( issue_credential=mock.CoroutineMock( @@ -1481,23 +1534,24 @@ async def test_credential_exchange_store(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_CREDENTIAL_RECEIVED ) mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ + None, # anoncreds mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"...": "..."}) ), @@ -1519,6 +1573,7 @@ async def test_credential_exchange_store(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": None, "indy": {"...": "..."}, "ld_proof": None, "vc_di": None, @@ -1531,19 +1586,22 @@ async def test_credential_exchange_store_bad_cred_id_json(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - LDProofCredFormatHandler, "get_detail_record", autospec=True - ) as mock_ld_proof_get_detail_record, mock.patch.object( - IndyCredFormatHandler, "get_detail_record", autospec=True - ) as mock_indy_get_detail_record: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + LDProofCredFormatHandler, "get_detail_record", autospec=True + ) as mock_ld_proof_get_detail_record, + mock.patch.object( + IndyCredFormatHandler, "get_detail_record", autospec=True + ) as mock_indy_get_detail_record, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_CREDENTIAL_RECEIVED @@ -1575,6 +1633,7 @@ async def test_credential_exchange_store_bad_cred_id_json(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": None, "indy": {"...": "..."}, "ld_proof": None, "vc_di": None, @@ -1600,13 +1659,15 @@ async def test_credential_exchange_store_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock( @@ -1634,13 +1695,13 @@ async def test_credential_exchange_store_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1659,15 +1720,17 @@ async def test_credential_exchange_store_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ), mock.patch.object(V20CredFormat.Format, "handler") as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response"), + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec = mock.MagicMock( state=mock_cx_rec_cls.STATE_CREDENTIAL_RECEIVED, serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -1678,6 +1741,7 @@ async def test_credential_exchange_store_x(self): ) mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ + None, # anoncreds mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"...": "..."}) ), @@ -1702,11 +1766,12 @@ async def test_credential_exchange_store_x(self): async def test_credential_exchange_remove(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value = mock.MagicMock( delete_cred_ex_record=mock.CoroutineMock() ) @@ -1751,15 +1816,16 @@ async def test_credential_exchange_problem_report(self): self.request.match_info = {"cred_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -1779,11 +1845,12 @@ async def test_credential_exchange_problem_report_bad_cred_ex_id(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() ) @@ -1797,13 +1864,13 @@ async def test_credential_exchange_problem_report_x(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( save_error_state=mock.CoroutineMock( diff --git a/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py b/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py index 9d1ae4b624..1e5b41ba7e 100644 --- a/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py @@ -399,11 +399,14 @@ async def test_create_invitation_multitenant_local(self): } ) - with mock.patch.object( - AskarWallet, "create_signing_key", autospec=True - ) as mock_wallet_create_signing_key, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator: + with ( + mock.patch.object( + AskarWallet, "create_signing_key", autospec=True + ) as mock_wallet_create_signing_key, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + ): mock_wallet_create_signing_key.return_value = KeyInfo( TestConfig.test_verkey, None, ED25519 ) @@ -455,11 +458,12 @@ async def test_create_invitation_mediation_overwrites_routing_and_endpoint(self) endpoint=self.test_mediator_endpoint, ) await mediation_record.save(session) - with mock.patch.object( - MediationManager, - "get_default_mediator_id", - ) as mock_get_default_mediator, mock.patch.object( - mock_conn_rec, "metadata_set", mock.CoroutineMock() + with ( + mock.patch.object( + MediationManager, + "get_default_mediator_id", + ) as mock_get_default_mediator, + mock.patch.object(mock_conn_rec, "metadata_set", mock.CoroutineMock()), ): invite = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, @@ -496,13 +500,16 @@ async def test_create_invitation_no_handshake_no_attachments_x(self): async def test_create_invitation_attachment_v1_0_cred_offer(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - V10CredentialExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -530,13 +537,16 @@ async def test_create_invitation_attachment_v1_0_cred_offer(self): async def test_create_invitation_attachment_v1_0_cred_offer_no_handshake(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - V10CredentialExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -564,17 +574,21 @@ async def test_create_invitation_attachment_v1_0_cred_offer_no_handshake(self): } async def test_create_invitation_attachment_v2_0_cred_offer(self): - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - test_module.V10CredentialExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid_v1, mock.patch.object( - test_module.V20CredExRecord, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid_v2: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + test_module.V10CredentialExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid_v1, + mock.patch.object( + test_module.V20CredExRecord, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid_v2, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -602,13 +616,16 @@ async def test_create_invitation_attachment_v2_0_cred_offer(self): async def test_create_invitation_attachment_present_proof_v1_0(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - test_module.V10PresentationExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_pxid: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + test_module.V10PresentationExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_pxid, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -637,17 +654,21 @@ async def test_create_invitation_attachment_present_proof_v1_0(self): async def test_create_invitation_attachment_present_proof_v2_0(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - test_module.V10PresentationExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_pxid_1, mock.patch.object( - test_module.V20PresExRecord, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_pxid_2: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + test_module.V10PresentationExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_pxid_1, + mock.patch.object( + test_module.V20PresExRecord, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_pxid_2, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -904,14 +925,17 @@ async def test_wait_for_conn_rec_active_retrieve_by_id(self): async def test_create_handshake_reuse_msg(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - OutOfBandManager, - "fetch_connection_targets", - autospec=True, - ) as oob_mgr_fetch_conn, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.test_conn_rec), + with ( + mock.patch.object( + OutOfBandManager, + "fetch_connection_targets", + autospec=True, + ) as oob_mgr_fetch_conn, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.test_conn_rec), + ), ): oob_mgr_fetch_conn.return_value = ConnectionTarget( did=TestConfig.test_did, @@ -974,17 +998,19 @@ async def test_receive_reuse_message_existing_found(self): self.test_conn_rec.invitation_msg_id = "test_123" self.test_conn_rec.state = ConnRecord.State.COMPLETED.rfc160 - with mock.patch.object( - OutOfBandManager, - "fetch_connection_targets", - autospec=True, - ) as oob_mgr_fetch_conn, mock.patch.object( - OobRecord, - "retrieve_by_tag_filter", - autospec=True, - ) as mock_retrieve_oob, mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify: + with ( + mock.patch.object( + OutOfBandManager, + "fetch_connection_targets", + autospec=True, + ) as oob_mgr_fetch_conn, + mock.patch.object( + OobRecord, + "retrieve_by_tag_filter", + autospec=True, + ) as mock_retrieve_oob, + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + ): mock_retrieve_oob.return_value = mock.MagicMock( emit_event=mock.CoroutineMock(), delete_record=mock.CoroutineMock(), @@ -1031,17 +1057,19 @@ async def test_receive_reuse_message_existing_found_multi_use(self): self.test_conn_rec.invitation_msg_id = "test_123" self.test_conn_rec.state = ConnRecord.State.COMPLETED.rfc160 - with mock.patch.object( - OutOfBandManager, - "fetch_connection_targets", - autospec=True, - ) as oob_mgr_fetch_conn, mock.patch.object( - OobRecord, - "retrieve_by_tag_filter", - autospec=True, - ) as mock_retrieve_oob, mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify: + with ( + mock.patch.object( + OutOfBandManager, + "fetch_connection_targets", + autospec=True, + ) as oob_mgr_fetch_conn, + mock.patch.object( + OobRecord, + "retrieve_by_tag_filter", + autospec=True, + ) as mock_retrieve_oob, + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + ): mock_retrieve_oob.return_value = mock.MagicMock( emit_event=mock.CoroutineMock(), delete_record=mock.CoroutineMock(), @@ -1085,11 +1113,12 @@ async def test_receive_reuse_accepted(self): reuse_msg_accepted = HandshakeReuseAccept() reuse_msg_accepted.assign_thread_id(thid="the-thread-id", pthid="the-pthid") - with mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify, mock.patch.object( - OobRecord, "retrieve_by_tag_filter", autospec=True - ) as mock_retrieve_oob: + with ( + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + mock.patch.object( + OobRecord, "retrieve_by_tag_filter", autospec=True + ) as mock_retrieve_oob, + ): mock_retrieve_oob.return_value = mock.MagicMock( emit_event=mock.CoroutineMock(), delete_record=mock.CoroutineMock(), @@ -1122,11 +1151,12 @@ async def test_receive_reuse_accepted_x(self): reuse_msg_accepted = HandshakeReuseAccept() reuse_msg_accepted.assign_thread_id(thid="the-thread-id", pthid="the-pthid") - with mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify, mock.patch.object( - OobRecord, "retrieve_by_tag_filter", autospec=True - ) as mock_retrieve_oob: + with ( + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + mock.patch.object( + OobRecord, "retrieve_by_tag_filter", autospec=True + ) as mock_retrieve_oob, + ): mock_retrieve_oob.side_effect = (StorageNotFoundError,) with self.assertRaises(test_module.OutOfBandManagerError) as err: @@ -1219,11 +1249,14 @@ async def test_receive_invitation_with_valid_mediation(self): endpoint=self.test_mediator_endpoint, ) await mediation_record.save(session) - with mock.patch.object( - DIDXManager, "receive_invitation", mock.CoroutineMock() - ) as mock_didx_recv_invi, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_conn_by_id: + with ( + mock.patch.object( + DIDXManager, "receive_invitation", mock.CoroutineMock() + ) as mock_didx_recv_invi, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_conn_by_id, + ): invite = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, my_label="test123", @@ -1249,15 +1282,18 @@ async def test_receive_invitation_with_valid_mediation(self): async def test_receive_invitation_with_invalid_mediation(self): mock_conn = mock.MagicMock(connection_id="dummy-connection") - with mock.patch.object( - DIDXManager, - "receive_invitation", - mock.CoroutineMock(), - ) as mock_didx_recv_invi, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_conn_by_id: + with ( + mock.patch.object( + DIDXManager, + "receive_invitation", + mock.CoroutineMock(), + ) as mock_didx_recv_invi, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_conn_by_id, + ): invite = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, my_label="test123", @@ -1287,11 +1323,12 @@ async def test_receive_invitation_didx_services_with_service_block(self): mock_conn = mock.MagicMock(connection_id="dummy-connection") - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as didx_mgr_cls, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_conn_by_id: + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as didx_mgr_cls, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_conn_by_id, + ): didx_mgr_cls.return_value = mock.MagicMock( receive_invitation=mock.CoroutineMock(return_value=mock_conn) ) @@ -1316,11 +1353,14 @@ async def test_receive_invitation_connection_protocol(self): mock_conn = mock.MagicMock(connection_id="dummy-connection") - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as conn_mgr_cls, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as conn_mgr_cls, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + ): conn_mgr_cls.return_value = mock.MagicMock( receive_invitation=mock.CoroutineMock(return_value=mock_conn) ) @@ -1405,17 +1445,20 @@ async def test_existing_conn_record_public_did(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(), - ) as oob_mgr_find_existing_conn, mock.patch.object( - OobRecord, "save", mock.CoroutineMock() - ) as oob_record_save, mock.patch.object( - OobRecord, "retrieve_by_id", mock.CoroutineMock() - ) as oob_record_retrieve_by_id, mock.patch.object( - OutOfBandManager, "fetch_connection_targets", autospec=True - ) as oob_mgr_fetch_conn: + with ( + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(), + ) as oob_mgr_find_existing_conn, + mock.patch.object(OobRecord, "save", mock.CoroutineMock()) as oob_record_save, + mock.patch.object( + OobRecord, "retrieve_by_id", mock.CoroutineMock() + ) as oob_record_retrieve_by_id, + mock.patch.object( + OutOfBandManager, "fetch_connection_targets", autospec=True + ) as oob_mgr_fetch_conn, + ): oob_mgr_find_existing_conn.return_value = test_exist_conn oob_mgr_fetch_conn.return_value = [] oob_invitation = InvitationMessage( @@ -1450,18 +1493,22 @@ async def test_receive_invitation_handshake_reuse(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - test_module.OutOfBandManager, - "_handle_handshake_reuse", - mock.CoroutineMock(), - ) as handle_handshake_reuse, mock.patch.object( - test_module.OutOfBandManager, - "_perform_handshake", - mock.CoroutineMock(), - ) as perform_handshake, mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(return_value=test_exist_conn), + with ( + mock.patch.object( + test_module.OutOfBandManager, + "_handle_handshake_reuse", + mock.CoroutineMock(), + ) as handle_handshake_reuse, + mock.patch.object( + test_module.OutOfBandManager, + "_perform_handshake", + mock.CoroutineMock(), + ) as perform_handshake, + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(return_value=test_exist_conn), + ), ): oob_invitation = InvitationMessage( handshake_protocols=[ @@ -1498,22 +1545,27 @@ async def test_receive_invitation_handshake_reuse_failed(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - test_module.OutOfBandManager, - "_handle_handshake_reuse", - mock.CoroutineMock(), - ) as handle_handshake_reuse, mock.patch.object( - test_module.OutOfBandManager, - "_perform_handshake", - mock.CoroutineMock(), - ) as perform_handshake, mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(return_value=test_exist_conn), - ), mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=test_exist_conn), + with ( + mock.patch.object( + test_module.OutOfBandManager, + "_handle_handshake_reuse", + mock.CoroutineMock(), + ) as handle_handshake_reuse, + mock.patch.object( + test_module.OutOfBandManager, + "_perform_handshake", + mock.CoroutineMock(), + ) as perform_handshake, + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(return_value=test_exist_conn), + ), + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=test_exist_conn), + ), ): oob_invitation = InvitationMessage( handshake_protocols=[ @@ -1562,12 +1614,13 @@ async def test_receive_invitation_services_with_service_did(self): mock_conn = mock.MagicMock(connection_id="dummy") - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as didx_mgr_cls, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_conn), + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as didx_mgr_cls, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_conn), + ), ): didx_mgr_cls.return_value = mock.MagicMock( receive_invitation=mock.CoroutineMock(return_value=mock_conn) @@ -1598,15 +1651,18 @@ async def test_request_attach_oob_message_processor_connectionless(self): endpoint=self.test_endpoint, recipient_keys=[self.test_verkey] ) - with mock.patch.object( - AskarWallet, - "create_signing_key", - mock.CoroutineMock(), - ) as mock_create_signing_key, mock.patch.object( - OutOfBandManager, - "_service_decorator_from_service", - mock.CoroutineMock(), - ) as mock_service_decorator_from_service: + with ( + mock.patch.object( + AskarWallet, + "create_signing_key", + mock.CoroutineMock(), + ) as mock_create_signing_key, + mock.patch.object( + OutOfBandManager, + "_service_decorator_from_service", + mock.CoroutineMock(), + ) as mock_service_decorator_from_service, + ): mock_create_signing_key.return_value = KeyInfo( verkey="H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", metadata={}, @@ -1696,13 +1752,16 @@ async def test_request_attach_wait_for_conn_rec_active(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - OutOfBandManager, "_wait_for_conn_rec_active" - ) as mock_wait_for_conn_rec_active, mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(), - ) as oob_mgr_find_existing_conn: + with ( + mock.patch.object( + OutOfBandManager, "_wait_for_conn_rec_active" + ) as mock_wait_for_conn_rec_active, + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(), + ) as oob_mgr_find_existing_conn, + ): oob_mgr_find_existing_conn.return_value = test_exist_conn mock_wait_for_conn_rec_active.return_value = None oob_invitation = InvitationMessage( @@ -1837,11 +1896,14 @@ async def test_delete_stale_connection_by_invitation(self): updated_at=datetime_to_str(older_datetime), ) ] - with mock.patch.object( - ConnRecord, "query", mock.CoroutineMock() - ) as mock_connrecord_query, mock.patch.object( - ConnRecord, "delete_record", mock.CoroutineMock() - ) as mock_connrecord_delete: + with ( + mock.patch.object( + ConnRecord, "query", mock.CoroutineMock() + ) as mock_connrecord_query, + mock.patch.object( + ConnRecord, "delete_record", mock.CoroutineMock() + ) as mock_connrecord_delete, + ): mock_connrecord_query.return_value = records await self.manager.delete_stale_connection_by_invitation("test123") mock_connrecord_delete.assert_called_once() @@ -1868,15 +1930,20 @@ async def test_delete_conn_and_oob_record_invitation(self): invitation_msg_id="test123", ) ] - with mock.patch.object( - ConnRecord, "query", mock.CoroutineMock() - ) as mock_connrecord_query, mock.patch.object( - ConnRecord, "delete_record", mock.CoroutineMock() - ) as mock_connrecord_delete, mock.patch.object( - OobRecord, "query", mock.CoroutineMock() - ) as mock_oobrecord_query, mock.patch.object( - OobRecord, "delete_record", mock.CoroutineMock() - ) as mock_oobrecord_delete: + with ( + mock.patch.object( + ConnRecord, "query", mock.CoroutineMock() + ) as mock_connrecord_query, + mock.patch.object( + ConnRecord, "delete_record", mock.CoroutineMock() + ) as mock_connrecord_delete, + mock.patch.object( + OobRecord, "query", mock.CoroutineMock() + ) as mock_oobrecord_query, + mock.patch.object( + OobRecord, "delete_record", mock.CoroutineMock() + ) as mock_oobrecord_delete, + ): mock_connrecord_query.return_value = conn_records mock_oobrecord_query.return_value = oob_records await self.manager.delete_conn_and_oob_record_invitation("test123") diff --git a/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py b/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py index a42378c811..6e25915185 100644 --- a/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py @@ -40,11 +40,14 @@ async def test_invitation_create(self): } self.request.json = mock.CoroutineMock(return_value=body) - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.create_invitation = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(return_value={"abc": "123"}) @@ -75,11 +78,14 @@ async def test_invitation_create(self): async def test_invitation_remove(self): self.request.match_info = {"invi_msg_id": "dummy"} - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.delete_conn_and_oob_record_invitation = ( mock.CoroutineMock(return_value=None) ) @@ -100,11 +106,14 @@ async def test_invitation_create_with_accept(self): } self.request.json = mock.CoroutineMock(return_value=body) - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.create_invitation = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(return_value={"abc": "123"}) @@ -142,11 +151,14 @@ async def test_invitation_create_x(self): } ) - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.create_invitation = mock.CoroutineMock( side_effect=test_module.OutOfBandManagerError() ) @@ -159,13 +171,15 @@ async def test_invitation_receive(self): self.request.json = mock.CoroutineMock() expected_connection_record = ConnRecord(connection_id="some-id") - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.InvitationMessage, "deserialize", mock.Mock() - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object(test_module.InvitationMessage, "deserialize", mock.Mock()), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.receive_invitation = mock.CoroutineMock( return_value=expected_connection_record ) @@ -183,11 +197,13 @@ async def test_invitation_receive_forbidden_x(self): async def test_invitation_receive_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.InvitationMessage, "deserialize", mock.Mock() - ), mock.patch.object(test_module.web, "json_response", mock.Mock()): + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object(test_module.InvitationMessage, "deserialize", mock.Mock()), + mock.patch.object(test_module.web, "json_response", mock.Mock()), + ): mock_oob_mgr.return_value.receive_invitation = mock.CoroutineMock( side_effect=test_module.StorageError("cannot write") ) diff --git a/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py b/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py index 0052a78873..d1d73f8a72 100644 --- a/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py @@ -1,4 +1,4 @@ -"""Utilities for dif presentation exchange attachment.""" +"""Utilities for anoncreds presentation exchange attachment.""" import json import logging @@ -6,14 +6,15 @@ from typing import Dict, Optional, Tuple, Union from ....anoncreds.holder import AnonCredsHolder, AnonCredsHolderError -from ....anoncreds.models.anoncreds_cred_def import CredDef -from ....anoncreds.models.anoncreds_revocation import RevRegDef -from ....anoncreds.models.anoncreds_schema import AnonCredsSchema +from ....anoncreds.models.credential_definition import CredDef +from ....anoncreds.models.revocation import RevRegDef +from ....anoncreds.models.schema import AnonCredsSchema +from ....anoncreds.models.utils import extract_non_revocation_intervals_from_proof_request from ....anoncreds.registry import AnonCredsRegistry from ....anoncreds.revocation import AnonCredsRevocation +from ....askar.profile_anon import AskarAnoncredsProfile from ....core.error import BaseError from ....core.profile import Profile -from ....indy.models.xform import indy_proof_req2non_revoc_intervals from ..v1_0.models.presentation_exchange import V10PresentationExchange from ..v2_0.messages.pres_format import V20PresFormat from ..v2_0.models.pres_exchange import V20PresExRecord @@ -22,7 +23,7 @@ class AnonCredsPresExchHandlerError(BaseError): - """Base class for Indy Presentation Exchange related errors.""" + """Base class for Anoncreds Presentation Exchange related errors.""" class AnonCredsPresExchHandler: @@ -39,7 +40,9 @@ def __init__( def _extract_proof_request(self, pres_ex_record): if isinstance(pres_ex_record, V20PresExRecord): - return pres_ex_record.pres_request.attachment(V20PresFormat.Format.INDY) + return pres_ex_record.pres_request.attachment( + V20PresFormat.Format.ANONCREDS + ) or pres_ex_record.pres_request.attachment(V20PresFormat.Format.INDY) elif isinstance(pres_ex_record, V10PresentationExchange): return pres_ex_record._presentation_request.ser @@ -229,10 +232,23 @@ async def return_presentation( pres_ex_record: Union[V10PresentationExchange, V20PresExRecord], requested_credentials: Optional[dict] = None, ) -> dict: - """Return Indy proof request as dict.""" + """Return Anoncreds proof request as dict.""" + + # If not anoncreds capable, try to use indy handler. This should be removed when + # indy filter is completely retired + if not isinstance(self._profile, AskarAnoncredsProfile): + from ..indy.pres_exch_handler import IndyPresExchHandler + + handler = IndyPresExchHandler(self._profile) + return await handler.return_presentation( + pres_ex_record, requested_credentials + ) + requested_credentials = requested_credentials or {} proof_request = self._extract_proof_request(pres_ex_record) - non_revoc_intervals = indy_proof_req2non_revoc_intervals(proof_request) + non_revoc_intervals = extract_non_revocation_intervals_from_proof_request( + proof_request + ) requested_referents = self._get_requested_referents( proof_request, requested_credentials, non_revoc_intervals @@ -253,12 +269,12 @@ async def return_presentation( self._set_timestamps(requested_credentials, requested_referents) - indy_proof_json = await self.holder.create_presentation( + proof_json = await self.holder.create_presentation( proof_request, requested_credentials, schemas, cred_defs, revocation_states, ) - indy_proof = json.loads(indy_proof_json) - return indy_proof + proof = json.loads(proof_json) + return proof diff --git a/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py b/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py index 654c62f432..3af1efe80e 100644 --- a/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py @@ -2177,27 +2177,33 @@ async def test_create_vp_no_issuer(self): cred_tags={"some": "tag"}, ), ] - with mock.patch.object( - DIFPresExchHandler, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info, mock.patch.object( - DIFPresExchHandler, - "make_requirement", - mock.CoroutineMock(), - ) as mock_make_req, mock.patch.object( - DIFPresExchHandler, - "apply_requirements", - mock.CoroutineMock(), - ) as mock_apply_req, mock.patch.object( - DIFPresExchHandler, - "merge", - mock.CoroutineMock(), - ) as mock_merge, mock.patch.object( - test_module, - "create_presentation", - mock.CoroutineMock(), - ) as mock_create_vp: + with ( + mock.patch.object( + DIFPresExchHandler, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + mock.patch.object( + DIFPresExchHandler, + "make_requirement", + mock.CoroutineMock(), + ) as mock_make_req, + mock.patch.object( + DIFPresExchHandler, + "apply_requirements", + mock.CoroutineMock(), + ) as mock_apply_req, + mock.patch.object( + DIFPresExchHandler, + "merge", + mock.CoroutineMock(), + ) as mock_merge, + mock.patch.object( + test_module, + "create_presentation", + mock.CoroutineMock(), + ) as mock_create_vp, + ): mock_make_req.return_value = mock.MagicMock() mock_apply_req.return_value = mock.MagicMock() mock_merge.return_value = (VC_RECORDS, {}) @@ -2229,31 +2235,38 @@ async def test_create_vp_with_bbs_suite(self): self.profile, proof_type=BbsBlsSignature2020.signature_type ) cred_list, pd_list = await self.setup_tuple(self.profile) - with mock.patch.object( - DIFPresExchHandler, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info, mock.patch.object( - DIFPresExchHandler, - "make_requirement", - mock.CoroutineMock(), - ) as mock_make_req, mock.patch.object( - DIFPresExchHandler, - "apply_requirements", - mock.CoroutineMock(), - ) as mock_apply_req, mock.patch.object( - DIFPresExchHandler, - "merge", - mock.CoroutineMock(), - ) as mock_merge, mock.patch.object( - test_module, - "create_presentation", - mock.CoroutineMock(), - ) as mock_create_vp, mock.patch.object( - test_module, - "sign_presentation", - mock.CoroutineMock(), - ) as mock_sign_vp: + with ( + mock.patch.object( + DIFPresExchHandler, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + mock.patch.object( + DIFPresExchHandler, + "make_requirement", + mock.CoroutineMock(), + ) as mock_make_req, + mock.patch.object( + DIFPresExchHandler, + "apply_requirements", + mock.CoroutineMock(), + ) as mock_apply_req, + mock.patch.object( + DIFPresExchHandler, + "merge", + mock.CoroutineMock(), + ) as mock_merge, + mock.patch.object( + test_module, + "create_presentation", + mock.CoroutineMock(), + ) as mock_create_vp, + mock.patch.object( + test_module, + "sign_presentation", + mock.CoroutineMock(), + ) as mock_sign_vp, + ): mock_make_req.return_value = mock.MagicMock() mock_apply_req.return_value = mock.MagicMock() mock_merge.return_value = (cred_list, {}) @@ -2286,31 +2299,38 @@ async def test_create_vp_no_issuer_with_bbs_suite(self): self.profile, proof_type=BbsBlsSignature2020.signature_type ) cred_list, pd_list = await self.setup_tuple(self.profile) - with mock.patch.object( - DIFPresExchHandler, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info, mock.patch.object( - DIFPresExchHandler, - "make_requirement", - mock.CoroutineMock(), - ) as mock_make_req, mock.patch.object( - DIFPresExchHandler, - "apply_requirements", - mock.CoroutineMock(), - ) as mock_apply_req, mock.patch.object( - DIFPresExchHandler, - "merge", - mock.CoroutineMock(), - ) as mock_merge, mock.patch.object( - test_module, - "create_presentation", - mock.CoroutineMock(), - ) as mock_create_vp, mock.patch.object( - DIFPresExchHandler, - "get_sign_key_credential_subject_id", - mock.CoroutineMock(), - ) as mock_sign_key_cred_subject: + with ( + mock.patch.object( + DIFPresExchHandler, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + mock.patch.object( + DIFPresExchHandler, + "make_requirement", + mock.CoroutineMock(), + ) as mock_make_req, + mock.patch.object( + DIFPresExchHandler, + "apply_requirements", + mock.CoroutineMock(), + ) as mock_apply_req, + mock.patch.object( + DIFPresExchHandler, + "merge", + mock.CoroutineMock(), + ) as mock_merge, + mock.patch.object( + test_module, + "create_presentation", + mock.CoroutineMock(), + ) as mock_create_vp, + mock.patch.object( + DIFPresExchHandler, + "get_sign_key_credential_subject_id", + mock.CoroutineMock(), + ) as mock_sign_key_cred_subject, + ): mock_make_req.return_value = mock.MagicMock() mock_apply_req.return_value = mock.MagicMock() mock_merge.return_value = (cred_list, {}) diff --git a/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py b/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py index 9c510afc9a..b62701ced1 100644 --- a/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py @@ -55,6 +55,13 @@ async def return_presentation( proof_request = pres_ex_record.pres_request.attachment( V20PresFormat.Format.INDY ) + # If indy filter fails try anoncreds filter format. This is for a + # non-anoncreds agent that gets a anoncreds format proof request and + # should removed when indy format is fully retired. + if not proof_request: + proof_request = pres_ex_record.pres_request.attachment( + V20PresFormat.Format.ANONCREDS + ) elif isinstance(pres_ex_record, V10PresentationExchange): proof_request = pres_ex_record._presentation_request.ser non_revoc_intervals = indy_proof_req2non_revoc_intervals(proof_request) diff --git a/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py b/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py index e43c2e80b0..25ccd85984 100644 --- a/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py +++ b/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py @@ -97,11 +97,14 @@ async def test_called(self): auto_present=True, ) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance ) @@ -149,11 +152,14 @@ async def test_called_not_found(self): auto_present=True, ) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( side_effect=StorageNotFoundError ) @@ -222,11 +228,14 @@ async def test_called_auto_present(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -302,11 +311,14 @@ async def test_called_auto_present_x(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = mock_px_rec mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -368,11 +380,14 @@ async def test_called_auto_present_no_preview(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -435,11 +450,14 @@ async def test_called_auto_present_pred_no_match(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -498,11 +516,14 @@ async def test_called_auto_present_pred_single_match(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -570,11 +591,14 @@ async def test_called_auto_present_pred_multi_match(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -694,11 +718,14 @@ async def test_called_auto_present_multi_cred_match_reft(self): self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -798,11 +825,14 @@ async def test_called_auto_present_bait_and_switch(self): mock_holder.get_credentials_for_presentation_request_by_referent = by_reft self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance diff --git a/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py b/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py index 6868be17f3..4556877338 100644 --- a/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py +++ b/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py @@ -129,11 +129,12 @@ async def test_save_error_state(self): record.state = V10PresentationExchange.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="testing") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py b/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py index 7674f7e1f7..574acb5139 100644 --- a/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py @@ -340,9 +340,10 @@ async def test_record_eq(self): async def test_create_exchange_for_proposal(self): proposal = PresentationProposal() - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object(PresentationProposal, "serialize", autospec=True): + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object(PresentationProposal, "serialize", autospec=True), + ): exchange = await self.manager.create_exchange_for_proposal( CONN_ID, proposal, @@ -441,13 +442,15 @@ async def test_create_presentation(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -484,13 +487,15 @@ async def test_create_presentation_proof_req_non_revoc_interval_none(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -545,13 +550,15 @@ async def test_create_presentation_self_asserted(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -616,13 +623,15 @@ async def test_create_presentation_no_revocation(self): self.holder.create_presentation = mock.CoroutineMock(return_value="{}") self.profile.context.injector.bind_instance(IndyHolder, self.holder) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module.LOGGER, "info", mock.MagicMock() - ) as mock_log_info: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module.LOGGER, "info", mock.MagicMock() + ) as mock_log_info, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -690,13 +699,15 @@ async def test_create_presentation_bad_revoc_state(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -776,13 +787,15 @@ async def test_create_presentation_multi_matching_proposal_creds_names(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -921,13 +934,14 @@ async def test_receive_presentation(self): }, ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - V10PresentationExchange, - "retrieve_by_tag_filter", - mock.CoroutineMock(return_value=exchange_dummy), - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + V10PresentationExchange, + "retrieve_by_tag_filter", + mock.CoroutineMock(return_value=exchange_dummy), + ) as retrieve_ex, + ): retrieve_ex.side_effect = [exchange_dummy] exchange_out = await self.manager.receive_presentation( PRES, connection_record, None @@ -1024,11 +1038,12 @@ async def test_receive_presentation_oob(self): }, ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [exchange_dummy] exchange_out = await self.manager.receive_presentation(PRES, None, None) assert exchange_out.state == ( @@ -1125,11 +1140,12 @@ async def test_receive_presentation_bait_and_switch(self): }, ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy with self.assertRaises(PresentationManagerError): await self.manager.receive_presentation(PRES, connection_record, None) @@ -1137,11 +1153,12 @@ async def test_receive_presentation_bait_and_switch(self): async def test_receive_presentation_connectionless(self): exchange_dummy = V10PresentationExchange() - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy exchange_out = await self.manager.receive_presentation(PRES, None, None) save_ex.assert_called_once() @@ -1221,11 +1238,12 @@ async def test_receive_presentation_ack_a(self): exchange_dummy = V10PresentationExchange() message = mock.MagicMock() - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy exchange_out = await self.manager.receive_presentation_ack( message, connection_record @@ -1242,11 +1260,12 @@ async def test_receive_presentation_ack_b(self): exchange_dummy = V10PresentationExchange() message = mock.MagicMock(_verification_result="true") - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy exchange_out = await self.manager.receive_presentation_ack( message, connection_record @@ -1275,17 +1294,19 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, - "retrieve_by_tag_filter", - mock.CoroutineMock(), - ) as retrieve_ex, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, + "retrieve_by_tag_filter", + mock.CoroutineMock(), + ) as retrieve_ex, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_problem_report( diff --git a/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py b/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py index afe923e8be..28c7930443 100644 --- a/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py @@ -4,8 +4,10 @@ from marshmallow import ValidationError from .....admin.request_context import AdminRequestContext +from .....anoncreds.models.presentation_request import ( + AnoncredsPresentationReqAttrSpecSchema, +) from .....indy.holder import IndyHolder -from .....indy.models.proof_request import IndyProofReqAttrSpecSchema from .....indy.verifier import IndyVerifier from .....ledger.base import BaseLedger from .....storage.error import StorageNotFoundError @@ -35,7 +37,7 @@ async def asyncSetUp(self): ) async def test_validate_proof_req_attr_spec(self): - aspec = IndyProofReqAttrSpecSchema() + aspec = AnoncredsPresentationReqAttrSpecSchema() aspec.validate_fields({"name": "attr0"}) aspec.validate_fields( { @@ -298,16 +300,20 @@ async def test_presentation_exchange_retrieve_x(self): async def test_presentation_exchange_send_proposal(self): self.request.json = mock.CoroutineMock() - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ), mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ) as mock_preview: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ), + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ) as mock_preview, + ): # Since we are mocking import importlib.reload(test_module) @@ -345,18 +351,22 @@ async def test_presentation_exchange_send_proposal_no_conn_record(self): async def test_presentation_exchange_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "messages.presentation_proposal.PresentationProposal" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "messages.presentation_proposal.PresentationProposal" + ), + autospec=True, ), - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -370,15 +380,19 @@ async def test_presentation_exchange_send_proposal_not_ready(self): async def test_presentation_exchange_send_proposal_x(self): self.request.json = mock.CoroutineMock() - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ), mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ), + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), ): # Since we are mocking import importlib.reload(test_module) @@ -400,26 +414,31 @@ async def test_presentation_exchange_create_request(self): return_value={"comment": "dummy", "proof_request": {}} ) - with mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ) as mock_attach_decorator, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ) as mock_attach_decorator, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -449,26 +468,31 @@ async def test_presentation_exchange_create_request_x(self): return_value={"comment": "dummy", "proof_request": {}} ) - with mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ), + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -494,30 +518,36 @@ async def test_presentation_exchange_send_free_request(self): } ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ) as mock_attach_decorator, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ) as mock_attach_decorator, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -590,28 +620,32 @@ async def test_presentation_exchange_send_free_request_x(self): } ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ) as mock_attach_decorator, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ) as mock_attach_decorator, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, ), - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -653,27 +687,33 @@ async def test_presentation_exchange_send_bound_request(self): ), ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ) as mock_presentation_request, mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange", - autospec=True, - ) as mock_presentation_exchange: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object( + test_module, "PresentationRequest", autospec=True + ) as mock_presentation_request, + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange", + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -710,29 +750,33 @@ async def test_presentation_exchange_send_bound_request_not_found(self): self.request.json = mock.CoroutineMock(return_value={"trace": False}) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -754,29 +798,33 @@ async def test_presentation_exchange_send_bound_request_not_ready(self): self.request.json = mock.CoroutineMock(return_value={"trace": False}) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -837,29 +885,33 @@ async def test_presentation_exchange_send_bound_request_x(self): self.request.json = mock.CoroutineMock(return_value={"trace": False}) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -919,21 +971,24 @@ async def test_presentation_exchange_send_presentation(self): ), ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" - ), - autospec=True, - ) as mock_presentation_exchange: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -985,29 +1040,33 @@ async def test_presentation_exchange_send_presentation_not_found(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1029,29 +1088,33 @@ async def test_presentation_exchange_send_presentation_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1103,29 +1166,33 @@ async def test_presentation_exchange_send_presentation_x(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1156,30 +1223,36 @@ async def test_presentation_exchange_send_presentation_x(self): async def test_presentation_exchange_verify_presentation(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1260,19 +1333,23 @@ async def test_presentation_exchange_verify_presentation_x(self): ), ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" - ), - autospec=True, - ) as mock_presentation_exchange: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1312,20 +1389,23 @@ async def test_presentation_exchange_problem_report(self): self.request.match_info = {"pres_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_pres_ex, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_pres_ex, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): # Since we are mocking import importlib.reload(test_module) @@ -1345,16 +1425,19 @@ async def test_presentation_exchange_problem_report_bad_pres_ex_id(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_pres_ex: + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_pres_ex, + ): # Since we are mocking import importlib.reload(test_module) @@ -1369,18 +1452,21 @@ async def test_presentation_exchange_problem_report_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_pres_ex, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_pres_ex, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object(test_module.web, "json_response"): + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object(test_module.web, "json_response"), + ): # Since we are mocking import importlib.reload(test_module) mock_pres_ex.retrieve_by_id = mock.CoroutineMock( diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py index d5618f4a50..2c19d13443 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py @@ -1,4 +1,4 @@ -"""V2.0 present-proof indy presentation-exchange format handler.""" +"""V2.0 present-proof anoncreds presentation-exchange format handler.""" import json import logging @@ -7,12 +7,12 @@ from marshmallow import RAISE from ......anoncreds.holder import AnonCredsHolder +from ......anoncreds.models.predicate import Predicate +from ......anoncreds.models.presentation_request import AnoncredsPresentationRequestSchema +from ......anoncreds.models.proof import AnoncredsProofSchema +from ......anoncreds.models.utils import get_requested_creds_from_proof_request_preview from ......anoncreds.util import generate_pr_nonce from ......anoncreds.verifier import AnonCredsVerifier -from ......indy.models.predicate import Predicate -from ......indy.models.proof import IndyProofSchema -from ......indy.models.proof_request import IndyProofRequestSchema -from ......indy.models.xform import indy_proof_req_preview2indy_requested_creds from ......messaging.decorators.attach_decorator import AttachDecorator from ......messaging.util import canon from ....anoncreds.pres_exch_handler import AnonCredsPresExchHandler @@ -33,7 +33,7 @@ class AnonCredsPresExchangeHandler(V20PresFormatHandler): """Anoncreds presentation format handler.""" - format = V20PresFormat.Format.INDY + format = V20PresFormat.Format.ANONCREDS @classmethod def validate_fields(cls, message_type: str, attachment_data: Mapping): @@ -55,9 +55,9 @@ def validate_fields(cls, message_type: str, attachment_data: Mapping): """ mapping = { - PRES_20_REQUEST: IndyProofRequestSchema, - PRES_20_PROPOSAL: IndyProofRequestSchema, - PRES_20: IndyProofSchema, + PRES_20_REQUEST: AnoncredsPresentationRequestSchema, + PRES_20_PROPOSAL: AnoncredsPresentationRequestSchema, + PRES_20: AnoncredsProofSchema, } # Get schema class @@ -109,20 +109,20 @@ async def create_bound_request( A tuple (updated presentation exchange record, presentation request message) """ - indy_proof_request = pres_ex_record.pres_proposal.attachment( + proof_request = pres_ex_record.pres_proposal.attachment( AnonCredsPresExchangeHandler.format ) if request_data: - indy_proof_request["name"] = request_data.get("name", "proof-request") - indy_proof_request["version"] = request_data.get("version", "1.0") - indy_proof_request["nonce"] = ( + proof_request["name"] = request_data.get("name", "proof-request") + proof_request["version"] = request_data.get("version", "1.0") + proof_request["nonce"] = ( request_data.get("nonce") or await generate_pr_nonce() ) else: - indy_proof_request["name"] = "proof-request" - indy_proof_request["version"] = "1.0" - indy_proof_request["nonce"] = await generate_pr_nonce() - return self.get_format_data(PRES_20_REQUEST, indy_proof_request) + proof_request["name"] = "proof-request" + proof_request["version"] = "1.0" + proof_request["nonce"] = await generate_pr_nonce() + return self.get_format_data(PRES_20_REQUEST, proof_request) async def create_pres( self, @@ -131,45 +131,58 @@ async def create_pres( ) -> Tuple[V20PresFormat, AttachDecorator]: """Create a presentation.""" requested_credentials = {} + + # This is used for the fallback to indy format + from ..indy.handler import IndyPresExchangeHandler + if not request_data: try: proof_request = pres_ex_record.pres_request - indy_proof_request = proof_request.attachment( + # Fall back to indy format should be removed when indy format retired + proof_request = proof_request.attachment( AnonCredsPresExchangeHandler.format - ) - requested_credentials = await indy_proof_req_preview2indy_requested_creds( - indy_proof_request, - preview=None, - holder=AnonCredsHolder(self._profile), + ) or proof_request.attachment(IndyPresExchangeHandler.format) + requested_credentials = ( + await get_requested_creds_from_proof_request_preview( + proof_request, + holder=AnonCredsHolder(self._profile), + ) ) except ValueError as err: LOGGER.warning(f"{err}") - raise V20PresFormatHandlerError( - f"No matching Indy credentials found: {err}" - ) + raise V20PresFormatHandlerError(f"No matching credentials found: {err}") else: - if AnonCredsPresExchangeHandler.format.api in request_data: - indy_spec = request_data.get(AnonCredsPresExchangeHandler.format.api) + # Fall back to indy format should be removed when indy format retired + if ( + AnonCredsPresExchangeHandler.format.api in request_data + or IndyPresExchangeHandler.format.api in request_data + ): + spec = request_data.get( + AnonCredsPresExchangeHandler.format.api + ) or request_data.get(IndyPresExchangeHandler.format.api) requested_credentials = { - "self_attested_attributes": indy_spec["self_attested_attributes"], - "requested_attributes": indy_spec["requested_attributes"], - "requested_predicates": indy_spec["requested_predicates"], + "self_attested_attributes": spec["self_attested_attributes"], + "requested_attributes": spec["requested_attributes"], + "requested_predicates": spec["requested_predicates"], } - indy_handler = AnonCredsPresExchHandler(self._profile) - indy_proof = await indy_handler.return_presentation( + handler = AnonCredsPresExchHandler(self._profile) + presentation_proof = await handler.return_presentation( pres_ex_record=pres_ex_record, requested_credentials=requested_credentials, ) - return self.get_format_data(PRES_20, indy_proof) + return self.get_format_data(PRES_20, presentation_proof) async def receive_pres(self, message: V20Pres, pres_ex_record: V20PresExRecord): """Receive a presentation and check for presented values vs. proposal request.""" def _check_proof_vs_proposal(): """Check for bait and switch in presented values vs. proposal request.""" + from ..indy.handler import IndyPresExchangeHandler + + # Fall back to indy format should be removed when indy format retired proof_req = pres_ex_record.pres_request.attachment( AnonCredsPresExchangeHandler.format - ) + ) or pres_ex_record.pres_request.attachment(IndyPresExchangeHandler.format) # revealed attrs for reft, attr_spec in proof["requested_proof"]["revealed_attrs"].items(): @@ -256,7 +269,8 @@ def _check_proof_vs_proposal(): for req_restriction in req_restrictions: for k in list(req_restriction): # cannot modify en passant if k.startswith("attr::"): - req_restriction.pop(k) # let indy-sdk reject mismatch here + # let anoncreds-sdk reject mismatch here + req_restriction.pop(k) sub_proof_index = pred_spec["sub_proof_index"] for ge_proof in proof["proof"]["proofs"][sub_proof_index][ "primary_proof" @@ -313,10 +327,8 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: """ pres_request_msg = pres_ex_record.pres_request - indy_proof_request = pres_request_msg.attachment( - AnonCredsPresExchangeHandler.format - ) - indy_proof = pres_ex_record.pres.attachment(AnonCredsPresExchangeHandler.format) + proof_request = pres_request_msg.attachment(AnonCredsPresExchangeHandler.format) + proof = pres_ex_record.pres.attachment(AnonCredsPresExchangeHandler.format) verifier = AnonCredsVerifier(self._profile) ( @@ -324,13 +336,13 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: cred_defs, rev_reg_defs, rev_lists, - ) = await verifier.process_pres_identifiers(indy_proof["identifiers"]) + ) = await verifier.process_pres_identifiers(proof["identifiers"]) verifier = AnonCredsVerifier(self._profile) (verified, verified_msgs) = await verifier.verify_presentation( - indy_proof_request, - indy_proof, + proof_request, + proof, schemas, cred_defs, rev_reg_defs, diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py index 820fe2771e..2d0f73d59d 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py @@ -727,17 +727,20 @@ async def test_create_pres_prover_proof_spec_with_record_ids(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - DIFPresExchHandler, - "create_vp", - mock.CoroutineMock(), - ) as mock_create_vp, mock.patch.object( - VCHolder, - "search_credentials", - mock.CoroutineMock( - return_value=mock.MagicMock( - fetch=mock.CoroutineMock(return_value=cred_list) - ) + with ( + mock.patch.object( + DIFPresExchHandler, + "create_vp", + mock.CoroutineMock(), + ) as mock_create_vp, + mock.patch.object( + VCHolder, + "search_credentials", + mock.CoroutineMock( + return_value=mock.MagicMock( + fetch=mock.CoroutineMock(return_value=cred_list) + ) + ), ), ): mock_create_vp.return_value = DIF_PRES @@ -2211,11 +2214,12 @@ async def test_verify_received_pres_fail_schema_filter(self): auto_present=True, error_msg="error", ) - with mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ) as mock_log_err, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_jsonld_expand: + with ( + mock.patch.object( + test_module.LOGGER, "error", mock.MagicMock() + ) as mock_log_err, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_jsonld_expand, + ): mock_jsonld_expand.return_value = EXPANDED_CRED_FHIR_TYPE_2 await self.handler.receive_pres(message=dif_pres, pres_ex_record=record) mock_log_err.assert_called_once() diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/handler.py index c4abf9d4c2..2a36cc3757 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/handler.py @@ -1,7 +1,7 @@ -"""present-proof-v2 format handler - supports DIF and INDY.""" +"""present-proof-v2 format handler - supports ANONCREDS, DIF and INDY.""" import logging -from abc import ABC, abstractclassmethod, abstractmethod +from abc import ABC, abstractmethod from typing import Optional, Tuple from .....core.error import BaseError @@ -56,7 +56,8 @@ def get_format_identifier(self, message_type: str) -> str: def get_format_data(self, message_type: str, data: dict) -> PresFormatAttachment: """Get presentation format and attach objects for use in pres_ex messages.""" - @abstractclassmethod + @classmethod + @abstractmethod def validate_fields(cls, message_type: str, attachment_data: dict) -> None: """Validate attachment data for specific message type and format.""" diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py index 306ed3b1af..bac3933919 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py @@ -88,9 +88,6 @@ def get_format_identifier(self, message_type: str) -> str: str: Issue credential attachment format identifier """ - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_identifier(message_type) return ATTACHMENT_FORMAT[message_type][IndyPresExchangeHandler.format.api] @@ -98,9 +95,6 @@ def get_format_data( self, message_type: str, data: dict ) -> Tuple[V20PresFormat, AttachDecorator]: """Get presentation format and attach objects for use in pres_ex messages.""" - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_data(message_type, data) return ( V20PresFormat( @@ -154,9 +148,12 @@ async def create_pres( request_data: Optional[dict] = None, ) -> Tuple[V20PresFormat, AttachDecorator]: """Create a presentation.""" - # Temporary shim while the new anoncreds library integration is in progress + if self.anoncreds_handler: - return await self.anoncreds_handler.create_pres(pres_ex_record, request_data) + return await self.anoncreds_handler.create_pres( + pres_ex_record, + request_data, + ) requested_credentials = {} if not request_data: @@ -349,8 +346,14 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: return await self.anoncreds_handler.verify_pres(pres_ex_record) pres_request_msg = pres_ex_record.pres_request - indy_proof_request = pres_request_msg.attachment(IndyPresExchangeHandler.format) - indy_proof = pres_ex_record.pres.attachment(IndyPresExchangeHandler.format) + + # The `or` anoncreds format is for the indy <--> anoncreds compatibility + indy_proof_request = pres_request_msg.attachment( + IndyPresExchangeHandler.format + ) or pres_request_msg.attachment(AnonCredsPresExchangeHandler.format) + indy_proof = pres_ex_record.pres.attachment( + IndyPresExchangeHandler.format + ) or pres_ex_record.pres.attachment(AnonCredsPresExchangeHandler.format) indy_handler = IndyPresExchHandler(self._profile) ( schemas, diff --git a/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py b/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py index 0168fa6a36..bbce190491 100644 --- a/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py @@ -220,11 +220,14 @@ async def test_called(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance ) @@ -261,11 +264,14 @@ async def test_called_not_found(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( side_effect=StorageNotFoundError ) @@ -304,11 +310,14 @@ async def test_called_auto_present_x_indy(self): save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -347,11 +356,14 @@ async def test_called_auto_present_x_anoncreds(self): save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -389,11 +401,14 @@ async def test_called_auto_present_indy(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -463,11 +478,14 @@ async def test_called_auto_present_anoncreds(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -526,11 +544,14 @@ async def test_called_auto_present_dif(self): pres_proposal=pres_proposal, auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -585,11 +606,14 @@ async def test_called_auto_present_no_preview_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -644,11 +668,14 @@ async def test_called_auto_present_no_preview_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -704,11 +731,14 @@ async def test_called_auto_present_pred_no_match_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -760,11 +790,14 @@ async def test_called_auto_present_pred_no_match_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -810,11 +843,14 @@ async def test_called_auto_present_pred_single_match_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -864,11 +900,14 @@ async def test_called_auto_present_pred_single_match_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -923,11 +962,14 @@ async def test_called_auto_present_pred_multi_match_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -982,11 +1024,14 @@ async def test_called_auto_present_pred_multi_match_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -1084,11 +1129,14 @@ async def test_called_auto_present_multi_cred_match_reft_indy(self): pres_proposal=pres_proposal.serialize(), auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -1186,11 +1234,14 @@ async def test_called_auto_present_multi_cred_match_reft_anoncreds(self): pres_proposal=pres_proposal.serialize(), auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance diff --git a/acapy_agent/protocols/present_proof/v2_0/message_types.py b/acapy_agent/protocols/present_proof/v2_0/message_types.py index 97b8f063fc..5654ef7d42 100644 --- a/acapy_agent/protocols/present_proof/v2_0/message_types.py +++ b/acapy_agent/protocols/present_proof/v2_0/message_types.py @@ -32,14 +32,17 @@ # Format specifications ATTACHMENT_FORMAT = { PRES_20_PROPOSAL: { + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-req@v2.0", V20PresFormat.Format.INDY.api: "hlindy/proof-req@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/definitions@v1.0", }, PRES_20_REQUEST: { + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-req@v2.0", V20PresFormat.Format.INDY.api: "hlindy/proof-req@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/definitions@v1.0", }, PRES_20: { + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof@v2.0", V20PresFormat.Format.INDY.api: "hlindy/proof@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/submission@v1.0", }, diff --git a/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py b/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py index 5c55384c86..e65e98644f 100644 --- a/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py +++ b/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py @@ -30,6 +30,13 @@ class Meta: class Format(Enum): """Attachment format.""" + ANONCREDS = FormatSpec( + "anoncreds/", + DeferLoad( + "acapy_agent.protocols.present_proof.v2_0" + ".formats.anoncreds.handler.AnonCredsPresExchangeHandler" + ), + ) INDY = FormatSpec( "hlindy/", DeferLoad( @@ -37,19 +44,6 @@ class Format(Enum): ".formats.indy.handler.IndyPresExchangeHandler" ), ) - """ - To make the switch from indy to anoncreds replace the above with the following. - - :: - - INDY = FormatSpec( - "hlindy/", - DeferLoad( - "acapy_agent.protocols.present_proof.v2_0" - ".formats.anoncreds.handler.AnonCredsPresExchangeHandler" - ), - ) - """ DIF = FormatSpec( "dif/", DeferLoad( diff --git a/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py b/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py index ee0255e9a6..eafd51d68c 100644 --- a/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py +++ b/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py @@ -124,11 +124,12 @@ async def test_save_error_state(self): record.state = V20PresExRecord.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="testing") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index 76fe68c1f6..b428226aa5 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -16,6 +16,7 @@ from ....admin.decorators.auth import tenant_authentication from ....admin.request_context import AdminRequestContext from ....anoncreds.holder import AnonCredsHolder, AnonCredsHolderError +from ....anoncreds.models.presentation_request import AnoncredsPresentationRequestSchema from ....connections.models.conn_record import ConnRecord from ....indy.holder import IndyHolder, IndyHolderError from ....indy.models.cred_precis import IndyCredPrecisSchema @@ -116,6 +117,11 @@ class V20PresExRecordListSchema(OpenAPISchema): class V20PresProposalByFormatSchema(OpenAPISchema): """Schema for presentation proposal per format.""" + anoncreds = fields.Nested( + AnoncredsPresentationRequestSchema, + required=False, + metadata={"description": "Presentation proposal for anoncreds"}, + ) indy = fields.Nested( IndyProofRequestSchema, required=False, @@ -190,6 +196,11 @@ class V20PresProposalRequestSchema(AdminAPIMessageTracingSchema): class V20PresRequestByFormatSchema(OpenAPISchema): """Presentation request per format.""" + anoncreds = fields.Nested( + AnoncredsPresentationRequestSchema, + required=False, + metadata={"description": "Presentation proposal for anoncreds"}, + ) indy = fields.Nested( IndyProofRequestSchema, required=False, @@ -291,6 +302,11 @@ class V20PresentationSendRequestToProposalSchema(AdminAPIMessageTracingSchema): class V20PresSpecByFormatRequestSchema(AdminAPIMessageTracingSchema): """Presentation specification schema by format, for send-presentation request.""" + anoncreds = fields.Nested( + IndyPresSpecSchema, + required=False, + metadata={"description": "Presentation specification for anoncreds"}, + ) indy = fields.Nested( IndyPresSpecSchema, required=False, @@ -425,7 +441,10 @@ def _formats_attach(by_format: Mapping, msg_type: str, spec: str) -> Mapping: """Break out formats and proposals/requests/presentations for v2.0 messages.""" attach = [] for fmt_api, item_by_fmt in by_format.items(): - if fmt_api == V20PresFormat.Format.INDY.api: + if ( + fmt_api == V20PresFormat.Format.ANONCREDS.api + or fmt_api == V20PresFormat.Format.INDY.api + ): attach.append(AttachDecorator.data_base64(mapping=item_by_fmt, ident=fmt_api)) elif fmt_api == V20PresFormat.Format.DIF.api: attach.append(AttachDecorator.data_json(mapping=item_by_fmt, ident=fmt_api)) @@ -582,19 +601,24 @@ async def present_proof_credentials_list(request: web.BaseRequest): wallet_type = profile.settings.get_value("wallet.type") if wallet_type == "askar-anoncreds": - indy_holder = AnonCredsHolder(profile) + holder = AnonCredsHolder(profile) else: - indy_holder = profile.inject(IndyHolder) - indy_credentials = [] - # INDY + holder = profile.inject(IndyHolder) + credentials = [] + # ANONCREDS or INDY try: - indy_pres_request = pres_ex_record.by_format["pres_request"].get( - V20PresFormat.Format.INDY.api + # try anoncreds and fallback to indy + pres_request = pres_ex_record.by_format["pres_request"].get( + V20PresFormat.Format.ANONCREDS.api ) - if indy_pres_request: - indy_credentials = ( - await indy_holder.get_credentials_for_presentation_request_by_referent( - indy_pres_request, + if not pres_request: + pres_request = pres_ex_record.by_format["pres_request"].get( + V20PresFormat.Format.INDY.api + ) + if pres_request: + credentials = ( + await holder.get_credentials_for_presentation_request_by_referent( + pres_request, pres_referents, offset=offset, limit=limit, @@ -796,7 +820,7 @@ async def present_proof_credentials_list(request: web.BaseRequest): pres_ex_record, outbound_handler, ) - credentials = list(indy_credentials) + dif_cred_value_list + credentials = list(credentials) + dif_cred_value_list return web.json_response(credentials) @@ -936,8 +960,11 @@ async def present_proof_create_request(request: web.BaseRequest): comment = body.get("comment") pres_request_spec = body.get("presentation_request") - if pres_request_spec and V20PresFormat.Format.INDY.api in pres_request_spec: - await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if pres_request_spec: + if V20PresFormat.Format.INDY.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if V20PresFormat.Format.ANONCREDS.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.ANONCREDS.api]) pres_request_message = V20PresRequest( comment=comment, @@ -1020,8 +1047,11 @@ async def present_proof_send_free_request(request: web.BaseRequest): comment = body.get("comment") pres_request_spec = body.get("presentation_request") - if pres_request_spec and V20PresFormat.Format.INDY.api in pres_request_spec: - await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if pres_request_spec: + if V20PresFormat.Format.INDY.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if V20PresFormat.Format.ANONCREDS.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.ANONCREDS.api]) pres_request_message = V20PresRequest( comment=comment, will_confirm=True, @@ -1182,7 +1212,7 @@ async def present_proof_send_presentation(request: web.BaseRequest): outbound_handler = request["outbound_message_router"] pres_ex_id = request.match_info["pres_ex_id"] body = await request.json() - supported_formats = ["dif", "indy"] + supported_formats = ["anoncreds", "dif", "indy"] if not any(x in body for x in supported_formats): raise web.HTTPBadRequest( reason=( diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py index 94a6ee2966..ccc823dabf 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py @@ -512,9 +512,10 @@ async def test_create_exchange_for_proposal(self): ] ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object(V20PresProposal, "serialize", autospec=True): + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object(V20PresProposal, "serialize", autospec=True), + ): px_rec = await self.manager.create_exchange_for_proposal( CONN_ID, proposal, @@ -704,11 +705,14 @@ async def test_receive_pres_catch_diferror(self): pres_request=pres_req.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object( - DIFPresFormatHandler, "receive_pres", autospec=True - ) as mock_receive_pres, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object( + DIFPresFormatHandler, "receive_pres", autospec=True + ) as mock_receive_pres, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): mock_receive_pres.return_value = False retrieve_ex.side_effect = [px_rec] with self.assertRaises(V20PresManagerError) as context: @@ -776,13 +780,15 @@ async def test_create_pres_indy(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -830,15 +836,18 @@ async def test_create_pres_indy_and_dif(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator_indy, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - DIFPresFormatHandler, "create_pres", autospec=True - ) as mock_create_pres: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator_indy, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object( + DIFPresFormatHandler, "create_pres", autospec=True + ) as mock_create_pres, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator_indy.data_base64 = mock.MagicMock( @@ -891,17 +900,20 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -943,13 +955,15 @@ async def test_create_pres_self_asserted(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1021,13 +1035,15 @@ async def test_create_pres_no_revocation(self): self.holder.create_presentation = mock.CoroutineMock(return_value="{}") self.profile.context.injector.bind_instance(IndyHolder, self.holder) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module.LOGGER, "info", mock.MagicMock() - ) as mock_log_info: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module.LOGGER, "info", mock.MagicMock() + ) as mock_log_info, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1116,12 +1132,15 @@ async def test_create_pres_bad_revoc_state(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - test_indy_util_module.LOGGER, "error", mock.MagicMock() + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object(test_indy_util_module.LOGGER, "error", mock.MagicMock()), ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) @@ -1203,13 +1222,15 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1287,9 +1308,12 @@ async def test_no_matching_creds_indy_handler(self): get_creds = mock.CoroutineMock(return_value=()) self.holder.get_credentials_for_presentation_request_by_referent = get_creds - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1352,11 +1376,12 @@ async def test_receive_pres(self): assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME assert by_format.get("pres_request").get("indy") == INDY_PROOF_REQ_NAME - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1421,11 +1446,12 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME assert by_format.get("pres_request").get("indy") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1497,11 +1523,12 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): assert by_format.get("pres_request").get("indy") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1569,11 +1596,12 @@ async def test_receive_pres_indy_no_attr_restrictions(self): assert by_format.get("pres_request").get("indy") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1630,9 +1658,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1678,9 +1709,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1733,9 +1767,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1785,9 +1822,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1838,9 +1878,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1890,9 +1933,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1942,9 +1988,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1994,9 +2043,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -2036,11 +2088,14 @@ async def test_verify_pres(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() @@ -2096,32 +2151,40 @@ async def test_verify_pres_indy_and_dif(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch( - "acapy_agent.vc.vc_ld.verify.verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=False) + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), ), - ), mock.patch.object( - IndyVerifier, - "verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=True) + mock.patch( + "acapy_agent.vc.vc_ld.verify.verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=False) + ), + ), + mock.patch.object( + IndyVerifier, + "verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=True) + ), ), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) @@ -2167,11 +2230,12 @@ async def test_receive_pres_ack_a(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock() - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2184,11 +2248,12 @@ async def test_receive_pres_ack_b(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock(_verification_result="true") - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2213,17 +2278,19 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, - "retrieve_by_tag_filter", - mock.CoroutineMock(), - ) as retrieve_ex, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, + "retrieve_by_tag_filter", + mock.CoroutineMock(), + ) as retrieve_ex, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + ): retrieve_ex.return_value = stored_exchange await self.manager.receive_problem_report(problem, connection_id) diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py index 0ee4f1ad38..9f88377968 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py @@ -74,7 +74,7 @@ ) ], ) -INDY_PROOF_REQ_NAME = { +ANONCREDS_PROOF_REQ_NAME = { "name": PROOF_REQ_NAME, "version": PROOF_REQ_VERSION, "nonce": PROOF_REQ_NONCE, @@ -100,7 +100,7 @@ } }, } -INDY_PROOF_REQ_NAMES = { +ANONCREDS_PROOF_REQ_NAMES = { "name": PROOF_REQ_NAME, "version": PROOF_REQ_VERSION, "nonce": PROOF_REQ_NONCE, @@ -121,7 +121,7 @@ } }, } -INDY_PROOF_REQ_SELFIE = { +ANONCREDS_PROOF_REQ_SELFIE = { "name": PROOF_REQ_NAME, "version": PROOF_REQ_VERSION, "nonce": PROOF_REQ_NONCE, @@ -133,7 +133,7 @@ "0_highscore_GE_uuid": {"name": "highScore", "p_type": ">=", "p_value": 1000000} }, } -INDY_PROOF = { +ANONCREDS_PROOF = { "proof": { "proofs": [ { @@ -252,7 +252,7 @@ } ], } -INDY_PROOF_NAMES = { +ANONCREDS_PROOF_NAMES = { "proof": { "proofs": [ { @@ -512,13 +512,16 @@ async def test_record_eq(self): async def test_create_exchange_for_proposal(self): proposal = V20PresProposal( formats=[ - V20PresFormat(attach_id="indy", format_=V20PresFormat.Format.INDY.aries) + V20PresFormat( + attach_id="anoncreds", format_=V20PresFormat.Format.ANONCREDS.aries + ) ] ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object(V20PresProposal, "serialize", autospec=True): + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object(V20PresProposal, "serialize", autospec=True), + ): px_rec = await self.manager.create_exchange_for_proposal( CONN_ID, proposal, @@ -537,7 +540,9 @@ async def test_receive_proposal(self): connection_record = mock.MagicMock(connection_id=CONN_ID) proposal = V20PresProposal( formats=[ - V20PresFormat(attach_id="indy", format_=V20PresFormat.Format.INDY.aries) + V20PresFormat( + attach_id="anoncreds", format_=V20PresFormat.Format.ANONCREDS.aries + ) ] ) with mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: @@ -555,14 +560,14 @@ async def test_create_bound_request_a(self): proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec = V20PresExRecord( @@ -589,14 +594,14 @@ async def test_create_bound_request_b(self): proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec = V20PresExRecord( @@ -708,11 +713,14 @@ async def test_receive_pres_catch_diferror(self): pres_request=pres_req.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object( - DIFPresFormatHandler, "receive_pres", autospec=True - ) as mock_receive_pres, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object( + DIFPresFormatHandler, "receive_pres", autospec=True + ) as mock_receive_pres, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): mock_receive_pres.return_value = False retrieve_ex.side_effect = [px_rec] with self.assertRaises(V20PresManagerError) as context: @@ -725,14 +733,16 @@ async def test_create_exchange_for_request(self): will_confirm=True, formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(mapping=INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64( + mapping=ANONCREDS_PROOF_REQ_NAME, ident="anoncreds" + ) ], ) pres_req.assign_thread_id("dummy") @@ -765,14 +775,14 @@ async def test_create_pres_indy(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -781,13 +791,15 @@ async def test_create_pres_indy(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -795,9 +807,9 @@ async def test_create_pres_indy(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAME, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAME, preview=None, holder=self.holder ) - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 2 assert len(req_creds["requested_predicates"]) == 1 @@ -813,9 +825,9 @@ async def test_create_pres_indy_and_dif(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ), V20PresFormat( @@ -826,7 +838,7 @@ async def test_create_pres_indy_and_dif(self): ), ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy"), + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds"), AttachDecorator.data_json(DIF_PRES_REQ, ident="dif"), ], ) @@ -836,15 +848,18 @@ async def test_create_pres_indy_and_dif(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator_indy, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - DIFPresFormatHandler, "create_pres", autospec=True - ) as mock_create_pres: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator_indy, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object( + DIFPresFormatHandler, "create_pres", autospec=True + ) as mock_create_pres, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator_indy.data_base64 = mock.MagicMock( @@ -857,9 +872,9 @@ async def test_create_pres_indy_and_dif(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAME, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAME, preview=None, holder=self.holder ) - request_data = {"indy": req_creds, "dif": DIF_PRES_REQ} + request_data = {"anoncreds": req_creds, "dif": DIF_PRES_REQ} assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 2 assert len(req_creds["requested_predicates"]) == 1 @@ -872,19 +887,19 @@ async def test_create_pres_indy_and_dif(self): @pytest.mark.skip(reason="Anoncreds-break") async def test_create_pres_proof_req_non_revoc_interval_none(self): - indy_proof_req_vcx = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req_vcx = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req_vcx["non_revoked"] = None # simulate interop with indy-vcx pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req_vcx, ident="indy") + AttachDecorator.data_base64(indy_proof_req_vcx, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -898,17 +913,20 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -918,7 +936,7 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): req_creds = await indy_proof_req_preview2indy_requested_creds( indy_proof_req_vcx, preview=None, holder=self.holder ) - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 2 assert len(req_creds["requested_predicates"]) == 1 @@ -934,14 +952,14 @@ async def test_create_pres_self_asserted(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_SELFIE, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_SELFIE, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -951,13 +969,15 @@ async def test_create_pres_self_asserted(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -965,9 +985,9 @@ async def test_create_pres_self_asserted(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_SELFIE, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_SELFIE, preview=None, holder=self.holder ) - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} assert len(req_creds["self_attested_attributes"]) == 3 assert not req_creds["requested_attributes"] @@ -991,14 +1011,14 @@ async def test_create_pres_no_revocation(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1030,22 +1050,24 @@ async def test_create_pres_no_revocation(self): self.holder.create_presentation = mock.AsyncMock(return_value="{}") self.profile.context.injector.bind_instance(AnonCredsHolder, self.holder) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module.LOGGER, "info", mock.MagicMock() - ) as mock_log_info: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module.LOGGER, "info", mock.MagicMock() + ) as mock_log_info, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAME, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAME, preview=None, holder=self.holder ) request_data = { - "indy": { + "anoncreds": { "self_attested_attributes": req_creds["self_attested_attributes"], "requested_attributes": req_creds["requested_attributes"], "requested_predicates": req_creds["requested_predicates"], @@ -1062,7 +1084,7 @@ async def test_create_pres_no_revocation(self): for pred_reft_spec in req_creds["requested_predicates"].values(): pred_reft_spec["timestamp"] = 1234567890 request_data = { - "indy": { + "anoncreds": { "self_attested_attributes": req_creds["self_attested_attributes"], "requested_attributes": req_creds["requested_attributes"], "requested_predicates": req_creds["requested_predicates"], @@ -1076,14 +1098,14 @@ async def test_create_pres_bad_revoc_state(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1126,12 +1148,15 @@ async def test_create_pres_bad_revoc_state(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - test_indy_util_module.LOGGER, "error", mock.MagicMock() + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object(test_indy_util_module.LOGGER, "error", mock.MagicMock()), ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) @@ -1147,14 +1172,14 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAMES, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1214,13 +1239,15 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1228,12 +1255,12 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAMES, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAMES, preview=None, holder=self.holder ) assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 1 assert len(req_creds["requested_predicates"]) == 1 - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} (px_rec_out, pres_msg) = await self.manager.create_pres( px_rec_in, request_data ) @@ -1244,14 +1271,14 @@ async def test_no_matching_creds_for_proof_req(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAMES, ident="anoncreds") ], ) V20PresExRecord(pres_request=pres_request.serialize()) @@ -1260,7 +1287,7 @@ async def test_no_matching_creds_for_proof_req(self): with self.assertRaises(ValueError): await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAMES, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAMES, preview=None, holder=self.holder ) get_creds = mock.CoroutineMock( @@ -1277,30 +1304,33 @@ async def test_no_matching_creds_for_proof_req(self): ) self.holder.get_credentials_for_presentation_request_by_referent = get_creds await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAMES, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAMES, preview=None, holder=self.holder ) async def test_no_matching_creds_indy_handler(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAMES, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) get_creds = mock.CoroutineMock(return_value=()) self.holder.get_credentials_for_presentation_request_by_referent = get_creds - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1311,44 +1341,50 @@ async def test_no_matching_creds_indy_handler(self): (px_rec_out, pres_msg) = await self.manager.create_pres( px_rec_in, request_data ) - assert "No matching Indy" in str(context.exception) + assert "AnonCreds interface requires AskarAnoncreds profile" in str( + context.exception + ) async def test_receive_pres(self): connection_record = mock.MagicMock(connection_id=CONN_ID) pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) pres.assign_thread_id("thread-id") @@ -1360,14 +1396,15 @@ async def test_receive_pres(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME - assert by_format.get("pres_request").get("indy") == INDY_PROOF_REQ_NAME + assert by_format.get("pres_proposal").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME + assert by_format.get("pres_request").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1383,41 +1420,45 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req["requested_predicates"]["0_highscore_GE_uuid"]["restrictions"][0][ "attr::player::value" ] = "impostor" pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) pres.assign_thread_id("thread-id") @@ -1429,14 +1470,15 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME - assert by_format.get("pres_request").get("indy") == indy_proof_req + assert by_format.get("pres_proposal").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME + assert by_format.get("pres_request").get("anoncreds") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1478,24 +1520,28 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) pres.assign_thread_id("thread-id") @@ -1506,13 +1552,14 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_request").get("indy") == indy_proof_req + assert by_format.get("pres_request").get("anoncreds") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1538,7 +1585,7 @@ async def test_receive_pres_indy_no_attr_restrictions(self): }, "requested_predicates": {}, } - proof = deepcopy(INDY_PROOF) + proof = deepcopy(ANONCREDS_PROOF) proof["requested_proof"]["revealed_attrs"] = { "0_player_uuid": { "sub_proof_index": 0, @@ -1550,24 +1597,26 @@ async def test_receive_pres_indy_no_attr_restrictions(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(proof, ident="indy")], + presentations_attach=[AttachDecorator.data_base64(proof, ident="anoncreds")], ) pres.assign_thread_id("thread-id") @@ -1578,13 +1627,14 @@ async def test_receive_pres_indy_no_attr_restrictions(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_request").get("indy") == indy_proof_req + assert by_format.get("pres_request").get("anoncreds") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1597,53 +1647,60 @@ async def test_receive_pres_indy_no_attr_restrictions(self): async def test_receive_pres_bait_and_switch_attr_name(self): connection_record = mock.MagicMock(connection_id=CONN_ID) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req["requested_attributes"]["0_screencapture_uuid"]["restrictions"][0][ "attr::screenCapture::value" ] = "c2NyZWVuIGNhcHR1cmUgc2hvd2luZyBzY29yZSBpbiB0aGUgbWlsbGlvbnM=" pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( pres_proposal=pres_proposal.serialize(), pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1655,33 +1712,41 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1689,9 +1754,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1699,43 +1767,47 @@ async def test_receive_pres_bait_and_switch_attr_name(self): async def test_receive_pres_bait_and_switch_attr_names(self): connection_record = mock.MagicMock(connection_id=CONN_ID) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAMES) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAMES) indy_proof_req["requested_attributes"]["0_player_uuid"]["restrictions"][0][ "attr::screenCapture::value" ] = "c2NyZWVuIGNhcHR1cmUgc2hvd2luZyBzY29yZSBpbiB0aGUgbWlsbGlvbnM=" pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_NAMES, ident="anoncreds") ], ) @@ -1744,9 +1816,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1760,34 +1835,40 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_NAMES, ident="anoncreds") ], ) @@ -1796,9 +1877,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1806,42 +1890,46 @@ async def test_receive_pres_bait_and_switch_attr_names(self): async def test_receive_pres_bait_and_switch_pred(self): connection_record = mock.MagicMock(connection_id=CONN_ID) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req["requested_predicates"] = {} pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1849,9 +1937,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1867,33 +1958,41 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1901,9 +2000,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1919,33 +2021,41 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1953,9 +2063,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1971,33 +2084,41 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -2005,9 +2126,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -2020,25 +2144,29 @@ async def test_verify_pres(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], will_confirm=True, request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_in = V20PresExRecord( pres_request=pres_request, @@ -2048,11 +2176,14 @@ async def test_verify_pres(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() @@ -2063,9 +2194,9 @@ async def test_verify_pres_indy_and_dif(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ), V20PresFormat( @@ -2077,15 +2208,17 @@ async def test_verify_pres_indy_and_dif(self): ], will_confirm=True, request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy"), + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds"), AttachDecorator.data_json(DIF_PRES_REQ, ident="dif"), ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ), V20PresFormat( attach_id="dif", @@ -2093,7 +2226,7 @@ async def test_verify_pres_indy_and_dif(self): ), ], presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF, ident="indy"), + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds"), AttachDecorator.data_json(DIF_PRES, ident="dif"), ], ) @@ -2109,32 +2242,40 @@ async def test_verify_pres_indy_and_dif(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch( - "acapy_agent.vc.vc_ld.verify.verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=False) + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch( + "acapy_agent.vc.vc_ld.verify.verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=False) + ), ), - ), mock.patch.object( - AnonCredsVerifier, - "verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=True) + mock.patch.object( + AnonCredsVerifier, + "verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=True) + ), ), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) @@ -2180,11 +2321,12 @@ async def test_receive_pres_ack_a(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock() - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2197,11 +2339,12 @@ async def test_receive_pres_ack_b(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock(_verification_result="true") - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2226,17 +2369,19 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, - "retrieve_by_tag_filter", - mock.CoroutineMock(), - ) as retrieve_ex, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, + "retrieve_by_tag_filter", + mock.CoroutineMock(), + ) as retrieve_ex, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + ): retrieve_ex.return_value = stored_exchange await self.manager.receive_problem_report(problem, connection_id) diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py index af70cd2d0b..7d120b0052 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py @@ -6,8 +6,10 @@ from marshmallow import ValidationError from .....admin.request_context import AdminRequestContext +from .....anoncreds.models.presentation_request import ( + AnoncredsPresentationReqAttrSpecSchema, +) from .....indy.holder import IndyHolder -from .....indy.models.proof_request import IndyProofReqAttrSpecSchema from .....indy.verifier import IndyVerifier from .....ledger.base import BaseLedger from .....storage.error import StorageNotFoundError @@ -221,7 +223,7 @@ async def test_validate(self): schema.validate_fields({"veres-one": {"no": "support"}}) async def test_validate_proof_req_attr_spec(self): - aspec = IndyProofReqAttrSpecSchema() + aspec = AnoncredsPresentationReqAttrSpecSchema() aspec.validate_fields({"name": "attr0"}) aspec.validate_fields( { @@ -254,11 +256,14 @@ async def test_present_proof_list(self): mock_pres_ex_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.query = mock.CoroutineMock( return_value=[mock_pres_ex_rec_inst] ) @@ -337,11 +342,14 @@ async def test_present_proof_credentials_list_single_referent(self): ) self.profile.context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -363,11 +371,14 @@ async def test_present_proof_credentials_list_multiple_referents(self): ) self.profile.context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -427,11 +438,14 @@ async def test_present_proof_credentials_list_dif(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -504,11 +518,14 @@ async def test_present_proof_credentials_list_dif_one_of_filter(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -577,11 +594,14 @@ async def test_present_proof_credentials_dif_no_tag_query(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -650,11 +670,14 @@ async def test_present_proof_credentials_single_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -723,11 +746,14 @@ async def test_present_proof_credentials_double_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -789,10 +815,11 @@ async def test_present_proof_credentials_single_ldp_vp_error(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -849,10 +876,11 @@ async def test_present_proof_credentials_double_ldp_vp_error(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -906,10 +934,11 @@ async def test_present_proof_credentials_list_limit_disclosure_no_bbs(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -966,10 +995,11 @@ async def test_present_proof_credentials_no_ldp_vp(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -1032,11 +1062,14 @@ async def test_present_proof_credentials_list_schema_uri(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) mock_response.assert_called_once_with( @@ -1095,10 +1128,11 @@ async def test_present_proof_credentials_list_dif_error(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): with self.assertRaises(test_module.web.HTTPBadRequest): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record @@ -1107,11 +1141,14 @@ async def test_present_proof_credentials_list_dif_error(self): async def test_present_proof_retrieve(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock( @@ -1163,15 +1200,16 @@ async def test_present_proof_send_proposal(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=True) ) @@ -1197,10 +1235,11 @@ async def test_present_proof_send_proposal_no_conn_record(self): async def test_present_proof_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresProposal", autospec=True + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object(test_module, "V20PresProposal", autospec=True), ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=False) @@ -1212,11 +1251,12 @@ async def test_present_proof_send_proposal_not_ready(self): async def test_present_proof_send_proposal_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + ): mock_pres_mgr.return_value.create_exchange_for_proposal = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.StorageError()), @@ -1238,13 +1278,15 @@ async def test_present_proof_create_request(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) @@ -1266,11 +1308,13 @@ async def test_present_proof_create_request_x(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module.web, "json_response", mock.MagicMock()): + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), + ): mock_pres_mgr_inst = mock.MagicMock( create_exchange_for_request=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1293,17 +1337,19 @@ async def test_present_proof_send_free_request(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock({"thread_id": "sample-thread-id"}) @@ -1357,13 +1403,16 @@ async def test_present_proof_send_free_request_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module, "V20PresExRecord", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + ): mock_conn_rec_inst = mock.MagicMock() mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_conn_rec_inst @@ -1399,15 +1448,20 @@ async def test_present_proof_send_bound_request(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1452,11 +1506,14 @@ async def test_present_proof_send_bound_request_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1490,11 +1547,14 @@ async def test_present_proof_send_bound_request_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1578,13 +1638,17 @@ async def test_present_proof_send_bound_request_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1632,15 +1696,18 @@ async def test_present_proof_send_presentation(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1683,15 +1750,18 @@ async def test_present_proof_send_presentation_dif(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1756,15 +1826,18 @@ async def test_present_proof_send_presentation_dif_error(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=px_rec_instance ) @@ -1829,11 +1902,14 @@ async def test_present_proof_send_presentation_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1871,11 +1947,14 @@ async def test_present_proof_send_presentation_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1943,13 +2022,18 @@ async def test_present_proof_send_presentation_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1983,15 +2067,20 @@ async def test_present_proof_send_presentation_x(self): async def test_present_proof_verify_presentation(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PRESENTATION_RECEIVED, @@ -2048,14 +2137,17 @@ async def test_present_proof_verify_presentation_bad_state(self): async def test_present_proof_verify_presentation_x(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", @@ -2093,15 +2185,16 @@ async def test_present_proof_problem_report(self): self.request.match_info = {"pres_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -2134,13 +2227,13 @@ async def test_present_proof_problem_report_x(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageError() ) @@ -2151,11 +2244,14 @@ async def test_present_proof_problem_report_x(self): async def test_present_proof_remove(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( state=test_module.V20PresExRecord.STATE_DONE, diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py index 96c3da744e..4a29ff2b08 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py @@ -8,8 +8,10 @@ from .....admin.request_context import AdminRequestContext from .....anoncreds.holder import AnonCredsHolder +from .....anoncreds.models.presentation_request import ( + AnoncredsPresentationReqAttrSpecSchema, +) from .....anoncreds.verifier import AnonCredsVerifier -from .....indy.models.proof_request import IndyProofReqAttrSpecSchema from .....ledger.base import BaseLedger from .....storage.error import StorageNotFoundError from .....storage.vc_holder.base import VCHolder @@ -223,7 +225,7 @@ async def test_validate(self): schema.validate_fields({"veres-one": {"no": "support"}}) async def test_validate_proof_req_attr_spec(self): - aspec = IndyProofReqAttrSpecSchema() + aspec = AnoncredsPresentationReqAttrSpecSchema() aspec.validate_fields({"name": "attr0"}) aspec.validate_fields( { @@ -256,11 +258,14 @@ async def test_present_proof_list(self): mock_pres_ex_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.query = mock.CoroutineMock( return_value=[mock_pres_ex_rec_inst] ) @@ -347,11 +352,14 @@ async def test_present_proof_credentials_list_single_referent(self): ), ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -377,11 +385,14 @@ async def test_present_proof_credentials_list_multiple_referents(self): ), ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -443,11 +454,14 @@ async def test_present_proof_credentials_list_dif(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -521,11 +535,14 @@ async def test_present_proof_credentials_list_dif_one_of_filter(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -596,11 +613,14 @@ async def test_present_proof_credentials_dif_no_tag_query(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -671,11 +691,14 @@ async def test_present_proof_credentials_single_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -746,11 +769,14 @@ async def test_present_proof_credentials_double_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -816,10 +842,11 @@ async def test_present_proof_credentials_single_ldp_vp_error(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -880,10 +907,11 @@ async def test_present_proof_credentials_double_ldp_vp_error(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -941,10 +969,11 @@ async def test_present_proof_credentials_list_limit_disclosure_no_bbs(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -1005,10 +1034,11 @@ async def test_present_proof_credentials_no_ldp_vp(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -1073,11 +1103,14 @@ async def test_present_proof_credentials_list_schema_uri(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) mock_response.assert_called_once_with( @@ -1137,10 +1170,11 @@ async def test_present_proof_credentials_list_dif_error(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): with self.assertRaises(test_module.web.HTTPBadRequest): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record @@ -1149,11 +1183,14 @@ async def test_present_proof_credentials_list_dif_error(self): async def test_present_proof_retrieve(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock( @@ -1205,15 +1242,16 @@ async def test_present_proof_send_proposal(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=True) ) @@ -1239,10 +1277,11 @@ async def test_present_proof_send_proposal_no_conn_record(self): async def test_present_proof_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresProposal", autospec=True + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object(test_module, "V20PresProposal", autospec=True), ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=False) @@ -1254,11 +1293,12 @@ async def test_present_proof_send_proposal_not_ready(self): async def test_present_proof_send_proposal_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + ): mock_pres_mgr.return_value.create_exchange_for_proposal = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.StorageError()), @@ -1280,13 +1320,15 @@ async def test_present_proof_create_request(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) @@ -1308,11 +1350,13 @@ async def test_present_proof_create_request_x(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module.web, "json_response", mock.MagicMock()): + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), + ): mock_pres_mgr_inst = mock.MagicMock( create_exchange_for_request=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1335,17 +1379,19 @@ async def test_present_proof_send_free_request(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock({"thread_id": "sample-thread-id"}) @@ -1399,13 +1445,16 @@ async def test_present_proof_send_free_request_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module, "V20PresExRecord", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + ): mock_conn_rec_inst = mock.MagicMock() mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_conn_rec_inst @@ -1441,15 +1490,20 @@ async def test_present_proof_send_bound_request(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1494,11 +1548,14 @@ async def test_present_proof_send_bound_request_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1532,11 +1589,14 @@ async def test_present_proof_send_bound_request_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1620,13 +1680,17 @@ async def test_present_proof_send_bound_request_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1674,15 +1738,18 @@ async def test_present_proof_send_presentation(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1725,15 +1792,18 @@ async def test_present_proof_send_presentation_dif(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1798,15 +1868,18 @@ async def test_present_proof_send_presentation_dif_error(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=px_rec_instance ) @@ -1871,11 +1944,14 @@ async def test_present_proof_send_presentation_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1912,11 +1988,14 @@ async def test_present_proof_send_presentation_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1984,13 +2063,18 @@ async def test_present_proof_send_presentation_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -2024,15 +2108,20 @@ async def test_present_proof_send_presentation_x(self): async def test_present_proof_verify_presentation(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PRESENTATION_RECEIVED, @@ -2089,14 +2178,17 @@ async def test_present_proof_verify_presentation_bad_state(self): async def test_present_proof_verify_presentation_x(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", @@ -2134,15 +2226,16 @@ async def test_present_proof_problem_report(self): self.request.match_info = {"pres_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -2175,13 +2268,13 @@ async def test_present_proof_problem_report_x(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageError() ) @@ -2192,11 +2285,14 @@ async def test_present_proof_problem_report_x(self): async def test_present_proof_remove(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( state=test_module.V20PresExRecord.STATE_DONE, diff --git a/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py b/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py index 4e3b19f933..73c642c489 100644 --- a/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py +++ b/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py @@ -28,13 +28,15 @@ async def test_handle(self): handler = test_module.ForwardHandler() responder = MockResponder() - with mock.patch.object( - test_module, "RoutingManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_connection_mgr, mock.patch.object( - self.context.profile, "notify", autospec=True - ) as mock_notify: + with ( + mock.patch.object(test_module, "RoutingManager", autospec=True) as mock_mgr, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_connection_mgr, + mock.patch.object( + self.context.profile, "notify", autospec=True + ) as mock_notify, + ): mock_mgr.return_value.get_recipient = mock.CoroutineMock( return_value=RouteRecord(connection_id="dummy") ) diff --git a/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py b/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py index cf05eae733..6012046e75 100644 --- a/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py @@ -31,13 +31,15 @@ async def test_connections_send_ping(self): self.request.json = mock.CoroutineMock(return_value={"comment": "some comment"}) self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module, "Ping", mock.MagicMock() - ) as mock_ping, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as json_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module, "Ping", mock.MagicMock()) as mock_ping, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as json_response, + ): mock_ping.return_value = mock.MagicMock(_thread_id="dummy") mock_retrieve.return_value = mock.MagicMock(is_ready=True) result = await test_module.connections_send_ping(self.request) @@ -48,10 +50,11 @@ async def test_connections_send_ping_no_conn(self): self.request.json = mock.CoroutineMock(return_value={"comment": "some comment"}) self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_retrieve.side_effect = test_module.StorageNotFoundError() with self.assertRaises(test_module.web.HTTPNotFound): @@ -61,10 +64,11 @@ async def test_connections_send_ping_not_ready(self): self.request.json = mock.CoroutineMock(return_value={"comment": "some comment"}) self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_retrieve.return_value = mock.MagicMock(is_ready=False) with self.assertRaises(test_module.web.HTTPBadRequest): diff --git a/acapy_agent/resolver/__init__.py b/acapy_agent/resolver/__init__.py index 005cce6df9..3998b3da1c 100644 --- a/acapy_agent/resolver/__init__.py +++ b/acapy_agent/resolver/__init__.py @@ -49,6 +49,12 @@ async def setup(context: InjectionContext): await web_resolver.setup(context) registry.register_resolver(web_resolver) + tdw_resolver = ClassProvider( + "acapy_agent.resolver.default.tdw.TdwDIDResolver" + ).provide(context.settings, context.injector) + await tdw_resolver.setup(context) + registry.register_resolver(tdw_resolver) + if context.settings.get("resolver.universal"): universal_resolver = ClassProvider( "acapy_agent.resolver.default.universal.UniversalResolver" diff --git a/acapy_agent/resolver/default/tdw.py b/acapy_agent/resolver/default/tdw.py new file mode 100644 index 0000000000..a35d38e15f --- /dev/null +++ b/acapy_agent/resolver/default/tdw.py @@ -0,0 +1,41 @@ +"""TDW DID Resolver. + +Resolution is performed by the did_tdw library. +""" + +from re import Pattern +from typing import Optional, Sequence, Text + +# from did_tdw.resolver import ResolutionResult, resolve_did + +from ...config.injection_context import InjectionContext +from ...core.profile import Profile +from ...messaging.valid import DIDTdw +from ..base import BaseDIDResolver, ResolverType + + +class TdwDIDResolver(BaseDIDResolver): + """TDW DID Resolver.""" + + def __init__(self): + """Initialize the TDW DID Resolver.""" + super().__init__(ResolverType.NATIVE) + + async def setup(self, context: InjectionContext): + """Perform required setup for TDW DID resolution.""" + + @property + def supported_did_regex(self) -> Pattern: + """Return supported DID regex of TDW DID Resolver.""" + return DIDTdw.PATTERN + + async def _resolve( + self, profile: Profile, did: str, service_accept: Optional[Sequence[Text]] = None + ) -> dict: + """Resolve DID using TDW.""" + # response: ResolutionResult = await resolve_did(did) + # if response.resolution_metadata and response.resolution_metadata.get("error"): + # return response.resolution_metadata + + # return response.document + return {} diff --git a/acapy_agent/resolver/default/tests/test_legacy_peer.py b/acapy_agent/resolver/default/tests/test_legacy_peer.py index fb7cb8f264..46f18caf8a 100644 --- a/acapy_agent/resolver/default/tests/test_legacy_peer.py +++ b/acapy_agent/resolver/default/tests/test_legacy_peer.py @@ -79,11 +79,10 @@ async def test_supports_x_unknown_did( @pytest.mark.asyncio async def test_resolve(self, resolver: LegacyPeerDIDResolver, profile: Profile): """Test resolve.""" - with mock.patch.object( - test_module, "BaseConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "LegacyDocCorrections" - ) as mock_corrections: + with ( + mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr, + mock.patch.object(test_module, "LegacyDocCorrections") as mock_corrections, + ): doc = object() mock_corrections.apply = mock.MagicMock(return_value=doc) mock_mgr.return_value = mock.MagicMock( @@ -102,11 +101,11 @@ async def test_resolve_x_not_found( This should be impossible in practice but still. """ - with mock.patch.object( - test_module, "BaseConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "LegacyDocCorrections" - ) as mock_corrections, pytest.raises(test_module.DIDNotFound): + with ( + mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr, + mock.patch.object(test_module, "LegacyDocCorrections") as mock_corrections, + pytest.raises(test_module.DIDNotFound), + ): doc = object mock_corrections.apply = mock.MagicMock(return_value=doc) mock_mgr.return_value = mock.MagicMock( diff --git a/acapy_agent/resolver/default/tests/test_tdw.py b/acapy_agent/resolver/default/tests/test_tdw.py new file mode 100644 index 0000000000..8829b9f031 --- /dev/null +++ b/acapy_agent/resolver/default/tests/test_tdw.py @@ -0,0 +1,36 @@ +import pytest + +from ....core.profile import Profile +from ....messaging.valid import DIDTdw +from ....utils.testing import create_test_profile +from ..tdw import TdwDIDResolver + +TEST_DID = "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example" + + +@pytest.fixture +def resolver(): + """Resolver fixture.""" + yield TdwDIDResolver() + + +@pytest.fixture +async def profile(): + """Profile fixture.""" + yield await create_test_profile() + + +@pytest.mark.asyncio +async def test_supported_did_regex(profile, resolver: TdwDIDResolver): + """Test the supported_did_regex.""" + assert resolver.supported_did_regex == DIDTdw.PATTERN + assert await resolver.supports( + profile, + TEST_DID, + ) + + +@pytest.mark.asyncio +async def test_resolve(resolver: TdwDIDResolver, profile: Profile): + """Test resolve method.""" + assert await resolver.resolve(profile, TEST_DID) diff --git a/acapy_agent/resolver/default/tests/test_universal.py b/acapy_agent/resolver/default/tests/test_universal.py index 36b2cc73db..c516ac7068 100644 --- a/acapy_agent/resolver/default/tests/test_universal.py +++ b/acapy_agent/resolver/default/tests/test_universal.py @@ -119,6 +119,7 @@ async def test_fetch_resolver_props(mock_client_session: MockClientSession): @pytest.mark.asyncio async def test_get_supported_did_regex(): + # Old response format props = {"example": {"http": {"pattern": "match a test string"}}} with mock.patch.object( UniversalResolver, @@ -128,6 +129,29 @@ async def test_get_supported_did_regex(): pattern = await UniversalResolver()._get_supported_did_regex() assert pattern.fullmatch("match a test string") + # Example response from dev universal resolver 1.0 + props = { + "^(did:sov:(?:(?:\\w[-\\w]*(?::\\w[-\\w]*)*):)?(?:[1-9A-HJ-NP-Za-km-z]{21,22}))$": { + "libIndyPath": "", + "openParallel": "false", + "poolVersions": "_;2;test;2;builder;2;danube;2;idunion;2;idunion:test;2;indicio;2;indicio:test;2;indicio:demo;2;nxd;2;findy:test;2;bcovrin;2;bcovrin:test;2;bcovrin:dev;2;candy;2;candy:test;2;candy:dev;2", + "submitterDidSeeds": "_;_;test;_;builder;_;danube;_;idunion;_;idunion:test;_;indicio;_;indicio:test;_;indicio:demo;_;nxd;_;findy:test;_;bcovrin;_;bcovrin:test;_;bcovrin:dev;_;candy;_;candy:test;_;candy:dev;_", + "http": { + "resolveUri": "http://driver-did-sov:8080/1.0/identifiers/", + "propertiesUri": "http://driver-did-sov:8080/1.0/properties", + }, + "walletNames": "_;w1;test;w2;builder;w3;danube;w4;idunion;w5;idunion:test;w6;indicio;w7;indicio:test;w8;indicio:demo;w9;nxd;w11;findy:test;w12;bcovrin;w13;bcovrin:test;w14;bcovrin:dev;w15;candy;w16;candy:test;w17;candy:dev;w18", + "poolConfigs": "_;./sovrin/_.txn;test;./sovrin/test.txn;builder;./sovrin/builder.txn;danube;./sovrin/danube.txn;idunion;./sovrin/idunion.txn;idunion:test;./sovrin/idunion-test.txn;indicio;./sovrin/indicio.txn;indicio:test;./sovrin/indicio-test.txn;indicio:demo;./sovrin/indicio-demo.txn;nxd;./sovrin/nxd.txn;bcovrin:test;./sovrin/bcovrin-test.txn;candy;./sovrin/candy.txn;candy:test;./sovrin/candy-test.txn;candy:dev;./sovrin/candy-dev.txn", + } + } + with mock.patch.object( + UniversalResolver, + "_fetch_resolver_props", + mock.CoroutineMock(return_value=props), + ): + pattern = await UniversalResolver()._get_supported_did_regex() + assert pattern.match("did:sov:WRfXPg8dantKVubE3HX8pw") + def test_compile_supported_did_regex(): patterns = ["one", "two", "three"] diff --git a/acapy_agent/resolver/default/universal.py b/acapy_agent/resolver/default/universal.py index 4d359a9a6e..8d4b1eb1d8 100644 --- a/acapy_agent/resolver/default/universal.py +++ b/acapy_agent/resolver/default/universal.py @@ -110,8 +110,16 @@ async def _fetch_resolver_props(self) -> dict: "Failed to retrieve resolver properties: " + await resp.text() ) - async def _get_supported_did_regex(self) -> Pattern: + async def _get_supported_did_regex(self): props = await self._fetch_resolver_props() - return _compile_supported_did_regex( - driver["http"]["pattern"] for driver in props.values() - ) + + def _get_patterns(): + """Handle both old and new properties responses.""" + patterns = list(props.values())[0].get("http", {}).get("pattern") + if not patterns: + return props.keys() + else: + return [driver["http"]["pattern"] for driver in props.values()] + + patterns = _get_patterns() + return _compile_supported_did_regex(patterns) diff --git a/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py b/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py index 8038414429..12488dd350 100644 --- a/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py +++ b/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py @@ -178,28 +178,32 @@ async def test_fix_ledger_entry(self, mock_handle): settings={"tails_server_base_url": "http://1.2.3.4:8088"}, ) _test_profile.context.injector.bind_instance(BaseLedger, self.ledger) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "query_by_ids", - mock.CoroutineMock( - return_value=[ - test_module.IssuerCredRevRecord( - record_id=test_module.UUID4_EXAMPLE, - state=test_module.IssuerCredRevRecord.STATE_REVOKED, - cred_ex_id=test_module.UUID4_EXAMPLE, - rev_reg_id=REV_REG_ID, - cred_rev_id="1", - ) - ] + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "query_by_ids", + mock.CoroutineMock( + return_value=[ + test_module.IssuerCredRevRecord( + record_id=test_module.UUID4_EXAMPLE, + state=test_module.IssuerCredRevRecord.STATE_REVOKED, + cred_ex_id=test_module.UUID4_EXAMPLE, + rev_reg_id=REV_REG_ID, + cred_rev_id="1", + ) + ] + ), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_revoc_reg_id", + mock.CoroutineMock(return_value=rec), + ), + mock.patch.object( + test_module, + "generate_ledger_rrrecovery_txn", + mock.CoroutineMock(return_value=rev_reg_delta), ), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_revoc_reg_id", - mock.CoroutineMock(return_value=rec), - ), mock.patch.object( - test_module, - "generate_ledger_rrrecovery_txn", - mock.CoroutineMock(return_value=rev_reg_delta), ): assert ( _test_rev_reg_delta, diff --git a/acapy_agent/revocation/models/tests/test_revocation_registry.py b/acapy_agent/revocation/models/tests/test_revocation_registry.py index 6416d38767..d438a42aa3 100644 --- a/acapy_agent/revocation/models/tests/test_revocation_registry.py +++ b/acapy_agent/revocation/models/tests/test_revocation_registry.py @@ -128,13 +128,11 @@ async def test_retrieve_tails(self): rmtree(TAILS_DIR, ignore_errors=True) more_magic = mock.MagicMock() - with mock.patch.object( - test_module, "Session", autospec=True - ) as mock_session, mock.patch.object( - base58, "b58encode", mock.MagicMock() - ) as mock_b58enc, mock.patch.object( - Path, "is_file", autospec=True - ) as mock_is_file: + with ( + mock.patch.object(test_module, "Session", autospec=True) as mock_session, + mock.patch.object(base58, "b58encode", mock.MagicMock()) as mock_b58enc, + mock.patch.object(Path, "is_file", autospec=True) as mock_is_file, + ): mock_session.return_value.__enter__ = mock.MagicMock(return_value=more_magic) more_magic.get = mock.MagicMock( return_value=mock.MagicMock( diff --git a/acapy_agent/revocation/tests/test_indy.py b/acapy_agent/revocation/tests/test_indy.py index 26a44e35a2..224369b372 100644 --- a/acapy_agent/revocation/tests/test_indy.py +++ b/acapy_agent/revocation/tests/test_indy.py @@ -226,13 +226,16 @@ async def test_get_ledger_registry(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=(None, self.ledger)), - ), mock.patch.object( - RevocationRegistry, "from_definition", mock.MagicMock() - ) as mock_from_def: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=(None, self.ledger)), + ), + mock.patch.object( + RevocationRegistry, "from_definition", mock.MagicMock() + ) as mock_from_def, + ): result = await self.revoc.get_ledger_registry("dummy2") assert result == mock_from_def.return_value assert "dummy2" in IndyRevocation.REV_REG_CACHE diff --git a/acapy_agent/revocation/tests/test_manager.py b/acapy_agent/revocation/tests/test_manager.py index 7e4d85baf5..3105141cb8 100644 --- a/acapy_agent/revocation/tests/test_manager.py +++ b/acapy_agent/revocation/tests/test_manager.py @@ -59,16 +59,18 @@ async def test_revoke_credential_publish(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -120,16 +122,18 @@ async def test_revoke_credential_notify(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -200,20 +204,23 @@ async def test_revoke_credential_publish_endorser(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), - ), mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=conn_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=conn_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -270,21 +277,24 @@ async def test_revoke_credential_publish_endorser_x(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), - ), mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError("no such rec") + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=test_module.StorageNotFoundError("no such rec") + ), ), ): mock_retrieve.return_value = mock.MagicMock( @@ -350,12 +360,13 @@ async def test_revoke_credential_pend(self): issuer = mock.MagicMock(IndyIssuer, autospec=True) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): revoc.return_value.get_issuer_rev_reg_record = mock.CoroutineMock( return_value=mock_issuer_rev_reg_record @@ -420,15 +431,18 @@ async def test_publish_pending_revocations_endorser(self): ) conn_id = conn_record.connection_id assert conn_id is not None - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -482,15 +496,18 @@ async def test_publish_pending_revocations_endorser_x(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -531,14 +548,17 @@ async def test_publish_pending_revocations_basic(self): send_entry=mock.CoroutineMock(), clear_pending=mock.CoroutineMock(), ) - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) issuer.merge_revocation_registry_deltas = mock.CoroutineMock( @@ -588,15 +608,18 @@ async def test_publish_pending_revocations_1_rev_reg_all(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -648,15 +671,18 @@ async def test_publish_pending_revocations_1_rev_reg_some(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) diff --git a/acapy_agent/revocation/tests/test_routes.py b/acapy_agent/revocation/tests/test_routes.py index f79a5590f9..97f33c5cc8 100644 --- a/acapy_agent/revocation/tests/test_routes.py +++ b/acapy_agent/revocation/tests/test_routes.py @@ -117,11 +117,12 @@ async def test_revoke(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -137,14 +138,17 @@ async def test_revoke_endorser_no_conn_id_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="dummy-conn-id"), - ), mock.patch.object(test_module.web, "json_response"), mock.patch.object( - TransactionManager, "create_record", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="dummy-conn-id"), + ), + mock.patch.object(test_module.web, "json_response"), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} @@ -163,15 +167,18 @@ async def test_revoke_endorser_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ), mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="test_conn_id"), - ), mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="test_conn_id"), + ), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} ) @@ -187,14 +194,17 @@ async def test_revoke_endorser_no_conn_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value=None), - ), mock.patch.object(test_module.web, "json_response"), mock.patch.object( - TransactionManager, "create_record", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value=None), + ), + mock.patch.object(test_module.web, "json_response"), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} @@ -213,15 +223,18 @@ async def test_revoke_endorser(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ), mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="test_conn_id"), - ), mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="test_conn_id"), + ), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} ) @@ -237,12 +250,15 @@ async def test_revoke_endorser_x(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value=None), + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value=None), + ), ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() with self.assertRaises(test_module.web.HTTPBadRequest): @@ -256,11 +272,12 @@ async def test_revoke_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -276,9 +293,12 @@ async def test_revoke_not_found(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() ) @@ -289,11 +309,12 @@ async def test_revoke_not_found(self): async def test_publish_revocations(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = mock.CoroutineMock( return_value=({}, pub_pending.return_value) @@ -318,20 +339,25 @@ async def test_publish_revocations_x(self): async def test_publish_revocations_endorser(self): self.author_request.json = mock.CoroutineMock(return_value={}) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="dummy-conn-id"), - ), mock.patch.object( - TransactionManager, - "create_record", - mock.CoroutineMock(return_value=TransactionRecord()), - ), mock.patch.object( - TransactionManager, - "create_request", - mock.CoroutineMock(), + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="dummy-conn-id"), + ), + mock.patch.object( + TransactionManager, + "create_record", + mock.CoroutineMock(return_value=TransactionRecord()), + ), + mock.patch.object( + TransactionManager, + "create_request", + mock.CoroutineMock(), + ), ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = mock.CoroutineMock( @@ -385,13 +411,17 @@ async def test_publish_revocations_endorser_exceptions(self): async def test_publish_revocations_endorser_x(self): self.author_request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value=None), - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value=None), + ), + mock.patch.object(test_module.web, "json_response"), + ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = mock.CoroutineMock( return_value=( @@ -410,11 +440,12 @@ async def test_publish_revocations_endorser_x(self): async def test_clear_pending_revocations(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): clear_pending = mock.CoroutineMock() mock_mgr.return_value.clear_pending_revocations = clear_pending @@ -427,9 +458,12 @@ async def test_clear_pending_revocations(self): async def test_clear_pending_revocations_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + ): clear_pending = mock.CoroutineMock(side_effect=test_module.StorageError()) mock_mgr.return_value.clear_pending_revocations = clear_pending @@ -445,11 +479,15 @@ async def test_create_rev_reg(self): } ) - with mock.patch.object(AskarStorage, "find_all_records"), mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object(AskarStorage, "find_all_records"), + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( init_issuer_registry=mock.CoroutineMock( return_value=mock.MagicMock( @@ -472,11 +510,14 @@ async def test_create_rev_reg_no_such_cred_def(self): } ) - with mock.patch.object( - BaseStorage, "find_all_records", autospec=True - ) as mock_find, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + BaseStorage, "find_all_records", autospec=True + ) as mock_find, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_find.return_value = False with self.assertRaises(HTTPNotFound): @@ -492,13 +533,17 @@ async def test_create_rev_reg_no_revo_support(self): } ) - with mock.patch.object( - AskarStorage, "find_all_records", autospec=True - ) as mock_find, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + AskarStorage, "find_all_records", autospec=True + ) as mock_find, + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_find.return_value = True mock_indy_revoc.return_value = mock.MagicMock( init_issuer_registry=mock.CoroutineMock( @@ -520,11 +565,14 @@ async def test_rev_regs_created(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module.IssuerRevRegRecord, "query", mock.CoroutineMock() - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, "query", mock.CoroutineMock() + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_query.return_value = [mock.MagicMock(revoc_reg_id="dummy")] result = await test_module.rev_regs_created(self.request) @@ -537,11 +585,14 @@ async def test_get_rev_reg(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -560,11 +611,14 @@ async def test_get_rev_reg_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -581,17 +635,21 @@ async def test_get_rev_reg_issued(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_revoc_reg_id", - mock.CoroutineMock(), - ), mock.patch.object( - test_module.IssuerCredRevRecord, - "query_by_ids", - mock.CoroutineMock(), - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_revoc_reg_id", + mock.CoroutineMock(), + ), + mock.patch.object( + test_module.IssuerCredRevRecord, + "query_by_ids", + mock.CoroutineMock(), + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_query.return_value = [{"...": "..."}, {"...": "..."}] result = await test_module.get_rev_reg_issued_count(self.request) @@ -625,13 +683,16 @@ async def test_get_cred_rev_record(self): "cred_rev_id": CRED_REV_ID, } - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_ids", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_ids", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -645,13 +706,16 @@ async def test_get_cred_rev_record_by_cred_ex_id(self): self.request.query = {"cred_ex_id": CRED_EX_ID} - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -687,11 +751,14 @@ async def test_get_active_rev_reg(self): CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" self.request.match_info = {"cred_def_id": CRED_DEF_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_active_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -708,11 +775,14 @@ async def test_get_active_rev_reg_not_found(self): CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" self.request.match_info = {"cred_def_id": CRED_DEF_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_active_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -729,11 +799,14 @@ async def test_get_tails_file(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock(tails_local_path="dummy") @@ -750,11 +823,14 @@ async def test_get_tails_file_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -771,11 +847,14 @@ async def test_upload_tails_file_basic(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_upload = mock.CoroutineMock() mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( @@ -841,11 +920,14 @@ async def test_send_rev_reg_def(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -866,11 +948,14 @@ async def test_send_rev_reg_def_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -909,11 +994,14 @@ async def test_send_rev_reg_entry(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -933,11 +1021,14 @@ async def test_send_rev_reg_entry_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -979,11 +1070,14 @@ async def test_update_rev_reg(self): return_value={"tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}"} ) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1007,11 +1101,14 @@ async def test_update_rev_reg_not_found(self): return_value={"tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}"} ) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -1061,11 +1158,14 @@ async def test_set_rev_reg_state(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1094,11 +1194,14 @@ async def test_set_rev_reg_state_not_found(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") diff --git a/acapy_agent/revocation_anoncreds/routes.py b/acapy_agent/revocation_anoncreds/routes.py index 928ef0ebd8..4c5b3bd8b0 100644 --- a/acapy_agent/revocation_anoncreds/routes.py +++ b/acapy_agent/revocation_anoncreds/routes.py @@ -24,7 +24,7 @@ ) from ..anoncreds.default.legacy_indy.registry import LegacyIndyRegistry from ..anoncreds.issuer import AnonCredsIssuerError -from ..anoncreds.models.anoncreds_revocation import RevRegDefState +from ..anoncreds.models.revocation import RevRegDefState from ..anoncreds.revocation import AnonCredsRevocation, AnonCredsRevocationError from ..anoncreds.routes import ( create_transaction_for_endorser_description, diff --git a/acapy_agent/revocation_anoncreds/tests/test_manager.py b/acapy_agent/revocation_anoncreds/tests/test_manager.py index 9c62d37d9d..eeacc02929 100644 --- a/acapy_agent/revocation_anoncreds/tests/test_manager.py +++ b/acapy_agent/revocation_anoncreds/tests/test_manager.py @@ -61,16 +61,18 @@ async def test_revoke_credential_publish(self): ) self.profile.context.injector.bind_instance(AnonCredsIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -139,20 +141,23 @@ async def test_revoke_credential_pend(self): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) self.profile.context.injector.bind_instance(AnonCredsIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session, mock.patch.object( - self.profile, - "transaction", - mock.MagicMock(return_value=session.return_value), - ) as session, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + mock.patch.object( + self.profile, + "transaction", + mock.MagicMock(return_value=session.return_value), + ) as session, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): revoc.return_value.get_issuer_rev_reg_record = mock.CoroutineMock( return_value=mock_issuer_rev_reg_record @@ -189,14 +194,17 @@ async def test_publish_pending_revocations_basic(self): send_entry=mock.CoroutineMock(), clear_pending=mock.CoroutineMock(), ) - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) issuer.merge_revocation_registry_deltas = mock.AsyncMock(side_effect=deltas) @@ -245,15 +253,18 @@ async def test_publish_pending_revocations_1_rev_reg_all(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) @@ -304,15 +315,18 @@ async def test_publish_pending_revocations_1_rev_reg_some(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) diff --git a/acapy_agent/revocation_anoncreds/tests/test_routes.py b/acapy_agent/revocation_anoncreds/tests/test_routes.py index 11d4ea25e3..6f0ea1577b 100644 --- a/acapy_agent/revocation_anoncreds/tests/test_routes.py +++ b/acapy_agent/revocation_anoncreds/tests/test_routes.py @@ -6,7 +6,7 @@ from aiohttp.web import HTTPNotFound from ...admin.request_context import AdminRequestContext -from ...anoncreds.models.anoncreds_revocation import RevRegDef, RevRegDefValue +from ...anoncreds.models.revocation import RevRegDef, RevRegDefValue from ...tests import mock from ...utils.testing import create_test_profile from .. import routes as test_module @@ -85,11 +85,12 @@ async def test_revoke(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -104,11 +105,12 @@ async def test_revoke_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -124,9 +126,12 @@ async def test_revoke_not_found(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() ) @@ -137,11 +142,12 @@ async def test_revoke_not_found(self): async def test_publish_revocations(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = pub_pending @@ -168,13 +174,16 @@ async def test_rev_regs_created(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definitions", - mock.AsyncMock(), - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definitions", + mock.AsyncMock(), + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_query.return_value = ["dummy"] result = await test_module.get_rev_regs(self.request) @@ -188,13 +197,15 @@ async def test_get_rev_reg(self): RECORD_ID = "4ba81d6e-f341-4e37-83d4-6b1d3e25a7bd" self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "AnonCredsRevocation", autospec=True - ) as mock_anon_creds_revoc, mock.patch.object( - test_module, "uuid4", mock.Mock() - ) as mock_uuid, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, + mock.patch.object(test_module, "uuid4", mock.Mock()) as mock_uuid, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_uuid.return_value = RECORD_ID mock_anon_creds_revoc.return_value = mock.MagicMock( get_created_revocation_registry_definition=mock.AsyncMock( @@ -250,11 +261,14 @@ async def test_get_rev_reg_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "AnonCredsRevocation", autospec=True - ) as mock_anon_creds_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_anon_creds_revoc.return_value = mock.MagicMock( get_created_revocation_registry_definition=mock.AsyncMock( return_value=None @@ -271,17 +285,21 @@ async def test_get_rev_reg_issued(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - autospec=True, - ) as mock_rev_reg_def, mock.patch.object( - test_module.IssuerCredRevRecord, - "query_by_ids", - mock.CoroutineMock(), - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + autospec=True, + ) as mock_rev_reg_def, + mock.patch.object( + test_module.IssuerCredRevRecord, + "query_by_ids", + mock.CoroutineMock(), + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_rev_reg_def.return_value = {} mock_query.return_value = [{}, {}] result = await test_module.get_rev_reg_issued_count(self.request) @@ -316,13 +334,16 @@ async def test_get_cred_rev_record(self): "cred_rev_id": CRED_REV_ID, } - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_ids", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_ids", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -336,13 +357,16 @@ async def test_get_cred_rev_record_by_cred_ex_id(self): self.request.query = {"cred_ex_id": CRED_EX_ID} - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -379,13 +403,16 @@ async def test_get_tails_file(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - mock.AsyncMock(), - ) as mock_get_rev_reg, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + mock.AsyncMock(), + ) as mock_get_rev_reg, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_get_rev_reg.return_value = RevRegDef( issuer_id="issuer_id", type="CL_ACCUM", @@ -409,13 +436,16 @@ async def test_get_tails_file_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - mock.AsyncMock(), - ) as mock_get_rev_reg, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + mock.AsyncMock(), + ) as mock_get_rev_reg, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_get_rev_reg.return_value = None with self.assertRaises(HTTPNotFound): @@ -433,13 +463,15 @@ async def test_set_rev_reg_state(self): "state": test_module.RevRegDefState.STATE_FINISHED, } - with mock.patch.object( - test_module, "AnonCredsRevocation", autospec=True - ) as mock_anon_creds_revoc, mock.patch.object( - test_module, "uuid4", mock.Mock() - ) as mock_uuid, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, + mock.patch.object(test_module, "uuid4", mock.Mock()) as mock_uuid, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_uuid.return_value = RECORD_ID mock_anon_creds_revoc.return_value = mock.MagicMock( set_rev_reg_state=mock.AsyncMock(return_value={}), @@ -500,13 +532,16 @@ async def test_set_rev_reg_state_not_found(self): "state": test_module.RevRegDefState.STATE_FINISHED, } - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - mock.AsyncMock(), - ) as mock_rev_reg_def, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + mock.AsyncMock(), + ) as mock_rev_reg_def, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_rev_reg_def.return_value = None with self.assertRaises(HTTPNotFound): diff --git a/acapy_agent/settings/tests/test_routes.py b/acapy_agent/settings/tests/test_routes.py index 7327093c78..707aa6760a 100644 --- a/acapy_agent/settings/tests/test_routes.py +++ b/acapy_agent/settings/tests/test_routes.py @@ -190,11 +190,12 @@ async def test_update_profile_settings(mock_response, profile): ), __getitem__=lambda _, k: request_dict[k], ) - with mock.patch.object( - multi_tenant_manager, "update_wallet" - ) as update_wallet, mock.patch.object( - multi_tenant_manager, "get_wallet_and_profile" - ) as get_wallet_and_profile: + with ( + mock.patch.object(multi_tenant_manager, "update_wallet") as update_wallet, + mock.patch.object( + multi_tenant_manager, "get_wallet_and_profile" + ) as get_wallet_and_profile, + ): get_wallet_and_profile.return_value = ( mock.MagicMock( settings={ diff --git a/acapy_agent/storage/tests/test_askar_storage.py b/acapy_agent/storage/tests/test_askar_storage.py index b36925ea7f..e9ddfce247 100644 --- a/acapy_agent/storage/tests/test_askar_storage.py +++ b/acapy_agent/storage/tests/test_askar_storage.py @@ -46,17 +46,23 @@ class TestAskarStorage: @pytest.mark.skip @pytest.mark.asyncio async def test_record(self): - with mock.patch.object( - indy.wallet, "create_wallet", mock.CoroutineMock() - ) as mock_create, mock.patch.object( - indy.wallet, "open_wallet", mock.CoroutineMock() - ) as mock_open, mock.patch.object( - indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() - ) as mock_master, mock.patch.object( - indy.wallet, "close_wallet", mock.CoroutineMock() - ) as mock_close, mock.patch.object( - indy.wallet, "delete_wallet", mock.CoroutineMock() - ) as mock_delete: + with ( + mock.patch.object( + indy.wallet, "create_wallet", mock.CoroutineMock() + ) as mock_create, + mock.patch.object( + indy.wallet, "open_wallet", mock.CoroutineMock() + ) as mock_open, + mock.patch.object( + indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() + ) as mock_master, + mock.patch.object( + indy.wallet, "close_wallet", mock.CoroutineMock() + ) as mock_close, + mock.patch.object( + indy.wallet, "delete_wallet", mock.CoroutineMock() + ) as mock_delete, + ): fake_wallet = AskarWallet( { "auto_create": True, @@ -154,19 +160,23 @@ async def test_record(self): with pytest.raises(test_module.StorageError): await storage.get_record("connection", "dummy-id") - with mock.patch.object( - test_module.non_secrets, - "update_wallet_record_value", - mock.CoroutineMock(), - ) as mock_update_value, mock.patch.object( - test_module.non_secrets, - "update_wallet_record_tags", - mock.CoroutineMock(), - ) as mock_update_tags, mock.patch.object( - test_module.non_secrets, - "delete_wallet_record", - mock.CoroutineMock(), - ) as mock_delete: + with ( + mock.patch.object( + test_module.non_secrets, + "update_wallet_record_value", + mock.CoroutineMock(), + ) as mock_update_value, + mock.patch.object( + test_module.non_secrets, + "update_wallet_record_tags", + mock.CoroutineMock(), + ) as mock_update_tags, + mock.patch.object( + test_module.non_secrets, + "delete_wallet_record", + mock.CoroutineMock(), + ) as mock_delete, + ): mock_update_value.side_effect = test_module.IndyError( test_module.ErrorCode.CommonInvalidStructure ) @@ -209,17 +219,23 @@ async def test_record(self): @pytest.mark.skip @pytest.mark.asyncio async def test_storage_search_x(self): - with mock.patch.object( - indy.wallet, "create_wallet", mock.CoroutineMock() - ) as mock_create, mock.patch.object( - indy.wallet, "open_wallet", mock.CoroutineMock() - ) as mock_open, mock.patch.object( - indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() - ) as mock_master, mock.patch.object( - indy.wallet, "close_wallet", mock.CoroutineMock() - ) as mock_close, mock.patch.object( - indy.wallet, "delete_wallet", mock.CoroutineMock() - ) as mock_delete: + with ( + mock.patch.object( + indy.wallet, "create_wallet", mock.CoroutineMock() + ) as mock_create, + mock.patch.object( + indy.wallet, "open_wallet", mock.CoroutineMock() + ) as mock_open, + mock.patch.object( + indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() + ) as mock_master, + mock.patch.object( + indy.wallet, "close_wallet", mock.CoroutineMock() + ) as mock_close, + mock.patch.object( + indy.wallet, "delete_wallet", mock.CoroutineMock() + ) as mock_delete, + ): fake_wallet = AskarWallet( { "auto_create": True, @@ -246,26 +262,33 @@ async def test_storage_search_x(self): with pytest.raises(StorageSearchError): await search.fetch(10) - with mock.patch.object( - indy.non_secrets, "open_wallet_search", mock.CoroutineMock() - ) as mock_indy_open_search, mock.patch.object( - indy.non_secrets, "close_wallet_search", mock.CoroutineMock() - ) as mock_indy_close_search: + with ( + mock.patch.object( + indy.non_secrets, "open_wallet_search", mock.CoroutineMock() + ) as mock_indy_open_search, + mock.patch.object( + indy.non_secrets, "close_wallet_search", mock.CoroutineMock() + ) as mock_indy_close_search, + ): mock_indy_open_search.side_effect = test_module.IndyError("no open") search = storage.search_records("connection") with pytest.raises(StorageSearchError): await search.open() await search.close() - with mock.patch.object( - indy.non_secrets, "open_wallet_search", mock.CoroutineMock() - ) as mock_indy_open_search, mock.patch.object( - indy.non_secrets, - "fetch_wallet_search_next_records", - mock.CoroutineMock(), - ) as mock_indy_fetch, mock.patch.object( - indy.non_secrets, "close_wallet_search", mock.CoroutineMock() - ) as mock_indy_close_search: + with ( + mock.patch.object( + indy.non_secrets, "open_wallet_search", mock.CoroutineMock() + ) as mock_indy_open_search, + mock.patch.object( + indy.non_secrets, + "fetch_wallet_search_next_records", + mock.CoroutineMock(), + ) as mock_indy_fetch, + mock.patch.object( + indy.non_secrets, "close_wallet_search", mock.CoroutineMock() + ) as mock_indy_close_search, + ): mock_indy_fetch.side_effect = test_module.IndyError("no fetch") search = storage.search_records("connection") await search.open() @@ -273,11 +296,14 @@ async def test_storage_search_x(self): await search.fetch(10) await search.close() - with mock.patch.object( - indy.non_secrets, "open_wallet_search", mock.CoroutineMock() - ) as mock_indy_open_search, mock.patch.object( - indy.non_secrets, "close_wallet_search", mock.CoroutineMock() - ) as mock_indy_close_search: + with ( + mock.patch.object( + indy.non_secrets, "open_wallet_search", mock.CoroutineMock() + ) as mock_indy_open_search, + mock.patch.object( + indy.non_secrets, "close_wallet_search", mock.CoroutineMock() + ) as mock_indy_close_search, + ): mock_indy_close_search.side_effect = test_module.IndyError("no close") search = storage.search_records("connection") await search.open() @@ -359,7 +385,7 @@ async def test_askar_storage_search_session(self): profile = "profileId" with mock.patch("acapy_agent.storage.askar.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, True) + askar_profile = await AskarProfile.create(None, True) askar_profile_scan = mock.MagicMock() askar_profile.store.scan.return_value = askar_profile_scan askar_profile.settings.get.return_value = profile diff --git a/acapy_agent/tests/test_main.py b/acapy_agent/tests/test_main.py index ea2d7b0573..c403d0469d 100644 --- a/acapy_agent/tests/test_main.py +++ b/acapy_agent/tests/test_main.py @@ -5,11 +5,11 @@ class TestMain(TestCase): def test_main(self): - with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "init_debug", mock.MagicMock() - ) as mock_debug, mock.patch.object( - test_module, "run", mock.MagicMock() - ) as mock_run: + with ( + mock.patch.object(test_module, "__name__", "__main__"), + mock.patch.object(test_module, "init_debug", mock.MagicMock()) as mock_debug, + mock.patch.object(test_module, "run", mock.MagicMock()) as mock_run, + ): args = ["aca-py"] test_module.main(args) mock_debug.assert_called_once_with(args) diff --git a/acapy_agent/transport/inbound/tests/test_session.py b/acapy_agent/transport/inbound/tests/test_session.py index 985fbc7f3a..421adcc3c8 100644 --- a/acapy_agent/transport/inbound/tests/test_session.py +++ b/acapy_agent/transport/inbound/tests/test_session.py @@ -134,11 +134,10 @@ async def test_receive(self): ) test_msg = mock.MagicMock() - with mock.patch.object( - sess, "parse_inbound", mock.CoroutineMock() - ) as encode, mock.patch.object( - sess, "receive_inbound", mock.MagicMock() - ) as receive: + with ( + mock.patch.object(sess, "parse_inbound", mock.CoroutineMock()) as encode, + mock.patch.object(sess, "receive_inbound", mock.MagicMock()) as receive, + ): result = await sess.receive(test_msg) encode.assert_awaited_once_with(test_msg) receive.assert_called_once_with(encode.return_value) @@ -165,11 +164,10 @@ async def test_receive_no_wallet_found(self): ) test_msg = mock.MagicMock() - with mock.patch.object( - sess, "parse_inbound", mock.CoroutineMock() - ) as encode, mock.patch.object( - sess, "receive_inbound", mock.MagicMock() - ) as receive: + with ( + mock.patch.object(sess, "parse_inbound", mock.CoroutineMock()) as encode, + mock.patch.object(sess, "receive_inbound", mock.MagicMock()) as receive, + ): result = await sess.receive(test_msg) encode.assert_awaited_once_with(test_msg) receive.assert_called_once_with(encode.return_value) diff --git a/acapy_agent/transport/outbound/tests/test_manager.py b/acapy_agent/transport/outbound/tests/test_manager.py index abdd0252a2..18ad129a8f 100644 --- a/acapy_agent/transport/outbound/tests/test_manager.py +++ b/acapy_agent/transport/outbound/tests/test_manager.py @@ -224,11 +224,13 @@ async def test_process_loop_new(self): message=mock.MagicMock(enc_payload=b"encr"), ) ] - with mock.patch.object( - mgr, "deliver_queued_message", mock.MagicMock() - ), mock.patch.object( - mgr.outbound_event, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object(test_module, "trace_event", mock.MagicMock()): + with ( + mock.patch.object(mgr, "deliver_queued_message", mock.MagicMock()), + mock.patch.object( + mgr.outbound_event, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(test_module, "trace_event", mock.MagicMock()), + ): mock_wait.side_effect = KeyError() # cover state=NEW logic and bail with self.assertRaises(KeyError): @@ -245,11 +247,13 @@ async def test_process_loop_new_deliver(self): message=mock.MagicMock(enc_payload=b"encr"), ) ] - with mock.patch.object( - mgr, "deliver_queued_message", mock.MagicMock() - ), mock.patch.object( - mgr.outbound_event, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object(test_module, "trace_event", mock.MagicMock()): + with ( + mock.patch.object(mgr, "deliver_queued_message", mock.MagicMock()), + mock.patch.object( + mgr.outbound_event, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(test_module, "trace_event", mock.MagicMock()), + ): mock_wait.side_effect = KeyError() # cover state=DELIVER logic and bail with self.assertRaises(KeyError): @@ -278,14 +282,13 @@ async def test_finished_deliver_x_log_debug(self): mock_handle_not_delivered = mock.MagicMock() mgr = OutboundTransportManager(self.profile, mock_handle_not_delivered) mgr.outbound_buffer.append(mock_queued) - with mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ), mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ), mock.patch.object( - test_module.LOGGER, "isEnabledFor", mock.MagicMock() - ) as mock_logger_enabled, mock.patch.object( - mgr, "process_queued", mock.MagicMock() + with ( + mock.patch.object(test_module.LOGGER, "exception", mock.MagicMock()), + mock.patch.object(test_module.LOGGER, "error", mock.MagicMock()), + mock.patch.object( + test_module.LOGGER, "isEnabledFor", mock.MagicMock() + ) as mock_logger_enabled, + mock.patch.object(mgr, "process_queued", mock.MagicMock()), ): mock_logger_enabled.return_value = True # cover debug logging mgr.finished_deliver(mock_queued, mock_completed_x) diff --git a/acapy_agent/transport/queue/tests/test_basic_queue.py b/acapy_agent/transport/queue/tests/test_basic_queue.py index 6d54899f69..992ba3a7be 100644 --- a/acapy_agent/transport/queue/tests/test_basic_queue.py +++ b/acapy_agent/transport/queue/tests/test_basic_queue.py @@ -37,13 +37,16 @@ async def test_dequeue_x(self): test_value = "test value" await queue.enqueue(test_value) - with mock.patch.object( - test_module.asyncio, "get_event_loop", mock.MagicMock() - ) as mock_get_event_loop, mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - queue, "stop_event" - ) as mock_stop_event, mock.patch.object(queue, "queue"): + with ( + mock.patch.object( + test_module.asyncio, "get_event_loop", mock.MagicMock() + ) as mock_get_event_loop, + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(queue, "stop_event") as mock_stop_event, + mock.patch.object(queue, "queue"), + ): mock_stop_event.is_set.return_value = False mock_wait.return_value = ( mock.MagicMock(), @@ -68,13 +71,16 @@ async def test_dequeue_none(self): test_value = "test value" await queue.enqueue(test_value) - with mock.patch.object( - test_module.asyncio, "get_event_loop", mock.MagicMock() - ) as mock_get_event_loop, mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - queue, "stop_event" - ) as mock_stop_event, mock.patch.object(queue, "queue"): + with ( + mock.patch.object( + test_module.asyncio, "get_event_loop", mock.MagicMock() + ) as mock_get_event_loop, + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(queue, "stop_event") as mock_stop_event, + mock.patch.object(queue, "queue"), + ): mock_stop_event.is_set.return_value = False mock_wait.return_value = ( mock.MagicMock(), diff --git a/acapy_agent/transport/v2_pack_format.py b/acapy_agent/transport/v2_pack_format.py index 266c0b8b08..92e26da698 100644 --- a/acapy_agent/transport/v2_pack_format.py +++ b/acapy_agent/transport/v2_pack_format.py @@ -63,8 +63,7 @@ async def parse_message( try: message_unpack = await messaging.unpack(message_json) except CryptoServiceError: - LOGGER.debug("Message unpack failed, falling back to JSON") - print("HIT CRTYPTO SER ERR EXCEPT BLOC") + LOGGER.info("Message unpack failed, falling back to JSON") else: # Set message_dict to be the dictionary that we unpacked message_dict = message_unpack.message diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 29fd81bc4d..7e8c1e3b31 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -1,6 +1,7 @@ """The classloader provides utilities to dynamically load classes and modules.""" import inspect +import logging import sys from importlib import import_module, resources from importlib.util import find_spec, resolve_name @@ -9,6 +10,8 @@ from ..core.error import BaseError +LOGGER = logging.getLogger(__name__) + class ModuleLoadError(BaseError): """Module load error.""" @@ -21,8 +24,13 @@ class ClassNotFoundError(BaseError): class ClassLoader: """Class used to load classes from modules dynamically.""" + _module_cache = {} # Cache for loaded modules + _class_cache = {} # Cache for loaded classes + @classmethod - def load_module(cls, mod_path: str, package: Optional[str] = None) -> ModuleType: + def load_module( + cls, mod_path: str, package: Optional[str] = None + ) -> Optional[ModuleType]: """Load a module by its absolute path. Args: @@ -36,6 +44,12 @@ def load_module(cls, mod_path: str, package: Optional[str] = None) -> ModuleType ModuleLoadError: If there was an error loading the module """ + + # Check the cache + cache_key = (mod_path, package) + if cache_key in cls._module_cache: + return cls._module_cache[cache_key] + if package: # preload parent package if not cls.load_module(package): @@ -45,8 +59,11 @@ def load_module(cls, mod_path: str, package: Optional[str] = None) -> ModuleType mod_path = f".{mod_path}" full_path = resolve_name(mod_path, package) + if full_path in sys.modules: - return sys.modules[full_path] + module = sys.modules[full_path] + cls._module_cache[cache_key] = module # Cache the module for future lookups + return module if "." in mod_path: parent_mod_path, mod_name = mod_path.rsplit(".", 1) @@ -58,14 +75,16 @@ def load_module(cls, mod_path: str, package: Optional[str] = None) -> ModuleType mod_path = f".{mod_name}" # Load the module spec first - # this means that a later ModuleNotFoundError indicates a code issue spec = find_spec(mod_path, package) if not spec: return None try: - return import_module(mod_path, package) + module = import_module(mod_path, package) + cls._module_cache[cache_key] = module # Cache the loaded module + return module except ModuleNotFoundError as e: + LOGGER.warning("Module %s not found during import", full_path) raise ModuleLoadError(f"Unable to import module {full_path}: {str(e)}") from e @classmethod @@ -91,29 +110,47 @@ def load_class( """ + # Check the cache + cache_key = (class_name, default_module, package) + if cache_key in cls._class_cache: + return cls._class_cache[cache_key] + if "." in class_name: # import module and find class mod_path, class_name = class_name.rsplit(".", 1) elif default_module: mod_path = default_module + LOGGER.debug("No module in class name, using default_module: %s", mod_path) else: + LOGGER.warning( + "Cannot resolve class name %s with no default module", class_name + ) raise ClassNotFoundError( f"Cannot resolve class name with no default module: {class_name}" ) mod = cls.load_module(mod_path, package) if not mod: - raise ClassNotFoundError(f"Module '{mod_path}' not found") + LOGGER.warning( + "Module %s not found when loading class %s", mod_path, class_name + ) + raise ClassNotFoundError(f"Module {mod_path} not found") resolved = getattr(mod, class_name, None) if not resolved: + LOGGER.warning("Class %s not found in module %s", class_name, mod_path) raise ClassNotFoundError( f"Class '{class_name}' not defined in module: {mod_path}" ) if not isinstance(resolved, type): + LOGGER.warning( + "Resolved attribute %s in module %s is not a class", class_name, mod_path + ) raise ClassNotFoundError( f"Resolved value is not a class: {mod_path}.{class_name}" ) + LOGGER.debug("Successfully loaded class %s from module %s", class_name, mod_path) + cls._class_cache[cache_key] = resolved # Cache the resolved class return resolved @classmethod @@ -138,9 +175,14 @@ def load_subclass_of( mod = cls.load_module(mod_path, package) if not mod: + LOGGER.warning( + "Module %s not found when loading subclass of %s", + mod_path, + base_class.__name__, + ) raise ClassNotFoundError(f"Module '{mod_path}' not found") - # Find an the first declared class that inherits from + # Find the first declared class that inherits from the base_class try: imported_class = next( obj @@ -148,6 +190,11 @@ def load_subclass_of( if issubclass(obj, base_class) and obj is not base_class ) except StopIteration: + LOGGER.debug( + "No subclass of %s found in module %s", + base_class.__name__, + mod_path, + ) raise ClassNotFoundError( f"Could not resolve a class that inherits from {base_class}" ) from None @@ -156,17 +203,22 @@ def load_subclass_of( @classmethod def scan_subpackages(cls, package: str) -> Sequence[str]: """Return a list of sub-packages defined under a named package.""" + LOGGER.debug("Scanning subpackages under package %s", package) if "." in package: package, sub_pkg = package.split(".", 1) + LOGGER.debug("Extracted main package: %s, sub-package: %s", package, sub_pkg) else: sub_pkg = "." + LOGGER.debug("No sub-package provided, defaulting to %s", sub_pkg) try: package_path = resources.files(package) except FileNotFoundError: + LOGGER.warning("Package %s not found during subpackage scan", package) raise ModuleLoadError(f"Undefined package {package}") if not (package_path / sub_pkg).is_dir(): + LOGGER.warning("Sub-package %s is not a directory under %s", sub_pkg, package) raise ModuleLoadError(f"Undefined package {package}") found = [] @@ -174,25 +226,30 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: sub_path = package_path / sub_pkg for item in sub_path.iterdir(): if (item / "__init__.py").exists(): - found.append(f"{package}.{joiner}{item.name}") + subpackage = f"{package}.{joiner}{item.name}" + found.append(subpackage) + LOGGER.debug("%d sub-packages found under %s: %s", len(found), package, found) return found class DeferLoad: """Helper to defer loading of a class definition.""" + _class_cache = {} # Shared cache for resolved classes + def __init__(self, cls_path: str): """Initialize the `DeferLoad` instance with a qualified class path.""" self._cls_path = cls_path - self._inst = None def __call__(self, *args, **kwargs): """Magic method to call the `DeferLoad` as a function.""" - return (self.resolved)(*args, **kwargs) + return self.resolved(*args, **kwargs) @property def resolved(self): """Accessor for the resolved class instance.""" - if not self._inst: - self._inst = ClassLoader.load_class(self._cls_path) - return self._inst + if self._cls_path not in DeferLoad._class_cache: + DeferLoad._class_cache[self._cls_path] = ClassLoader.load_class( + self._cls_path + ) + return DeferLoad._class_cache[self._cls_path] diff --git a/acapy_agent/utils/testing.py b/acapy_agent/utils/testing.py index 2ee34cf125..169bfb3cd8 100644 --- a/acapy_agent/utils/testing.py +++ b/acapy_agent/utils/testing.py @@ -38,11 +38,11 @@ async def create_test_profile( opened = await store_config.open_store(provision=True, in_memory=True) if settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( opened=opened, context=context, ) - return AskarProfile( + return await AskarProfile.create( opened=opened, context=context, ) diff --git a/acapy_agent/utils/tests/test_classloader.py b/acapy_agent/utils/tests/test_classloader.py index 5a9c8be5e5..daead84132 100644 --- a/acapy_agent/utils/tests/test_classloader.py +++ b/acapy_agent/utils/tests/test_classloader.py @@ -42,9 +42,12 @@ def test_import_missing(self): assert ClassLoader.load_module("acapy_agent", "not.a-module") is None def test_import_error(self): - with mock.patch.object( - test_module, "import_module", autospec=True - ) as import_module, mock.patch.object(test_module.sys, "modules", {}): + with ( + mock.patch.object( + test_module, "import_module", autospec=True + ) as import_module, + mock.patch.object(test_module.sys, "modules", {}), + ): import_module.side_effect = ModuleNotFoundError with self.assertRaises(ModuleLoadError): ClassLoader.load_module("acapy_agent.config") diff --git a/acapy_agent/utils/tests/test_task_queue.py b/acapy_agent/utils/tests/test_task_queue.py index 26815e87cc..b079bf53bb 100644 --- a/acapy_agent/utils/tests/test_task_queue.py +++ b/acapy_agent/utils/tests/test_task_queue.py @@ -106,11 +106,10 @@ def done(complete: CompletedTask): async def noop(): return - with mock.patch.object( - queue, "drain", mock.MagicMock() - ) as mock_drain, mock.patch.object( - queue, "wait_for", mock.CoroutineMock() - ) as mock_wait_for: + with ( + mock.patch.object(queue, "drain", mock.MagicMock()) as mock_drain, + mock.patch.object(queue, "wait_for", mock.CoroutineMock()) as mock_wait_for, + ): mock_drain.side_effect = [queue.loop.create_task(noop()), None] await queue.complete(cleanup=True) diff --git a/acapy_agent/vc/ld_proofs/crypto/key_pair.py b/acapy_agent/vc/ld_proofs/crypto/key_pair.py index 0409bc3769..c11e249eea 100644 --- a/acapy_agent/vc/ld_proofs/crypto/key_pair.py +++ b/acapy_agent/vc/ld_proofs/crypto/key_pair.py @@ -1,6 +1,6 @@ """Base key pair class.""" -from abc import ABC, abstractmethod, abstractproperty +from abc import ABC, abstractmethod from typing import List, Optional, Union @@ -15,7 +15,8 @@ async def sign(self, message: Union[List[bytes], bytes]) -> bytes: async def verify(self, message: Union[List[bytes], bytes], signature: bytes) -> bool: """Verify message(s) against signature using key pair.""" - @abstractproperty + @property + @abstractmethod def has_public_key(self) -> bool: """Whether key pair has a public key. @@ -23,7 +24,8 @@ def has_public_key(self) -> bool: in the verification process. """ - @abstractproperty + @property + @abstractmethod def public_key(self) -> Optional[bytes]: """Getter for the public key bytes. diff --git a/acapy_agent/vc/vc_di/prove.py b/acapy_agent/vc/vc_di/prove.py index 33c94fa544..acba4359fe 100644 --- a/acapy_agent/vc/vc_di/prove.py +++ b/acapy_agent/vc/vc_di/prove.py @@ -1,6 +1,7 @@ """Verifiable Credential and Presentation proving methods.""" import asyncio +import logging import re from hashlib import sha256 from typing import Any, Optional, Tuple @@ -20,6 +21,8 @@ from ...core.profile import Profile from ..ld_proofs import LinkedDataProofException, ProofPurpose +LOGGER = logging.getLogger(__name__) + async def create_signed_anoncreds_presentation( *, @@ -311,7 +314,7 @@ async def prepare_data_for_presentation( # issuer_id = field["filter"]["const"] pass else: - print("... skipping:", path) + LOGGER.info("... skipping: %s", path) return anoncreds_proofrequest, w3c_creds_metadata diff --git a/acapy_agent/vc/vc_ld/models/linked_data_proof.py b/acapy_agent/vc/vc_ld/models/linked_data_proof.py index c441ff5911..57853000c6 100644 --- a/acapy_agent/vc/vc_ld/models/linked_data_proof.py +++ b/acapy_agent/vc/vc_ld/models/linked_data_proof.py @@ -6,8 +6,8 @@ from ....messaging.models.base import BaseModel, BaseModelSchema from ....messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, UUID4_EXAMPLE, Uri, ) @@ -93,13 +93,13 @@ class Meta: created = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "The string value of an ISO8601 combined date and time string generated" " by the Signature Algorithm" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/vc/vc_ld/models/options.py b/acapy_agent/vc/vc_ld/models/options.py index 2d7adbe4e2..a939df56ac 100644 --- a/acapy_agent/vc/vc_ld/models/options.py +++ b/acapy_agent/vc/vc_ld/models/options.py @@ -5,8 +5,8 @@ from marshmallow import INCLUDE, Schema, fields from acapy_agent.messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, UUID4_EXAMPLE, ) @@ -124,13 +124,13 @@ class Meta: created = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "The date and time of the proof (with a maximum accuracy in seconds)." " Defaults to current system time" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/vc/vc_ld/tests/test_manager.py b/acapy_agent/vc/vc_ld/tests/test_manager.py index 7b5dd4c81b..bc6a5b3d4b 100644 --- a/acapy_agent/vc/vc_ld/tests/test_manager.py +++ b/acapy_agent/vc/vc_ld/tests/test_manager.py @@ -158,15 +158,18 @@ async def test_get_did_info_for_did_sov(self): assert did_info == did async def test_get_suite_for_document(self): - with mock.patch.object( - self.manager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ) as mock_can_issue, mock.patch.object( - self.manager, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info: + with ( + mock.patch.object( + self.manager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ) as mock_can_issue, + mock.patch.object( + self.manager, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + ): suite = await self.manager._get_suite_for_document(self.vc, self.options) assert suite.signature_type == self.options.proof_type diff --git a/acapy_agent/wallet/anoncreds_upgrade.py b/acapy_agent/wallet/anoncreds_upgrade.py index 12f2cb2dd3..4261acf0eb 100644 --- a/acapy_agent/wallet/anoncreds_upgrade.py +++ b/acapy_agent/wallet/anoncreds_upgrade.py @@ -21,15 +21,15 @@ CATEGORY_CRED_DEF_PRIVATE, CATEGORY_SCHEMA, ) -from ..anoncreds.models.anoncreds_cred_def import CredDef, CredDefState -from ..anoncreds.models.anoncreds_revocation import ( +from ..anoncreds.models.credential_definition import CredDef, CredDefState +from ..anoncreds.models.revocation import ( RevList, RevListState, RevRegDef, RevRegDefState, RevRegDefValue, ) -from ..anoncreds.models.anoncreds_schema import SchemaState +from ..anoncreds.models.schema import SchemaState from ..anoncreds.revocation import ( CATEGORY_REV_LIST, CATEGORY_REV_REG_DEF, @@ -699,6 +699,7 @@ async def check_upgrade_completion_loop(profile: Profile, is_subwallet=False): UpgradeInProgressSingleton().remove_wallet(profile.name) if is_subwallet: await upgrade_subwallet(profile) + await finish_upgrade(profile) LOGGER.info( f"""Upgrade of subwallet {profile.settings.get('wallet.name')} has completed. Profile is now askar-anoncreds""" # noqa: E501 ) diff --git a/acapy_agent/wallet/crypto.py b/acapy_agent/wallet/crypto.py index 0ceef63a91..37ddeb7a13 100644 --- a/acapy_agent/wallet/crypto.py +++ b/acapy_agent/wallet/crypto.py @@ -1,5 +1,6 @@ """Cryptography functions used by BasicWallet.""" +import logging import re from collections import OrderedDict from typing import Callable, List, Optional, Sequence, Tuple, Union @@ -20,6 +21,8 @@ from .key_type import BLS12381G2, ED25519, KeyType from .util import b58_to_bytes, b64_to_bytes, bytes_to_b58, random_seed +LOGGER = logging.getLogger(__name__) + def create_keypair( key_type: KeyType, seed: Optional[bytes] = None @@ -423,7 +426,7 @@ def decode_pack_message_outer(enc_message: bytes) -> Tuple[dict, dict, bool]: try: wrapper = JweEnvelope.from_json(enc_message) except ValidationError as err: - print(err) + LOGGER.error(err) raise ValueError("Invalid packed message") alg = wrapper.protected.get("alg") diff --git a/acapy_agent/wallet/did_method.py b/acapy_agent/wallet/did_method.py index bf6ff57304..2acf670837 100644 --- a/acapy_agent/wallet/did_method.py +++ b/acapy_agent/wallet/did_method.py @@ -90,6 +90,13 @@ def holder_defined_did(self) -> HolderDefinedDid: holder_defined_did=HolderDefinedDid.NO, ) +TDW = DIDMethod( + name="tdw", + key_types=[ED25519, X25519], + rotation=False, + holder_defined_did=HolderDefinedDid.NO, +) + class DIDMethods: """DID Method class specifying DID methods with supported key types.""" @@ -102,6 +109,7 @@ def __init__(self) -> None: WEB.method_name: WEB, PEER2.method_name: PEER2, PEER4.method_name: PEER4, + TDW.method_name: TDW, } def registered(self, method: str) -> bool: diff --git a/acapy_agent/wallet/routes.py b/acapy_agent/wallet/routes.py index 00bc48cfb1..cf539d61ac 100644 --- a/acapy_agent/wallet/routes.py +++ b/acapy_agent/wallet/routes.py @@ -9,11 +9,10 @@ from aiohttp_apispec import docs, querystring_schema, request_schema, response_schema from marshmallow import fields, validate -from acapy_agent.connections.base_manager import BaseConnectionManager - from ..admin.decorators.auth import tenant_authentication from ..admin.request_context import AdminRequestContext from ..config.injection_context import InjectionContext +from ..connections.base_manager import BaseConnectionManager from ..connections.models.conn_record import ConnRecord from ..core.event_bus import Event, EventBus from ..core.profile import Profile @@ -35,12 +34,12 @@ GENERIC_DID_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, JWT_EXAMPLE, JWT_VALIDATE, NON_SD_LIST_EXAMPLE, NON_SD_LIST_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, SD_JWT_EXAMPLE, SD_JWT_VALIDATE, UUID4_EXAMPLE, @@ -95,10 +94,10 @@ class DIDSchema(OpenAPISchema): ) verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Public verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) posture = fields.Str( @@ -293,10 +292,10 @@ class DIDListQueryStringSchema(OpenAPISchema): ) verkey = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Verification key of interest", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) posture = fields.Str( diff --git a/acapy_agent/wallet/tests/test_anoncreds_upgrade.py b/acapy_agent/wallet/tests/test_anoncreds_upgrade.py index 37f6ab94d1..9e6c0f04ad 100644 --- a/acapy_agent/wallet/tests/test_anoncreds_upgrade.py +++ b/acapy_agent/wallet/tests/test_anoncreds_upgrade.py @@ -329,17 +329,19 @@ async def test_failed_upgrade(self): ) ) - with mock.patch.object( - anoncreds_upgrade, "upgrade_and_delete_schema_records" - ), mock.patch.object( - anoncreds_upgrade, "upgrade_and_delete_cred_def_records" - ), mock.patch.object( - AskarProfileSession, "rollback" - ) as mock_rollback, mock.patch.object( - AskarProfileSession, - "commit", - # Don't wait for sleep in retry to speed up test - ) as mock_commit, mock.patch.object(asyncio, "sleep"): + with ( + mock.patch.object(anoncreds_upgrade, "upgrade_and_delete_schema_records"), + mock.patch.object( + anoncreds_upgrade, "upgrade_and_delete_cred_def_records" + ), + mock.patch.object(AskarProfileSession, "rollback") as mock_rollback, + mock.patch.object( + AskarProfileSession, + "commit", + # Don't wait for sleep in retry to speed up test + ) as mock_commit, + mock.patch.object(asyncio, "sleep"), + ): """ Only tests schemas and cred_defs failing to upgrade because the other objects are hard to mock. These tests should be enough to cover them as the logic is the same. diff --git a/acapy_agent/wallet/tests/test_crypto.py b/acapy_agent/wallet/tests/test_crypto.py index 0596f30821..429a551179 100644 --- a/acapy_agent/wallet/tests/test_crypto.py +++ b/acapy_agent/wallet/tests/test_crypto.py @@ -39,11 +39,14 @@ def test_seeds_keys(self): assert test_module.sign_pk_from_sk(secret_key) in secret_key def test_decode_pack_message_x(self): - with mock.patch.object( - test_module, "decode_pack_message_outer", mock.MagicMock() - ) as mock_decode_outer, mock.patch.object( - test_module, "extract_payload_key", mock.MagicMock() - ) as mock_extract: + with ( + mock.patch.object( + test_module, "decode_pack_message_outer", mock.MagicMock() + ) as mock_decode_outer, + mock.patch.object( + test_module, "extract_payload_key", mock.MagicMock() + ) as mock_extract, + ): mock_decode_outer.return_value = (b"wrapper", {"my": b"recip"}, True) with pytest.raises(ValueError) as excinfo: diff --git a/demo/bdd_support/agent_backchannel_client.py b/demo/bdd_support/agent_backchannel_client.py index 5d116e2fea..fa6db011c7 100644 --- a/demo/bdd_support/agent_backchannel_client.py +++ b/demo/bdd_support/agent_backchannel_client.py @@ -143,11 +143,13 @@ def aries_container_issue_credential( the_container: AgentContainer, cred_def_id: str, cred_attrs: list, + filter_type: str = "indy", ): return run_coroutine( the_container.issue_credential, cred_def_id, cred_attrs, + filter_type=filter_type, ) @@ -167,11 +169,13 @@ def aries_container_request_proof( the_container: AgentContainer, proof_request: dict, explicit_revoc_required: bool = False, + is_anoncreds: bool = False, ): return run_coroutine( the_container.request_proof, proof_request, explicit_revoc_required=explicit_revoc_required, + is_anoncreds=is_anoncreds, ) diff --git a/demo/features/0453-issue-credential.feature b/demo/features/0453-issue-credential.feature index 3927bbf4d9..4f9b47e46d 100644 --- a/demo/features/0453-issue-credential.feature +++ b/demo/features/0453-issue-credential.feature @@ -30,7 +30,7 @@ Feature: RFC 0453 Aries agent issue credential | --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense | Data_DL_NormalizedValues | | | | --public-did --wallet-type askar-anoncreds --cred-type vc_di | --wallet-type askar-anoncreds | driverslicense | Data_DL_NormalizedValues | | | - @Release @WalletType_Askar_AnonCreds @AltTests + @PR @Release @WalletType_Askar_AnonCreds Examples: | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Acme_extra | Bob_extra | | --public-did --wallet-type askar-anoncreds | | driverslicense | Data_DL_NormalizedValues | | | diff --git a/demo/features/steps/0453-issue-credential.py b/demo/features/steps/0453-issue-credential.py index 97106d3e1d..d96fdae10a 100644 --- a/demo/features/steps/0453-issue-credential.py +++ b/demo/features/steps/0453-issue-credential.py @@ -62,10 +62,9 @@ def step_impl(context, issuer, credential_data): agent = context.active_agents[issuer] cred_attrs = read_credential_data(context.schema_name, credential_data) + filter_type = "indy" if not is_anoncreds(agent) else "anoncreds" cred_exchange = aries_container_issue_credential( - agent["agent"], - context.cred_def_id, - cred_attrs, + agent["agent"], context.cred_def_id, cred_attrs, filter_type ) context.cred_attrs = cred_attrs diff --git a/demo/features/steps/0454-present-proof.py b/demo/features/steps/0454-present-proof.py index 984ee72e63..31e91930f5 100644 --- a/demo/features/steps/0454-present-proof.py +++ b/demo/features/steps/0454-present-proof.py @@ -34,7 +34,11 @@ def step_impl(context, verifier, request_for_proof, prover): "restrictions" ] = cred_def_restrictions - proof_exchange = aries_container_request_proof(agent["agent"], proof_request_info) + proof_exchange = aries_container_request_proof( + agent["agent"], + proof_request_info, + agent["agent"].wallet_type == "askar-anoncreds", + ) context.proof_request = proof_request_info context.proof_exchange = proof_exchange @@ -49,7 +53,10 @@ def step_impl(context, verifier, request_for_proof, prover): proof_request_info = read_proof_req_data(request_for_proof) proof_exchange = aries_container_request_proof( - agent["agent"], proof_request_info, explicit_revoc_required=True + agent["agent"], + proof_request_info, + explicit_revoc_required=True, + is_anoncreds=agent["agent"].wallet_type == "askar-anoncreds", ) context.proof_request = proof_request_info diff --git a/demo/features/steps/0586-sign-transaction.py b/demo/features/steps/0586-sign-transaction.py index bf5a8a0c3c..f8ade72f98 100644 --- a/demo/features/steps/0586-sign-transaction.py +++ b/demo/features/steps/0586-sign-transaction.py @@ -593,14 +593,15 @@ def step_impl(context, agent_name): agent["agent"], "/issue-credential-2.0/records/" + cred_exchange["cred_ex_id"] ) context.cred_exchange = cred_exchange + cred_exchange_format = cred_exchange.get("indy") or cred_exchange.get("anoncreds") agent_container_POST( agent["agent"], endpoint, data={ - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "cred_rev_id": cred_exchange_format["cred_rev_id"], "publish": False, - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], + "rev_reg_id": cred_exchange_format["rev_reg_id"], "connection_id": cred_exchange["cred_ex_record"]["connection_id"], }, ) @@ -627,11 +628,13 @@ def step_impl(context, agent_name): context.cred_exchange = cred_exchange connection_id = agent["agent"].agent.connection_id + cred_exchange_format = cred_exchange.get("indy") or cred_exchange.get("anoncreds") + # revoke the credential if not is_anoncreds(agent): data = { - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "rev_reg_id": cred_exchange_format["rev_reg_id"], + "cred_rev_id": cred_exchange_format["cred_rev_id"], "publish": False, "connection_id": cred_exchange["cred_ex_record"]["connection_id"], } @@ -642,9 +645,9 @@ def step_impl(context, agent_name): endpoint = "/revocation/revoke" else: data = { - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "cred_rev_id": cred_exchange_format["cred_rev_id"], "publish": False, - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], + "rev_reg_id": cred_exchange_format["rev_reg_id"], "connection_id": cred_exchange["cred_ex_record"]["connection_id"], "options": { "endorser_connection_id": connection_id, @@ -676,15 +679,17 @@ def step_impl(context, agent_name): else: endpoint = "/anoncreds/revocation/publish-revocations" + cred_exchange_format = context.cred_exchange.get("indy") or context.cred_exchange.get( + "anoncreds" + ) + # create rev_reg entry transaction created_rev_reg = agent_container_POST( agent["agent"], endpoint, data={ "rrid2crid": { - context.cred_exchange["indy"]["rev_reg_id"]: [ - context.cred_exchange["indy"]["cred_rev_id"] - ] + cred_exchange_format["rev_reg_id"]: [cred_exchange_format["cred_rev_id"]] } }, params={}, @@ -703,14 +708,15 @@ def step_impl(context, agent_name): agent = context.active_agents[agent_name] connection_id = agent["agent"].agent.connection_id + cred_exchange_format = context.cred_exchange.get("indy") or context.cred_exchange.get( + "anoncreds" + ) # create rev_reg entry transaction if not is_anoncreds(agent): data = { "rrid2crid": { - context.cred_exchange["indy"]["rev_reg_id"]: [ - context.cred_exchange["indy"]["cred_rev_id"] - ] + cred_exchange_format["rev_reg_id"]: [cred_exchange_format["cred_rev_id"]] } } params = { @@ -721,9 +727,7 @@ def step_impl(context, agent_name): else: data = { "rrid2crid": { - context.cred_exchange["indy"]["rev_reg_id"]: [ - context.cred_exchange["indy"]["cred_rev_id"] - ] + cred_exchange_format["rev_reg_id"]: [cred_exchange_format["cred_rev_id"]] }, "options": { "endorser_connection_id": connection_id, diff --git a/demo/features/upgrade.feature b/demo/features/upgrade.feature index 259c7a485a..557dd75646 100644 --- a/demo/features/upgrade.feature +++ b/demo/features/upgrade.feature @@ -19,10 +19,7 @@ Feature: ACA-Py Anoncreds Upgrade Then "Faber" has the proof verification fail Then "Bob" can verify the credential from "" was revoked And "" upgrades the wallet to anoncreds - And "Bob" has an issued credential from "" And "Bob" upgrades the wallet to anoncreds - And "Bob" has an issued credential from "" - When "Faber" sends a request for proof presentation to "Bob" Examples: | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | diff --git a/demo/runners/agent_container.py b/demo/runners/agent_container.py index c2ad39fe5f..61b07f4ef7 100644 --- a/demo/runners/agent_container.py +++ b/demo/runners/agent_container.py @@ -36,6 +36,8 @@ log_timer, ) +from .support.agent import CRED_FORMAT_ANONCREDS + CRED_PREVIEW_TYPE = "https://didcomm.org/issue-credential/2.0/credential-preview" SELF_ATTESTED = os.getenv("SELF_ATTESTED") TAILS_FILE_COUNT = int(os.getenv("TAILS_FILE_COUNT", 100)) @@ -272,16 +274,25 @@ async def handle_issue_credential_v2_0(self, message): elif state == "offer-received": log_status("#15 After receiving credential offer, send credential request") + + def _should_send_request_without_data(message): + """Formats that do not require credential request data.""" + cred_offer_by_format = message["by_format"].get("cred_offer") + + return ( + not message.get("by_format") + or cred_offer_by_format.get("anoncreds") + or cred_offer_by_format.get("indy") + or cred_offer_by_format.get("vc_di") + ) + # Should wait for a tiny bit for the delete tests await asyncio.sleep(0.2) if not message.get("by_format"): # this should not happen, something hinky when running in IDE... # this will work if using indy payloads self.log(f"No 'by_format' in message: {message}") - await self.admin_POST( - f"/issue-credential-2.0/records/{cred_ex_id}/send-request" - ) - elif message["by_format"]["cred_offer"].get("indy"): + elif _should_send_request_without_data(message): await self.admin_POST( f"/issue-credential-2.0/records/{cred_ex_id}/send-request" ) @@ -294,10 +305,6 @@ async def handle_issue_credential_v2_0(self, message): await self.admin_POST( f"/issue-credential-2.0/records/{cred_ex_id}/send-request", data ) - elif message["by_format"]["cred_offer"].get("vc_di"): - await self.admin_POST( - f"/issue-credential-2.0/records/{cred_ex_id}/send-request" - ) elif state == "done": pass @@ -327,6 +334,26 @@ async def handle_issue_credential_v2_0_indy(self, message): self.log(f"Revocation registry ID: {rev_reg_id}") self.log(f"Credential revocation ID: {cred_rev_id}") + async def handle_issue_credential_v2_0_anoncreds(self, message): + rev_reg_id = message.get("rev_reg_id") + cred_rev_id = message.get("cred_rev_id") + cred_id_stored = message.get("cred_id_stored") + + if cred_id_stored: + cred_id = message["cred_id_stored"] + log_status(f"#18.1 Stored credential {cred_id} in wallet") + cred = await self.admin_GET(f"/credential/{cred_id}") + log_json(cred, label="Credential details:") + self.log("credential_id", cred_id) + self.log("cred_def_id", cred["cred_def_id"]) + self.log("schema_id", cred["schema_id"]) + # track last successfully received credential + self.last_credential_received = cred + + if rev_reg_id and cred_rev_id: + self.log(f"Revocation registry ID: {rev_reg_id}") + self.log(f"Credential revocation ID: {cred_rev_id}") + async def handle_issue_credential_v2_0_vc_di(self, message): self.log(f"Handle VC_DI Credential: message = {message}") @@ -442,16 +469,18 @@ async def handle_present_proof_v2_0(self, message): # this should not happen, something hinky when running in IDE... self.log(f"No 'by_format' in message: {message}") else: - pres_request_indy = ( - message["by_format"].get("pres_request", {}).get("indy") - ) - pres_request_dif = message["by_format"].get("pres_request", {}).get("dif") + pres_request_by_format = message["by_format"].get("pres_request", {}) + pres_request = pres_request_by_format.get( + "indy" + ) or pres_request_by_format.get("anoncreds") + + pres_request_dif = pres_request_by_format.get("dif") request = {} - if not pres_request_dif and not pres_request_indy: + if not pres_request_dif and not pres_request: raise Exception("Invalid presentation request received") - if pres_request_indy: + if pres_request: # include self-attested attributes (not included in credentials) creds_by_reft = {} revealed = {} @@ -463,7 +492,6 @@ async def handle_present_proof_v2_0(self, message): creds = await self.admin_GET( f"/present-proof-2.0/records/{pres_ex_id}/credentials" ) - # print(">>> creds:", creds) if creds: # select only indy credentials creds = [x for x in creds if "cred_info" in x] @@ -484,7 +512,7 @@ async def handle_present_proof_v2_0(self, message): # submit the proof wit one unrevealed revealed attribute revealed_flag = False - for referent in pres_request_indy["requested_attributes"]: + for referent in pres_request["requested_attributes"]: if referent in creds_by_reft: revealed[referent] = { "cred_id": creds_by_reft[referent]["cred_info"][ @@ -496,7 +524,7 @@ async def handle_present_proof_v2_0(self, message): else: self_attested[referent] = "my self-attested value" - for referent in pres_request_indy["requested_predicates"]: + for referent in pres_request["requested_predicates"]: if referent in creds_by_reft: predicates[referent] = { "cred_id": creds_by_reft[referent]["cred_info"][ @@ -504,15 +532,15 @@ async def handle_present_proof_v2_0(self, message): ] } - log_status("#25 Generate the indy proof") - indy_request = { - "indy": { + log_status("#25 Generate the proof") + request = { + "indy" if "indy" in pres_request_by_format else "anoncreds": { "requested_predicates": predicates, "requested_attributes": revealed, "self_attested_attributes": self_attested, } } - request.update(indy_request) + request.update(request) except ClientError: pass @@ -779,7 +807,7 @@ def __init__( # endorsers and authors need public DIDs (assume cred_type is Indy) if endorser_role == "author" or endorser_role == "endorser": self.public_did = True - self.cred_type = CRED_FORMAT_INDY + # self.cred_type = CRED_FORMAT_INDY self.reuse_connections = reuse_connections self.multi_use_invitations = multi_use_invitations @@ -938,7 +966,7 @@ async def create_schema_and_cred_def( ): if not self.public_did: raise Exception("Can't create a schema/cred def without a public DID :-(") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: # need to redister schema and cred def on the ledger self.cred_def_id = await self.agent.create_schema_and_cred_def( schema_name, @@ -981,20 +1009,26 @@ async def issue_credential( self, cred_def_id: str, cred_attrs: list, + filter_type: str = "indy", ): log_status("#13 Issue credential offer to X") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": cred_attrs, } + if filter_type == "indy": + _filter = {"indy": {"cred_def_id": cred_def_id}} + else: + _filter = {"anoncreds": {"cred_def_id": cred_def_id}} + offer_request = { "connection_id": self.agent.connection_id, "comment": f"Offer on cred def id {cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, - "filter": {"indy": {"cred_def_id": cred_def_id}}, + "filter": _filter, "trace": self.exchange_tracing, } cred_exchange = await self.agent.admin_POST( @@ -1041,11 +1075,13 @@ async def receive_credential( return matched - async def request_proof(self, proof_request, explicit_revoc_required: bool = False): + async def request_proof( + self, proof_request, explicit_revoc_required: bool = False, is_anoncreds=False + ): log_status("#20 Request proof of degree from alice") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: - indy_proof_request = { + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + proof_request = { "name": ( proof_request["name"] if "name" in proof_request else "Proof of stuff" ), @@ -1061,24 +1097,24 @@ async def request_proof(self, proof_request, explicit_revoc_required: bool = Fal # plug in revocation where requested in the supplied proof request non_revoked = {"to": int(time.time())} if "non_revoked" in proof_request: - indy_proof_request["non_revoked"] = non_revoked + proof_request["non_revoked"] = non_revoked non_revoked_supplied = True for attr in proof_request["requested_attributes"]: if "non_revoked" in proof_request["requested_attributes"][attr]: - indy_proof_request["requested_attributes"][attr][ - "non_revoked" - ] = non_revoked + proof_request["requested_attributes"][attr]["non_revoked"] = ( + non_revoked + ) non_revoked_supplied = True for pred in proof_request["requested_predicates"]: if "non_revoked" in proof_request["requested_predicates"][pred]: - indy_proof_request["requested_predicates"][pred][ - "non_revoked" - ] = non_revoked + proof_request["requested_predicates"][pred]["non_revoked"] = ( + non_revoked + ) non_revoked_supplied = True if not non_revoked_supplied and not explicit_revoc_required: # else just make it global - indy_proof_request["non_revoked"] = non_revoked + proof_request["non_revoked"] = non_revoked else: # make sure we are not leaking non-revoc requests @@ -1091,13 +1127,16 @@ async def request_proof(self, proof_request, explicit_revoc_required: bool = Fal if "non_revoked" in proof_request["requested_predicates"][pred]: del proof_request["requested_predicates"][pred]["non_revoked"] - log_status(f" >>> asking for proof for request: {indy_proof_request}") + log_status(f" >>> asking for proof for request: {proof_request}") + + if is_anoncreds: + presentation_request = {"anoncreds": proof_request} + else: + presentation_request = {"indy": proof_request} proof_request_web_request = { "connection_id": self.agent.connection_id, - "presentation_request": { - "indy": indy_proof_request, - }, + "presentation_request": presentation_request, "trace": self.exchange_tracing, } proof_exchange = await self.agent.admin_POST( @@ -1108,7 +1147,6 @@ async def request_proof(self, proof_request, explicit_revoc_required: bool = Fal elif self.cred_type == CRED_FORMAT_JSON_LD: # TODO create and send the json-ld proof request - pass return None else: @@ -1125,7 +1163,7 @@ async def verify_proof(self, proof_request): # log_status(f">>> last proof received: {self.agent.last_proof_received}") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: # return verified status return self.agent.last_proof_received["verified"] @@ -1514,12 +1552,14 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non aip = 20 if "cred_type" in args and args.cred_type not in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: public_did = None aip = 20 elif "cred_type" in args and args.cred_type in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: @@ -1528,6 +1568,12 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non public_did = args.public_did if "public_did" in args else None cred_type = args.cred_type if "cred_type" in args else None + + # Set anoncreds agent to use anoncreds credential format + wallet_type = arg_file_dict.get("wallet-type") or args.wallet_type + if wallet_type == "askar-anoncreds": + cred_type = CRED_FORMAT_ANONCREDS + log_msg( f"Initializing demo agent {agent_ident} with AIP {aip} and credential type {cred_type}" ) @@ -1564,7 +1610,7 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non mediation=args.mediation, cred_type=cred_type, use_did_exchange=(aip == 20) if ("aip" in args) else args.did_exchange, - wallet_type=arg_file_dict.get("wallet-type") or args.wallet_type, + wallet_type=wallet_type, public_did=public_did, seed="random" if public_did else None, arg_file=arg_file, diff --git a/demo/runners/faber.py b/demo/runners/faber.py index 5cecf47d37..00cc9a2e98 100644 --- a/demo/runners/faber.py +++ b/demo/runners/faber.py @@ -17,6 +17,7 @@ create_agent_with_args, ) from runners.support.agent import ( # noqa:E402 + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_JSON_LD, CRED_FORMAT_VC_DI, @@ -111,7 +112,7 @@ def generate_credential_offer(self, aip, cred_type, cred_def_id, exchange_tracin return offer_request elif aip == 20: - if cred_type == CRED_FORMAT_INDY: + if cred_type == CRED_FORMAT_ANONCREDS or cred_type == CRED_FORMAT_INDY: self.cred_attrs[cred_def_id] = { "name": "Alice Smith", "date": "2018-05-28", @@ -127,12 +128,16 @@ def generate_credential_offer(self, aip, cred_type, cred_def_id, exchange_tracin for (n, v) in self.cred_attrs[cred_def_id].items() ], } + if cred_type == CRED_FORMAT_ANONCREDS: + _filter = {"anoncreds": {"cred_def_id": cred_def_id}} + else: + _filter = {"indy": {"cred_def_id": cred_def_id}} offer_request = { "connection_id": self.connection_id, "comment": f"Offer on cred def id {cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, - "filter": {"indy": {"cred_def_id": cred_def_id}}, + "filter": _filter, "trace": exchange_tracing, } return offer_request @@ -249,7 +254,7 @@ def generate_proof_request_web_request( "restrictions": [{"schema_name": "degree schema"}], } ] - indy_proof_request = { + proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { @@ -261,10 +266,10 @@ def generate_proof_request_web_request( } if revocation: - indy_proof_request["non_revoked"] = {"to": int(time.time())} + proof_request["non_revoked"] = {"to": int(time.time())} proof_request_web_request = { - "proof_request": indy_proof_request, + "proof_request": proof_request, "trace": exchange_tracing, } if not connectionless: @@ -272,7 +277,7 @@ def generate_proof_request_web_request( return proof_request_web_request elif aip == 20: - if cred_type == CRED_FORMAT_INDY: + if cred_type == CRED_FORMAT_ANONCREDS or cred_type == CRED_FORMAT_INDY: req_attrs = [ { "name": "name", @@ -312,7 +317,7 @@ def generate_proof_request_web_request( "restrictions": [{"schema_name": "degree schema"}], } ] - indy_proof_request = { + proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { @@ -325,14 +330,19 @@ def generate_proof_request_web_request( } if revocation: - indy_proof_request["non_revoked"] = {"to": int(time.time())} + proof_request["non_revoked"] = {"to": int(time.time())} + if cred_type == CRED_FORMAT_ANONCREDS: + presentation_request = {"anoncreds": proof_request} + else: + presentation_request = {"indy": proof_request} proof_request_web_request = { - "presentation_request": {"indy": indy_proof_request}, + "presentation_request": presentation_request, "trace": exchange_tracing, } if not connectionless: proof_request_web_request["connection_id"] = self.connection_id + return proof_request_web_request elif cred_type == CRED_FORMAT_VC_DI: @@ -537,7 +547,11 @@ async def main(args): "birthdate_dateint", "timestamp", ] - if faber_agent.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + ]: faber_agent.public_did = True await faber_agent.initialize( the_agent=agent, @@ -569,6 +583,7 @@ async def main(args): exchange_tracing = False options = " (1) Issue Credential\n" if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: @@ -664,12 +679,14 @@ async def main(args): elif option == "1a": new_cred_type = await prompt( - "Enter credential type ({}, {}): ".format( + "Enter credential type ({}, {}, {}): ".format( + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ) ) if new_cred_type in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: @@ -689,7 +706,11 @@ async def main(args): ) elif faber_agent.aip == 20: - if faber_agent.cred_type == CRED_FORMAT_INDY: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + ]: offer_request = faber_agent.agent.generate_credential_offer( faber_agent.aip, faber_agent.cred_type, @@ -705,14 +726,6 @@ async def main(args): exchange_tracing, ) - elif faber_agent.cred_type == CRED_FORMAT_VC_DI: - offer_request = faber_agent.agent.generate_credential_offer( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.cred_def_id, - exchange_tracing, - ) - else: raise Exception( f"Error invalid credential type: {faber_agent.cred_type}" @@ -742,27 +755,12 @@ async def main(args): pass elif faber_agent.aip == 20: - if faber_agent.cred_type == CRED_FORMAT_INDY: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - ) - ) - - elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - ) - ) - - elif faber_agent.cred_type == CRED_FORMAT_VC_DI: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + CRED_FORMAT_JSON_LD, + ]: proof_request_web_request = ( faber_agent.agent.generate_proof_request_web_request( faber_agent.aip, @@ -771,7 +769,6 @@ async def main(args): exchange_tracing, ) ) - else: raise Exception( "Error invalid credential type:" + faber_agent.cred_type @@ -819,28 +816,12 @@ async def main(args): qr.print_ascii(invert=True) elif faber_agent.aip == 20: - if faber_agent.cred_type == CRED_FORMAT_INDY: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - connectionless=True, - ) - ) - elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - connectionless=True, - ) - ) - - elif faber_agent.cred_type == CRED_FORMAT_VC_DI: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + CRED_FORMAT_JSON_LD, + ]: proof_request_web_request = ( faber_agent.agent.generate_proof_request_web_request( faber_agent.aip, diff --git a/demo/runners/support/agent.py b/demo/runners/support/agent.py index 2905ad4912..5d1e10ccd6 100644 --- a/demo/runners/support/agent.py +++ b/demo/runners/support/agent.py @@ -70,6 +70,7 @@ WALLET_TYPE_ASKAR = "askar" WALLET_TYPE_ANONCREDS = "askar-anoncreds" +CRED_FORMAT_ANONCREDS = "anoncreds" CRED_FORMAT_INDY = "indy" CRED_FORMAT_JSON_LD = "json-ld" CRED_FORMAT_VC_DI = "vc_di" @@ -672,7 +673,7 @@ async def register_did( role: str = "TRUST_ANCHOR", cred_type: str = CRED_FORMAT_INDY, ): - if cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: # if registering a did for issuing indy credentials, publish the did on the ledger self.log(f"Registering {self.ident} ...") if not ledger_url: diff --git a/mkdocs-requirements.txt b/mkdocs-requirements.txt index eb1ee40600..a6d710f6af 100644 --- a/mkdocs-requirements.txt +++ b/mkdocs-requirements.txt @@ -1,3 +1,3 @@ -mkdocs-material==9.5.44 +mkdocs-material==9.5.46 mike==2.1.3 diff --git a/poetry.lock b/poetry.lock index fc7b8e046d..06890cb7f9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,87 +13,87 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.0" +version = "3.11.8" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:024409c1b1d6076d0ed933dcebd7e4fc6f3320a227bfa0c1b6b93a8b5a146f04"}, - {file = "aiohttp-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:62502b8ffee8c6a4b5c6bf99d1de277d42bf51b2fb713975d9b63b560150b7ac"}, - {file = "aiohttp-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c54c635d1f52490cde7ef3a423645167a8284e452a35405d5c7dc1242a8e75c9"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:104ea21994b1403e4c1b398866f1187c1694fa291314ad7216ec1d8ec6b49f38"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b24497b3baf15035730de5f207ade88a67d4483a5f16ced7ece348933a5b47"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08474e71772a516ba2e2167b4707af8361d2c452b3d8a5364c984f4867869499"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40380c96dd407dfa84eb2d264e68aa47717b53bdbe210a59cc3c35a4635f195"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1668ef2f3a7ec9881f4b6a917e5f97c87a343fa6b0d5fc826b7b0297ddd0887"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f3bf5c132eb48002bcc3825702d241d35b4e9585009e65e9dcf9c4635d0b7424"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0315978b2a4569e03fb59100f6a7e7d23f718a4521491f5c13d946d37549f3d"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d5cae4cd271e20b7ab757e966cc919186b9f02535418ab36c471a5377ef4deaa"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:31b91ff3a1fcb206a1fa76e0de1f08c9ffb1dc0deb7296fa2618adfe380fc676"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ebf610c37df4f09c71c9bbf8309b4b459107e6fe889ac0d7e16f6e4ebd975f86"}, - {file = "aiohttp-3.11.0-cp310-cp310-win32.whl", hash = "sha256:b40c304ab01e89ad0aeeecf91bbaa6ae3b00e27b796c9e8d50b71a4a7e885cc8"}, - {file = "aiohttp-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd0834e4260eab78671b81d34f110fbaac449563e48d419cec0030d9a8e58693"}, - {file = "aiohttp-3.11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:89a96a0696dc67d548f69cb518c581a7a33cc1f26ab42229dea1709217c9d926"}, - {file = "aiohttp-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6b925c7775ab857bdc1e52e1f5abcae7d18751c09b751aeb641a5276d9b990e"}, - {file = "aiohttp-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7867d0808614f04e78e0a8d5a2c1f8ac6bc626a0c0e2f62be48be6b749e2f8b2"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:229ae13959a5f499d90ffbb4b9eac2255d8599315027d6f7c22fa9803a94d5b1"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a2f5268b672087c45b33479ba1bb1d5a48c6d76c133cfce3a4f77410c200d1"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a896059b6937d1a22d8ee8377cdcd097bd26cd8c653b8f972051488b9baadee9"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:104deb7873681273c5daa13c41924693df394043a118dae90387d35bc5531788"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae36ae52b0c22fb69fb8b744eff82a20db512a29eafc6e3a4ab43b17215b219d"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7349205bb163318dcc102329d30be59a647a3d24c82c3d91ed35b7e7301ea7e"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9095580806d9ed07c0c29b23364a0b1fb78258ef9f4bddf7e55bac0e475d4edf"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4d218d3eca40196384ad3b481309c56fd60e664128885d1734da0a8aa530d433"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6533dd06df3d17d1756829b68b365b1583929b54082db8f65083a4184bf68322"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72cd984f7f14e8c01b3e38f18f39ea85dba84e52ea05e37116ba5e2a72eef396"}, - {file = "aiohttp-3.11.0-cp311-cp311-win32.whl", hash = "sha256:c1828e10c3a49e2b234b87600ecb68a92b8a8dcf8b99bca9447f16c4baaa1630"}, - {file = "aiohttp-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:900ff74d78eb580ae4aa5883242893b123a0c442a46570902500f08d6a7e6696"}, - {file = "aiohttp-3.11.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f8f0d79b923070f25674e4ea8f3d61c9d89d24d9598d50ff32c5b9b23c79a25b"}, - {file = "aiohttp-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:113bf06b029143e94a47c4f36e11a8b7e396e9d1f1fc8cea58e6b7e370cfed38"}, - {file = "aiohttp-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3e1ed8d152cccceffb1ee7a2ac227c16372e453fb11b3aeaa56783049b85d3f6"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2e82e515e268b965424ecabebd91834a41b36260b6ef5db015ee12ddb28ef3"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1c49bc393d854d4421ebc174a0a41f9261f50d3694d8ca277146cbbcfd24ee7"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57e17c6d71f2dc857a8a1d09be1be7802e35d90fb4ba4b06cf1aab6414a57894"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12071dd2cc95ba81e0f2737bebcb98b2a8656015e87772e84e8fb9e635b5da6e"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97056d3422594e0787733ac4c45bef58722d452f4dc6615fee42f59fe51707dd"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2ec5efbc872b00ddd85e3904059d274f284cff314e13f48776050ca2c58f451d"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd505a1121ad5b666191840b7bd1d8cb917df2647deeca6f3474331b72452362"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:600b1d9f86a130131915e2f2127664311b33902c486b21a747d626f5144b4471"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8c47a0ba6c2b3d3e5715f8338d657badd21f778c6be16701922c65521c5ecfc9"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8b323b5d3aef7dd811424c269322eec58a977c0c8152e650159e47210d900504"}, - {file = "aiohttp-3.11.0-cp312-cp312-win32.whl", hash = "sha256:aabc4e92cb153636d6be54e84dad1b252ddb9aebe077942b6dcffe5e468d476a"}, - {file = "aiohttp-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:508cfcc99534b1282595357592d8367b44392b21f6eb5d4dc021f8d0d809e94d"}, - {file = "aiohttp-3.11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c98a596ac20e8980cc6f34c0c92a113e98eb08f3997c150064d26d2aeb043e5a"}, - {file = "aiohttp-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ad14cdc0fba4df31c0f6e06c21928c5b924725cbf60d0ccc5f6e7132636250e9"}, - {file = "aiohttp-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:170fb2324826bb9f08055a8291f42192ae5ee2f25b2966c8f0f4537c61d73a7b"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdad66685fcf2ad14ce522cf849d4a025f4fd206d6cfc3f403d9873e4c243b03"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8b95a63a8e8b5f0464bd8b1b0d59d2bec98a59b6aacc71e9be23df6989b3dfb"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7bcfcede95531589295f56e924702cef7f9685c9e4e5407592e04ded6a65bf3"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ecc2fb1a0a9d48cf773add34196cddf7e488e48e9596e090849751bf43098f4"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fef105113d56e817cb9bcc609667ee461321413a7b972b03f5b4939f40f307c"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d33b4490026968bdc7f0729b9d87a3a6b1e09043557d2fc1c605c6072deb2f11"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6362f50a6f0e5482c4330d2151cb682779230683da0e155c15ec9fc58cb50b6a"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4f698aa61879df64425191d41213dfd99efdc1627e6398e6d7aa5c312fac9702"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0e7a0762cc29cd3acd01a4d2b547b3af7956ad230ebb80b529a8e4f3e4740fe8"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e4fb7f5354d39490d8209aefdf5830b208d01c7293a2164e404312c3d8bc55"}, - {file = "aiohttp-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6c5a6958f4366496004cf503d847093d464814543f157ef3b738bbf604232415"}, - {file = "aiohttp-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:3ed360d6672a9423aad39902a4e9fe305464d20ed7931dbdba30a4625782d875"}, - {file = "aiohttp-3.11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d1ea006426edf7e1299c52a58b0443158012f7a56fed3515164b60bfcb1503a9"}, - {file = "aiohttp-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c5e6a1f8b0268ffa1c84d7c3558724956002ba8361176e76406233e704bbcffb"}, - {file = "aiohttp-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:40dc9446cff326672fcbf93efdb8ef7e949824de1097624efe4f61ac7f0d2c43"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b4545e8d96870da9652930c5198366605ff8f982757030e2148cf341e5746b"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37f8cf3c43f292d9bb3e6760476c2b55b9663a581fad682a586a410c43a7683e"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329f5059e0bf6983dceebac8e6ed20e75eaff6163b3414f4a4cb59e0d7037672"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ae6f182be72c3531915e90625cc65afce4df8a0fc4988bd52d8a5d5faaeb68"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d664e5f937c08adb7908ea9f391fbf2928a9b09cb412ac0aba602bde9e499e4"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:feca9fafa4385aea6759c171cd25ea82f7375312fca04178dae35331be45e538"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c415b9601ff50709d6050c8a9281733a9b042b9e589265ac40305b875cf9c463"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:91d3991fad8b65e5dbc13cd95669ea689fe0a96ff63e4e64ac24ed724e4f8103"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9231d610754724273a6ac05a1f177979490bfa6f84d49646df3928af2e88cfd5"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4e4e155968040e32c124a89852a1a5426d0e920a35f4331e1b3949037bfe93a3"}, - {file = "aiohttp-3.11.0-cp39-cp39-win32.whl", hash = "sha256:76d6ee8bb132f8ee0fcb0e205b4708ddb6fba524eb515ee168113063d825131b"}, - {file = "aiohttp-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:577c7429f8869fa30186fc2c9eee64d75a30b51b61f26aac9725866ae5985cfd"}, - {file = "aiohttp-3.11.0.tar.gz", hash = "sha256:f57a0de48dda792629e7952d34a0c7b81ea336bb9b721391c7c58145b237fe55"}, + {file = "aiohttp-3.11.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d2ca685c6a851ce64e511fbcb906e4dd97d13e567ca7ecb5cb30b184e15dc6d"}, + {file = "aiohttp-3.11.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52913bb8a0a72a57479f54b281300c9d23036aa9aa3ebbc9a32a643484eadfc2"}, + {file = "aiohttp-3.11.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:35dafc70051b6cbd6dafb533b4e3f0df6225a4896be373ef86367b2987409331"}, + {file = "aiohttp-3.11.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:561b9596a9f90266673ef0b950c27e04ab597cdb53785e2ac91b83b33c31b509"}, + {file = "aiohttp-3.11.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d479c1fdcc920056a06d04059db52eb8590ecbbb3acdcaeeea26a88ff782e94a"}, + {file = "aiohttp-3.11.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ce8eb6444bb6e862feca664ce365afa8e2e32db24dcf1a502719a8a002f9274"}, + {file = "aiohttp-3.11.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df9bf08eb93611b1d4d6245b6fecf88728e90eece00e00d554e1b0c445557d83"}, + {file = "aiohttp-3.11.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a20ddaa58fea717177fac9a4a1fb8b39be868aa4fed2af6de4313b7a08f0f71"}, + {file = "aiohttp-3.11.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9f4aadfea6b48cfa17aef1a68ba6bee5a0246374f5a588e299a4f4ff5bd1c77b"}, + {file = "aiohttp-3.11.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:aa7deebb4bc5143745e6282139d7b9de50beb6d06609df64d2c993ef496bc7eb"}, + {file = "aiohttp-3.11.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fe503a76b9e3a13b62e64545693c9463afe9d429e0909120f7bb66de91ed8bc2"}, + {file = "aiohttp-3.11.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1c5838a68e31712354129add1b5fe32b06aa05275f835130edc650e6288af05f"}, + {file = "aiohttp-3.11.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:832e58d9454fe501b0d092cdf660c0e34e16005f61acd06e1c79b0fc45019c94"}, + {file = "aiohttp-3.11.8-cp310-cp310-win32.whl", hash = "sha256:00618c37a350884c08e87cf9a6532be274d564227ac49e0b474cf41f27e1f190"}, + {file = "aiohttp-3.11.8-cp310-cp310-win_amd64.whl", hash = "sha256:8eeaac75203da1a54afe1faea3c855a1973026b54929112aa9b67bceadbcb0ca"}, + {file = "aiohttp-3.11.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f8dd02b44555893adfe7cc4b3b454fee04f9dcec45cf66ef5bb53ebf393f0505"}, + {file = "aiohttp-3.11.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:658052941324edea3dee1f681375e70779f55e437e07bdfc4b5bbe65ad53cefb"}, + {file = "aiohttp-3.11.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c829471a9e2266da4a0666f8a9e215f19320f79778af379c1c7db324ac24ed2"}, + {file = "aiohttp-3.11.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d21951756690f5d86d0215da38eb0fd65def03b5e2a1c08a4a39718a6d0d48f2"}, + {file = "aiohttp-3.11.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2fa50ddc6b21cc1ae23e13524d6f75b27e279fdf5cf905b2df6fd171891ac4e2"}, + {file = "aiohttp-3.11.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a5afbd805e449048ecebb1a256176e953d4ca9e48bab387d4d1c8524f1c7a95"}, + {file = "aiohttp-3.11.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea68db69f2a4ddc24b28b8e754fc0b963ed7f9b9a76137f06fe44643d6821fbd"}, + {file = "aiohttp-3.11.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b3ac163145660ce660aed2f1005e6d4de840d39728990b7250525eeec4e4a8"}, + {file = "aiohttp-3.11.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e9ac0cce897904b77e109e5403ed713187dbdf96832bfd061ac07164264be16c"}, + {file = "aiohttp-3.11.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3260c77cff4e35245bc517658bd54d7a64787f71f3c4f723877c82f22835b032"}, + {file = "aiohttp-3.11.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f7fd9c11ffad6b022bf02a41a70418cb2ab3b33f2c27842a5999e3ab78daf280"}, + {file = "aiohttp-3.11.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:16bda233a7b159ab08107e8858fedca90a9de287057fab54cafde51bd83f9819"}, + {file = "aiohttp-3.11.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4867008617bbf86e9fb5b00f72dd0e3a00a579b32233caff834320867f9b7cac"}, + {file = "aiohttp-3.11.8-cp311-cp311-win32.whl", hash = "sha256:17e6b9d8e29e3bfc7f893f327e92c9769d3582cee2fb1652c1431ac3f60115a0"}, + {file = "aiohttp-3.11.8-cp311-cp311-win_amd64.whl", hash = "sha256:7f3be4961a5c2c670f31caab7641a37ea2a97031f0d8ae15bcfd36b6bf273200"}, + {file = "aiohttp-3.11.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0e3b5bfef913d6be270c81976fbc0cbf66625cd92663bbb7e03b3adbd6aa4ac6"}, + {file = "aiohttp-3.11.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cb51a81cb637b9a072c9cfae1839e35c6579638861eb3479eb5d6e6ce8bc6782"}, + {file = "aiohttp-3.11.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd2ca84e5f7a35f313a62eb7d6a50bac6760b60bafce34586750712731c0aeff"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47c6663df9446aa848b478413219600da4b54bc0409e1ac4bc80fb1a81501363"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c665ed4b52256614858b20711bbbd2755b0e19ec86870f8ff1645acf9ae9e760"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35d4545e7684da7a954ffc2dce495462cb16a902dffdebe98572408f6aaaee83"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85be3899e6860dd2cd3f4370ded6708e939d00d5ec922a8eb328d114db605a47"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ed9f1f2697713c48efc9ec483ad5d062e4aa91854f090a3eba0b19c002851d"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c0dbae99737badf3f5e862088a118e28d3b36f03eb608a6382eddfd68178e05b"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:beae08f900b2980af4353a0200eb162b39f276fd8a6e43079a540f83964671f4"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d6f9e5fd1b3ecbaca3e04a15a02d1fa213248608caee99fd5bdddd4759959cf7"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7def89a41fe32120d89cd4577f5efbab3c52234c5890066ced8a2f7202dff88"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:98f596cf59292e779bc387f22378a3d2c5e052c9fe2bf822ac4f547c6fe57758"}, + {file = "aiohttp-3.11.8-cp312-cp312-win32.whl", hash = "sha256:b64fa6b76b35b695cd3e5c42a4e568cbea8d41c9e59165e2a43da00976e2027e"}, + {file = "aiohttp-3.11.8-cp312-cp312-win_amd64.whl", hash = "sha256:afba47981ff73b1794c00dce774334dcfe62664b3b4f78f278b77d21ce9daf43"}, + {file = "aiohttp-3.11.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a81525430da5ca356fae6e889daeb6f5cc0d5f0cef88e59cdde48e2394ea1365"}, + {file = "aiohttp-3.11.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7565689e86a88c1d258351ebd14e343337b76a56ca5c0a2c1db96ec28149386f"}, + {file = "aiohttp-3.11.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d0f9dbe9763c014c408ad51a027dc9582518e992dc63e2ffe359ac1b4840a560"}, + {file = "aiohttp-3.11.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca580edc3ccd7f6ea76ad9cf59f5a8756d338e770b5eda7be26bcda8fa7ef53"}, + {file = "aiohttp-3.11.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7d141631a7348038fc7b5d1a81b3c9afa9aa056188ded7902fe754028fdea5c5"}, + {file = "aiohttp-3.11.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64e6b14608a56a4c76c60daac730b0c0eeaf9d10dfc3231f7fc26521a0d628fd"}, + {file = "aiohttp-3.11.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0983d0ce329f2f9dbeb355c3744bd6333f34e0dc56025b6b7d4f285b90acb51e"}, + {file = "aiohttp-3.11.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d96b93a46a3742880fa21bcb35c6c40cf27714ec0fb8ec85fe444d73b95131b9"}, + {file = "aiohttp-3.11.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f4f1779c3142d913c509c2ed1de8b8f920e07a5cd65ac1f57c61cfb6bfded5a4"}, + {file = "aiohttp-3.11.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:48be7cff468c9c0d86a02e6a826e1fe159094b16d5aa2c17703e7317f791b0f9"}, + {file = "aiohttp-3.11.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:daea456b79ca2bacc7f062845bbb1139c3b3231fc83169da5a682cf385416dd1"}, + {file = "aiohttp-3.11.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c92e763cf641e10ad9342597d20060ba23de5e411aada96660e679e3f9371189"}, + {file = "aiohttp-3.11.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a750ee5a177e0f873d6b2d7d0fa6e1e7c658fc0ca8ea56438dcba2ac94bedb09"}, + {file = "aiohttp-3.11.8-cp313-cp313-win32.whl", hash = "sha256:4448c9c7f77bad48a6569062c0c16deb77fbb7363de1dc71ed087f66fb3b3c96"}, + {file = "aiohttp-3.11.8-cp313-cp313-win_amd64.whl", hash = "sha256:481075a1949de79a8a6841e0086f2f5f464785c592cf527ed0db2c0cbd0e1ba2"}, + {file = "aiohttp-3.11.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:72779bfb34d6d6b51e55a7f4901b410e416b5431738b367d49696928c91a2ca8"}, + {file = "aiohttp-3.11.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e6523f39071a01757048985e4cc22d04aa130bc40d9128503f3a61a3ee98328"}, + {file = "aiohttp-3.11.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:220bbce18b3046973465be45415430f1cab39d7fdc40cbcf0a8c05485c6902fe"}, + {file = "aiohttp-3.11.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:336bbf7a33dd8cb4a7afb98c70e9935a81e5e88f7ac595ba2e84b1fb5da190d6"}, + {file = "aiohttp-3.11.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c5e4f1ba5059b85e05c551961a448ce2689c6249ed6a2e2174796842c191d10"}, + {file = "aiohttp-3.11.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9f9fd5c672c962389429abd11ed32c9c93f7932fd58584cae1e43951b141c6b"}, + {file = "aiohttp-3.11.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58bd94ad48143e1d42e05fc055da41de0a9933f378ad87760595b8aec83d317b"}, + {file = "aiohttp-3.11.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bf52642b12d70d78c18882915201bc5345f7c8f0f2ab8919d99b886aa6475a7"}, + {file = "aiohttp-3.11.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fee12d8487b0df2b683424cca2a0d8fb7281d5607518d742e98119a74af01026"}, + {file = "aiohttp-3.11.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:65fd04f1fea668ad1af48ac31b752000e222dccffedcad3de8ccf9d34489ccd3"}, + {file = "aiohttp-3.11.8-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c3f397e0511a0ec4fe331e602fc057dfd336d352062deb9969ebd81e253a149c"}, + {file = "aiohttp-3.11.8-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:cf8f05f4abe3288fe2e106e1461fd20d8abf6103886ddfb6d746a5b8fb830d2b"}, + {file = "aiohttp-3.11.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7d71d4ac0792ff89541179394d303be846a0b6cd3821ae67286ee69ecec16f9f"}, + {file = "aiohttp-3.11.8-cp39-cp39-win32.whl", hash = "sha256:2b6f8716044ae5e5f2a3b4e4b6bfee48e97c8b2a92e56f43aadd728c7fd26b7d"}, + {file = "aiohttp-3.11.8-cp39-cp39-win_amd64.whl", hash = "sha256:da343903214bf9f9d314b913caa499fa19e26d73e6e23a3db7d4898ea6d47028"}, + {file = "aiohttp-3.11.8.tar.gz", hash = "sha256:7bc9d64a2350cbb29a9732334e1a0743cbb6844de1731cbdf5949b235653f3fd"}, ] [package.dependencies] @@ -564,73 +564,73 @@ yaml = ["PyYAML"] [[package]] name = "coverage" -version = "7.6.4" +version = "7.6.8" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07"}, - {file = "coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a"}, - {file = "coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa"}, - {file = "coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522"}, - {file = "coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf"}, - {file = "coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5"}, - {file = "coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17"}, - {file = "coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a"}, - {file = "coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e"}, - {file = "coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef"}, - {file = "coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e"}, - {file = "coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901"}, - {file = "coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09"}, - {file = "coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f"}, - {file = "coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e"}, - {file = "coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, + {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, + {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, + {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, + {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, + {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, + {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, + {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, + {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, + {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, + {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, + {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, + {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, + {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, + {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, ] [package.extras] @@ -638,51 +638,53 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "43.0.3" +version = "44.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, - {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, - {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, - {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, - {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, - {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, - {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, - {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, - {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, - {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, - {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, +python-versions = "!=3.9.0,!=3.9.1,>=3.7" +files = [ + {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:60eb32934076fa07e4316b7b2742fa52cbb190b42c2df2863dbc4230a0a9b385"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, + {file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, + {file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, + {file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9abcc2e083cbe8dde89124a47e5e53ec38751f0d7dfd36801008f316a127d7ba"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, + {file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, + {file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, + {file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, ] [package.dependencies] cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] @@ -788,37 +790,37 @@ cython = ["cython"] [[package]] name = "debugpy" -version = "1.8.8" +version = "1.8.9" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.8-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:e59b1607c51b71545cb3496876544f7186a7a27c00b436a62f285603cc68d1c6"}, - {file = "debugpy-1.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6531d952b565b7cb2fbd1ef5df3d333cf160b44f37547a4e7cf73666aca5d8d"}, - {file = "debugpy-1.8.8-cp310-cp310-win32.whl", hash = "sha256:b01f4a5e5c5fb1d34f4ccba99a20ed01eabc45a4684f4948b5db17a319dfb23f"}, - {file = "debugpy-1.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:535f4fb1c024ddca5913bb0eb17880c8f24ba28aa2c225059db145ee557035e9"}, - {file = "debugpy-1.8.8-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:c399023146e40ae373753a58d1be0a98bf6397fadc737b97ad612886b53df318"}, - {file = "debugpy-1.8.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09cc7b162586ea2171eea055985da2702b0723f6f907a423c9b2da5996ad67ba"}, - {file = "debugpy-1.8.8-cp311-cp311-win32.whl", hash = "sha256:eea8821d998ebeb02f0625dd0d76839ddde8cbf8152ebbe289dd7acf2cdc6b98"}, - {file = "debugpy-1.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:d4483836da2a533f4b1454dffc9f668096ac0433de855f0c22cdce8c9f7e10c4"}, - {file = "debugpy-1.8.8-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:0cc94186340be87b9ac5a707184ec8f36547fb66636d1029ff4f1cc020e53996"}, - {file = "debugpy-1.8.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64674e95916e53c2e9540a056e5f489e0ad4872645399d778f7c598eacb7b7f9"}, - {file = "debugpy-1.8.8-cp312-cp312-win32.whl", hash = "sha256:5c6e885dbf12015aed73770f29dec7023cb310d0dc2ba8bfbeb5c8e43f80edc9"}, - {file = "debugpy-1.8.8-cp312-cp312-win_amd64.whl", hash = "sha256:19ffbd84e757a6ca0113574d1bf5a2298b3947320a3e9d7d8dc3377f02d9f864"}, - {file = "debugpy-1.8.8-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:705cd123a773d184860ed8dae99becd879dfec361098edbefb5fc0d3683eb804"}, - {file = "debugpy-1.8.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890fd16803f50aa9cb1a9b9b25b5ec321656dd6b78157c74283de241993d086f"}, - {file = "debugpy-1.8.8-cp313-cp313-win32.whl", hash = "sha256:90244598214bbe704aa47556ec591d2f9869ff9e042e301a2859c57106649add"}, - {file = "debugpy-1.8.8-cp313-cp313-win_amd64.whl", hash = "sha256:4b93e4832fd4a759a0c465c967214ed0c8a6e8914bced63a28ddb0dd8c5f078b"}, - {file = "debugpy-1.8.8-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:143ef07940aeb8e7316de48f5ed9447644da5203726fca378f3a6952a50a9eae"}, - {file = "debugpy-1.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f95651bdcbfd3b27a408869a53fbefcc2bcae13b694daee5f1365b1b83a00113"}, - {file = "debugpy-1.8.8-cp38-cp38-win32.whl", hash = "sha256:26b461123a030e82602a750fb24d7801776aa81cd78404e54ab60e8b5fecdad5"}, - {file = "debugpy-1.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3cbf1833e644a3100eadb6120f25be8a532035e8245584c4f7532937edc652a"}, - {file = "debugpy-1.8.8-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:53709d4ec586b525724819dc6af1a7703502f7e06f34ded7157f7b1f963bb854"}, - {file = "debugpy-1.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a9c013077a3a0000e83d97cf9cc9328d2b0bbb31f56b0e99ea3662d29d7a6a2"}, - {file = "debugpy-1.8.8-cp39-cp39-win32.whl", hash = "sha256:ffe94dd5e9a6739a75f0b85316dc185560db3e97afa6b215628d1b6a17561cb2"}, - {file = "debugpy-1.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5c0e5a38c7f9b481bf31277d2f74d2109292179081f11108e668195ef926c0f9"}, - {file = "debugpy-1.8.8-py2.py3-none-any.whl", hash = "sha256:ec684553aba5b4066d4de510859922419febc710df7bba04fe9e7ef3de15d34f"}, - {file = "debugpy-1.8.8.zip", hash = "sha256:e6355385db85cbd666be703a96ab7351bc9e6c61d694893206f8001e22aee091"}, + {file = "debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e"}, + {file = "debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f"}, + {file = "debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037"}, + {file = "debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e"}, + {file = "debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040"}, + {file = "debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70"}, + {file = "debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66"}, + {file = "debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d"}, + {file = "debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2"}, + {file = "debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe"}, + {file = "debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11"}, + {file = "debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53"}, + {file = "debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd"}, + {file = "debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee"}, + {file = "debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee"}, + {file = "debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a"}, + {file = "debugpy-1.8.9-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:472a3994999fe6c0756945ffa359e9e7e2d690fb55d251639d07208dbc37caea"}, + {file = "debugpy-1.8.9-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365e556a4772d7d0d151d7eb0e77ec4db03bcd95f26b67b15742b88cacff88e9"}, + {file = "debugpy-1.8.9-cp38-cp38-win32.whl", hash = "sha256:54a7e6d3014c408eb37b0b06021366ee985f1539e12fe49ca2ee0d392d9ceca5"}, + {file = "debugpy-1.8.9-cp38-cp38-win_amd64.whl", hash = "sha256:8e99c0b1cc7bf86d83fb95d5ccdc4ad0586d4432d489d1f54e4055bcc795f693"}, + {file = "debugpy-1.8.9-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:7e8b079323a56f719977fde9d8115590cb5e7a1cba2fcee0986ef8817116e7c1"}, + {file = "debugpy-1.8.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6953b335b804a41f16a192fa2e7851bdcfd92173cbb2f9f777bb934f49baab65"}, + {file = "debugpy-1.8.9-cp39-cp39-win32.whl", hash = "sha256:7e646e62d4602bb8956db88b1e72fe63172148c1e25c041e03b103a25f36673c"}, + {file = "debugpy-1.8.9-cp39-cp39-win_amd64.whl", hash = "sha256:3d9755e77a2d680ce3d2c5394a444cf42be4a592caaf246dbfbdd100ffcf7ae5"}, + {file = "debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899"}, + {file = "debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e"}, ] [[package]] @@ -1161,13 +1163,13 @@ files = [ [[package]] name = "identify" -version = "2.6.2" +version = "2.6.3" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ - {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, - {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, + {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, + {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, ] [package.extras] @@ -1989,22 +1991,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, + {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, -] +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -2012,100 +2011,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] @@ -2173,13 +2183,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.0" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, ] [package.extras] @@ -2506,29 +2516,29 @@ test = ["hypothesis (==5.19.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "ruff" -version = "0.7.3" +version = "0.8.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344"}, - {file = "ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0"}, - {file = "ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16"}, - {file = "ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc"}, - {file = "ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088"}, - {file = "ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c"}, - {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, + {file = "ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea"}, + {file = "ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b"}, + {file = "ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426"}, + {file = "ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468"}, + {file = "ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f"}, + {file = "ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6"}, + {file = "ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44"}, ] [[package]] @@ -2793,98 +2803,49 @@ files = [ [[package]] name = "uuid-utils" -version = "0.9.0" +version = "0.10.0" description = "Drop-in replacement for Python UUID in Rust" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "uuid_utils-0.9.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:28da15c275ef06a759efe0fcba7c58eab8ae2217f7a7f66289dee6ae332605a0"}, - {file = "uuid_utils-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:81144165068e84a1ac8b92f23bfc961e5b5dbb89ddcff70c5e7d096ae07a439c"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:362695ed7756b1b89d9a2dd193fe2523ca1d4a31235606f7cb516a322789ffc4"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:36cb70e29f5749b554ae06f1a88926c9b47d5b48004b6903fb7ea47e8b398080"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa39a95eb67e2b98a61d4e64ddf622ee902fe9142b579921ab3e9027472f5080"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9b7029044d40f66366cebb6a94ecb04d8c0a745029561552d527ac52dc0deb9"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c883c6f815d2af344dab585d7b16a77410fcb1f6c097e6ad0384bd12cd84e16e"}, - {file = "uuid_utils-0.9.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:be5f83e9002a43aac868fa9cbc73f28cfb0b4e8b14f5a449fef04fea31bf2904"}, - {file = "uuid_utils-0.9.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8f84b0fd38df8a211230b8bbd02d5e7e631f1d35c1ba67efb895f80c7d9215aa"}, - {file = "uuid_utils-0.9.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:89cc342b061d8e3f669b8aaeb8d9e2973407c93aaa675dc6a59e985feda2805c"}, - {file = "uuid_utils-0.9.0-cp310-none-win32.whl", hash = "sha256:3d5554f44aeab9706770169316897f79089b51a061800684b7f29bccf663ad0f"}, - {file = "uuid_utils-0.9.0-cp310-none-win_amd64.whl", hash = "sha256:db35df169f17617129cc070e3a8fba00598ee55adcbe22c79b2c2f306eeb3b9e"}, - {file = "uuid_utils-0.9.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:cdb7224fb8b1f18edcd4357f83fcbe33b9f82ac392095e5d9e0e05336d65d587"}, - {file = "uuid_utils-0.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5312449ea5427a94edab3aebf2cff8f99a3112f273dd9d5919e332bc4e6a031f"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6837677217b3d0aa375f8aa7b89935c3ebf2ee5e1667be50b2090741684baa"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:402e522f62ceb8344f579e37f9a25c9274d484675afd71ad725ddd61ced7cd36"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e24a27724b2289d66d75358ffecf698ae36816458897cfdec972e6ede1ead328"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db04420c0b1a99f3160ddc90ba52986484ce8304b54586ea161133f755a4605b"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:152f3c1a0634558e329b64ff4a9592ee83b722e3fdc214f648f851fa14163c36"}, - {file = "uuid_utils-0.9.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5710b6ca95966f80125f48dad9e3d70ef99f48dd892bec3cb38673d087a7d71a"}, - {file = "uuid_utils-0.9.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3b9b9cf0cc544ef552c955bc2caaecf5e38cc8ed65e23f208b0dcdb6d37719e"}, - {file = "uuid_utils-0.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6d715b6321d4728a1aa0d5e26a338c97aaba2bf337f3ef9804ef5027f07de61d"}, - {file = "uuid_utils-0.9.0-cp311-none-win32.whl", hash = "sha256:3b61b0543404c99f7f23fb556b69090bc58358e8bd9d570381722221281f3706"}, - {file = "uuid_utils-0.9.0-cp311-none-win_amd64.whl", hash = "sha256:b4bdd9e80c92b1f253e66392e1d6ad0ec4926d5c7e2de3d852ee6fed1939f58b"}, - {file = "uuid_utils-0.9.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:9cfcfb222f62612bea58bdec32b6842d9636fca53ca4579f88c1b620b1c4cbf7"}, - {file = "uuid_utils-0.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7253039ecfa534b3177b3225764cede9c6dae5db572e17d8582dd7cc5b3af484"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fb6e792ae1e3a7bf9d357f87dcf628923d0881f1d13a9cba826b848ca1774b1"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fbea3bb9ad319de7f69d6a60b6921acaa97d577aaeceb247b1ff4a8a92b3aa6a"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09043b3f48e20d631c7a81030be8c4f6ea9a6d44cccda8cbbdc1ad18da301c89"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9ba2681f5f177f800e40f5a0f09ed03c49f4290a245e4273d21cb48a7e88969"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:866811473f3d9dc38c02dd08e076e333b9e4d41ce952353941b49d0724d2327b"}, - {file = "uuid_utils-0.9.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:14aa9917ef11bd0ee1648237dddbf33aa0459e609ebe2f9202ffb259ca80f763"}, - {file = "uuid_utils-0.9.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:22cae83bc486a6c12b38239eb0546f2f81c81c34fcf833f84c2c7cd0cab1ad8f"}, - {file = "uuid_utils-0.9.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9513399045169435563c284caba0f1802748b02f27c95769426b7a00ed246e1"}, - {file = "uuid_utils-0.9.0-cp312-none-win_amd64.whl", hash = "sha256:284e6d24ba659d003bd47fcfc404d374c7807983407d4d61f26c80a3b7f4cb41"}, - {file = "uuid_utils-0.9.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:fd3d09c53d5a96c78c77211786fa25bbdbe031566b927383c10ab81a27c7e431"}, - {file = "uuid_utils-0.9.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:2b052d01176d2d1afa476ebe158eae052e265c92110d987d5801f0c3c1c8852a"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e636a9603dc04e15b8305129619b2b45843f883e58355c91dc6cc22d51dde8"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37d2f9ec3a99caf29531fe257b7906f8a5946a3ee7000c744d73e5187a2542a1"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ace932d10a83141d22c42287a0c707cfa41522ecb797f17e63820f09688c6d7"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:843ec54337233d5f99a99b156ba5be5659f5ea193db8287035bf85d6a6a00c58"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f16a60ef4ddf9fe16fcd4793f83932d2b5198af6873d0a0478acfe0bd19d8e2f"}, - {file = "uuid_utils-0.9.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:901da31d61f78ec8df96741326541ae7af156a2628ca82ccf2806bcee257de1a"}, - {file = "uuid_utils-0.9.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:fad20ba28a11f2b33f06b2d7e0e77be73a8c3a41de833a123c6d93025d463b4b"}, - {file = "uuid_utils-0.9.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c5c30716a0dcffd1a7a66853f5a8372a276d454510f48fc7e4c39c13212bb1f6"}, - {file = "uuid_utils-0.9.0-cp38-none-win32.whl", hash = "sha256:2912c9a810e74cb3abaebd0fdfa5b1f202cf60a8f0fec9cc76117dab6c42cb77"}, - {file = "uuid_utils-0.9.0-cp38-none-win_amd64.whl", hash = "sha256:b55bcffc260356c84a09ac3a391e2442ad4df0beaaf71670d4e8ffd8b7328e75"}, - {file = "uuid_utils-0.9.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:08aec826a8ed4d3baab29d144ad634091e5accabcb88dfa0a834b9ba9e74930f"}, - {file = "uuid_utils-0.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e7de8fcf3d22e299582ab61c67390abdf37cc7d5b330066c3f792a082167c419"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8de8da71bc5a6a527952648357acca8d6d1717bbbc044304c5a9cf53eb06568c"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce3ef96aa6ba760e1d0481ed076fe9e8f0386e27c7039bc6ffa377c98979fae7"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69dd8c0d622e4e40b1b993a2e452bbed21127b97f8e4a3fdbde6e5f556253265"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4600d5dcd9d0759be4bc580daf6d521da99a825a25db3d492abcbb12f6dc98f6"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:067d5f36ccc70896c76a9dafc8220a942db0e42ab58b84c43208e0ff84c1bdf0"}, - {file = "uuid_utils-0.9.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7a23d20f08636899a1b24394a12a2c469262af56d5279dbac1c6b14b059e5d4b"}, - {file = "uuid_utils-0.9.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6a2cbc5da89f0e701d2b80df0e6b30da16a0adcd2883da3d3e1f7aac1f046c1c"}, - {file = "uuid_utils-0.9.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bbf93bdd3c8a3e3b2b2f82ad4dfafcd2aaecc1d6ec924fd5da2b712ab324ee51"}, - {file = "uuid_utils-0.9.0-cp39-none-win32.whl", hash = "sha256:9d9b3ba5be11a017c568e904eac76f6cd6f82f956ca65ffbaa73ee8d7cdbe13b"}, - {file = "uuid_utils-0.9.0-cp39-none-win_amd64.whl", hash = "sha256:b3e494547cfef124f0c51831a303bfc0278e3c33b9ab9d9db90d94728d9871c2"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:98c7c7b414b405b547c9bc1f972513b3a0bfb3dca248c89c623ab60efdd36ad8"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7b75241666cae4bc5786e6c68e862ccf4e15b2f98c81e47a6b0a85c907b7b6fa"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf6b43723a2d4af21c07fec98385a97e2023a808fd6eaf4296a163bffca76cf5"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c260bb9a9fdd484cadc437cdb26ad07d66c8049a365c4ef49c9f09d7ed9ac2e"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4605c6326a7914d1b59c548f0ae4ef119619fe09c3ab4f07d99f3fbec39d470"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d498673249826ce7c47aa481709a5dd647bbff764fb64370bc691c7e43c7a2a1"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a37c48cba2f4eb6182a3857d045aa1420fa9878bfd268f6855fce7293a006677"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:eeb9c56d401e4a422ae7fd818ef1376bda384ae0bed86e339c9a256c6b10d252"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:33dd97e9c59891fbfb4e4a11596c42cc3d10774b843daaf75316d036a0a07799"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5e67fc3c6def9d62de4caf19529bd8044e821eb2f5c39821cfd011940f96394"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:241ab8ddb76ef8d4294c09cd6045dd62a1aa46acf8ff0a017796a54a530a87ae"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a9a16d2af4b4ad59d4cef7f43ba33644353b12769fafabf6e1663aa230cca38"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:897a167659d30a8431a094533bcb58d2b16005f7456408bd40f3e5872e1b2f46"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b4f56ab5ce19697552df9689c24c742054e8fd8e2ef8c26f9b8393f6d7ae893"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b219d9341de117e2e608f3fe08e31480ad60fb6128f8fffd2151ba88e53508c"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b5c08de8a94181c0ba209a8b8275993499f424b57958bea6c39739311526fd18"}, - {file = "uuid_utils-0.9.0.tar.gz", hash = "sha256:239f45b7e71d0ea61e3a4957aa4b8f3b49bfb009cf768d11c3f464787dbb737f"}, + {file = "uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d5a4508feefec62456cd6a41bcdde458d56827d908f226803b886d22a3d5e63"}, + {file = "uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dbefc2b9113f9dfe56bdae58301a2b3c53792221410d422826f3d1e3e6555fe7"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc49c33edf87d1ec8112a9b43e4cf55326877716f929c165a2cc307d31c73d5"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0636b6208f69d5a4e629707ad2a89a04dfa8d1023e1999181f6830646ca048a1"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc06452856b724df9dedfc161c3582199547da54aeb81915ec2ed54f92d19b0"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:263b2589111c61decdd74a762e8f850c9e4386fb78d2cf7cb4dfc537054cda1b"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a558db48b7096de6b4d2d2210d82bba8586a6d55f99106b03bb7d01dc5c5bcd6"}, + {file = "uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:807465067f3c892514230326ac71a79b28a8dfe2c88ecd2d5675fc844f3c76b5"}, + {file = "uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:57423d4a2b9d7b916de6dbd75ba85465a28f9578a89a97f7d3e098d9aa4e5d4a"}, + {file = "uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:76d8d660f18ff6b767e319b1b5f927350cd92eafa4831d7ef5b57fdd1d91f974"}, + {file = "uuid_utils-0.10.0-cp39-abi3-win32.whl", hash = "sha256:6c11a71489338837db0b902b75e1ba7618d5d29f05fde4f68b3f909177dbc226"}, + {file = "uuid_utils-0.10.0-cp39-abi3-win_amd64.whl", hash = "sha256:11c55ae64f6c0a7a0c741deae8ca2a4eaa11e9c09dbb7bec2099635696034cf7"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:acea543dfc7b87df749e3e814c54ac739a82ff5e3800d25bd25a3e00599e1554"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0767eefa7b1e96f06cfa9b95758d286240c01bbf19e9d8f1b6043cdbe76cc639"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973fe4bb5258fd2ccb144d8b40c2d3158f16cc856a20527f8b40d14b2ae1dee9"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:71b8505b67a0d77d0fbd765d8463094a8f447677125da7647bec7ea0b99406f0"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6bdcb1211bb61476cbef12a87101fa48243e20ed82b2bd324c816b1b5826bd5e"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c5247f1df040aae71ea313819b563debe69bca7086a2cc6a3ac0eaddd3dadac"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a50bd29ef89660b93aa07ffa95ac691a0e12832375030569a8bd5c9272f3b8e6"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a778cd9d8f995b94bba6e51f3ebee5b338fd834b0c4ecc8f932bd23e29db3e19"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d3d5b5c5ed66ff923961b9ebb902232cd67f6a7ec6b6f7a58e05e00ff44e3c7f"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:789ed6335225326c66f5d6162649bed978105a85f232be7811387c395c226801"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:05d1aa7b944b719eb1ee472435ae5444a3f8a00eb6350e3b1d1217d738477d33"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa8d8559c2d25d6ac87e0adeee601d2c91ec40b357ab780bcf79061cc23324e6"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0badcbfe3c72b5b30d59c2b12f120923127abd95a0d2aa64ddc1234e495abc2"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a7c1c494012335113748815156c5b6234c59b0fe0d3a8eede1b1a46f7e25a69"}, + {file = "uuid_utils-0.10.0.tar.gz", hash = "sha256:5db0e1890e8f008657ffe6ded4d9459af724ab114cfe82af1557c87545301539"}, ] [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.28.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, + {file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"}, + {file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"}, ] [package.dependencies] @@ -2931,93 +2892,93 @@ tests = ["Django (>=2.2.0)", "Flask (>=0.12.5)", "aiohttp (>=3.0.8)", "bottle (> [[package]] name = "yarl" -version = "1.17.1" +version = "1.18.0" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91"}, - {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da"}, - {file = "yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931"}, - {file = "yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b"}, - {file = "yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, - {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, - {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, - {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, - {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258"}, - {file = "yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2"}, - {file = "yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f"}, - {file = "yarl-1.17.1-cp39-cp39-win32.whl", hash = "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473"}, - {file = "yarl-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138"}, - {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, - {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:074fee89caab89a97e18ef5f29060ef61ba3cae6cd77673acc54bfdd3214b7b7"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b026cf2c32daf48d90c0c4e406815c3f8f4cfe0c6dfccb094a9add1ff6a0e41a"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae38bd86eae3ba3d2ce5636cc9e23c80c9db2e9cb557e40b98153ed102b5a736"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:685cc37f3f307c6a8e879986c6d85328f4c637f002e219f50e2ef66f7e062c1d"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8254dbfce84ee5d1e81051ee7a0f1536c108ba294c0fdb5933476398df0654f3"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20de4a8b04de70c49698dc2390b7fd2d18d424d3b876371f9b775e2b462d4b41"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0a2074a37285570d54b55820687de3d2f2b9ecf1b714e482e48c9e7c0402038"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f576ed278860df2721a5d57da3381040176ef1d07def9688a385c8330db61a1"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3a3709450a574d61be6ac53d582496014342ea34876af8dc17cc16da32826c9a"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bd80ed29761490c622edde5dd70537ca8c992c2952eb62ed46984f8eff66d6e8"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:32141e13a1d5a48525e519c9197d3f4d9744d818d5c7d6547524cc9eccc8971e"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8b8d3e4e014fb4274f1c5bf61511d2199e263909fb0b8bda2a7428b0894e8dc6"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:701bb4a8f4de191c8c0cc9a1e6d5142f4df880e9d1210e333b829ca9425570ed"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a45d94075ac0647621eaaf693c8751813a3eccac455d423f473ffed38c8ac5c9"}, + {file = "yarl-1.18.0-cp310-cp310-win32.whl", hash = "sha256:34176bfb082add67cb2a20abd85854165540891147f88b687a5ed0dc225750a0"}, + {file = "yarl-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:73553bbeea7d6ec88c08ad8027f4e992798f0abc459361bf06641c71972794dc"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b8e8c516dc4e1a51d86ac975b0350735007e554c962281c432eaa5822aa9765c"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e6b4466714a73f5251d84b471475850954f1fa6acce4d3f404da1d55d644c34"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c893f8c1a6d48b25961e00922724732d00b39de8bb0b451307482dc87bddcd74"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13aaf2bdbc8c86ddce48626b15f4987f22e80d898818d735b20bd58f17292ee8"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd21c0128e301851de51bc607b0a6da50e82dc34e9601f4b508d08cc89ee7929"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205de377bd23365cd85562c9c6c33844050a93661640fda38e0567d2826b50df"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed69af4fe2a0949b1ea1d012bf065c77b4c7822bad4737f17807af2adb15a73c"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e1c18890091aa3cc8a77967943476b729dc2016f4cfe11e45d89b12519d4a93"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91b8fb9427e33f83ca2ba9501221ffaac1ecf0407f758c4d2f283c523da185ee"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:536a7a8a53b75b2e98ff96edb2dfb91a26b81c4fed82782035767db5a465be46"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a64619a9c47c25582190af38e9eb382279ad42e1f06034f14d794670796016c0"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c73a6bbc97ba1b5a0c3c992ae93d721c395bdbb120492759b94cc1ac71bc6350"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a173401d7821a2a81c7b47d4e7d5c4021375a1441af0c58611c1957445055056"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7520e799b1f84e095cce919bd6c23c9d49472deeef25fe1ef960b04cca51c3fc"}, + {file = "yarl-1.18.0-cp311-cp311-win32.whl", hash = "sha256:c4cb992d8090d5ae5f7afa6754d7211c578be0c45f54d3d94f7781c495d56716"}, + {file = "yarl-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:52c136f348605974c9b1c878addd6b7a60e3bf2245833e370862009b86fa4689"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7"}, + {file = "yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75"}, + {file = "yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af"}, + {file = "yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88"}, + {file = "yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fa2c9cb607e0f660d48c54a63de7a9b36fef62f6b8bd50ff592ce1137e73ac7d"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0f4808644baf0a434a3442df5e0bedf8d05208f0719cedcd499e168b23bfdc4"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7db9584235895a1dffca17e1c634b13870852094f6389b68dcc6338086aa7b08"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:309f8d27d6f93ceeeb80aa6980e883aa57895270f7f41842b92247e65d7aeddf"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:609ffd44fed2ed88d9b4ef62ee860cf86446cf066333ad4ce4123505b819e581"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f172b8b2c72a13a06ea49225a9c47079549036ad1b34afa12d5491b881f5b993"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89ae7de94631b60d468412c18290d358a9d805182373d804ec839978b120422"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:466d31fd043ef9af822ee3f1df8fdff4e8c199a7f4012c2642006af240eade17"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7609b8462351c4836b3edce4201acb6dd46187b207c589b30a87ffd1813b48dc"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d9d4f5e471e8dc49b593a80766c2328257e405f943c56a3dc985c125732bc4cf"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:67b336c15e564d76869c9a21316f90edf546809a5796a083b8f57c845056bc01"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b212452b80cae26cb767aa045b051740e464c5129b7bd739c58fbb7deb339e7b"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:38b39b7b3e692b6c92b986b00137a3891eddb66311b229d1940dcbd4f025083c"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ee6884a8848792d58b854946b685521f41d8871afa65e0d4a774954e9c9e89"}, + {file = "yarl-1.18.0-cp39-cp39-win32.whl", hash = "sha256:b4095c5019bb889aa866bf12ed4c85c0daea5aafcb7c20d1519f02a1e738f07f"}, + {file = "yarl-1.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:2d90f2e4d16a5b0915ee065218b435d2ef619dd228973b1b47d262a6f7cd8fa5"}, + {file = "yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0"}, + {file = "yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715"}, ] [package.dependencies] @@ -3033,4 +2994,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "32b3a449d520f812a5be03ed306d923d4476c1fcaf8750470587a3a8da09fed3" +content-hash = "cb8b649f6c4779cc8e3680d088b22b35c96b912a3c1ed3c17441d82f3a10f7eb" diff --git a/pyproject.toml b/pyproject.toml index 8d3365a8e7..67df9fd78a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "acapy_agent_didx" -version = "1.1.1-20241115" +version = "1.1.1a5" description = "(ACA-Py) A Cloud Agent Python is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = [] license = "Apache-2.0" @@ -16,7 +16,7 @@ repository = "https://github.com/openwallet-foundation/acapy" [tool.poetry.dependencies] python = "^3.12" -aiohttp = "~3.11.0" +aiohttp = "~3.11.7" aiohttp-apispec-acapy = "~3.0.2" aiohttp-cors = "~0.7.0" apispec = "^6.6.0" @@ -34,7 +34,7 @@ packaging = "~23.2" portalocker = "~2.10.1" prompt_toolkit = ">=2.0.9,<2.1.0" pydid = "^0.5.1" -pyjwt = "~2.9.0" +pyjwt = "~2.10.0" pyld = "^2.0.4" pynacl = "~1.5.0" python-dateutil = "^2.9.0" @@ -45,9 +45,13 @@ requests = "~2.32.3" rlp = "4.0.1" unflatten = "~0.2" sd-jwt = "^0.10.3" +uuid_utils = "^0.10.0" + +# did libraries did-peer-2 = "^0.1.2" did-peer-4 = "^0.1.4" -uuid_utils = "^0.9.0" +# did-tdw = "^0.2.1" + # askar aries-askar-ff137 = {version = "==0.3.3b0", source = "testpypi", optional = true} @@ -65,7 +69,7 @@ canonicaljson = "^2.0.0" [tool.poetry.group.dev.dependencies] pre-commit = "~3.8.0" # Sync with version in .pre-commit-config.yaml -ruff = "0.7.3" +ruff = "0.8.0" sphinx = "^5.3.0" sphinx-rtd-theme = ">=0.4.3" @@ -80,7 +84,7 @@ pytest-asyncio = "^0.24.0" pytest-cov = "^5.0.0" pytest-ruff = "^0.4.1" pytest-xdist = "^3.6.1" -debugpy = "^1.8.8" +debugpy = "^1.8.9" [tool.poetry.extras] askar = ["aries-askar-ff137", "indy-credx", "indy-vdr", "anoncreds"] diff --git a/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml b/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml index 247a0b7daf..6e0a757fbd 100644 --- a/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml +++ b/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml @@ -1,22 +1,26 @@ services: - alice: + agency: image: acapy-test ports: - "3001:3001" command: > start - --label Alice + --label Agency --inbound-transport http 0.0.0.0 3000 --outbound-transport http - --endpoint http://alice:3000 + --endpoint http://agency:3000 --admin 0.0.0.0 3001 --admin-insecure-mode --tails-server-base-url http://tails:6543 --genesis-url http://test.bcovrin.vonx.io/genesis - --wallet-type askar-anoncreds - --wallet-name alice + --wallet-type askar + --wallet-name agency --wallet-key insecure --auto-provision + --multitenant + --multitenant-admin + --jwt-secret insecure + --multitenancy-config wallet_type=single-wallet-askar key_derivation_method=RAW --log-level info --debug-webhooks --notify-revocation @@ -30,22 +34,50 @@ tails: condition: service_started - bob: + holder_anoncreds: image: acapy-test ports: - "3002:3001" command: > start - --label Bob + --label Holder-Anoncreds --inbound-transport http 0.0.0.0 3000 --outbound-transport http - --endpoint http://bob:3000 + --endpoint http://holder_anoncreds:3000 --admin 0.0.0.0 3001 --admin-insecure-mode --tails-server-base-url http://tails:6543 --genesis-url http://test.bcovrin.vonx.io/genesis --wallet-type askar-anoncreds - --wallet-name bob + --wallet-name holder_anoncreds + --wallet-key insecure + --auto-provision + --log-level info + --debug-webhooks + --monitor-revocation-notification + healthcheck: + test: curl -s -o /dev/null -w '%{http_code}' "http://localhost:3001/status/live" | grep "200" > /dev/null + start_period: 30s + interval: 7s + timeout: 5s + retries: 5 + + holder_indy: + image: acapy-test + ports: + - "3003:3001" + command: > + start + --label Holder-Indy + --inbound-transport http 0.0.0.0 3000 + --outbound-transport http + --endpoint http://holder_indy:3000 + --admin 0.0.0.0 3001 + --admin-insecure-mode + --tails-server-base-url http://tails:6543 + --genesis-url http://test.bcovrin.vonx.io/genesis + --wallet-type askar + --wallet-name holder_indy --wallet-key insecure --auto-provision --log-level info @@ -63,15 +95,18 @@ build: context: ../.. environment: - - ALICE=http://alice:3001 - - BOB=http://bob:3001 + - AGENCY=http://agency:3001 + - HOLDER_ANONCREDS=http://holder_anoncreds:3001 + - HOLDER_INDY=http://holder_indy:3001 volumes: - ./example.py:/usr/src/app/example.py:ro,z command: python -m example depends_on: - alice: + agency: + condition: service_healthy + holder_anoncreds: condition: service_healthy - bob: + holder_indy: condition: service_healthy tails: diff --git a/scenarios/examples/anoncreds_issuance_and_revocation/example.py b/scenarios/examples/anoncreds_issuance_and_revocation/example.py index 6d7d1a1bd2..05a68c395a 100644 --- a/scenarios/examples/anoncreds_issuance_and_revocation/example.py +++ b/scenarios/examples/anoncreds_issuance_and_revocation/example.py @@ -7,23 +7,30 @@ import json from dataclasses import dataclass from os import getenv -from secrets import token_hex +from secrets import randbelow, token_hex +from typing import Any, Dict, List, Mapping, Optional, Tuple, Type, Union +from uuid import uuid4 from acapy_controller import Controller -from acapy_controller.controller import Minimal +from acapy_controller.controller import Minimal, MinType from acapy_controller.logging import logging_to_stdout -from acapy_controller.models import V20PresExRecord, V20PresExRecordList +from acapy_controller.models import ( + CreateWalletResponse, + V20CredExRecordIndy, + V20PresExRecord, + V20PresExRecordList, +) from acapy_controller.protocols import ( DIDResult, didexchange, - indy_issue_credential_v2, - indy_present_proof_v2, + indy_anoncred_credential_artifacts, params, ) from aiohttp import ClientSession -ALICE = getenv("ALICE", "http://alice:3001") -BOB = getenv("BOB", "http://bob:3001") +AGENCY = getenv("AGENCY", "http://agency:3001") +HOLDER_ANONCREDS = getenv("HOLDER_ANONCREDS", "http://holder_anoncreds:3001") +HOLDER_INDY = getenv("HOLDER_INDY", "http://holder_indy:3001") def summary(presentation: V20PresExRecord) -> str: @@ -33,7 +40,9 @@ def summary(presentation: V20PresExRecord) -> str: { "state": presentation.state, "verified": presentation.verified, - "presentation_request": request.dict(by_alias=True) if request else None, + "presentation_request": request.model_dump(by_alias=True) + if request + else None, }, indent=2, sort_keys=True, @@ -41,32 +50,395 @@ def summary(presentation: V20PresExRecord) -> str: @dataclass -class SchemaResult(Minimal): +class SchemaResultAnoncreds(Minimal): """Schema result.""" schema_state: dict @dataclass -class CredDefResult(Minimal): +class CredDefResultAnoncreds(Minimal): """Credential definition result.""" credential_definition_state: dict +@dataclass +class V20CredExRecord(Minimal): + """V2.0 credential exchange record.""" + + state: str + cred_ex_id: str + connection_id: str + thread_id: str + + +@dataclass +class V20CredExRecordFormat(Minimal): + """V2.0 credential exchange record anoncreds.""" + + rev_reg_id: Optional[str] = None + cred_rev_id: Optional[str] = None + + +@dataclass +class V20CredExRecordDetail(Minimal): + """V2.0 credential exchange record detail.""" + + cred_ex_record: V20CredExRecord + details: Optional[V20CredExRecordFormat] = None + + +@dataclass +class ProofRequest(Minimal): + """Proof request.""" + + requested_attributes: Dict[str, Any] + requested_predicates: Dict[str, Any] + + +@dataclass +class PresSpec(Minimal): + """Presentation specification.""" + + requested_attributes: Dict[str, Any] + requested_predicates: Dict[str, Any] + self_attested_attributes: Dict[str, Any] + + +@dataclass +class CredInfo(Minimal): + """Credential information.""" + + referent: str + attrs: Dict[str, Any] + + +@dataclass +class CredPrecis(Minimal): + """Credential precis.""" + + cred_info: CredInfo + presentation_referents: List[str] + + @classmethod + def deserialize(cls: Type[MinType], value: Mapping[str, Any]) -> MinType: + """Deserialize the credential precis.""" + value = dict(value) + if cred_info := value.get("cred_info"): + value["cred_info"] = CredInfo.deserialize(cred_info) + return super().deserialize(value) + + +@dataclass +class Settings(Minimal): + """Settings information.""" + + +def auto_select_credentials_for_presentation_request( + presentation_request: Union[ProofRequest, dict], + relevant_creds: List[CredPrecis], +) -> PresSpec: + """Select credentials to use for presentation automatically.""" + if isinstance(presentation_request, dict): + presentation_request = ProofRequest.deserialize(presentation_request) + + requested_attributes = {} + for pres_referrent in presentation_request.requested_attributes.keys(): + for cred_precis in relevant_creds: + if pres_referrent in cred_precis.presentation_referents: + requested_attributes[pres_referrent] = { + "cred_id": cred_precis.cred_info.referent, + "revealed": True, + } + requested_predicates = {} + for pres_referrent in presentation_request.requested_predicates.keys(): + for cred_precis in relevant_creds: + if pres_referrent in cred_precis.presentation_referents: + requested_predicates[pres_referrent] = { + "cred_id": cred_precis.cred_info.referent, + } + + return PresSpec.deserialize( + { + "requested_attributes": requested_attributes, + "requested_predicates": requested_predicates, + "self_attested_attributes": {}, + } + ) + + +async def issue_credential_v2( + issuer: Controller, + holder: Controller, + issuer_connection_id: str, + holder_connection_id: str, + cred_def_id: str, + attributes: Mapping[str, str], +) -> Tuple[V20CredExRecordDetail, V20CredExRecordDetail]: + """Issue an credential using issue-credential/2.0. + + Issuer and holder should already be connected. + """ + + is_issuer_anoncreds = (await issuer.get("/settings", response=Settings)).get( + "wallet.type" + ) == "askar-anoncreds" + is_holder_anoncreds = (await holder.get("/settings", response=Settings)).get( + "wallet.type" + ) == "askar-anoncreds" + + if is_issuer_anoncreds: + _filter = {"anoncreds": {"cred_def_id": cred_def_id}} + else: + _filter = {"indy": {"cred_def_id": cred_def_id}} + issuer_cred_ex = await issuer.post( + "/issue-credential-2.0/send-offer", + json={ + "auto_issue": False, + "auto_remove": False, + "comment": "Credential from minimal example", + "trace": False, + "connection_id": issuer_connection_id, + "filter": _filter, + "credential_preview": { + "type": "issue-credential-2.0/2.0/credential-preview", # pyright: ignore + "attributes": [ + { + "mime_type": None, + "name": name, + "value": value, + } + for name, value in attributes.items() + ], + }, + }, + response=V20CredExRecord, + ) + issuer_cred_ex_id = issuer_cred_ex.cred_ex_id + + holder_cred_ex = await holder.event_with_values( + topic="issue_credential_v2_0", + event_type=V20CredExRecord, + connection_id=holder_connection_id, + state="offer-received", + ) + holder_cred_ex_id = holder_cred_ex.cred_ex_id + + await holder.post( + f"/issue-credential-2.0/records/{holder_cred_ex_id}/send-request", + response=V20CredExRecord, + ) + + await issuer.event_with_values( + topic="issue_credential_v2_0", + cred_ex_id=issuer_cred_ex_id, + state="request-received", + ) + + await issuer.post( + f"/issue-credential-2.0/records/{issuer_cred_ex_id}/issue", + json={}, + response=V20CredExRecordDetail, + ) + + await holder.event_with_values( + topic="issue_credential_v2_0", + cred_ex_id=holder_cred_ex_id, + state="credential-received", + ) + + await holder.post( + f"/issue-credential-2.0/records/{holder_cred_ex_id}/store", + json={}, + response=V20CredExRecordDetail, + ) + issuer_cred_ex = await issuer.event_with_values( + topic="issue_credential_v2_0", + event_type=V20CredExRecord, + cred_ex_id=issuer_cred_ex_id, + state="done", + ) + issuer_indy_record = await issuer.event_with_values( + topic="issue_credential_v2_0_anoncreds" + if is_issuer_anoncreds + else "issue_credential_v2_0_indy", + event_type=V20CredExRecordIndy, + ) + + holder_cred_ex = await holder.event_with_values( + topic="issue_credential_v2_0", + event_type=V20CredExRecord, + cred_ex_id=holder_cred_ex_id, + state="done", + ) + holder_indy_record = await holder.event_with_values( + topic="issue_credential_v2_0_anoncreds" + if is_holder_anoncreds + else "issue_credential_v2_0_indy", + event_type=V20CredExRecordIndy, + ) + + return ( + V20CredExRecordDetail(cred_ex_record=issuer_cred_ex, details=issuer_indy_record), + V20CredExRecordDetail( + cred_ex_record=holder_cred_ex, + details=holder_indy_record, + ), + ) + + +async def present_proof_v2( + holder: Controller, + verifier: Controller, + holder_connection_id: str, + verifier_connection_id: str, + *, + name: Optional[str] = None, + version: Optional[str] = None, + comment: Optional[str] = None, + requested_attributes: Optional[List[Mapping[str, Any]]] = None, + requested_predicates: Optional[List[Mapping[str, Any]]] = None, + non_revoked: Optional[Mapping[str, int]] = None, +): + """Present an credential using present proof v2.""" + + is_verifier_anoncreds = (await verifier.get("/settings", response=Settings)).get( + "wallet.type" + ) == "askar-anoncreds" + + attrs = { + "name": name or "proof", + "version": version or "0.1.0", + "nonce": str(randbelow(10**10)), + "requested_attributes": { + str(uuid4()): attr for attr in requested_attributes or [] + }, + "requested_predicates": { + str(uuid4()): pred for pred in requested_predicates or [] + }, + "non_revoked": (non_revoked if non_revoked else None), + } + + if is_verifier_anoncreds: + presentation_request = { + "anoncreds": attrs, + } + else: + presentation_request = { + "indy": attrs, + } + verifier_pres_ex = await verifier.post( + "/present-proof-2.0/send-request", + json={ + "auto_verify": False, + "comment": comment or "Presentation request from minimal", + "connection_id": verifier_connection_id, + "presentation_request": presentation_request, + "trace": False, + }, + response=V20PresExRecord, + ) + verifier_pres_ex_id = verifier_pres_ex.pres_ex_id + + holder_pres_ex = await holder.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + connection_id=holder_connection_id, + state="request-received", + ) + assert holder_pres_ex.pres_request + holder_pres_ex_id = holder_pres_ex.pres_ex_id + + relevant_creds = await holder.get( + f"/present-proof-2.0/records/{holder_pres_ex_id}/credentials", + response=List[CredPrecis], + ) + assert holder_pres_ex.by_format.pres_request + proof_request = holder_pres_ex.by_format.pres_request.get( + "anoncreds" + ) or holder_pres_ex.by_format.pres_request.get("indy") + pres_spec = auto_select_credentials_for_presentation_request( + proof_request, relevant_creds + ) + if is_verifier_anoncreds: + proof = {"anoncreds": pres_spec.serialize()} + else: + proof = {"indy": pres_spec.serialize()} + await holder.post( + f"/present-proof-2.0/records/{holder_pres_ex_id}/send-presentation", + json=proof, + response=V20PresExRecord, + ) + + await verifier.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + pres_ex_id=verifier_pres_ex_id, + state="presentation-received", + ) + await verifier.post( + f"/present-proof-2.0/records/{verifier_pres_ex_id}/verify-presentation", + json={}, + response=V20PresExRecord, + ) + verifier_pres_ex = await verifier.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + pres_ex_id=verifier_pres_ex_id, + state="done", + ) + + holder_pres_ex = await holder.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + pres_ex_id=holder_pres_ex_id, + state="done", + ) + + return holder_pres_ex, verifier_pres_ex + + async def main(): """Test Controller protocols.""" - async with Controller(base_url=ALICE) as alice, Controller(base_url=BOB) as bob: + issuer_name = "issuer" + token_hex(8) + async with Controller(base_url=AGENCY) as agency: + issuer = await agency.post( + "/multitenancy/wallet", + json={ + "label": issuer_name, + "wallet_name": issuer_name, + "wallet_type": "askar", + }, + response=CreateWalletResponse, + ) + + async with Controller( + base_url=AGENCY, + wallet_id=issuer.wallet_id, + subwallet_token=issuer.token, + ) as issuer, Controller(base_url=HOLDER_ANONCREDS) as holder_anoncreds, Controller( + base_url=HOLDER_INDY + ) as holder_indy: + """ + This section of the test script demonstrates the issuance, presentation and + revocation of a credential where both the issuer is not anoncreds capable + (wallet type askar) and the holder is anoncreds capable + (wallet type askar-anoncreds). + """ + # Connecting - alice_conn, bob_conn = await didexchange(alice, bob) + issuer_conn_with_anoncreds_holder, holder_anoncreds_conn = await didexchange( + issuer, holder_anoncreds + ) # Issuance prep - config = (await alice.get("/status/config"))["config"] + config = (await issuer.get("/status/config"))["config"] genesis_url = config.get("ledger.genesis_url") - public_did = (await alice.get("/wallet/did/public", response=DIDResult)).result + public_did = (await issuer.get("/wallet/did/public", response=DIDResult)).result if not public_did: public_did = ( - await alice.post( + await issuer.post( "/wallet/did/create", json={"method": "sov", "options": {"key_type": "ed25519"}}, response=DIDResult, @@ -87,21 +459,154 @@ async def main(): ) as resp: assert resp.ok - await alice.post("/wallet/did/public", params=params(did=public_did.did)) + await issuer.post("/wallet/did/public", params=params(did=public_did.did)) + + _, cred_def = await indy_anoncred_credential_artifacts( + issuer, + ["firstname", "lastname"], + support_revocation=True, + ) + + # Issue a credential + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_anoncreds, + issuer_conn_with_anoncreds_holder.connection_id, + holder_anoncreds_conn.connection_id, + cred_def.credential_definition_id, + {"firstname": "Anoncreds", "lastname": "Holder"}, + ) + + # Present the the credential's attributes + await present_proof_v2( + holder_anoncreds, + issuer, + holder_anoncreds_conn.connection_id, + issuer_conn_with_anoncreds_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + + # Revoke credential + await issuer.post( + url="/revocation/revoke", + json={ + "connection_id": issuer_conn_with_anoncreds_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, + "publish": True, + "notify": True, + "notify_version": "v1_0", + }, + ) + + await holder_anoncreds.record(topic="revocation-notification") + + """ + This section of the test script demonstrates the issuance, presentation and + revocation of a credential where the issuer and holder are not anoncreds + capable. Both are askar wallet type. + """ + + # Connecting + issuer_conn_with_indy_holder, holder_indy_conn = await didexchange( + issuer, holder_indy + ) + + # Issue a credential + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_indy, + issuer_conn_with_indy_holder.connection_id, + holder_indy_conn.connection_id, + cred_def.credential_definition_id, + {"firstname": "Indy", "lastname": "Holder"}, + ) + + # Present the the credential's attributes + await present_proof_v2( + holder_indy, + issuer, + holder_indy_conn.connection_id, + issuer_conn_with_indy_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + # Query presentations + presentations = await issuer.get( + "/present-proof-2.0/records", + response=V20PresExRecordList, + ) + + # Presentation summary + for _, pres in enumerate(presentations.results): + print(summary(pres)) + + # Revoke credential + await issuer.post( + url="/revocation/revoke", + json={ + "connection_id": issuer_conn_with_indy_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, + "publish": True, + "notify": True, + "notify_version": "v1_0", + }, + ) + + await holder_indy.record(topic="revocation-notification") - schema = await alice.post( + """ + Upgrade the issuer tenant to anoncreds capable wallet type. When upgrading a + tenant the agent doesn't require a restart. That is why the test is done + with multitenancy + """ + await issuer.post( + "/anoncreds/wallet/upgrade", + params={ + "wallet_name": issuer_name, + }, + ) + + # Wait for the upgrade to complete + await asyncio.sleep(2) + + """ + Do issuance and presentation again after the upgrade. This time the issuer is + an anoncreds capable wallet (wallet type askar-anoncreds). + """ + # Presentation for anoncreds capable holder on existing credential + await present_proof_v2( + holder_anoncreds, + issuer, + holder_anoncreds_conn.connection_id, + issuer_conn_with_anoncreds_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + + # Presentation for indy capable holder on existing credential + await present_proof_v2( + holder_indy, + issuer, + holder_indy_conn.connection_id, + issuer_conn_with_indy_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + + # Create a new schema and cred def with different attributes on new + # anoncreds endpoints + schema = await issuer.post( "/anoncreds/schema", json={ "schema": { "name": "anoncreds-test-" + token_hex(8), "version": "1.0", - "attrNames": ["firstname", "lastname"], + "attrNames": ["middlename"], "issuerId": public_did.did, } }, - response=SchemaResult, + response=SchemaResultAnoncreds, ) - cred_def = await alice.post( + cred_def = await issuer.post( "/anoncreds/credential-definition", json={ "credential_definition": { @@ -109,77 +614,73 @@ async def main(): "schemaId": schema.schema_state["schema_id"], "tag": token_hex(8), }, - "options": { - "revocation_registry_size": 2000, - "support_revocation": True, - }, + "options": {"support_revocation": True, "revocation_registry_size": 10}, }, - response=CredDefResult, + response=CredDefResultAnoncreds, ) - # Issue a credential - alice_cred_ex, _ = await indy_issue_credential_v2( - alice, - bob, - alice_conn.connection_id, - bob_conn.connection_id, + # Issue a new credential to anoncreds holder + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_anoncreds, + issuer_conn_with_anoncreds_holder.connection_id, + holder_anoncreds_conn.connection_id, cred_def.credential_definition_state["credential_definition_id"], - {"firstname": "Bob", "lastname": "Builder"}, + {"middlename": "Anoncreds"}, ) - - # Present the the credential's attributes - await indy_present_proof_v2( - bob, - alice, - bob_conn.connection_id, - alice_conn.connection_id, - requested_attributes=[{"name": "firstname"}], + # Presentation for anoncreds capable holder + await present_proof_v2( + holder_anoncreds, + issuer, + holder_anoncreds_conn.connection_id, + issuer_conn_with_anoncreds_holder.connection_id, + requested_attributes=[{"name": "middlename"}], ) - # Revoke credential - await alice.post( + await issuer.post( url="/anoncreds/revocation/revoke", json={ - "connection_id": alice_conn.connection_id, - "rev_reg_id": alice_cred_ex.indy.rev_reg_id, - "cred_rev_id": alice_cred_ex.indy.cred_rev_id, + "connection_id": issuer_conn_with_anoncreds_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, "publish": True, "notify": True, "notify_version": "v1_0", }, ) + await holder_anoncreds.record(topic="revocation-notification") - await bob.record(topic="revocation-notification") - - # Request proof, no interval - await indy_present_proof_v2( - bob, - alice, - bob_conn.connection_id, - alice_conn.connection_id, - requested_attributes=[ - { - "name": "firstname", - "restrictions": [ - { - "cred_def_id": cred_def.credential_definition_state[ - "credential_definition_id" - ] - } - ], - } - ], + # Issue a new credential to indy holder + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_indy, + issuer_conn_with_indy_holder.connection_id, + holder_indy_conn.connection_id, + cred_def.credential_definition_state["credential_definition_id"], + {"middlename": "Indy"}, ) - - # Query presentations - presentations = await alice.get( - "/present-proof-2.0/records", - response=V20PresExRecordList, + # Presentation for indy holder + await present_proof_v2( + holder_indy, + issuer, + holder_indy_conn.connection_id, + issuer_conn_with_indy_holder.connection_id, + requested_attributes=[{"name": "middlename"}], + ) + # Revoke credential + await issuer.post( + url="/anoncreds/revocation/revoke", + json={ + "connection_id": issuer_conn_with_indy_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, + "publish": True, + "notify": True, + "notify_version": "v1_0", + }, ) - # Presentation summary - for i, pres in enumerate(presentations.results): - print(summary(pres)) + await holder_indy.record(topic="revocation-notification") if __name__ == "__main__": diff --git a/scenarios/poetry.lock b/scenarios/poetry.lock index 512f6c51a0..87805a2cb5 100644 --- a/scenarios/poetry.lock +++ b/scenarios/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "acapy-controller" @@ -36,112 +36,112 @@ files = [ [[package]] name = "aiohttp" -version = "3.10.5" +version = "3.10.11" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"}, - {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"}, - {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"}, - {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"}, - {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"}, - {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"}, - {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"}, - {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"}, - {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"}, - {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"}, - {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"}, - {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"}, - {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"}, - {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"}, + {file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"}, + {file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"}, + {file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"}, + {file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"}, + {file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"}, + {file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"}, + {file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"}, + {file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"}, + {file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"}, + {file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"}, + {file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"}, + {file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"}, + {file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"}, ] [package.dependencies] aiohappyeyeballs = ">=2.3.0" aiosignal = ">=1.1.2" -async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.0,<2.0" +yarl = ">=1.12.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] @@ -485,6 +485,113 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "propcache" +version = "0.2.0" +description = "Accelerated property cache" +optional = false +python-versions = ">=3.8" +files = [ + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, + {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, + {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, + {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, + {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, + {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, + {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, + {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, + {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, +] + [[package]] name = "pydantic" version = "2.8.2" @@ -683,106 +790,99 @@ files = [ [[package]] name = "yarl" -version = "1.9.4" +version = "1.17.2" description = "Yet another URL library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, - {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, - {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, - {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, - {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, - {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, - {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, - {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, - {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, - {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, - {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, - {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, - {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, - {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, - {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, - {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93771146ef048b34201bfa382c2bf74c524980870bb278e6df515efaf93699ff"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8281db240a1616af2f9c5f71d355057e73a1409c4648c8949901396dc0a3c151"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:170ed4971bf9058582b01a8338605f4d8c849bd88834061e60e83b52d0c76870"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc61b005f6521fcc00ca0d1243559a5850b9dd1e1fe07b891410ee8fe192d0c0"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871e1b47eec7b6df76b23c642a81db5dd6536cbef26b7e80e7c56c2fd371382e"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a58a2f2ca7aaf22b265388d40232f453f67a6def7355a840b98c2d547bd037f"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:736bb076f7299c5c55dfef3eb9e96071a795cb08052822c2bb349b06f4cb2e0a"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fd51299e21da709eabcd5b2dd60e39090804431292daacbee8d3dabe39a6bc0"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:358dc7ddf25e79e1cc8ee16d970c23faee84d532b873519c5036dbb858965795"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:50d866f7b1a3f16f98603e095f24c0eeba25eb508c85a2c5939c8b3870ba2df8"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b9c4643e7d843a0dca9cd9d610a0876e90a1b2cbc4c5ba7930a0d90baf6903f"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d63123bfd0dce5f91101e77c8a5427c3872501acece8c90df457b486bc1acd47"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4e76381be3d8ff96a4e6c77815653063e87555981329cf8f85e5be5abf449021"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:734144cd2bd633a1516948e477ff6c835041c0536cef1d5b9a823ae29899665b"}, + {file = "yarl-1.17.2-cp310-cp310-win32.whl", hash = "sha256:26bfb6226e0c157af5da16d2d62258f1ac578d2899130a50433ffee4a5dfa673"}, + {file = "yarl-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:76499469dcc24759399accd85ec27f237d52dec300daaca46a5352fcbebb1071"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:792155279dc093839e43f85ff7b9b6493a8eaa0af1f94f1f9c6e8f4de8c63500"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38bc4ed5cae853409cb193c87c86cd0bc8d3a70fd2268a9807217b9176093ac6"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4a8c83f6fcdc327783bdc737e8e45b2e909b7bd108c4da1892d3bc59c04a6d84"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6d5fed96f0646bfdf698b0a1cebf32b8aae6892d1bec0c5d2d6e2df44e1e2d"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:782ca9c58f5c491c7afa55518542b2b005caedaf4685ec814fadfcee51f02493"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff6af03cac0d1a4c3c19e5dcc4c05252411bf44ccaa2485e20d0a7c77892ab6e"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a3f47930fbbed0f6377639503848134c4aa25426b08778d641491131351c2c8"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1fa68a3c921365c5745b4bd3af6221ae1f0ea1bf04b69e94eda60e57958907f"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:187df91395c11e9f9dc69b38d12406df85aa5865f1766a47907b1cc9855b6303"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:93d1c8cc5bf5df401015c5e2a3ce75a5254a9839e5039c881365d2a9dcfc6dc2"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11d86c6145ac5c706c53d484784cf504d7d10fa407cb73b9d20f09ff986059ef"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c42774d1d1508ec48c3ed29e7b110e33f5e74a20957ea16197dbcce8be6b52ba"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8e589379ef0407b10bed16cc26e7392ef8f86961a706ade0a22309a45414d7"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1056cadd5e850a1c026f28e0704ab0a94daaa8f887ece8dfed30f88befb87bb0"}, + {file = "yarl-1.17.2-cp311-cp311-win32.whl", hash = "sha256:be4c7b1c49d9917c6e95258d3d07f43cfba2c69a6929816e77daf322aaba6628"}, + {file = "yarl-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:ac8eda86cc75859093e9ce390d423aba968f50cf0e481e6c7d7d63f90bae5c9c"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dd90238d3a77a0e07d4d6ffdebc0c21a9787c5953a508a2231b5f191455f31e9"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c74f0b0472ac40b04e6d28532f55cac8090e34c3e81f118d12843e6df14d0909"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d486ddcaca8c68455aa01cf53d28d413fb41a35afc9f6594a730c9779545876"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25b7e93f5414b9a983e1a6c1820142c13e1782cc9ed354c25e933aebe97fcf2"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a0baff7827a632204060f48dca9e63fbd6a5a0b8790c1a2adfb25dc2c9c0d50"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:460024cacfc3246cc4d9f47a7fc860e4fcea7d1dc651e1256510d8c3c9c7cde0"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5870d620b23b956f72bafed6a0ba9a62edb5f2ef78a8849b7615bd9433384171"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2941756754a10e799e5b87e2319bbec481ed0957421fba0e7b9fb1c11e40509f"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9611b83810a74a46be88847e0ea616794c406dbcb4e25405e52bff8f4bee2d0a"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cd7e35818d2328b679a13268d9ea505c85cd773572ebb7a0da7ccbca77b6a52e"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6b981316fcd940f085f646b822c2ff2b8b813cbd61281acad229ea3cbaabeb6b"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:688058e89f512fb7541cb85c2f149c292d3fa22f981d5a5453b40c5da49eb9e8"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56afb44a12b0864d17b597210d63a5b88915d680f6484d8d202ed68ade38673d"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:17931dfbb84ae18b287279c1f92b76a3abcd9a49cd69b92e946035cff06bcd20"}, + {file = "yarl-1.17.2-cp312-cp312-win32.whl", hash = "sha256:ff8d95e06546c3a8c188f68040e9d0360feb67ba8498baf018918f669f7bc39b"}, + {file = "yarl-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:4c840cc11163d3c01a9d8aad227683c48cd3e5be5a785921bcc2a8b4b758c4f3"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3294f787a437cb5d81846de3a6697f0c35ecff37a932d73b1fe62490bef69211"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1e7fedb09c059efee2533119666ca7e1a2610072076926fa028c2ba5dfeb78c"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da9d3061e61e5ae3f753654813bc1cd1c70e02fb72cf871bd6daf78443e9e2b1"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91c012dceadc695ccf69301bfdccd1fc4472ad714fe2dd3c5ab4d2046afddf29"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f11fd61d72d93ac23718d393d2a64469af40be2116b24da0a4ca6922df26807e"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46c465ad06971abcf46dd532f77560181387b4eea59084434bdff97524444032"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef6eee1a61638d29cd7c85f7fd3ac7b22b4c0fabc8fd00a712b727a3e73b0685"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4434b739a8a101a837caeaa0137e0e38cb4ea561f39cb8960f3b1e7f4967a3fc"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:752485cbbb50c1e20908450ff4f94217acba9358ebdce0d8106510859d6eb19a"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:17791acaa0c0f89323c57da7b9a79f2174e26d5debbc8c02d84ebd80c2b7bff8"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5c6ea72fe619fee5e6b5d4040a451d45d8175f560b11b3d3e044cd24b2720526"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db5ac3871ed76340210fe028f535392f097fb31b875354bcb69162bba2632ef4"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7a1606ba68e311576bcb1672b2a1543417e7e0aa4c85e9e718ba6466952476c0"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9bc27dd5cfdbe3dc7f381b05e6260ca6da41931a6e582267d5ca540270afeeb2"}, + {file = "yarl-1.17.2-cp313-cp313-win32.whl", hash = "sha256:52492b87d5877ec405542f43cd3da80bdcb2d0c2fbc73236526e5f2c28e6db28"}, + {file = "yarl-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:8e1bf59e035534ba4077f5361d8d5d9194149f9ed4f823d1ee29ef3e8964ace3"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c556fbc6820b6e2cda1ca675c5fa5589cf188f8da6b33e9fc05b002e603e44fa"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f44a4247461965fed18b2573f3a9eb5e2c3cad225201ee858726cde610daca"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a3ede8c248f36b60227eb777eac1dbc2f1022dc4d741b177c4379ca8e75571a"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2654caaf5584449d49c94a6b382b3cb4a246c090e72453493ea168b931206a4d"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d41c684f286ce41fa05ab6af70f32d6da1b6f0457459a56cf9e393c1c0b2217"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2270d590997445a0dc29afa92e5534bfea76ba3aea026289e811bf9ed4b65a7f"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18662443c6c3707e2fc7fad184b4dc32dd428710bbe72e1bce7fe1988d4aa654"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75ac158560dec3ed72f6d604c81090ec44529cfb8169b05ae6fcb3e986b325d9"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1fee66b32e79264f428dc8da18396ad59cc48eef3c9c13844adec890cd339db5"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:585ce7cd97be8f538345de47b279b879e091c8b86d9dbc6d98a96a7ad78876a3"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c019abc2eca67dfa4d8fb72ba924871d764ec3c92b86d5b53b405ad3d6aa56b0"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c6e659b9a24d145e271c2faf3fa6dd1fcb3e5d3f4e17273d9e0350b6ab0fe6e2"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d17832ba39374134c10e82d137e372b5f7478c4cceeb19d02ae3e3d1daed8721"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bc3003710e335e3f842ae3fd78efa55f11a863a89a72e9a07da214db3bf7e1f8"}, + {file = "yarl-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f5ffc6b7ace5b22d9e73b2a4c7305740a339fbd55301d52735f73e21d9eb3130"}, + {file = "yarl-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:48e424347a45568413deec6f6ee2d720de2cc0385019bedf44cd93e8638aa0ed"}, + {file = "yarl-1.17.2-py3-none-any.whl", hash = "sha256:dd7abf4f717e33b7487121faf23560b3a50924f80e4bef62b22dab441ded8f3b"}, + {file = "yarl-1.17.2.tar.gz", hash = "sha256:753eaaa0c7195244c84b5cc159dc8204b7fd99f716f11198f999f2332a86b178"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" +propcache = ">=0.2.0" [metadata] lock-version = "2.0"