From 15ee6a8492608b7538c8596b3aed6689f087c958 Mon Sep 17 00:00:00 2001 From: Matic Di Batista Date: Mon, 25 Oct 2021 10:48:57 +0200 Subject: [PATCH 1/7] feat(IDENT-3373): using async with to get the session needed for the wallet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 368 +++++++++++++++--------------- 1 file changed, 187 insertions(+), 181 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index e1d5c318e7..065cd57168 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -198,92 +198,93 @@ async def wallet_did_list(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") + filter_did = request.query.get("did") filter_verkey = request.query.get("verkey") filter_method = DIDMethod.from_method(request.query.get("method")) filter_posture = DIDPosture.get(request.query.get("posture")) filter_key_type = KeyType.from_key_type(request.query.get("key_type")) results = [] - - if filter_posture is DIDPosture.PUBLIC: - public_did_info = await wallet.get_public_did() - if ( - public_did_info - and (not filter_verkey or public_did_info.verkey == filter_verkey) - and (not filter_did or public_did_info.did == filter_did) - and (not filter_method or public_did_info.method == filter_method) - and (not filter_key_type or public_did_info.key_type == filter_key_type) - ): - results.append(format_did_info(public_did_info)) - elif filter_posture is DIDPosture.POSTED: - results = [] - posted_did_infos = await wallet.get_posted_dids() - for info in posted_did_infos: + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + if filter_posture is DIDPosture.PUBLIC: + public_did_info = await wallet.get_public_did() + if ( + public_did_info + and (not filter_verkey or public_did_info.verkey == filter_verkey) + and (not filter_did or public_did_info.did == filter_did) + and (not filter_method or public_did_info.method == filter_method) + and (not filter_key_type or public_did_info.key_type == filter_key_type) + ): + results.append(format_did_info(public_did_info)) + elif filter_posture is DIDPosture.POSTED: + results = [] + posted_did_infos = await wallet.get_posted_dids() + for info in posted_did_infos: + if ( + (not filter_verkey or info.verkey == filter_verkey) + and (not filter_did or info.did == filter_did) + and (not filter_method or info.method == filter_method) + and (not filter_key_type or info.key_type == filter_key_type) + ): + results.append(format_did_info(info)) + elif filter_did: + try: + info = await wallet.get_local_did(filter_did) + except WalletError: + # badly formatted DID or record not found + info = None if ( - (not filter_verkey or info.verkey == filter_verkey) - and (not filter_did or info.did == filter_did) + info + and (not filter_verkey or info.verkey == filter_verkey) and (not filter_method or info.method == filter_method) and (not filter_key_type or info.key_type == filter_key_type) + and ( + filter_posture is None + or ( + filter_posture is DIDPosture.WALLET_ONLY + and not info.metadata.get("posted") + ) + ) ): results.append(format_did_info(info)) - elif filter_did: - try: - info = await wallet.get_local_did(filter_did) - except WalletError: - # badly formatted DID or record not found - info = None - if ( - info - and (not filter_verkey or info.verkey == filter_verkey) - and (not filter_method or info.method == filter_method) - and (not filter_key_type or info.key_type == filter_key_type) - and ( - filter_posture is None - or ( - filter_posture is DIDPosture.WALLET_ONLY - and not info.metadata.get("posted") + elif filter_verkey: + try: + info = await wallet.get_local_did_for_verkey(filter_verkey) + except WalletError: + info = None + if ( + info + and (not filter_method or info.method == filter_method) + and (not filter_key_type or info.key_type == filter_key_type) + and ( + filter_posture is None + or ( + filter_posture is DID_POSTURE.WALLET_ONLY + and not info.metadata.get("posted") + ) ) - ) - ): - results.append(format_did_info(info)) - elif filter_verkey: - try: - info = await wallet.get_local_did_for_verkey(filter_verkey) - except WalletError: - info = None - if ( - info - and (not filter_method or info.method == filter_method) - and (not filter_key_type or info.key_type == filter_key_type) - and ( - filter_posture is None - or ( - filter_posture is DID_POSTURE.WALLET_ONLY - and not info.metadata.get("posted") + ): + results.append(format_did_info(info)) + else: + dids = await wallet.get_local_dids() + results = [ + format_did_info(info) + for info in dids + if ( + filter_posture is None + or DIDPosture.get(info.metadata) is DIDPosture.WALLET_ONLY ) - ) - ): - results.append(format_did_info(info)) - else: - dids = await wallet.get_local_dids() - results = [ - format_did_info(info) - for info in dids - if ( - filter_posture is None - or DIDPosture.get(info.metadata) is DIDPosture.WALLET_ONLY - ) - and (not filter_method or info.method == filter_method) - and (not filter_key_type or info.key_type == filter_key_type) - ] + and (not filter_method or info.method == filter_method) + and (not filter_key_type or info.key_type == filter_key_type) + ] + + results.sort( + key=lambda info: (DIDPosture.get(info["posture"]).ordinal, info["did"]) + ) - results.sort( - key=lambda info: (DIDPosture.get(info["posture"]).ordinal, info["did"]) - ) return web.json_response({"results": results}) @@ -322,16 +323,16 @@ async def wallet_create_did(request: web.BaseRequest): f" support key type {key_type.key_type}" ) ) + info = None + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + try: + info = await wallet.create_local_did(method=method, key_type=key_type) - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") - try: - info = await wallet.create_local_did(method=method, key_type=key_type) - - except WalletError as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + except WalletError as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({"result": format_did_info(info)}) @@ -350,14 +351,15 @@ async def wallet_get_public_did(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") - try: - info = await wallet.get_public_did() - except WalletError as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + info = None + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + try: + info = await wallet.get_public_did() + except WalletError as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({"result": format_did_info(info)}) @@ -377,53 +379,56 @@ async def wallet_set_public_did(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") - did = request.query.get("did") - if not did: - raise web.HTTPBadRequest(reason="Request query must include DID") - # Multitenancy setup - multitenant_mgr = session.inject_or(BaseMultitenantManager) - wallet_id = session.settings.get("wallet.id") - - try: - ledger = session.inject_or(BaseLedger) - if not ledger: - reason = "No ledger available" - if not session.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" - raise web.HTTPForbidden(reason=reason) - - async with ledger: - if not await ledger.get_key_for_did(did): - raise web.HTTPNotFound(reason=f"DID {did} is not posted to the ledger") - - did_info = await wallet.get_local_did(did) - info = await wallet.set_public_did(did_info) - if info: - # Publish endpoint if necessary - endpoint = did_info.metadata.get("endpoint") + info: DIDInfo = None + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + did = request.query.get("did") + if not did: + raise web.HTTPBadRequest(reason="Request query must include DID") + wallet_id = session.settings.get("wallet.id") - if not endpoint: - endpoint = session.settings.get("default_endpoint") - await wallet.set_did_endpoint(info.did, endpoint, ledger) + try: + ledger = session.inject_or(BaseLedger) + if not ledger: + reason = "No ledger available" + if not session.settings.get_value("wallet.type"): + reason += ": missing wallet-type?" + raise web.HTTPForbidden(reason=reason) async with ledger: - await ledger.update_endpoint_for_did(info.did, endpoint) - - # Add multitenant relay mapping so implicit invitations are still routed - if multitenant_mgr and wallet_id: - await multitenant_mgr.add_key( - wallet_id, info.verkey, skip_if_exists=True - ) - - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except (LedgerError, WalletError) as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + if not await ledger.get_key_for_did(did): + raise web.HTTPNotFound( + reason=f"DID {did} is not posted to the ledger" + ) + + did_info = await wallet.get_local_did(did) + info = await wallet.set_public_did(did_info) + if info: + # Publish endpoint if necessary + endpoint = did_info.metadata.get("endpoint") + + if not endpoint: + endpoint = session.settings.get("default_endpoint") + await wallet.set_did_endpoint(info.did, endpoint, ledger) + + async with ledger: + await ledger.update_endpoint_for_did(info.did, endpoint) + + # Multitenancy setup + multitenant_mgr = session.inject_or(BaseMultitenantManager) + # Add multitenant relay mapping so implicit invitations are still routed + if multitenant_mgr and wallet_id: + await multitenant_mgr.add_key( + wallet_id, info.verkey, skip_if_exists=True + ) + + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except (LedgerError, WalletError) as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({"result": format_did_info(info)}) @@ -441,27 +446,26 @@ async def wallet_set_did_endpoint(request: web.BaseRequest): request: aiohttp request object """ context: AdminRequestContext = request["context"] - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") - - body = await request.json() - did = body["did"] - endpoint = body.get("endpoint") - endpoint_type = EndpointType.get( - body.get("endpoint_type", EndpointType.ENDPOINT.w3c) - ) - try: - ledger = session.inject_or(BaseLedger) - await wallet.set_did_endpoint(did, endpoint, ledger, endpoint_type) - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except LedgerConfigError as err: - raise web.HTTPForbidden(reason=err.roll_up) from err - except (LedgerError, WalletError) as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + body = await request.json() + did = body["did"] + endpoint = body.get("endpoint") + endpoint_type = EndpointType.get( + body.get("endpoint_type", EndpointType.ENDPOINT.w3c) + ) + try: + ledger = session.inject_or(BaseLedger) + await wallet.set_did_endpoint(did, endpoint, ledger, endpoint_type) + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except LedgerConfigError as err: + raise web.HTTPForbidden(reason=err.roll_up) from err + except (LedgerError, WalletError) as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({}) @@ -481,20 +485,21 @@ async def wallet_get_did_endpoint(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") - did = request.query.get("did") - if not did: - raise web.HTTPBadRequest(reason="Request query must include DID") - try: - did_info = await wallet.get_local_did(did) - endpoint = did_info.metadata.get("endpoint") - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except WalletError as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + did = request.query.get("did") + if not did: + raise web.HTTPBadRequest(reason="Request query must include DID") + + try: + did_info = await wallet.get_local_did(did) + endpoint = did_info.metadata.get("endpoint") + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except WalletError as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({"did": did, "endpoint": endpoint}) @@ -514,24 +519,25 @@ async def wallet_rotate_did_keypair(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - session = await context.session() - wallet = session.inject_or(BaseWallet) - if not wallet: - raise web.HTTPForbidden(reason="No wallet available") did = request.query.get("did") if not did: raise web.HTTPBadRequest(reason="Request query must include DID") - try: - did_info = await wallet.get_local_did(did) - if did_info.metadata.get("posted", False): - # call from ledger API instead to propagate through ledger NYM transaction - raise web.HTTPBadRequest(reason=f"DID {did} is posted to the ledger") - await wallet.rotate_did_keypair_start(did) # do not take seed over the wire - await wallet.rotate_did_keypair_apply(did) - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except WalletError as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + + async with context.session() as session: + wallet = session.inject_or(BaseWallet) + if not wallet: + raise web.HTTPForbidden(reason="No wallet available") + try: + did_info = await wallet.get_local_did(did) + if did_info.metadata.get("posted", False): + # call from ledger API instead to propagate through ledger NYM transaction + raise web.HTTPBadRequest(reason=f"DID {did} is posted to the ledger") + await wallet.rotate_did_keypair_start(did) # do not take seed over the wire + await wallet.rotate_did_keypair_apply(did) + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except WalletError as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({}) From 2f21ed40e12d1747ea3910293494a1fab89db32e Mon Sep 17 00:00:00 2001 From: Matic Di Batista Date: Mon, 25 Oct 2021 15:39:58 +0200 Subject: [PATCH 2/7] fix(IDENT-3373): small refactor to wallet_set_public_did function. to use seperate sessions for wallet calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 80 +++++++++++--------- aries_cloudagent/wallet/tests/test_routes.py | 54 +++++++++---- 2 files changed, 82 insertions(+), 52 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index 065cd57168..3c9b248bfb 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -379,56 +379,62 @@ async def wallet_set_public_did(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - - info: DIDInfo = None async with context.session() as session: wallet = session.inject_or(BaseWallet) if not wallet: raise web.HTTPForbidden(reason="No wallet available") - did = request.query.get("did") - if not did: - raise web.HTTPBadRequest(reason="Request query must include DID") - wallet_id = session.settings.get("wallet.id") - try: - ledger = session.inject_or(BaseLedger) - if not ledger: - reason = "No ledger available" - if not session.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" - raise web.HTTPForbidden(reason=reason) - - async with ledger: - if not await ledger.get_key_for_did(did): - raise web.HTTPNotFound( - reason=f"DID {did} is not posted to the ledger" - ) + did = request.query.get("did") + if not did: + raise web.HTTPBadRequest(reason="Request query must include DID") + wallet_id = context.settings.get("wallet.id") + info: DIDInfo = None + try: + ledger = context.profile.inject_or(BaseLedger) + if not ledger: + reason = "No ledger available" + if not context.settings.get_value("wallet.type"): + reason += ": missing wallet-type?" + raise web.HTTPForbidden(reason=reason) + + async with ledger: + if not await ledger.get_key_for_did(did): + raise web.HTTPNotFound( + reason=f"DID {did} is not posted to the ledger" + ) + async with context.session() as session: + wallet = session.inject_or(BaseWallet) did_info = await wallet.get_local_did(did) + info: DIDInfo = None + async with context.session() as session: + wallet = session.inject_or(BaseWallet) info = await wallet.set_public_did(did_info) - if info: - # Publish endpoint if necessary - endpoint = did_info.metadata.get("endpoint") + if info: + # Publish endpoint if necessary + endpoint = did_info.metadata.get("endpoint") - if not endpoint: + if not endpoint: + async with context.session() as session: + wallet = session.inject_or(BaseWallet) endpoint = session.settings.get("default_endpoint") await wallet.set_did_endpoint(info.did, endpoint, ledger) - async with ledger: - await ledger.update_endpoint_for_did(info.did, endpoint) - - # Multitenancy setup - multitenant_mgr = session.inject_or(BaseMultitenantManager) - # Add multitenant relay mapping so implicit invitations are still routed - if multitenant_mgr and wallet_id: - await multitenant_mgr.add_key( - wallet_id, info.verkey, skip_if_exists=True - ) + async with ledger: + await ledger.update_endpoint_for_did(info.did, endpoint) + + # Multitenancy setup + multitenant_mgr = context.profile.inject_or(BaseMultitenantManager) + # Add multitenant relay mapping so implicit invitations are still routed + if multitenant_mgr and wallet_id: + await multitenant_mgr.add_key( + wallet_id, info.verkey, skip_if_exists=True + ) - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except (LedgerError, WalletError) as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except (LedgerError, WalletError) as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({"result": format_did_info(info)}) diff --git a/aries_cloudagent/wallet/tests/test_routes.py b/aries_cloudagent/wallet/tests/test_routes.py index c534cf03bf..df1e1807b2 100644 --- a/aries_cloudagent/wallet/tests/test_routes.py +++ b/aries_cloudagent/wallet/tests/test_routes.py @@ -1,3 +1,4 @@ +from ...core.in_memory import InMemoryProfile from asynctest import mock as async_mock, TestCase as AsyncTestCase from aiohttp.web import HTTPForbidden @@ -18,7 +19,8 @@ class TestWalletRoutes(AsyncTestCase): def setUp(self): self.wallet = async_mock.create_autospec(BaseWallet) self.session_inject = {BaseWallet: self.wallet} - self.context = AdminRequestContext.test_context(self.session_inject) + self.profile = InMemoryProfile.test_profile() + self.context = AdminRequestContext.test_context(self.session_inject, self.profile) self.request_dict = { "context": self.context, "outbound_message_router": async_mock.CoroutineMock(), @@ -369,7 +371,9 @@ async def test_set_public_did(self): ledger.get_key_for_did = async_mock.CoroutineMock() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -408,11 +412,14 @@ async def test_set_public_did_multitenant(self): ledger.get_key_for_did = async_mock.CoroutineMock() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) multitenant_mgr = async_mock.MagicMock(MultitenantManager, autospec=True) - self.session_inject[BaseMultitenantManager] = multitenant_mgr - + self.profile.context.injector.bind_instance( + BaseMultitenantManager, multitenant_mgr + ) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ): @@ -446,7 +453,9 @@ async def test_set_public_did_not_public(self): ledger = Ledger() ledger.get_key_for_did = async_mock.CoroutineMock(return_value=None) ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) with self.assertRaises(test_module.web.HTTPNotFound): await test_module.wallet_set_public_did(self.request) @@ -458,7 +467,9 @@ async def test_set_public_did_not_found(self): ledger = Ledger() ledger.get_key_for_did = async_mock.CoroutineMock(return_value=None) ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) self.wallet.get_local_did.side_effect = test_module.WalletNotFoundError() with self.assertRaises(test_module.web.HTTPNotFound): @@ -472,8 +483,9 @@ async def test_set_public_did_x(self): ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger - + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as json_response: @@ -496,7 +508,9 @@ async def test_set_public_did_no_wallet_did(self): ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -520,7 +534,9 @@ async def test_set_public_did_update_endpoint(self): ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -558,7 +574,9 @@ async def test_set_public_did_update_endpoint_use_default_update_in_wallet(self) ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -602,7 +620,9 @@ async def test_set_did_endpoint(self): ledger = Ledger() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) self.wallet.get_local_did.return_value = DIDInfo( self.test_did, @@ -664,7 +684,9 @@ async def test_set_did_endpoint_x(self): ledger = Ledger() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) self.wallet.set_did_endpoint.side_effect = test_module.WalletError() @@ -683,7 +705,9 @@ async def test_set_did_endpoint_no_wallet_did(self): ledger = Ledger() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.session_inject[BaseLedger] = ledger + self.profile.context.injector.bind_instance( + BaseLedger, ledger + ) self.wallet.set_did_endpoint.side_effect = test_module.WalletNotFoundError() From 70d3b81819d9499a90a58243406ef977a366d075 Mon Sep 17 00:00:00 2001 From: Matic Di Batista Date: Tue, 26 Oct 2021 09:42:04 +0200 Subject: [PATCH 3/7] fix(IDENT-3373): moved wallet calls into seperate sessions for function wallet_rotate_did_keypair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index 3c9b248bfb..02723db0fa 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -533,17 +533,24 @@ async def wallet_rotate_did_keypair(request: web.BaseRequest): wallet = session.inject_or(BaseWallet) if not wallet: raise web.HTTPForbidden(reason="No wallet available") - try: + try: + did_info: DIDInfo = None + async with context.session() as session: + wallet = session.inject_or(BaseWallet) did_info = await wallet.get_local_did(did) if did_info.metadata.get("posted", False): # call from ledger API instead to propagate through ledger NYM transaction raise web.HTTPBadRequest(reason=f"DID {did} is posted to the ledger") + async with context.session() as session: + wallet = session.inject_or(BaseWallet) await wallet.rotate_did_keypair_start(did) # do not take seed over the wire + async with context.session() as session: + wallet = session.inject_or(BaseWallet) await wallet.rotate_did_keypair_apply(did) - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except WalletError as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except WalletError as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({}) From 2cf80f9d2d561ec236cc6fb248d531dcd407267f Mon Sep 17 00:00:00 2001 From: Matic Di Batista Date: Tue, 26 Oct 2021 14:20:12 +0200 Subject: [PATCH 4/7] fix(IDENT-3373): resused sessions in wallet_set_public_did and moved sort out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index 02723db0fa..99414f07a3 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -281,9 +281,9 @@ async def wallet_did_list(request: web.BaseRequest): and (not filter_key_type or info.key_type == filter_key_type) ] - results.sort( - key=lambda info: (DIDPosture.get(info["posture"]).ordinal, info["did"]) - ) + results.sort( + key=lambda info: (DIDPosture.get(info["posture"]).ordinal, info["did"]) + ) return web.json_response({"results": results}) @@ -403,12 +403,10 @@ async def wallet_set_public_did(request: web.BaseRequest): raise web.HTTPNotFound( reason=f"DID {did} is not posted to the ledger" ) + did_info: DIDInfo = None async with context.session() as session: wallet = session.inject_or(BaseWallet) did_info = await wallet.get_local_did(did) - info: DIDInfo = None - async with context.session() as session: - wallet = session.inject_or(BaseWallet) info = await wallet.set_public_did(did_info) if info: # Publish endpoint if necessary From 5150ed5ab72f247c7042ebfd58baf01c9bbd128b Mon Sep 17 00:00:00 2001 From: Matic Di Batista Date: Tue, 26 Oct 2021 14:43:46 +0200 Subject: [PATCH 5/7] fix(IDENT-3373): moved functions from different sessions together if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 33 +++++++++----------- aries_cloudagent/wallet/tests/test_routes.py | 6 ++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index 99414f07a3..4a417ac435 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -415,7 +415,7 @@ async def wallet_set_public_did(request: web.BaseRequest): if not endpoint: async with context.session() as session: wallet = session.inject_or(BaseWallet) - endpoint = session.settings.get("default_endpoint") + endpoint = context.settings.get("default_endpoint") await wallet.set_did_endpoint(info.did, endpoint, ledger) async with ledger: @@ -450,17 +450,17 @@ async def wallet_set_did_endpoint(request: web.BaseRequest): request: aiohttp request object """ context: AdminRequestContext = request["context"] - + body = await request.json() + did = body["did"] + endpoint = body.get("endpoint") + endpoint_type = EndpointType.get( + body.get("endpoint_type", EndpointType.ENDPOINT.w3c) + ) async with context.session() as session: wallet = session.inject_or(BaseWallet) if not wallet: raise web.HTTPForbidden(reason="No wallet available") - body = await request.json() - did = body["did"] - endpoint = body.get("endpoint") - endpoint_type = EndpointType.get( - body.get("endpoint_type", EndpointType.ENDPOINT.w3c) - ) + try: ledger = session.inject_or(BaseLedger) await wallet.set_did_endpoint(did, endpoint, ledger, endpoint_type) @@ -531,24 +531,19 @@ async def wallet_rotate_did_keypair(request: web.BaseRequest): wallet = session.inject_or(BaseWallet) if not wallet: raise web.HTTPForbidden(reason="No wallet available") - try: - did_info: DIDInfo = None - async with context.session() as session: + try: + did_info: DIDInfo = None wallet = session.inject_or(BaseWallet) did_info = await wallet.get_local_did(did) if did_info.metadata.get("posted", False): # call from ledger API instead to propagate through ledger NYM transaction raise web.HTTPBadRequest(reason=f"DID {did} is posted to the ledger") - async with context.session() as session: - wallet = session.inject_or(BaseWallet) await wallet.rotate_did_keypair_start(did) # do not take seed over the wire - async with context.session() as session: - wallet = session.inject_or(BaseWallet) await wallet.rotate_did_keypair_apply(did) - except WalletNotFoundError as err: - raise web.HTTPNotFound(reason=err.roll_up) from err - except WalletError as err: - raise web.HTTPBadRequest(reason=err.roll_up) from err + except WalletNotFoundError as err: + raise web.HTTPNotFound(reason=err.roll_up) from err + except WalletError as err: + raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({}) diff --git a/aries_cloudagent/wallet/tests/test_routes.py b/aries_cloudagent/wallet/tests/test_routes.py index df1e1807b2..f6963ef447 100644 --- a/aries_cloudagent/wallet/tests/test_routes.py +++ b/aries_cloudagent/wallet/tests/test_routes.py @@ -53,6 +53,12 @@ async def test_missing_wallet(self): await test_module.wallet_set_public_did(self.request) with self.assertRaises(HTTPForbidden): + self.request.json = async_mock.CoroutineMock( + return_value={ + "did": self.test_did, + "endpoint": "https://my-endpoint.ca:8020", + } + ) await test_module.wallet_set_did_endpoint(self.request) with self.assertRaises(HTTPForbidden): From 2d6e1ad19d3311cadd0f25b4485af6bad569d97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andra=C5=BE=20Cuderman?= Date: Tue, 2 Nov 2021 10:24:53 +0100 Subject: [PATCH 6/7] fix(IDENT-3671): Fixed lint issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 4 +- aries_cloudagent/wallet/tests/test_routes.py | 48 ++++++-------------- 2 files changed, 15 insertions(+), 37 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index 4a417ac435..7d6850dedf 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -400,9 +400,7 @@ async def wallet_set_public_did(request: web.BaseRequest): async with ledger: if not await ledger.get_key_for_did(did): - raise web.HTTPNotFound( - reason=f"DID {did} is not posted to the ledger" - ) + raise web.HTTPNotFound(reason=f"DID {did} is not posted to the ledger") did_info: DIDInfo = None async with context.session() as session: wallet = session.inject_or(BaseWallet) diff --git a/aries_cloudagent/wallet/tests/test_routes.py b/aries_cloudagent/wallet/tests/test_routes.py index f6963ef447..83147be5bc 100644 --- a/aries_cloudagent/wallet/tests/test_routes.py +++ b/aries_cloudagent/wallet/tests/test_routes.py @@ -20,7 +20,9 @@ def setUp(self): self.wallet = async_mock.create_autospec(BaseWallet) self.session_inject = {BaseWallet: self.wallet} self.profile = InMemoryProfile.test_profile() - self.context = AdminRequestContext.test_context(self.session_inject, self.profile) + self.context = AdminRequestContext.test_context( + self.session_inject, self.profile + ) self.request_dict = { "context": self.context, "outbound_message_router": async_mock.CoroutineMock(), @@ -377,9 +379,7 @@ async def test_set_public_did(self): ledger.get_key_for_did = async_mock.CoroutineMock() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -418,9 +418,7 @@ async def test_set_public_did_multitenant(self): ledger.get_key_for_did = async_mock.CoroutineMock() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) multitenant_mgr = async_mock.MagicMock(MultitenantManager, autospec=True) self.profile.context.injector.bind_instance( @@ -459,9 +457,7 @@ async def test_set_public_did_not_public(self): ledger = Ledger() ledger.get_key_for_did = async_mock.CoroutineMock(return_value=None) ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) with self.assertRaises(test_module.web.HTTPNotFound): await test_module.wallet_set_public_did(self.request) @@ -473,9 +469,7 @@ async def test_set_public_did_not_found(self): ledger = Ledger() ledger.get_key_for_did = async_mock.CoroutineMock(return_value=None) ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) self.wallet.get_local_did.side_effect = test_module.WalletNotFoundError() with self.assertRaises(test_module.web.HTTPNotFound): @@ -489,9 +483,7 @@ async def test_set_public_did_x(self): ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as json_response: @@ -514,9 +506,7 @@ async def test_set_public_did_no_wallet_did(self): ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -540,9 +530,7 @@ async def test_set_public_did_update_endpoint(self): ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -580,9 +568,7 @@ async def test_set_public_did_update_endpoint_use_default_update_in_wallet(self) ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.get_key_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) with async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() @@ -626,9 +612,7 @@ async def test_set_did_endpoint(self): ledger = Ledger() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) self.wallet.get_local_did.return_value = DIDInfo( self.test_did, @@ -690,9 +674,7 @@ async def test_set_did_endpoint_x(self): ledger = Ledger() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) self.wallet.set_did_endpoint.side_effect = test_module.WalletError() @@ -711,9 +693,7 @@ async def test_set_did_endpoint_no_wallet_did(self): ledger = Ledger() ledger.update_endpoint_for_did = async_mock.CoroutineMock() ledger.__aenter__ = async_mock.CoroutineMock(return_value=ledger) - self.profile.context.injector.bind_instance( - BaseLedger, ledger - ) + self.profile.context.injector.bind_instance(BaseLedger, ledger) self.wallet.set_did_endpoint.side_effect = test_module.WalletNotFoundError() From 1d05f73dabd4d3205227d1bc1fc4b5f71e7ca9ba Mon Sep 17 00:00:00 2001 From: Matic Di Batista Date: Wed, 27 Oct 2021 15:00:01 +0200 Subject: [PATCH 7/7] fix(IDENT-3373): removed unnecessary registration of session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andraž Cuderman --- aries_cloudagent/wallet/routes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/aries_cloudagent/wallet/routes.py b/aries_cloudagent/wallet/routes.py index 7d6850dedf..b3d84c01a9 100644 --- a/aries_cloudagent/wallet/routes.py +++ b/aries_cloudagent/wallet/routes.py @@ -460,7 +460,7 @@ async def wallet_set_did_endpoint(request: web.BaseRequest): raise web.HTTPForbidden(reason="No wallet available") try: - ledger = session.inject_or(BaseLedger) + ledger = context.profile.inject_or(BaseLedger) await wallet.set_did_endpoint(did, endpoint, ledger, endpoint_type) except WalletNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err @@ -531,7 +531,6 @@ async def wallet_rotate_did_keypair(request: web.BaseRequest): raise web.HTTPForbidden(reason="No wallet available") try: did_info: DIDInfo = None - wallet = session.inject_or(BaseWallet) did_info = await wallet.get_local_did(did) if did_info.metadata.get("posted", False): # call from ledger API instead to propagate through ledger NYM transaction