diff --git a/aries_cloudagent/indy/models/pres_preview.py b/aries_cloudagent/indy/models/pres_preview.py index 7ab771309f..5f73978f33 100644 --- a/aries_cloudagent/indy/models/pres_preview.py +++ b/aries_cloudagent/indy/models/pres_preview.py @@ -14,6 +14,7 @@ from ...messaging.models.base import BaseModel, BaseModelSchema from ...messaging.util import canon from ...messaging.valid import INDY_CRED_DEF_ID, INDY_PREDICATE +from ...multitenant.base import BaseMultitenantManager from ...protocols.didcomm_prefix import DIDCommPrefix from ...wallet.util import b64_to_str @@ -351,7 +352,11 @@ def non_revoc(cred_def_id: str) -> IndyNonRevocationInterval: revoc_support = False if cd_id: if profile: - ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(profile) + else: + ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) ledger = ( await ledger_exec_inst.get_ledger_for_identifier( cd_id, @@ -410,7 +415,11 @@ def non_revoc(cred_def_id: str) -> IndyNonRevocationInterval: revoc_support = False if cd_id: if profile: - ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(profile) + else: + ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) ledger = ( await ledger_exec_inst.get_ledger_for_identifier( cd_id, diff --git a/aries_cloudagent/indy/models/tests/test_pres_preview.py b/aries_cloudagent/indy/models/tests/test_pres_preview.py index eee3071e49..5f5809b889 100644 --- a/aries_cloudagent/indy/models/tests/test_pres_preview.py +++ b/aries_cloudagent/indy/models/tests/test_pres_preview.py @@ -13,6 +13,8 @@ IndyLedgerRequestsExecutor, ) from ....messaging.util import canon +from ....multitenant.base import BaseMultitenantManager +from ....multitenant.manager import MultitenantManager from ....protocols.didcomm_prefix import DIDCommPrefix @@ -443,6 +445,10 @@ async def test_to_indy_proof_request_revo(self): context.injector.bind_instance( IndyLedgerRequestsExecutor, IndyLedgerRequestsExecutor(mock_profile) ) + context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) with async_mock.patch.object( IndyLedgerRequestsExecutor, "get_ledger_for_identifier" ) as mock_get_ledger: diff --git a/aries_cloudagent/indy/tests/test_verifier.py b/aries_cloudagent/indy/tests/test_verifier.py index 7a00c7276d..90b75b92a6 100644 --- a/aries_cloudagent/indy/tests/test_verifier.py +++ b/aries_cloudagent/indy/tests/test_verifier.py @@ -10,6 +10,8 @@ from ...ledger.multiple_ledger.ledger_requests_executor import ( IndyLedgerRequestsExecutor, ) +from ...multitenant.base import BaseMultitenantManager +from ...multitenant.manager import MultitenantManager from .. import verifier as test_module from ..verifier import IndyVerifier @@ -332,6 +334,28 @@ def setUp(self): self.verifier = MockVerifier() async def test_check_timestamps(self): + # multitenant + mock_profile = InMemoryProfile.test_profile() + context = mock_profile.context + context.injector.bind_instance( + IndyLedgerRequestsExecutor, + IndyLedgerRequestsExecutor(mock_profile), + ) + context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, "get_ledger_for_identifier" + ) as mock_get_ledger: + mock_get_ledger.return_value = (None, self.ledger) + await self.verifier.check_timestamps( + mock_profile, + INDY_PROOF_REQ_NAME, + INDY_PROOF_NAME, + REV_REG_DEFS, + ) + # all clear, with timestamps mock_profile = InMemoryProfile.test_profile() context = mock_profile.context diff --git a/aries_cloudagent/indy/verifier.py b/aries_cloudagent/indy/verifier.py index d8a2d61a10..f6bbe6d26b 100644 --- a/aries_cloudagent/indy/verifier.py +++ b/aries_cloudagent/indy/verifier.py @@ -12,6 +12,7 @@ IndyLedgerRequestsExecutor, ) from ..messaging.util import canon, encode +from ..multitenant.base import BaseMultitenantManager from .models.xform import indy_proof_req2non_revoc_intervals @@ -111,7 +112,11 @@ async def check_timestamps( for (index, ident) in enumerate(pres["identifiers"]): if ident.get("timestamp"): cred_def_id = ident["cred_def_id"] - ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(profile) + else: + ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) ledger = ( await ledger_exec_inst.get_ledger_for_identifier( cred_def_id, diff --git a/aries_cloudagent/ledger/routes.py b/aries_cloudagent/ledger/routes.py index dfeffee73b..fc24386aaa 100644 --- a/aries_cloudagent/ledger/routes.py +++ b/aries_cloudagent/ledger/routes.py @@ -18,6 +18,7 @@ INT_EPOCH, UUIDFour, ) +from ..multitenant.base import BaseMultitenantManager from ..protocols.endorse_transaction.v1_0.manager import ( TransactionManager, @@ -369,7 +370,11 @@ async def get_nym_role(request: web.BaseRequest): raise web.HTTPBadRequest(reason="Request query must include DID") async with context.profile.session() as session: - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( did, txn_record_type=GET_NYM_ROLE, @@ -442,7 +447,11 @@ async def get_did_verkey(request: web.BaseRequest): raise web.HTTPBadRequest(reason="Request query must include DID") async with context.profile.session() as session: - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( did, txn_record_type=GET_KEY_FOR_DID, @@ -487,7 +496,11 @@ async def get_did_endpoint(request: web.BaseRequest): raise web.HTTPBadRequest(reason="Request query must include DID") async with context.profile.session() as session: - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( did, txn_record_type=GET_ENDPOINT_FOR_DID, diff --git a/aries_cloudagent/ledger/tests/test_routes.py b/aries_cloudagent/ledger/tests/test_routes.py index fb94d5c692..aa682e2249 100644 --- a/aries_cloudagent/ledger/tests/test_routes.py +++ b/aries_cloudagent/ledger/tests/test_routes.py @@ -12,6 +12,8 @@ BaseMultipleLedgerManager, MultipleLedgerManagerError, ) +from ...multitenant.base import BaseMultitenantManager +from ...multitenant.manager import MultitenantManager from .. import routes as test_module from ..indy import Role @@ -121,6 +123,29 @@ async def test_get_verkey_b(self): ) assert result is json_response.return_value + async def test_get_verkey_multitenant(self): + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + self.request.query = {"did": self.test_did} + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_mock.patch.object( + test_module.web, "json_response", async_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( + { + "ledger_id": "test_ledger_id", + "verkey": self.ledger.get_key_for_did.return_value, + } + ) + assert result is json_response.return_value + async def test_get_verkey_no_did(self): self.request.query = {"no": "did"} with self.assertRaises(test_module.web.HTTPBadRequest): @@ -174,6 +199,29 @@ async def test_get_endpoint(self): ) assert result is json_response.return_value + async def test_get_endpoint_multitenant(self): + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + self.request.query = {"did": self.test_did} + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_mock.patch.object( + test_module.web, "json_response", async_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( + { + "ledger_id": "test_ledger_id", + "endpoint": self.ledger.get_endpoint_for_did.return_value, + } + ) + assert result is json_response.return_value + async def test_get_endpoint_of_type_profile(self): self.profile.context.injector.bind_instance( IndyLedgerRequestsExecutor, @@ -486,6 +534,27 @@ async def test_get_nym_role_b(self): ) assert result is json_response.return_value + async def test_get_nym_role_multitenant(self): + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + self.request.query = {"did": self.test_did} + + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_mock.patch.object( + test_module.web, "json_response", async_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( + {"ledger_id": "test_ledger_id", "role": "USER"} + ) + assert result is json_response.return_value + async def test_get_nym_role_bad_request(self): self.request.query = {"no": "did"} with self.assertRaises(test_module.web.HTTPBadRequest): diff --git a/aries_cloudagent/messaging/credential_definitions/routes.py b/aries_cloudagent/messaging/credential_definitions/routes.py index 1603c76cd1..cd78c623f1 100644 --- a/aries_cloudagent/messaging/credential_definitions/routes.py +++ b/aries_cloudagent/messaging/credential_definitions/routes.py @@ -28,6 +28,7 @@ GET_CRED_DEF, IndyLedgerRequestsExecutor, ) +from ...multitenant.base import BaseMultitenantManager from ...protocols.endorse_transaction.v1_0.manager import ( TransactionManager, TransactionManagerError, @@ -371,7 +372,11 @@ async def credential_definitions_get_credential_definition(request: web.BaseRequ cred_def_id = request.match_info["cred_def_id"] async with context.profile.session() as session: - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( cred_def_id, txn_record_type=GET_CRED_DEF, @@ -416,7 +421,11 @@ async def credential_definitions_fix_cred_def_wallet_record(request: web.BaseReq async with context.profile.session() as session: storage = session.inject(BaseStorage) - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( cred_def_id, txn_record_type=GET_CRED_DEF, diff --git a/aries_cloudagent/messaging/credential_definitions/tests/test_routes.py b/aries_cloudagent/messaging/credential_definitions/tests/test_routes.py index 953f185d73..88164b437a 100644 --- a/aries_cloudagent/messaging/credential_definitions/tests/test_routes.py +++ b/aries_cloudagent/messaging/credential_definitions/tests/test_routes.py @@ -8,6 +8,8 @@ from ....ledger.multiple_ledger.ledger_requests_executor import ( IndyLedgerRequestsExecutor, ) +from ....multitenant.base import BaseMultitenantManager +from ....multitenant.manager import MultitenantManager from ....storage.base import BaseStorage from ....tails.base import BaseTailsServer @@ -354,6 +356,28 @@ async def test_get_credential_definition(self): } ) + async def test_get_credential_definition_multitenant(self): + self.profile_injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + self.request.match_info = {"cred_def_id": CRED_DEF_ID} + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_mock.patch.object(test_module.web, "json_response") as mock_response: + result = await test_module.credential_definitions_get_credential_definition( + self.request + ) + assert result == mock_response.return_value + mock_response.assert_called_once_with( + { + "ledger_id": "test_ledger_id", + "credential_definition": {"cred": "def", "signed_txn": "..."}, + } + ) + async def test_get_credential_definition_no_ledger(self): self.profile_injector.bind_instance( IndyLedgerRequestsExecutor, diff --git a/aries_cloudagent/messaging/schemas/routes.py b/aries_cloudagent/messaging/schemas/routes.py index 9a44dddbcf..c494adda5b 100644 --- a/aries_cloudagent/messaging/schemas/routes.py +++ b/aries_cloudagent/messaging/schemas/routes.py @@ -28,6 +28,7 @@ GET_SCHEMA, IndyLedgerRequestsExecutor, ) +from ...multitenant.base import BaseMultitenantManager from ...protocols.endorse_transaction.v1_0.manager import ( TransactionManager, TransactionManagerError, @@ -355,7 +356,11 @@ async def schemas_get_schema(request: web.BaseRequest): schema_id = request.match_info["schema_id"] async with context.profile.session() as session: - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( schema_id, txn_record_type=GET_SCHEMA, @@ -400,7 +405,11 @@ async def schemas_fix_schema_wallet_record(request: web.BaseRequest): async with profile.session() as session: storage = session.inject(BaseStorage) - ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = session.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(context.profile) + else: + ledger_exec_inst = session.inject(IndyLedgerRequestsExecutor) ledger_id, ledger = await ledger_exec_inst.get_ledger_for_identifier( schema_id, txn_record_type=GET_SCHEMA, diff --git a/aries_cloudagent/messaging/schemas/tests/test_routes.py b/aries_cloudagent/messaging/schemas/tests/test_routes.py index 74b9f79e82..91a826d628 100644 --- a/aries_cloudagent/messaging/schemas/tests/test_routes.py +++ b/aries_cloudagent/messaging/schemas/tests/test_routes.py @@ -8,6 +8,8 @@ from ....ledger.multiple_ledger.ledger_requests_executor import ( IndyLedgerRequestsExecutor, ) +from ....multitenant.base import BaseMultitenantManager +from ....multitenant.manager import MultitenantManager from ....storage.base import BaseStorage from .. import routes as test_module @@ -324,6 +326,26 @@ async def test_get_schema(self): } ) + async def test_get_schema_multitenant(self): + self.profile_injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + self.request.match_info = {"schema_id": SCHEMA_ID} + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_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( + { + "ledger_id": "test_ledger_id", + "schema": {"schema": "def", "signed_txn": "..."}, + } + ) + async def test_get_schema_on_seq_no(self): self.profile_injector.bind_instance( IndyLedgerRequestsExecutor, diff --git a/aries_cloudagent/protocols/issue_credential/v1_0/manager.py b/aries_cloudagent/protocols/issue_credential/v1_0/manager.py index b4b9291be4..9b87e934c9 100644 --- a/aries_cloudagent/protocols/issue_credential/v1_0/manager.py +++ b/aries_cloudagent/protocols/issue_credential/v1_0/manager.py @@ -21,6 +21,7 @@ CRED_DEF_SENT_RECORD_TYPE, ) from ....messaging.responder import BaseResponder +from ....multitenant.base import BaseMultitenantManager from ....revocation.indy import IndyRevocation from ....revocation.models.revocation_registry import RevocationRegistry from ....revocation.models.issuer_rev_reg_record import IssuerRevRegRecord @@ -266,7 +267,11 @@ async def _create(cred_def_id): credential_preview = credential_proposal_message.credential_proposal # vet attributes - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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, @@ -406,7 +411,11 @@ async def create_request( cred_req_meta = None async def _create(): - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( credential_definition_id, @@ -572,7 +581,11 @@ async def issue_credential( cred_offer_ser = cred_ex_record._credential_offer.ser cred_req_ser = cred_ex_record._credential_request.ser schema_id = cred_ex_record.schema_id - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( schema_id, @@ -804,7 +817,11 @@ async def store_credential( raw_cred_serde = cred_ex_record._raw_credential revoc_reg_def = None - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( raw_cred_serde.de.cred_def_id, diff --git a/aries_cloudagent/protocols/issue_credential/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/issue_credential/v1_0/tests/test_manager.py index 24287a6523..201eb8c494 100644 --- a/aries_cloudagent/protocols/issue_credential/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/issue_credential/v1_0/tests/test_manager.py @@ -17,6 +17,8 @@ from .....ledger.multiple_ledger.ledger_requests_executor import ( IndyLedgerRequestsExecutor, ) +from .....multitenant.base import BaseMultitenantManager +from .....multitenant.manager import MultitenantManager from .....storage.base import StorageRecord from .....storage.error import StorageNotFoundError @@ -366,6 +368,10 @@ async def test_create_free_offer_attr_mismatch(self): credential_proposal_dict=proposal.serialize(), new_with_id=True, ) + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) await stored_exchange.save(self.session) with async_mock.patch.object( @@ -685,6 +691,10 @@ async def test_create_request_no_cache(self): thread_id=thread_id, new_with_id=True, ) + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) await stored_exchange.save(self.session) with async_mock.patch.object( @@ -941,7 +951,10 @@ async def test_issue_credential_non_revocable(self): comment = "comment" cred_values = {"attr": "value"} thread_id = "thread-id" - + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) stored_exchange = V10CredentialExchange( credential_exchange_id="dummy-cxid", connection_id=connection_id, @@ -979,17 +992,13 @@ async def test_issue_credential_non_revocable(self): self.ledger.__aenter__ = async_mock.CoroutineMock(return_value=self.ledger) self.context.injector.clear_binding(BaseLedger) self.context.injector.bind_instance(BaseLedger, self.ledger) - self.context.injector.bind_instance( - IndyLedgerRequestsExecutor, - async_mock.MagicMock( - get_ledger_for_identifier=async_mock.CoroutineMock( - return_value=("test_ledger_id", self.ledger) - ) - ), - ) with async_mock.patch.object( V10CredentialExchange, "save", autospec=True - ) as save_ex: + ) as save_ex, async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_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 ) @@ -1468,7 +1477,10 @@ async def test_store_credential_no_preview(self): connection_id = "test_conn_id" cred_req_meta = {"req": "meta"} thread_id = "thread-id" - + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) cred_no_rev = {**INDY_CRED} cred_no_rev["rev_reg_id"] = None cred_no_rev["rev_reg"] = None diff --git a/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py b/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py index b536e69300..3561687065 100644 --- a/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py +++ b/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py @@ -24,6 +24,7 @@ CredDefQueryStringSchema, ) from ......messaging.decorators.attach_decorator import AttachDecorator +from ......multitenant.base import BaseMultitenantManager from ......revocation.models.issuer_rev_reg_record import IssuerRevRegRecord from ......revocation.models.revocation_registry import RevocationRegistry from ......revocation.indy import IndyRevocation @@ -202,7 +203,11 @@ async def _create(): offer_json = await issuer.create_credential_offer(cred_def_id) return json.loads(offer_json) - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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, @@ -263,7 +268,11 @@ async def create_request( cred_def_id = cred_offer["cred_def_id"] async def _create(): - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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, @@ -331,7 +340,11 @@ async def issue_credential( rev_reg_id = None rev_reg = None - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( schema_id, @@ -475,7 +488,11 @@ async def store_credential( cred = cred_ex_record.cred_issue.attachment(IndyCredFormatHandler.format) rev_reg_def = None - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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["cred_def_id"], diff --git a/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py b/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py index 9bffbad2a9..c759e37e17 100644 --- a/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py +++ b/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py @@ -13,6 +13,8 @@ from .......ledger.multiple_ledger.ledger_requests_executor import ( IndyLedgerRequestsExecutor, ) +from .......multitenant.base import BaseMultitenantManager +from .......multitenant.manager import MultitenantManager from .......indy.issuer import IndyIssuer from .......cache.in_memory import InMemoryCache from .......cache.base import BaseCache @@ -497,6 +499,10 @@ async def test_create_offer_attr_mismatch(self): AttachDecorator.data_base64({"cred_def_id": CRED_DEF_ID}, ident="0") ], ) + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) cred_def_record = StorageRecord( CRED_DEF_SENT_RECORD_TYPE, @@ -516,9 +522,13 @@ async def test_create_offer_attr_mismatch(self): self.issuer.create_credential_offer = async_mock.CoroutineMock( return_value=json.dumps(INDY_OFFER) ) - - with self.assertRaises(V20CredFormatError): - await self.handler.create_offer(cred_proposal) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=(None, self.ledger)), + ): + with self.assertRaises(V20CredFormatError): + await self.handler.create_offer(cred_proposal) async def test_create_offer_no_matching_sent_cred_def(self): cred_proposal = V20CredProposal( @@ -602,7 +612,18 @@ async def test_create_request(self): # cover case with no cache in injection context self.context.injector.clear_binding(BaseCache) cred_ex_record._id = "dummy-id3" - await self.handler.create_request(cred_ex_record, {"holder_did": holder_did}) + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=(None, self.ledger)), + ): + await self.handler.create_request( + cred_ex_record, {"holder_did": holder_did} + ) async def test_create_request_bad_state(self): cred_ex_record = V20CredExRecord(state=V20CredExRecord.STATE_OFFER_SENT) @@ -802,20 +823,28 @@ async def test_issue_credential_non_revocable(self): self.ledger.get_credential_definition = async_mock.CoroutineMock( return_value=CRED_DEF_NR ) - - (cred_format, attachment) = await self.handler.issue_credential( - cred_ex_record, retries=0 + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ): + (cred_format, attachment) = await self.handler.issue_credential( + cred_ex_record, retries=0 + ) - self.issuer.create_credential.assert_called_once_with( - SCHEMA, - INDY_OFFER, - INDY_CRED_REQ, - attr_values, - cred_ex_record.cred_ex_id, - None, - None, - ) + self.issuer.create_credential.assert_called_once_with( + SCHEMA, + INDY_OFFER, + INDY_CRED_REQ, + attr_values, + cred_ex_record.cred_ex_id, + None, + None, + ) # assert identifier match assert cred_format.attach_id == self.handler.format.api == attachment.ident @@ -1254,8 +1283,15 @@ async def test_store_credential(self): with self.assertRaises(V20CredFormatError) as context: await self.handler.store_credential(stored_cx_rec, cred_id=cred_id) assert "No credential exchange " in str(context.exception) - + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_mock.patch.object( test_module, "RevocationRegistry", autospec=True ) as mock_rev_reg, async_mock.patch.object( test_module.IndyCredFormatHandler, "get_detail_record", autospec=True diff --git a/aries_cloudagent/protocols/present_proof/indy/pres_exch_handler.py b/aries_cloudagent/protocols/present_proof/indy/pres_exch_handler.py index 56cec44dfd..51c6c264a9 100644 --- a/aries_cloudagent/protocols/present_proof/indy/pres_exch_handler.py +++ b/aries_cloudagent/protocols/present_proof/indy/pres_exch_handler.py @@ -14,6 +14,7 @@ GET_REVOC_REG_DELTA, IndyLedgerRequestsExecutor, ) +from ....multitenant.base import BaseMultitenantManager from ....revocation.models.revocation_registry import RevocationRegistry from ..v1_0.models.presentation_exchange import V10PresentationExchange @@ -93,7 +94,11 @@ async def return_presentation( for credential in credentials.values(): schema_id = credential["schema_id"] - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( schema_id, @@ -127,7 +132,11 @@ async def return_presentation( if "timestamp" in precis: continue rev_reg_id = credentials[credential_id]["rev_reg_id"] - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( rev_reg_id, @@ -222,7 +231,11 @@ async def process_pres_identifiers( for identifier in identifiers: schema_ids.append(identifier["schema_id"]) cred_def_ids.append(identifier["cred_def_id"]) - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( identifier["schema_id"], diff --git a/aries_cloudagent/protocols/present_proof/v2_0/tests/test_manager.py b/aries_cloudagent/protocols/present_proof/v2_0/tests/test_manager.py index bf293f3cb6..defd623572 100644 --- a/aries_cloudagent/protocols/present_proof/v2_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/present_proof/v2_0/tests/test_manager.py @@ -20,6 +20,8 @@ ) from .....messaging.decorators.attach_decorator import AttachDecorator from .....messaging.responder import BaseResponder, MockResponder +from .....multitenant.base import BaseMultitenantManager +from .....multitenant.manager import MultitenantManager from .....storage.error import StorageNotFoundError from ...indy import pres_exch_handler as test_indy_util_module @@ -805,7 +807,15 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): return_value="/tmp/sample/tails/path" ) ) + self.profile.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_mock.patch.object( V20PresExRecord, "save", autospec=True ) as save_ex, async_mock.patch.object( test_indy_handler, "AttachDecorator", autospec=True @@ -1858,8 +1868,15 @@ async def test_verify_pres(self): pres_request=pres_request, pres=pres, ) - - with async_mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + self.profile.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), async_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() diff --git a/aries_cloudagent/resolver/default/indy.py b/aries_cloudagent/resolver/default/indy.py index a7364306d9..d1088121ba 100644 --- a/aries_cloudagent/resolver/default/indy.py +++ b/aries_cloudagent/resolver/default/indy.py @@ -17,6 +17,7 @@ IndyLedgerRequestsExecutor, ) from ...messaging.valid import IndyDID +from ...multitenant.base import BaseMultitenantManager from ..base import BaseDIDResolver, DIDNotFound, ResolverError, ResolverType @@ -44,7 +45,11 @@ def supported_did_regex(self) -> Pattern: async def _resolve(self, profile: Profile, did: str) -> dict: """Resolve an indy DID.""" - ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) + multitenant_mgr = profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(profile) + else: + ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) ledger = ( await ledger_exec_inst.get_ledger_for_identifier( did, diff --git a/aries_cloudagent/resolver/default/tests/test_indy.py b/aries_cloudagent/resolver/default/tests/test_indy.py index f9d4ad944a..7781dac13f 100644 --- a/aries_cloudagent/resolver/default/tests/test_indy.py +++ b/aries_cloudagent/resolver/default/tests/test_indy.py @@ -12,6 +12,8 @@ IndyLedgerRequestsExecutor, ) from ....messaging.valid import IndyDID +from ....multitenant.base import BaseMultitenantManager +from ....multitenant.manager import MultitenantManager from ...base import DIDNotFound, ResolverError from .. import indy as test_module @@ -65,6 +67,22 @@ async def test_resolve(self, profile: Profile, resolver: IndyDIDResolver): """Test resolve method.""" assert await resolver.resolve(profile, TEST_DID0) + @pytest.mark.asyncio + async def test_resolve_multitenant( + self, profile: Profile, resolver: IndyDIDResolver, ledger: BaseLedger + ): + """Test resolve method.""" + profile.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=("test_ledger_id", ledger)), + ): + assert await resolver.resolve(profile, TEST_DID0) + @pytest.mark.asyncio async def test_resolve_x_no_ledger( self, profile: Profile, resolver: IndyDIDResolver diff --git a/aries_cloudagent/revocation/indy.py b/aries_cloudagent/revocation/indy.py index 3dcab450f7..669db1f31a 100644 --- a/aries_cloudagent/revocation/indy.py +++ b/aries_cloudagent/revocation/indy.py @@ -8,6 +8,7 @@ GET_REVOC_REG_DEF, IndyLedgerRequestsExecutor, ) +from ..multitenant.base import BaseMultitenantManager from ..storage.base import StorageNotFoundError from .error import RevocationNotSupportedError, RevocationRegistryBadSizeError @@ -32,7 +33,11 @@ async def init_issuer_registry( tag: str = None, ) -> "IssuerRevRegRecord": """Create a new revocation registry record for a credential definition.""" - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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, @@ -108,7 +113,11 @@ async def get_ledger_registry(self, revoc_reg_id: str) -> "RevocationRegistry": if revoc_reg_id in IndyRevocation.REV_REG_CACHE: return IndyRevocation.REV_REG_CACHE[revoc_reg_id] - ledger_exec_inst = self._profile.inject(IndyLedgerRequestsExecutor) + 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( revoc_reg_id, diff --git a/aries_cloudagent/revocation/tests/test_indy.py b/aries_cloudagent/revocation/tests/test_indy.py index 10708c6d28..e1a79ab585 100644 --- a/aries_cloudagent/revocation/tests/test_indy.py +++ b/aries_cloudagent/revocation/tests/test_indy.py @@ -7,6 +7,8 @@ from ...ledger.multiple_ledger.ledger_requests_executor import ( IndyLedgerRequestsExecutor, ) +from ...multitenant.base import BaseMultitenantManager +from ...multitenant.manager import MultitenantManager from ...storage.error import StorageNotFoundError from ..error import ( @@ -54,6 +56,22 @@ async def test_init_issuer_registry(self): assert result.revoc_def_type == IssuerRevRegRecord.REVOC_DEF_TYPE_CL assert result.tag is None + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=(None, self.ledger)), + ): + result = await self.revoc.init_issuer_registry(CRED_DEF_ID) + assert result.cred_def_id == CRED_DEF_ID + assert result.issuer_did == self.test_did + assert result.max_cred_num == DEFAULT_REGISTRY_SIZE + assert result.revoc_def_type == IssuerRevRegRecord.REVOC_DEF_TYPE_CL + assert result.tag is None + async def test_init_issuer_registry_no_cred_def(self): CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" @@ -152,3 +170,24 @@ async def test_get_ledger_registry(self): mock_from_def.assert_called_once_with( self.ledger.get_revoc_reg_def.return_value, True ) + + self.context.injector.bind_instance( + BaseMultitenantManager, + async_mock.MagicMock(MultitenantManager, autospec=True), + ) + with async_mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + async_mock.CoroutineMock(return_value=(None, self.ledger)), + ), async_mock.patch.object( + RevocationRegistry, "from_definition", async_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 + + await self.revoc.get_ledger_registry("dummy2") + + mock_from_def.assert_called_once_with( + self.ledger.get_revoc_reg_def.return_value, True + )