From 1e85151127d859f0834ca9830095e5dfd4568828 Mon Sep 17 00:00:00 2001 From: jamshale Date: Fri, 6 Dec 2024 22:23:47 +0000 Subject: [PATCH 01/13] Fix anoncreds issuance and compatibility Signed-off-by: jamshale --- acapy_agent/anoncreds/base.py | 4 ++ .../anoncreds/default/did_indy/registry.py | 4 ++ .../anoncreds/default/did_web/registry.py | 4 ++ .../anoncreds/default/legacy_indy/registry.py | 9 ++++ acapy_agent/anoncreds/holder.py | 27 ++++------ .../anoncreds/models/credential_request.py | 13 ++++- .../anoncreds/models/presentation_request.py | 12 ++--- acapy_agent/anoncreds/registry.py | 5 ++ acapy_agent/anoncreds/tests/test_holder.py | 50 +++++-------------- acapy_agent/indy/credx/issuer.py | 5 ++ .../formats/anoncreds/tests/test_handler.py | 2 +- .../v2_0/tests/test_manager_anoncreds.py | 2 +- 12 files changed, 73 insertions(+), 64 deletions(-) diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index 32c0a1c1f1..26ad015713 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -130,6 +130,10 @@ async def get_revocation_list( ) -> GetRevListResult: """Get a revocation list from the registry.""" + @abstractmethod + async def get_schema_info_by_id(self, schema_id: str) -> dict: + """Get a schema info from the registry.""" + class BaseAnonCredsRegistrar(BaseAnonCredsHandler): """Base Anon Creds Registrar.""" diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index dcaafe4c06..687385f9d8 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -118,3 +118,7 @@ async def update_revocation_list( ) -> RevListResult: """Update a revocation list on the registry.""" raise NotImplementedError() + + async def get_schema_info_by_id(self, schema_id: str) -> dict: + """Get a schema info from the registry.""" + return await super().get_schema_info_by_id(schema_id) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index f97ba88fb8..2b2dcbf27f 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -113,3 +113,7 @@ async def update_revocation_list( ) -> RevListResult: """Update a revocation list on the registry.""" raise NotImplementedError() + + async def get_schema_info_by_id(self, schema_id: str) -> dict: + """Get a schema info from the registry.""" + return await super().get_schema_info_by_id(schema_id) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index aff1040616..f0cbaee780 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -1229,3 +1229,12 @@ async def txn_submit( ) except LedgerError as err: raise AnonCredsRegistrationError(err.roll_up) from err + + async def get_schema_info_by_id(self, schema_id: str) -> dict: + """Get schema info by schema id.""" + schema_id_parts = re.match(r"^(\w+):2:([^:]+):([^:]+)$", schema_id) + return { + "issuer_id": schema_id_parts.group(1), + "name": schema_id_parts.group(2), + "version": schema_id_parts.group(3), + } diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index f8dd4445f7..d7543b2ed9 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -3,7 +3,6 @@ import asyncio import json import logging -import re from typing import Dict, Optional, Sequence, Tuple, Union from anoncreds import ( @@ -150,8 +149,8 @@ async def create_credential_request( ) = await asyncio.get_event_loop().run_in_executor( None, CredentialRequest.create, - None, holder_did, + None, credential_definition.to_native(), secret, AnonCredsHolder.MASTER_SECRET_ID, @@ -231,25 +230,17 @@ async def _finish_store_credential( rev_reg_def: Optional[dict] = None, ) -> str: credential_data = cred_recvd.to_dict() - schema_id = cred_recvd.schema_id - schema_id_parts = re.match(r"^(\w+):2:([^:]+):([^:]+)$", schema_id) - if not schema_id_parts: - raise AnonCredsHolderError(f"Error parsing credential schema ID: {schema_id}") - cred_def_id = cred_recvd.cred_def_id - cdef_id_parts = re.match(r"^(\w+):3:CL:([^:]+):([^:]+)$", cred_def_id) - if not cdef_id_parts: - raise AnonCredsHolderError( - f"Error parsing credential definition ID: {cred_def_id}" - ) + registry = self.profile.inject(AnonCredsRegistry) + schema_info = await registry.get_schema_info_by_id(credential_data["schema_id"]) credential_id = credential_id or str(uuid4()) tags = { - "schema_id": schema_id, - "schema_issuer_did": schema_id_parts[1], - "schema_name": schema_id_parts[2], - "schema_version": schema_id_parts[3], - "issuer_did": cdef_id_parts[1], - "cred_def_id": cred_def_id, + "schema_id": credential_data["schema_id"], + "schema_issuer_id": schema_info["issuer_id"], + "schema_name": schema_info["name"], + "schema_version": schema_info["version"], + "issuer_id": credential_definition["issuerId"], + "cred_def_id": cred_recvd.cred_def_id, "rev_reg_id": cred_recvd.rev_reg_id or "None", } diff --git a/acapy_agent/anoncreds/models/credential_request.py b/acapy_agent/anoncreds/models/credential_request.py index 49fd58e996..2d5147b4a6 100644 --- a/acapy_agent/anoncreds/models/credential_request.py +++ b/acapy_agent/anoncreds/models/credential_request.py @@ -24,6 +24,8 @@ class Meta: def __init__( self, + entropy: Optional[str] = None, + # For compatibility with credx agents, which uses `prover_did` instead of `entropy` # noqa prover_did: Optional[str] = None, cred_def_id: Optional[str] = None, blinded_ms: Optional[Mapping] = None, @@ -33,6 +35,7 @@ def __init__( ): """Initialize anoncreds credential request.""" super().__init__(**kwargs) + self.entropy = entropy self.prover_did = prover_did self.cred_def_id = cred_def_id self.blinded_ms = blinded_ms @@ -49,8 +52,16 @@ class Meta: model_class = AnoncredsCredRequest unknown = EXCLUDE + entropy = fields.Str( + required=False, + metadata={ + "description": "Prover DID/Random String/UUID", + "example": UUID4_EXAMPLE, + }, + ) + # For compatibility with credx agents, which uses `prover_did` instead of `entropy` prover_did = fields.Str( - required=True, + required=False, metadata={ "description": "Prover DID/Random String/UUID", "example": UUID4_EXAMPLE, diff --git a/acapy_agent/anoncreds/models/presentation_request.py b/acapy_agent/anoncreds/models/presentation_request.py index 12855e1ee6..1d7c238064 100644 --- a/acapy_agent/anoncreds/models/presentation_request.py +++ b/acapy_agent/anoncreds/models/presentation_request.py @@ -47,7 +47,7 @@ class AnoncredsPresentationReqPredSpecSchema(OpenAPISchema): fields.Dict( keys=fields.Str( validate=validate.Regexp( - "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" + "^schema_id|schema_issuer_id|schema_name|schema_version|issuer_id|" "cred_def_id|attr::.+::value$" ), metadata={"example": "cred_def_id"}, @@ -58,8 +58,8 @@ class AnoncredsPresentationReqPredSpecSchema(OpenAPISchema): 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" + " schema_id, schema_issuer_id, schema_name, schema_version," + " issuer_id, cred_def_id, and/or attr::::value where" " represents a credential attribute name" ) }, @@ -113,7 +113,7 @@ class AnoncredsPresentationReqAttrSpecSchema(OpenAPISchema): fields.Dict( keys=fields.Str( validate=validate.Regexp( - "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" + "^schema_id|schema_issuer_id|schema_name|schema_version|issuer_id|" "cred_def_id|attr::.+::value$" ), metadata={"example": "cred_def_id"}, @@ -124,8 +124,8 @@ class AnoncredsPresentationReqAttrSpecSchema(OpenAPISchema): 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" + " schema_id, schema_issuer_id, schema_name, schema_version," + " issuer_id, cred_def_id, and/or attr::::value where" " represents a credential attribute name" ) }, diff --git a/acapy_agent/anoncreds/registry.py b/acapy_agent/anoncreds/registry.py index c355b447cd..ff82c0d818 100644 --- a/acapy_agent/anoncreds/registry.py +++ b/acapy_agent/anoncreds/registry.py @@ -99,6 +99,11 @@ async def get_credential_definition( credential_definition_id, ) + async def get_schema_info_by_id(self, schema_id: str) -> dict: + """Get a schema info from the registry.""" + resolver = await self._resolver_for_identifier(schema_id) + return await resolver.get_schema_info_by_id(schema_id) + async def register_credential_definition( self, profile: Profile, diff --git a/acapy_agent/anoncreds/tests/test_holder.py b/acapy_agent/anoncreds/tests/test_holder.py index 34d23ef75f..9667fe76e5 100644 --- a/acapy_agent/anoncreds/tests/test_holder.py +++ b/acapy_agent/anoncreds/tests/test_holder.py @@ -55,11 +55,6 @@ def __init__(self, bad_schema=False, bad_cred_def=False): self.schema_id = "Sc886XPwD1gDcHwmmLDeR2:2:degree schema:45.101.94" self.cred_def_id = "Sc886XPwD1gDcHwmmLDeR2:3:CL:229975:faber.agent.degree_schema" - if bad_schema: - self.schema_id = "bad-schema-id" - if bad_cred_def: - self.cred_def_id = "bad-cred-def-id" - schema_id = "Sc886XPwD1gDcHwmmLDeR2:2:degree schema:45.101.94" cred_def_id = "Sc886XPwD1gDcHwmmLDeR2:3:CL:229975:faber.agent.degree_schema" rev_reg_id = None @@ -72,15 +67,10 @@ def to_dict(self): class MockCredReceivedW3C: - def __init__(self, bad_schema=False, bad_cred_def=False): + def __init__(self): self.schema_id = "Sc886XPwD1gDcHwmmLDeR2:2:degree schema:45.101.94" self.cred_def_id = "Sc886XPwD1gDcHwmmLDeR2:3:CL:229975:faber.agent.degree_schema" - if bad_schema: - self.schema_id = "bad-schema-id" - if bad_cred_def: - self.cred_def_id = "bad-cred-def-id" - def to_json_buffer(self): return b"credential" @@ -89,9 +79,7 @@ def to_dict(self): class MockCredential: - def __init__(self, bad_schema=False, bad_cred_def=False): - self.bad_schema = bad_schema - self.bad_cred_def = bad_cred_def + def __init__(self): self.rev_reg_id = "rev-reg-id" self.rev_reg_index = 0 @@ -101,21 +89,17 @@ def to_dict(self): return MOCK_CRED def process(self, *args, **kwargs): - return MockCredReceived(self.bad_schema, self.bad_cred_def) + return MockCredReceived() class MockW3Credential: - def __init__(self, bad_schema=False, bad_cred_def=False): - self.bad_schema = bad_schema - self.bad_cred_def = bad_cred_def - cred = mock.AsyncMock(auto_spec=W3cCredential) def to_dict(self): return MOCK_W3C_CRED def process(self, *args, **kwargs): - return MockCredReceivedW3C(self.bad_schema, self.bad_cred_def) + return MockCredReceivedW3C() class MockMasterSecret: @@ -285,8 +269,6 @@ async def test_store_credential_fails_to_load_raises_x(self, mock_master_secret) side_effect=[ MockCredential(), MockCredential(), - MockCredential(bad_schema=True), - MockCredential(bad_cred_def=True), ], ) async def test_store_credential(self, mock_load, mock_master_secret): @@ -296,6 +278,9 @@ async def test_store_credential(self, mock_load, mock_master_secret): commit=mock.CoroutineMock(return_value=None), ) ) + self.profile.context.injector.bind_instance( + AnonCredsRegistry, mock.MagicMock(AnonCredsRegistry, autospec=True) + ) # Valid result = await self.holder.store_credential( @@ -321,20 +306,6 @@ async def test_store_credential(self, mock_load, mock_master_secret): {"cred-req-meta": "cred-req-meta"}, ) - # Test bad id's - with self.assertRaises(AnonCredsHolderError): - await self.holder.store_credential( - MOCK_CRED_DEF, - MOCK_PRES, - {"cred-req-meta": "cred-req-meta"}, - ) - with self.assertRaises(AnonCredsHolderError): - await self.holder.store_credential( - MOCK_CRED_DEF, - MOCK_CRED, - {"cred-req-meta": "cred-req-meta"}, - ) - @mock.patch.object(AnonCredsHolder, "get_master_secret", return_value="master-secret") @mock.patch.object( W3cCredential, @@ -362,7 +333,9 @@ async def test_store_credential_w3c( commit=mock.CoroutineMock(return_value=None), ) ) - + self.profile.context.injector.bind_instance( + AnonCredsRegistry, mock.MagicMock(AnonCredsRegistry, autospec=True) + ) with mock.patch.object(jsonld, "expand", return_value=MagicMock()): with mock.patch.object(JsonLdProcessor, "get_values", return_value=["type1"]): result = await self.holder.store_credential_w3c( @@ -384,6 +357,9 @@ async def test_store_credential_failed_trx(self, *_): self.profile.transaction = mock.MagicMock( side_effect=[AskarError(AskarErrorCode.UNEXPECTED, "test")] ) + self.profile.context.injector.bind_instance( + AnonCredsRegistry, mock.MagicMock(AnonCredsRegistry, autospec=True) + ) with self.assertRaises(AnonCredsHolderError): await self.holder.store_credential( diff --git a/acapy_agent/indy/credx/issuer.py b/acapy_agent/indy/credx/issuer.py index 8cd857df9e..c67b4d911a 100644 --- a/acapy_agent/indy/credx/issuer.py +++ b/acapy_agent/indy/credx/issuer.py @@ -330,6 +330,11 @@ async def create_credential( revoc = None credential_revocation_id = None + # This is for compatibility with an anoncreds holder + if not credential_request.get("prover_did"): + credential_request["prover_did"] = credential_request["entropy"] + del credential_request["entropy"] + try: ( credential, 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 f795929e8b..07f2d948c4 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 @@ -132,7 +132,7 @@ "nonce": "1234567890", } ANONCREDS_CRED_REQ = { - "prover_did": TEST_DID, + "entropy": TEST_DID, "cred_def_id": CRED_DEF_ID, "blinded_ms": { "u": "12345", 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 9f88377968..8fd0db66fc 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 @@ -2078,7 +2078,7 @@ async def test_receive_pres_bait_and_switch_pred(self): "name": "highScore", "p_type": ">=", "p_value": 1000000, - "restrictions": [{"issuer_did": "FFFFFFFFFFFFFFFFFFFFFF"}], # fake issuer + "restrictions": [{"issuer_id": "FFFFFFFFFFFFFFFFFFFFFF"}], # fake issuer "non_revoked": {"from": NOW, "to": NOW}, } pres_proposal = V20PresProposal( From 457ce1acbc679681aea1895aac90b65c4ce8ec19 Mon Sep 17 00:00:00 2001 From: jamshale Date: Tue, 10 Dec 2024 18:16:40 +0000 Subject: [PATCH 02/13] Change schema info from dict to class. Signed-off-by: jamshale --- acapy_agent/anoncreds/base.py | 3 ++- .../anoncreds/default/did_indy/registry.py | 3 ++- .../anoncreds/default/did_web/registry.py | 3 ++- .../anoncreds/default/legacy_indy/registry.py | 13 +++++----- acapy_agent/anoncreds/holder.py | 6 ++--- acapy_agent/anoncreds/models/schema_info.py | 26 +++++++++++++++++++ acapy_agent/anoncreds/registry.py | 3 ++- 7 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 acapy_agent/anoncreds/models/schema_info.py diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index 26ad015713..7576510993 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -16,6 +16,7 @@ RevRegDefResult, ) from .models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from .models.schema_info import AnoncredsSchemaInfo T = TypeVar("T") @@ -131,7 +132,7 @@ async def get_revocation_list( """Get a revocation list from the registry.""" @abstractmethod - async def get_schema_info_by_id(self, schema_id: str) -> dict: + async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 687385f9d8..51784d6f53 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -17,6 +17,7 @@ RevRegDefResult, ) from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from ...models.schema_info import AnoncredsSchemaInfo LOGGER = logging.getLogger(__name__) @@ -119,6 +120,6 @@ async def update_revocation_list( """Update a revocation list on the registry.""" raise NotImplementedError() - async def get_schema_info_by_id(self, schema_id: str) -> dict: + async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 2b2dcbf27f..88d2216358 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -16,6 +16,7 @@ RevRegDefResult, ) from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from ...models.schema_info import AnoncredsSchemaInfo class DIDWebRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar): @@ -114,6 +115,6 @@ async def update_revocation_list( """Update a revocation list on the registry.""" raise NotImplementedError() - async def get_schema_info_by_id(self, schema_id: str) -> dict: + async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index f0cbaee780..b4ed1a2f8f 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -80,6 +80,7 @@ SchemaResult, SchemaState, ) +from ...models.schema_info import AnoncredsSchemaInfo from ...revocation import ( CATEGORY_REV_LIST, CATEGORY_REV_REG_DEF, @@ -1230,11 +1231,11 @@ async def txn_submit( except LedgerError as err: raise AnonCredsRegistrationError(err.roll_up) from err - async def get_schema_info_by_id(self, schema_id: str) -> dict: + async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get schema info by schema id.""" schema_id_parts = re.match(r"^(\w+):2:([^:]+):([^:]+)$", schema_id) - return { - "issuer_id": schema_id_parts.group(1), - "name": schema_id_parts.group(2), - "version": schema_id_parts.group(3), - } + return AnoncredsSchemaInfo( + issuer_id=schema_id_parts.group(1), + name=schema_id_parts.group(2), + version=schema_id_parts.group(3), + ) diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index d7543b2ed9..e75498969d 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -236,9 +236,9 @@ async def _finish_store_credential( credential_id = credential_id or str(uuid4()) tags = { "schema_id": credential_data["schema_id"], - "schema_issuer_id": schema_info["issuer_id"], - "schema_name": schema_info["name"], - "schema_version": schema_info["version"], + "schema_issuer_id": schema_info.issuer_id, + "schema_name": schema_info.name, + "schema_version": schema_info.version, "issuer_id": credential_definition["issuerId"], "cred_def_id": cred_recvd.cred_def_id, "rev_reg_id": cred_recvd.rev_reg_id or "None", diff --git a/acapy_agent/anoncreds/models/schema_info.py b/acapy_agent/anoncreds/models/schema_info.py new file mode 100644 index 0000000000..e5cda7100d --- /dev/null +++ b/acapy_agent/anoncreds/models/schema_info.py @@ -0,0 +1,26 @@ +"""This class represents schema information for anoncreds.""" + +from typing import Optional + + +class AnoncredsSchemaInfo: + """Represents the schema information for anonymous credentials. + + Attributes: + issuer_id (str): The identifier of the issuer. + name (Optional[str]): The name of the schema. Defaults to None. + version (Optional[str]): The version of the schema. Defaults to None. + + Args: + issuer_id (str): The identifier of the issuer. + name (Optional[str], optional): The name of the schema. Defaults to None. + version (Optional[str], optional): The version of the schema. Defaults to None. + """ + + def __init__( + self, issuer_id: str, name: Optional[str] = None, version: Optional[str] = None + ): + """Initialize the schema information.""" + self.issuer_id = issuer_id + self.name = name + self.version = version diff --git a/acapy_agent/anoncreds/registry.py b/acapy_agent/anoncreds/registry.py index ff82c0d818..b610c5dbe5 100644 --- a/acapy_agent/anoncreds/registry.py +++ b/acapy_agent/anoncreds/registry.py @@ -21,6 +21,7 @@ RevRegDefResult, ) from .models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from .models.schema_info import AnoncredsSchemaInfo LOGGER = logging.getLogger(__name__) @@ -99,7 +100,7 @@ async def get_credential_definition( credential_definition_id, ) - async def get_schema_info_by_id(self, schema_id: str) -> dict: + async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" resolver = await self._resolver_for_identifier(schema_id) return await resolver.get_schema_info_by_id(schema_id) From 8de331256e7dc3e735b2afafe9640183506ebe5d Mon Sep 17 00:00:00 2001 From: jamshale Date: Tue, 10 Dec 2024 19:31:34 +0000 Subject: [PATCH 03/13] Add a unit test Signed-off-by: jamshale --- .../anoncreds/default/legacy_indy/tests/test_registry.py | 8 ++++++++ 1 file changed, 8 insertions(+) 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 c41eb80797..df3af6f44f 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py @@ -1210,3 +1210,11 @@ async def test_sync_wallet_rev_list_with_issuer_cred_rev_records( ), ) assert isinstance(result, RevList) + + async def test_get_schem_info(self): + result = await self.registry.get_schema_info_by_id( + "XduBsoPyEA4szYMy3pZ8De:2:minimal-33279d005748b3cc:1.0", + ) + assert result.issuer_id == "XduBsoPyEA4szYMy3pZ8De" + assert result.name == "minimal-33279d005748b3cc" + assert result.version == "1.0" From b7792ed746ca68b6d17cad788468f4ef775b3eff Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 12 Dec 2024 18:59:35 +0000 Subject: [PATCH 04/13] Revert holder credentail tag key changes Signed-off-by: jamshale --- acapy_agent/anoncreds/holder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index e75498969d..c192d38933 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -236,10 +236,10 @@ async def _finish_store_credential( credential_id = credential_id or str(uuid4()) tags = { "schema_id": credential_data["schema_id"], - "schema_issuer_id": schema_info.issuer_id, + "schema_issuer_did": schema_info.issuer_id, "schema_name": schema_info.name, "schema_version": schema_info.version, - "issuer_id": credential_definition["issuerId"], + "issuer_did": credential_definition["issuerId"], "cred_def_id": cred_recvd.cred_def_id, "rev_reg_id": cred_recvd.rev_reg_id or "None", } From 234c8814af08ce75369adedf817775ffab40ad24 Mon Sep 17 00:00:00 2001 From: jamshale Date: Tue, 17 Dec 2024 18:17:55 +0000 Subject: [PATCH 05/13] Add get cred def info function to anoncreds registry Signed-off-by: jamshale --- acapy_agent/anoncreds/base.py | 6 +++++- acapy_agent/anoncreds/default/did_indy/registry.py | 5 +++++ acapy_agent/anoncreds/default/did_web/registry.py | 5 +++++ acapy_agent/anoncreds/default/legacy_indy/registry.py | 7 +++++++ acapy_agent/anoncreds/models/cred_def_info.py | 9 +++++++++ 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 acapy_agent/anoncreds/models/cred_def_info.py diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index 7576510993..bdd7bf8c2d 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -135,9 +135,13 @@ async def get_revocation_list( async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" + @abstractmethod + async def get_cred_def_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: + """Get a cred def info from the registry.""" + class BaseAnonCredsRegistrar(BaseAnonCredsHandler): - """Base Anon Creds Registrar.""" + """Base Anoncreds Registrar.""" @abstractmethod async def register_schema( diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 51784d6f53..916cdcb571 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -7,6 +7,7 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver +from ...models.cred_def_info import AnoncredsCredDefInfo from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult from ...models.revocation import ( GetRevListResult, @@ -123,3 +124,7 @@ async def update_revocation_list( async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) + + async def get_cred_def_info_by_id(self, cred_def_id: str) -> AnoncredsCredDefInfo: + """Get cred def info by cred def id.""" + return await super().get_cred_def_info_by_id(cred_def_id) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 88d2216358..00d3b928db 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -6,6 +6,7 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver +from ...models.cred_def_info import AnoncredsCredDefInfo from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult from ...models.revocation import ( GetRevListResult, @@ -118,3 +119,7 @@ async def update_revocation_list( async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) + + async def get_cred_def_info_by_id(self, cred_def_id: str) -> AnoncredsCredDefInfo: + """Get cred def info by cred def id.""" + return await super().get_cred_def_info_by_id(cred_def_id) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index b4ed1a2f8f..dc33339fa7 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -56,6 +56,7 @@ ) from ...events import RevListFinishedEvent from ...issuer import CATEGORY_CRED_DEF, AnonCredsIssuer, AnonCredsIssuerError +from ...models.cred_def_info import AnoncredsCredDefInfo from ...models.credential_definition import ( CredDef, CredDefResult, @@ -1239,3 +1240,9 @@ async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: name=schema_id_parts.group(2), version=schema_id_parts.group(3), ) + + async def get_cred_def_info_by_id(self, cred_def_id: str) -> AnoncredsCredDefInfo: + """Get cred def info by cred def id.""" + return AnoncredsCredDefInfo( + issuer_id=cred_def_id.split(":")[-5], + ) diff --git a/acapy_agent/anoncreds/models/cred_def_info.py b/acapy_agent/anoncreds/models/cred_def_info.py new file mode 100644 index 0000000000..f7a9b2360b --- /dev/null +++ b/acapy_agent/anoncreds/models/cred_def_info.py @@ -0,0 +1,9 @@ +"""This class represents cred def information for anoncreds.""" + + +class AnoncredsCredDefInfo: + """Represents the credential definition information for anonymous credentials.""" + + def __init__(self, issuer_id: str): + """Initialize the cred def information.""" + self.issuer_id = issuer_id From 9de145447c5e2e16f70d04ea27785fce73013cac Mon Sep 17 00:00:00 2001 From: jamshale Date: Tue, 17 Dec 2024 18:18:29 +0000 Subject: [PATCH 06/13] Update anoncreds presentation handler to avoid indy parsing Signed-off-by: jamshale --- .../v2_0/formats/anoncreds/handler.py | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) 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 2c19d13443..59b1e38178 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 @@ -11,6 +11,7 @@ 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.registry import AnonCredsRegistry from ......anoncreds.util import generate_pr_nonce from ......anoncreds.verifier import AnonCredsVerifier from ......messaging.decorators.attach_decorator import AttachDecorator @@ -175,7 +176,7 @@ async def create_pres( 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(): + async def _check_proof_vs_proposal(): """Check for bait and switch in presented values vs. proposal request.""" from ..indy.handler import IndyPresExchangeHandler @@ -231,15 +232,18 @@ def _check_proof_vs_proposal(): name: values["raw"] for name, values in attr_spec["values"].items() } sub_proof_index = attr_spec["sub_proof_index"] + registry = self.profile.inject(AnonCredsRegistry) schema_id = proof["identifiers"][sub_proof_index]["schema_id"] + schema_info = await registry.get_schema_info_by_id(schema_id) cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] + cred_def_info = await registry.get_cred_def_info_by_id(cred_def_id) criteria = { "schema_id": schema_id, - "schema_issuer_did": schema_id.split(":")[-4], - "schema_name": schema_id.split(":")[-2], - "schema_version": schema_id.split(":")[-1], + "schema_issuer_did": schema_info.issuer_id, + "schema_name": schema_info.name, + "schema_version": schema_info.version, "cred_def_id": cred_def_id, - "issuer_did": cred_def_id.split(":")[-5], + "issuer_did": cred_def_info.issuer_id, **{ f"attr::{name}::value": value for name, value in proof_values.items() @@ -292,15 +296,18 @@ def _check_proof_vs_proposal(): f"Proposed request predicate on {req_name} not in presentation" ) + registry = self.profile.inject(AnonCredsRegistry) schema_id = proof["identifiers"][sub_proof_index]["schema_id"] + schema_info = await registry.get_schema_info_by_id(schema_id) cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] + cred_def_info = await registry.get_cred_def_info_by_id(cred_def_id) criteria = { "schema_id": schema_id, - "schema_issuer_did": schema_id.split(":")[-4], - "schema_name": schema_id.split(":")[-2], - "schema_version": schema_id.split(":")[-1], + "schema_issuer_did": schema_info.issuer_id, + "schema_name": schema_info.name, + "schema_version": schema_info.version, "cred_def_id": cred_def_id, - "issuer_did": cred_def_id.split(":")[-5], + "issuer_did": cred_def_info.issuer_id, } if ( @@ -313,7 +320,7 @@ def _check_proof_vs_proposal(): ) proof = message.attachment(AnonCredsPresExchangeHandler.format) - _check_proof_vs_proposal() + await _check_proof_vs_proposal() async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: """Verify a presentation. From 5dfa08970f22938befa5c716e9dc74af5d695a72 Mon Sep 17 00:00:00 2001 From: jamshale Date: Tue, 17 Dec 2024 19:30:39 +0000 Subject: [PATCH 07/13] Fix unit tests Signed-off-by: jamshale --- .../present_proof/v2_0/tests/test_manager_anoncreds.py | 7 +++++++ 1 file changed, 7 insertions(+) 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 8fd0db66fc..c0f135ef07 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 @@ -6,6 +6,8 @@ import pytest from .....anoncreds.holder import AnonCredsHolder +from .....anoncreds.models.cred_def_info import AnoncredsCredDefInfo +from .....anoncreds.registry import AnonCredsRegistry from .....anoncreds.verifier import AnonCredsVerifier from .....indy.models.pres_preview import ( IndyPresAttrSpec, @@ -469,6 +471,11 @@ async def asyncSetUp(self): ) ) injector.bind_instance(AnonCredsHolder, self.holder) + registry = mock.MagicMock(AnonCredsRegistry, autospec=True) + registry.get_cred_def_info_by_id = mock.CoroutineMock( + return_value=AnoncredsCredDefInfo(issuer_id=ISSUER_DID) + ) + injector.bind_instance(AnonCredsRegistry, registry) self.verifier = mock.MagicMock(AnonCredsVerifier, autospec=True) self.verifier.verify_presentation = mock.CoroutineMock(return_value=("true", [])) From 3581b016f6b68ee86ebefc2e2572f56c356d1eb5 Mon Sep 17 00:00:00 2001 From: jamshale Date: Wed, 18 Dec 2024 17:06:12 +0000 Subject: [PATCH 08/13] Switch verifier away from get_info methods in handler Signed-off-by: jamshale --- acapy_agent/anoncreds/base.py | 4 -- .../anoncreds/default/did_indy/registry.py | 5 --- .../anoncreds/default/did_web/registry.py | 5 --- .../anoncreds/default/legacy_indy/registry.py | 7 ---- acapy_agent/anoncreds/models/cred_def_info.py | 9 ----- .../v2_0/formats/anoncreds/handler.py | 40 ++++++++++--------- .../v2_0/tests/test_manager_anoncreds.py | 38 ++++++++++++++++-- 7 files changed, 57 insertions(+), 51 deletions(-) delete mode 100644 acapy_agent/anoncreds/models/cred_def_info.py diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index bdd7bf8c2d..36e6f816c1 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -135,10 +135,6 @@ async def get_revocation_list( async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" - @abstractmethod - async def get_cred_def_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: - """Get a cred def info from the registry.""" - class BaseAnonCredsRegistrar(BaseAnonCredsHandler): """Base Anoncreds Registrar.""" diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 916cdcb571..51784d6f53 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -7,7 +7,6 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver -from ...models.cred_def_info import AnoncredsCredDefInfo from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult from ...models.revocation import ( GetRevListResult, @@ -124,7 +123,3 @@ async def update_revocation_list( async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) - - async def get_cred_def_info_by_id(self, cred_def_id: str) -> AnoncredsCredDefInfo: - """Get cred def info by cred def id.""" - return await super().get_cred_def_info_by_id(cred_def_id) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 00d3b928db..88d2216358 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -6,7 +6,6 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver -from ...models.cred_def_info import AnoncredsCredDefInfo from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult from ...models.revocation import ( GetRevListResult, @@ -119,7 +118,3 @@ async def update_revocation_list( async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) - - async def get_cred_def_info_by_id(self, cred_def_id: str) -> AnoncredsCredDefInfo: - """Get cred def info by cred def id.""" - return await super().get_cred_def_info_by_id(cred_def_id) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index dc33339fa7..b4ed1a2f8f 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -56,7 +56,6 @@ ) from ...events import RevListFinishedEvent from ...issuer import CATEGORY_CRED_DEF, AnonCredsIssuer, AnonCredsIssuerError -from ...models.cred_def_info import AnoncredsCredDefInfo from ...models.credential_definition import ( CredDef, CredDefResult, @@ -1240,9 +1239,3 @@ async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: name=schema_id_parts.group(2), version=schema_id_parts.group(3), ) - - async def get_cred_def_info_by_id(self, cred_def_id: str) -> AnoncredsCredDefInfo: - """Get cred def info by cred def id.""" - return AnoncredsCredDefInfo( - issuer_id=cred_def_id.split(":")[-5], - ) diff --git a/acapy_agent/anoncreds/models/cred_def_info.py b/acapy_agent/anoncreds/models/cred_def_info.py deleted file mode 100644 index f7a9b2360b..0000000000 --- a/acapy_agent/anoncreds/models/cred_def_info.py +++ /dev/null @@ -1,9 +0,0 @@ -"""This class represents cred def information for anoncreds.""" - - -class AnoncredsCredDefInfo: - """Represents the credential definition information for anonymous credentials.""" - - def __init__(self, issuer_id: str): - """Initialize the cred def information.""" - self.issuer_id = issuer_id 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 59b1e38178..dbf854892e 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 @@ -199,13 +199,16 @@ async def _check_proof_vs_proposal(): sub_proof_index = attr_spec["sub_proof_index"] schema_id = proof["identifiers"][sub_proof_index]["schema_id"] cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] + registry = self.profile.inject(AnonCredsRegistry) + schema = await registry.get_schema(self.profile, schema_id) + cred_def = await registry.get_credential_definition(cred_def_id) criteria = { "schema_id": schema_id, - "schema_issuer_did": schema_id.split(":")[-4], - "schema_name": schema_id.split(":")[-2], - "schema_version": schema_id.split(":")[-1], + "schema_issuer_did": schema.schema_value.issuer_id, + "schema_name": schema.schema_value.name, + "schema_version": schema.schema_value.version, "cred_def_id": cred_def_id, - "issuer_did": cred_def_id.split(":")[-5], + "issuer_did": cred_def.credential_definition.issuer_id, f"attr::{name}::value": proof_value, } @@ -232,18 +235,18 @@ async def _check_proof_vs_proposal(): name: values["raw"] for name, values in attr_spec["values"].items() } sub_proof_index = attr_spec["sub_proof_index"] - registry = self.profile.inject(AnonCredsRegistry) schema_id = proof["identifiers"][sub_proof_index]["schema_id"] - schema_info = await registry.get_schema_info_by_id(schema_id) cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] - cred_def_info = await registry.get_cred_def_info_by_id(cred_def_id) + registry = self.profile.inject(AnonCredsRegistry) + schema = await registry.get_schema(self.profile, schema_id) + cred_def = await registry.get_credential_definition(cred_def_id) criteria = { "schema_id": schema_id, - "schema_issuer_did": schema_info.issuer_id, - "schema_name": schema_info.name, - "schema_version": schema_info.version, + "schema_issuer_did": schema.schema_value.issuer_id, + "schema_name": schema.schema_value.name, + "schema_version": schema.schema_value.version, "cred_def_id": cred_def_id, - "issuer_did": cred_def_info.issuer_id, + "issuer_did": cred_def.credential_definition.issuer_id, **{ f"attr::{name}::value": value for name, value in proof_values.items() @@ -296,18 +299,19 @@ async def _check_proof_vs_proposal(): f"Proposed request predicate on {req_name} not in presentation" ) - registry = self.profile.inject(AnonCredsRegistry) + sub_proof_index = attr_spec["sub_proof_index"] schema_id = proof["identifiers"][sub_proof_index]["schema_id"] - schema_info = await registry.get_schema_info_by_id(schema_id) cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] - cred_def_info = await registry.get_cred_def_info_by_id(cred_def_id) + registry = self.profile.inject(AnonCredsRegistry) + schema = await registry.get_schema(self.profile, schema_id) + cred_def = await registry.get_credential_definition(cred_def_id) criteria = { "schema_id": schema_id, - "schema_issuer_did": schema_info.issuer_id, - "schema_name": schema_info.name, - "schema_version": schema_info.version, + "schema_issuer_did": schema.schema_value.issuer_id, + "schema_name": schema.schema_value.name, + "schema_version": schema.schema_value.version, "cred_def_id": cred_def_id, - "issuer_did": cred_def_info.issuer_id, + "issuer_did": cred_def.credential_definition.issuer_id, } if ( 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 c0f135ef07..6692bde6de 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 @@ -6,7 +6,13 @@ import pytest from .....anoncreds.holder import AnonCredsHolder -from .....anoncreds.models.cred_def_info import AnoncredsCredDefInfo +from .....anoncreds.models.credential_definition import ( + CredDef, + CredDefValue, + CredDefValuePrimary, + GetCredDefResult, +) +from .....anoncreds.models.schema import AnonCredsSchema, GetSchemaResult from .....anoncreds.registry import AnonCredsRegistry from .....anoncreds.verifier import AnonCredsVerifier from .....indy.models.pres_preview import ( @@ -472,8 +478,34 @@ async def asyncSetUp(self): ) injector.bind_instance(AnonCredsHolder, self.holder) registry = mock.MagicMock(AnonCredsRegistry, autospec=True) - registry.get_cred_def_info_by_id = mock.CoroutineMock( - return_value=AnoncredsCredDefInfo(issuer_id=ISSUER_DID) + registry.get_schema = mock.CoroutineMock( + return_value=GetSchemaResult( + schema=AnonCredsSchema( + issuer_id=ISSUER_DID, + name="vidya", + version="1.0", + attr_names=["player", "screenCapture", "highScore"], + ), + schema_id=S_ID, + resolution_metadata={}, + schema_metadata={}, + ) + ) + registry.get_credential_definition = mock.CoroutineMock( + return_value=GetCredDefResult( + credential_definition_id="TUku9MDGa7QALbAJX4oAww:3:CL:531757:MYCO_Consent_Enablement", + credential_definition=CredDef( + issuer_id=ISSUER_DID, + schema_id=S_ID, + tag="tag", + type="CL", + value=CredDefValue( + primary=CredDefValuePrimary("n", "s", {}, "rctxt", "z") + ), + ), + credential_definition_metadata={}, + resolution_metadata={}, + ) ) injector.bind_instance(AnonCredsRegistry, registry) From 5920e8f95195cba9586ff69f2800a7caf57c200d Mon Sep 17 00:00:00 2001 From: jamshale Date: Wed, 18 Dec 2024 17:15:44 +0000 Subject: [PATCH 09/13] Revert presentation request metadata and restrictions changes Signed-off-by: jamshale --- acapy_agent/anoncreds/models/presentation_request.py | 12 ++++++------ .../v2_0/tests/test_manager_anoncreds.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/acapy_agent/anoncreds/models/presentation_request.py b/acapy_agent/anoncreds/models/presentation_request.py index 1d7c238064..12855e1ee6 100644 --- a/acapy_agent/anoncreds/models/presentation_request.py +++ b/acapy_agent/anoncreds/models/presentation_request.py @@ -47,7 +47,7 @@ class AnoncredsPresentationReqPredSpecSchema(OpenAPISchema): fields.Dict( keys=fields.Str( validate=validate.Regexp( - "^schema_id|schema_issuer_id|schema_name|schema_version|issuer_id|" + "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" "cred_def_id|attr::.+::value$" ), metadata={"example": "cred_def_id"}, @@ -58,8 +58,8 @@ class AnoncredsPresentationReqPredSpecSchema(OpenAPISchema): metadata={ "description": ( "If present, credential must satisfy one of given restrictions: specify" - " schema_id, schema_issuer_id, schema_name, schema_version," - " issuer_id, cred_def_id, and/or attr::::value where" + " schema_id, schema_issuer_did, schema_name, schema_version," + " issuer_did, cred_def_id, and/or attr::::value where" " represents a credential attribute name" ) }, @@ -113,7 +113,7 @@ class AnoncredsPresentationReqAttrSpecSchema(OpenAPISchema): fields.Dict( keys=fields.Str( validate=validate.Regexp( - "^schema_id|schema_issuer_id|schema_name|schema_version|issuer_id|" + "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" "cred_def_id|attr::.+::value$" ), metadata={"example": "cred_def_id"}, @@ -124,8 +124,8 @@ class AnoncredsPresentationReqAttrSpecSchema(OpenAPISchema): metadata={ "description": ( "If present, credential must satisfy one of given restrictions: specify" - " schema_id, schema_issuer_id, schema_name, schema_version," - " issuer_id, cred_def_id, and/or attr::::value where" + " schema_id, schema_issuer_did, schema_name, schema_version," + " issuer_did, cred_def_id, and/or attr::::value where" " represents a credential attribute name" ) }, 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 6692bde6de..a836e55ab3 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 @@ -2117,7 +2117,7 @@ async def test_receive_pres_bait_and_switch_pred(self): "name": "highScore", "p_type": ">=", "p_value": 1000000, - "restrictions": [{"issuer_id": "FFFFFFFFFFFFFFFFFFFFFF"}], # fake issuer + "restrictions": [{"issuer_did": "FFFFFFFFFFFFFFFFFFFFFF"}], # fake issuer "non_revoked": {"from": NOW, "to": NOW}, } pres_proposal = V20PresProposal( From aeb255f3aaf0bf5dd252be675655690311998a31 Mon Sep 17 00:00:00 2001 From: jamshale Date: Wed, 18 Dec 2024 17:32:09 +0000 Subject: [PATCH 10/13] Fix get_cred_def usage Signed-off-by: jamshale --- .../present_proof/v2_0/formats/anoncreds/handler.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 dbf854892e..615144f3e0 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 @@ -201,7 +201,9 @@ async def _check_proof_vs_proposal(): cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] registry = self.profile.inject(AnonCredsRegistry) schema = await registry.get_schema(self.profile, schema_id) - cred_def = await registry.get_credential_definition(cred_def_id) + cred_def = await registry.get_credential_definition( + self.profile, cred_def_id + ) criteria = { "schema_id": schema_id, "schema_issuer_did": schema.schema_value.issuer_id, @@ -239,7 +241,9 @@ async def _check_proof_vs_proposal(): cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] registry = self.profile.inject(AnonCredsRegistry) schema = await registry.get_schema(self.profile, schema_id) - cred_def = await registry.get_credential_definition(cred_def_id) + cred_def = await registry.get_credential_definition( + self.profile, cred_def_id + ) criteria = { "schema_id": schema_id, "schema_issuer_did": schema.schema_value.issuer_id, @@ -304,7 +308,9 @@ async def _check_proof_vs_proposal(): cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] registry = self.profile.inject(AnonCredsRegistry) schema = await registry.get_schema(self.profile, schema_id) - cred_def = await registry.get_credential_definition(cred_def_id) + cred_def = await registry.get_credential_definition( + self.profile, cred_def_id + ) criteria = { "schema_id": schema_id, "schema_issuer_did": schema.schema_value.issuer_id, From b5630c4480cba73880961445bdaaced8d998af43 Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 19 Dec 2024 16:49:53 +0000 Subject: [PATCH 11/13] Add profile to get_shcema_info_by_id Signed-off-by: jamshale --- acapy_agent/anoncreds/base.py | 4 +++- acapy_agent/anoncreds/default/did_indy/registry.py | 4 +++- acapy_agent/anoncreds/default/did_web/registry.py | 4 +++- acapy_agent/anoncreds/default/legacy_indy/registry.py | 4 +++- acapy_agent/anoncreds/holder.py | 4 +++- acapy_agent/anoncreds/registry.py | 6 ++++-- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index 36e6f816c1..4c5b79d345 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -132,7 +132,9 @@ async def get_revocation_list( """Get a revocation list from the registry.""" @abstractmethod - async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: + async def get_schema_info_by_id( + self, profile: Profile, schema_id: str + ) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 51784d6f53..6bd6cae693 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -120,6 +120,8 @@ async def update_revocation_list( """Update a revocation list on the registry.""" raise NotImplementedError() - async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: + async def get_schema_info_by_id( + self, profile: Profile, schema_id: str + ) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 88d2216358..718b624842 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -115,6 +115,8 @@ async def update_revocation_list( """Update a revocation list on the registry.""" raise NotImplementedError() - async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: + async def get_schema_info_by_id( + self, profile: Profile, schema_id: str + ) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" return await super().get_schema_info_by_id(schema_id) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index b4ed1a2f8f..aad288d053 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -1231,7 +1231,9 @@ async def txn_submit( except LedgerError as err: raise AnonCredsRegistrationError(err.roll_up) from err - async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: + async def get_schema_info_by_id( + self, profile: Profile, schema_id: str + ) -> AnoncredsSchemaInfo: """Get schema info by schema id.""" schema_id_parts = re.match(r"^(\w+):2:([^:]+):([^:]+)$", schema_id) return AnoncredsSchemaInfo( diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index c192d38933..08006fe176 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -231,7 +231,9 @@ async def _finish_store_credential( ) -> str: credential_data = cred_recvd.to_dict() registry = self.profile.inject(AnonCredsRegistry) - schema_info = await registry.get_schema_info_by_id(credential_data["schema_id"]) + schema_info = await registry.get_schema_info_by_id( + self.profile, credential_data["schema_id"] + ) credential_id = credential_id or str(uuid4()) tags = { diff --git a/acapy_agent/anoncreds/registry.py b/acapy_agent/anoncreds/registry.py index b610c5dbe5..92b70ac516 100644 --- a/acapy_agent/anoncreds/registry.py +++ b/acapy_agent/anoncreds/registry.py @@ -100,10 +100,12 @@ async def get_credential_definition( credential_definition_id, ) - async def get_schema_info_by_id(self, schema_id: str) -> AnoncredsSchemaInfo: + async def get_schema_info_by_id( + self, profile: Profile, schema_id: str + ) -> AnoncredsSchemaInfo: """Get a schema info from the registry.""" resolver = await self._resolver_for_identifier(schema_id) - return await resolver.get_schema_info_by_id(schema_id) + return await resolver.get_schema_info_by_id(profile, schema_id) async def register_credential_definition( self, From a8f47d10b53a16a27c88598e3b5a1239e7c3f9c5 Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 19 Dec 2024 17:00:00 +0000 Subject: [PATCH 12/13] Update unit test Signed-off-by: jamshale --- acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py | 1 + 1 file changed, 1 insertion(+) 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 df3af6f44f..76ebbee7a2 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py @@ -1213,6 +1213,7 @@ async def test_sync_wallet_rev_list_with_issuer_cred_rev_records( async def test_get_schem_info(self): result = await self.registry.get_schema_info_by_id( + self.profile, "XduBsoPyEA4szYMy3pZ8De:2:minimal-33279d005748b3cc:1.0", ) assert result.issuer_id == "XduBsoPyEA4szYMy3pZ8De" From 93ccff03a4bf3b45eef7fda359a7f6c05893ce4d Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 19 Dec 2024 18:02:00 +0000 Subject: [PATCH 13/13] Remove redeclared variable Signed-off-by: jamshale --- .../protocols/present_proof/v2_0/formats/anoncreds/handler.py | 1 - 1 file changed, 1 deletion(-) 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 615144f3e0..19b3264687 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 @@ -303,7 +303,6 @@ async def _check_proof_vs_proposal(): f"Proposed request predicate on {req_name} not in presentation" ) - sub_proof_index = attr_spec["sub_proof_index"] schema_id = proof["identifiers"][sub_proof_index]["schema_id"] cred_def_id = proof["identifiers"][sub_proof_index]["cred_def_id"] registry = self.profile.inject(AnonCredsRegistry)