From 0cb514ff1fe1e7a6cdeccb1f2c5161a61a9dff05 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Mon, 22 Aug 2022 12:07:28 -0600 Subject: [PATCH 01/10] feat: remove public/multi mutual exclusion Signed-off-by: Micah Peltier --- .../protocols/out_of_band/v1_0/manager.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py index 4bdfcc39a6..2670d4bf89 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py @@ -133,10 +133,10 @@ async def create_invitation( "Cannot store metadata without handshake protocols" ) if public: - if multi_use: - raise OutOfBandManagerError( - "Cannot create public invitation with multi_use" - ) + # if multi_use: + # raise OutOfBandManagerError( + # "Cannot create public invitation with multi_use" + # ) if metadata: raise OutOfBandManagerError( "Cannot store metadata on public invitations" @@ -235,9 +235,15 @@ async def create_invitation( # Only create connection record if hanshake_protocols is defined if handshake_protocols: + invitation_mode = ( + ConnRecord.INVITATION_MODE_MULTI + if multi_use + else ConnRecord.INVITATION_MODE_ONCE + ) conn_rec = ConnRecord( # create connection record invitation_key=public_did.verkey, invitation_msg_id=invi_msg._id, + invitation_mode=invitation_mode, their_role=ConnRecord.Role.REQUESTER.rfc23, state=ConnRecord.State.INVITATION.rfc23, accept=ConnRecord.ACCEPT_AUTO From 56adc18ca26eadbcc701df501411fd1baed08aa8 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Mon, 29 Aug 2022 11:24:45 -0600 Subject: [PATCH 02/10] feat: remove commented code Signed-off-by: Micah Peltier --- aries_cloudagent/protocols/out_of_band/v1_0/manager.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py index 2670d4bf89..1fa0756740 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py @@ -133,10 +133,6 @@ async def create_invitation( "Cannot store metadata without handshake protocols" ) if public: - # if multi_use: - # raise OutOfBandManagerError( - # "Cannot create public invitation with multi_use" - # ) if metadata: raise OutOfBandManagerError( "Cannot store metadata on public invitations" From 9cdb75ed2f738c66193bdd903bff33ec10b71b3c Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 12 Oct 2022 11:49:52 -0600 Subject: [PATCH 03/10] feat: add flag for unsolicited requests Signed-off-by: Micah Peltier --- aries_cloudagent/config/argparse.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/aries_cloudagent/config/argparse.py b/aries_cloudagent/config/argparse.py index c3cc337f6b..90b2abb2a0 100644 --- a/aries_cloudagent/config/argparse.py +++ b/aries_cloudagent/config/argparse.py @@ -1014,7 +1014,17 @@ def add_arguments(self, parser: ArgumentParser): action="store_true", env_var="ACAPY_PUBLIC_INVITES", help=( - "Send invitations out, and receive connection requests, " + "Send invitations out using the public DID for the agent, " + "and receive connection requests solicited by invitations " + "which use the public DID. Default: false." + ), + ) + parser.add_argument( + "--requests-through-public-did", + action="store_true", + env_var="ACAPY_REQUESTS_THROUGH_PUBLIC_DID", + help=( + "Allow agent to receive unsolicited connection requests, " "using the public DID for the agent. Default: false." ), ) @@ -1109,6 +1119,11 @@ def get_settings(self, args: Namespace) -> dict: settings["monitor_forward"] = args.monitor_forward if args.public_invites: settings["public_invites"] = True + if args.requests_through_public_did: + if not args.public_invites: + raise ArgsParseError("--public-invites is required to use " + "--requests-through-public-did") + settings["requests_through_public_did"] = True if args.timing: settings["timing.enabled"] = True if args.timing_log: From ff3edd851012c3774f622fdb4997c05c83936897 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 12 Oct 2022 11:57:56 -0600 Subject: [PATCH 04/10] feat: allow metadata on public invites Signed-off-by: Micah Peltier --- aries_cloudagent/protocols/out_of_band/v1_0/manager.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py index 1fa0756740..29ba806f5c 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py @@ -132,11 +132,6 @@ async def create_invitation( raise OutOfBandManagerError( "Cannot store metadata without handshake protocols" ) - if public: - if metadata: - raise OutOfBandManagerError( - "Cannot store metadata on public invitations" - ) if attachments and multi_use: raise OutOfBandManagerError( From 91ba45ba7cb7ef8d3025751cf6289948a0c6b1e4 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 12 Oct 2022 12:05:01 -0600 Subject: [PATCH 05/10] feat: check for new flag Signed-off-by: Micah Peltier --- aries_cloudagent/protocols/didexchange/v1_0/manager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aries_cloudagent/protocols/didexchange/v1_0/manager.py b/aries_cloudagent/protocols/didexchange/v1_0/manager.py index 587e6b56b5..523d307362 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/manager.py @@ -483,6 +483,9 @@ async def receive_request( ) else: # request is against implicit invitation on public DID + if not self.profile.settings.get("requests_through_public_did"): + raise DIDXManagerError("Unsolicited connection requests to " + "public DID is not enabled") async with self.profile.session() as session: wallet = session.inject(BaseWallet) my_info = await wallet.create_local_did( From 55e52d62b39a34f40c11ed16a19b7f9d1d7b2556 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 12 Oct 2022 12:06:48 -0600 Subject: [PATCH 06/10] test: implicit invites Signed-off-by: Micah Peltier --- .../didexchange/v1_0/tests/test_manager.py | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py index 131d87670e..a59c52c10a 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py @@ -971,6 +971,149 @@ async def test_receive_request_public_did_no_auto_accept(self): messages = self.responder.messages assert not messages + async def test_receive_request_implicit_public_did_not_enabled(self): + async with self.profile.session() as session: + mock_request = async_mock.MagicMock( + did=TestConfig.test_did, + did_doc_attach=async_mock.MagicMock( + data=async_mock.MagicMock( + verify=async_mock.CoroutineMock(return_value=True), + signed=async_mock.MagicMock( + decode=async_mock.MagicMock(return_value="dummy-did-doc") + ), + ) + ), + _thread=async_mock.MagicMock(pthid="did:sov:publicdid0000000000000"), + ) + mediation_record = MediationRecord( + role=MediationRecord.ROLE_CLIENT, + state=MediationRecord.STATE_GRANTED, + connection_id=self.test_mediator_conn_id, + routing_keys=self.test_mediator_routing_keys, + endpoint=self.test_mediator_endpoint, + ) + await mediation_record.save(session) + + await session.wallet.create_local_did( + method=DIDMethod.SOV, + key_type=KeyType.ED25519, + seed=None, + did=TestConfig.test_did, + ) + + self.profile.context.update_settings({"public_invites": True}) + + with async_mock.patch.object( + test_module, "ConnRecord", async_mock.MagicMock() + ) as mock_conn_rec_cls, async_mock.patch.object( + test_module, "DIDDoc", autospec=True + ) as mock_did_doc, async_mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, async_mock.patch.object( + self.manager, + "verify_diddoc", + async_mock.CoroutineMock(return_value=DIDDoc(TestConfig.test_did))): + mock_did_posture.get = async_mock.MagicMock( + return_value=test_module.DIDPosture.PUBLIC + ) + mock_conn_rec_cls.retrieve_by_invitation_key = async_mock.CoroutineMock( + side_effect=StorageNotFoundError() + ) + mock_conn_rec_cls.retrieve_by_invitation_msg_id = ( + async_mock.CoroutineMock(return_value=None) + ) + + with self.assertRaises(DIDXManagerError) as context: + await self.manager.receive_request( + request=mock_request, + recipient_did=TestConfig.test_did, + my_endpoint=None, + alias=None, + auto_accept_implicit=None, + ) + assert "Unsolicited connection requests" in str(context.exception) + + async def test_receive_request_implicit_public_did(self): + async with self.profile.session() as session: + mock_request = async_mock.MagicMock( + did=TestConfig.test_did, + did_doc_attach=async_mock.MagicMock( + data=async_mock.MagicMock( + verify=async_mock.CoroutineMock(return_value=True), + signed=async_mock.MagicMock( + decode=async_mock.MagicMock(return_value="dummy-did-doc") + ), + ) + ), + _thread=async_mock.MagicMock(pthid="did:sov:publicdid0000000000000"), + ) + mediation_record = MediationRecord( + role=MediationRecord.ROLE_CLIENT, + state=MediationRecord.STATE_GRANTED, + connection_id=self.test_mediator_conn_id, + routing_keys=self.test_mediator_routing_keys, + endpoint=self.test_mediator_endpoint, + ) + await mediation_record.save(session) + + await session.wallet.create_local_did( + method=DIDMethod.SOV, + key_type=KeyType.ED25519, + seed=None, + did=TestConfig.test_did, + ) + + self.profile.context.update_settings({"public_invites": True}) + self.profile.context.update_settings({"requests_through_public_did": True}) + ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO + STATE_REQUEST = ConnRecord.State.REQUEST + + with async_mock.patch.object( + test_module, "ConnRecord", async_mock.MagicMock() + ) as mock_conn_rec_cls, async_mock.patch.object( + test_module, "DIDDoc", autospec=True + ) as mock_did_doc, async_mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, async_mock.patch.object( + self.manager, + "verify_diddoc", + async_mock.CoroutineMock(return_value=DIDDoc(TestConfig.test_did))): + mock_did_posture.get = async_mock.MagicMock( + return_value=test_module.DIDPosture.PUBLIC + ) + mock_conn_rec_cls.retrieve_by_invitation_key = async_mock.CoroutineMock( + side_effect=StorageNotFoundError() + ) + mock_conn_rec_cls.retrieve_by_invitation_msg_id = ( + async_mock.CoroutineMock(return_value=None) + ) + + mock_conn_record = async_mock.MagicMock( + accept=ACCEPT_AUTO, + my_did=None, + state=STATE_REQUEST.rfc23, + attach_request=async_mock.CoroutineMock(), + retrieve_request=async_mock.CoroutineMock(), + metadata_get_all=async_mock.CoroutineMock(return_value={}), + metadata_get=async_mock.CoroutineMock(return_value=True), + save=async_mock.CoroutineMock(), + ) + + mock_conn_rec_cls.return_value = mock_conn_record + + conn_rec = await self.manager.receive_request( + request=mock_request, + recipient_did=TestConfig.test_did, + recipient_verkey=None, + my_endpoint=None, + alias=None, + auto_accept_implicit=None, + ) + assert conn_rec + self.oob_mock.clean_finished_oob_record.assert_called_once_with( + self.profile, mock_request + ) + async def test_receive_request_peer_did(self): async with self.profile.session() as session: mock_request = async_mock.MagicMock( From 6ecd8e6f87eec05cab5d0de99ba4070e4133f5c1 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 12 Oct 2022 12:12:13 -0600 Subject: [PATCH 07/10] feat: allow public did + multi-use conn invites Signed-off-by: Micah Peltier --- .../protocols/connections/v1_0/manager.py | 146 ++++++++++-------- 1 file changed, 78 insertions(+), 68 deletions(-) diff --git a/aries_cloudagent/protocols/connections/v1_0/manager.py b/aries_cloudagent/protocols/connections/v1_0/manager.py index d937b7ecb2..6f5f07a861 100644 --- a/aries_cloudagent/protocols/connections/v1_0/manager.py +++ b/aries_cloudagent/protocols/connections/v1_0/manager.py @@ -127,10 +127,42 @@ async def create_invitation( or_default=True, ) image_url = self.profile.context.settings.get("image_url") + invitation = None + connection = None + + invitation_mode = ConnRecord.INVITATION_MODE_ONCE + if multi_use: + invitation_mode = ConnRecord.INVITATION_MODE_MULTI if not my_label: my_label = self.profile.settings.get("default_label") + accept = ( + ConnRecord.ACCEPT_AUTO + if ( + auto_accept + or ( + auto_accept is None + and self.profile.settings.get("debug.auto_accept_requests") + ) + ) + else ConnRecord.ACCEPT_MANUAL + ) + + if recipient_keys: + # TODO: register recipient keys for relay + # TODO: check that recipient keys are in wallet + invitation_key = recipient_keys[0] # TODO first key appropriate? + else: + # Create and store new invitation key + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + invitation_signing_key = await wallet.create_signing_key( + key_type=KeyType.ED25519 + ) + invitation_key = invitation_signing_key.verkey + recipient_keys = [invitation_key] + if public: if not self.profile.settings.get("public_invites"): raise ConnectionManagerError("Public invitations are not enabled") @@ -143,89 +175,64 @@ async def create_invitation( "Cannot create public invitation with no public DID" ) - if multi_use: - raise ConnectionManagerError( - "Cannot use public and multi_use at the same time" - ) - - if metadata: - raise ConnectionManagerError( - "Cannot use public and set metadata at the same time" - ) - # FIXME - allow ledger instance to format public DID with prefix? invitation = ConnectionInvitation( label=my_label, did=f"did:sov:{public_did.did}", image_url=image_url ) + connection = ConnRecord( # create connection record + invitation_key=public_did.verkey, + invitation_msg_id=invitation._id, + invitation_mode=invitation_mode, + their_role=ConnRecord.Role.REQUESTER.rfc23, + state=ConnRecord.State.INVITATION.rfc23, + accept=accept, + alias=alias, + connection_protocol=CONN_PROTO, + ) + + async with self.profile.session() as session: + await connection.save(session, reason="Created new invitation") + # Add mapping for multitenant relaying. # Mediation of public keys is not supported yet await self._route_manager.route_public_did(self.profile, public_did.verkey) - return None, invitation - - invitation_mode = ConnRecord.INVITATION_MODE_ONCE - if multi_use: - invitation_mode = ConnRecord.INVITATION_MODE_MULTI - - if recipient_keys: - # TODO: register recipient keys for relay - # TODO: check that recipient keys are in wallet - invitation_key = recipient_keys[0] # TODO first key appropriate? else: - # Create and store new invitation key + # Create connection record + connection = ConnRecord( + invitation_key=invitation_key, # TODO: determine correct key to use + their_role=ConnRecord.Role.REQUESTER.rfc160, + state=ConnRecord.State.INVITATION.rfc160, + accept=accept, + invitation_mode=invitation_mode, + alias=alias, + connection_protocol=CONN_PROTO, + ) async with self.profile.session() as session: - wallet = session.inject(BaseWallet) - invitation_signing_key = await wallet.create_signing_key( - key_type=KeyType.ED25519 - ) - invitation_key = invitation_signing_key.verkey - recipient_keys = [invitation_key] + await connection.save(session, reason="Created new invitation") - accept = ( - ConnRecord.ACCEPT_AUTO - if ( - auto_accept - or ( - auto_accept is None - and self.profile.settings.get("debug.auto_accept_requests") - ) + await self._route_manager.route_invitation( + self.profile, connection, mediation_record + ) + routing_keys, my_endpoint = await self._route_manager.routing_info( + self.profile, + my_endpoint or cast(str, self.profile.settings.get("default_endpoint")), + mediation_record, ) - else ConnRecord.ACCEPT_MANUAL - ) - - # Create connection record - connection = ConnRecord( - invitation_key=invitation_key, # TODO: determine correct key to use - their_role=ConnRecord.Role.REQUESTER.rfc160, - state=ConnRecord.State.INVITATION.rfc160, - accept=accept, - invitation_mode=invitation_mode, - alias=alias, - connection_protocol=CONN_PROTO, - ) - async with self.profile.session() as session: - await connection.save(session, reason="Created new invitation") - await self._route_manager.route_invitation( - self.profile, connection, mediation_record - ) - routing_keys, my_endpoint = await self._route_manager.routing_info( - self.profile, - my_endpoint or cast(str, self.profile.settings.get("default_endpoint")), - mediation_record, - ) + # Create connection invitation message + # Note: Need to split this into two stages + # to support inbound routing of invites + # Would want to reuse create_did_document and convert the result + invitation = ConnectionInvitation( + label=my_label, + recipient_keys=recipient_keys, + routing_keys=routing_keys, + endpoint=my_endpoint, + image_url=image_url, + ) - # Create connection invitation message - # Note: Need to split this into two stages to support inbound routing of invites - # Would want to reuse create_did_document and convert the result - invitation = ConnectionInvitation( - label=my_label, - recipient_keys=recipient_keys, - routing_keys=routing_keys, - endpoint=my_endpoint, - image_url=image_url, - ) async with self.profile.session() as session: await connection.attach_invitation(session, invitation) @@ -531,6 +538,9 @@ async def receive_request( their_role=ConnRecord.Role.REQUESTER.rfc160, ) if not connection: + if not self.profile.settings.get("requests_through_public_did"): + raise ConnectionManagerError("Unsolicited connection requests to " + "public DID is not enabled") connection = ConnRecord() connection.invitation_key = connection_key connection.my_did = my_info.did From e640a4e61957b225315396e09c1c5a4a1fbdf280 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 12 Oct 2022 12:13:19 -0600 Subject: [PATCH 08/10] tests: check new flags, conn manager changes Signed-off-by: Micah Peltier --- .../connections/v1_0/tests/test_manager.py | 113 +++++++++++++----- 1 file changed, 80 insertions(+), 33 deletions(-) diff --git a/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py index d7c3836236..15d6e18454 100644 --- a/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py @@ -35,6 +35,7 @@ from ....discovery.v2_0.manager import V20DiscoveryMgr from ..manager import ConnectionManager, ConnectionManagerError +from .. import manager as test_module from ..messages.connection_invitation import ConnectionInvitation from ..messages.connection_request import ConnectionRequest from ..messages.connection_response import ConnectionResponse @@ -112,21 +113,6 @@ async def setUp(self): self.manager = ConnectionManager(self.profile) assert self.manager.profile - async def test_create_invitation_public_and_multi_use_fails(self): - self.context.update_settings({"public_invites": True}) - with async_mock.patch.object( - InMemoryWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did: - mock_wallet_get_public_did.return_value = DIDInfo( - self.test_did, - self.test_verkey, - None, - method=DIDMethod.SOV, - key_type=KeyType.ED25519, - ) - with self.assertRaises(ConnectionManagerError): - await self.manager.create_invitation(public=True, multi_use=True) - async def test_create_invitation_non_multi_use_invitation_fails_on_reuse(self): connect_record, connect_invite = await self.manager.create_invitation() @@ -174,7 +160,7 @@ async def test_create_invitation_public(self): public=True, my_endpoint="testendpoint" ) - assert connect_record is None + assert connect_record assert connect_invite.did.endswith(self.test_did) self.route_manager.route_public_did.assert_called_once_with( self.profile, self.test_verkey @@ -266,23 +252,6 @@ async def test_create_invitation_metadata_assigned(self): assert await record.metadata_get_all(session) == {"hello": "world"} - async def test_create_invitation_public_and_metadata_fails(self): - self.context.update_settings({"public_invites": True}) - with async_mock.patch.object( - InMemoryWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did: - mock_wallet_get_public_did.return_value = DIDInfo( - self.test_did, - self.test_verkey, - None, - method=DIDMethod.SOV, - key_type=KeyType.ED25519, - ) - with self.assertRaises(ConnectionManagerError): - await self.manager.create_invitation( - public=True, metadata={"hello": "world"} - ) - async def test_create_invitation_multi_use_metadata_transfers_to_connection(self): async with self.profile.session() as session: connect_record, _ = await self.manager.create_invitation( @@ -643,7 +612,84 @@ async def test_receive_request_public_did_oob_invite(self): self.profile, mock_request ) + async def test_receive_request_public_did_unsolicited_fails(self): + async with self.profile.session() as session: + mock_request = async_mock.MagicMock() + mock_request.connection = async_mock.MagicMock() + mock_request.connection.did = self.test_did + mock_request.connection.did_doc = async_mock.MagicMock() + mock_request.connection.did_doc.did = self.test_did + + receipt = MessageReceipt( + recipient_did=self.test_did, recipient_did_public=True + ) + await session.wallet.create_local_did( + method=DIDMethod.SOV, + key_type=KeyType.ED25519, + seed=None, + did=self.test_did, + ) + + self.context.update_settings({"public_invites": True}) + with self.assertRaises( + ConnectionManagerError + ), async_mock.patch.object( + ConnRecord, "connection_id", autospec=True + ), async_mock.patch.object( + ConnRecord, "save", autospec=True + ) as mock_conn_rec_save, async_mock.patch.object( + ConnRecord, "attach_request", autospec=True + ) as mock_conn_attach_request, async_mock.patch.object( + ConnRecord, "retrieve_by_id", autospec=True + ) as mock_conn_retrieve_by_id, async_mock.patch.object( + ConnRecord, "retrieve_request", autospec=True + ), async_mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", async_mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id: + mock_conn_retrieve_by_invitation_msg_id.return_value = None + conn_rec = await self.manager.receive_request(mock_request, receipt) + async def test_receive_request_public_did_conn_invite(self): + async with self.profile.session() as session: + mock_request = async_mock.MagicMock() + mock_request.connection = async_mock.MagicMock() + mock_request.connection.did = self.test_did + mock_request.connection.did_doc = async_mock.MagicMock() + mock_request.connection.did_doc.did = self.test_did + + receipt = MessageReceipt( + recipient_did=self.test_did, recipient_did_public=True + ) + await session.wallet.create_local_did( + method=DIDMethod.SOV, + key_type=KeyType.ED25519, + seed=None, + did=self.test_did, + ) + + mock_connection_record = async_mock.MagicMock() + mock_connection_record.save = async_mock.CoroutineMock() + mock_connection_record.attach_request = async_mock.CoroutineMock() + + + self.context.update_settings({"public_invites": True}) + with async_mock.patch.object( + ConnRecord, "connection_id", autospec=True + ), async_mock.patch.object( + ConnRecord, "save", autospec=True + ) as mock_conn_rec_save, async_mock.patch.object( + ConnRecord, "attach_request", autospec=True + ) as mock_conn_attach_request, async_mock.patch.object( + ConnRecord, "retrieve_by_id", autospec=True + ) as mock_conn_retrieve_by_id, async_mock.patch.object( + ConnRecord, "retrieve_request", autospec=True + ), async_mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", async_mock.CoroutineMock(return_value=mock_connection_record) + ) as mock_conn_retrieve_by_invitation_msg_id: + conn_rec = await self.manager.receive_request(mock_request, receipt) + assert conn_rec + + async def test_receive_request_public_did_unsolicited(self): async with self.profile.session() as session: mock_request = async_mock.MagicMock() mock_request.connection = async_mock.MagicMock() @@ -662,6 +708,7 @@ async def test_receive_request_public_did_conn_invite(self): ) self.context.update_settings({"public_invites": True}) + self.context.update_settings({"requests_through_public_did": True}) with async_mock.patch.object( ConnRecord, "connection_id", autospec=True ), async_mock.patch.object( From 93cbd2a22ccb5ca9b34735ef8744f4ab6a7bd756 Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Mon, 28 Nov 2022 11:55:48 -0700 Subject: [PATCH 09/10] fix: save metadata on OOB invitation with public DID Signed-off-by: Micah Peltier --- aries_cloudagent/protocols/out_of_band/v1_0/manager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py index 30e51e1e99..7737891d3a 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py @@ -258,6 +258,12 @@ async def create_invitation( async with self.profile.session() as session: await conn_rec.save(session, reason="Created new invitation") await conn_rec.attach_invitation(session, invi_msg) + + await conn_rec.attach_invitation(session, invi_msg) + + if metadata: + for key, value in metadata.items(): + await conn_rec.metadata_set(session, key, value) else: our_service = ServiceDecorator( recipient_keys=[our_recipient_key], From 8d370c1fd0d544b846d8fb9193f3a0ad0bcb906b Mon Sep 17 00:00:00 2001 From: Micah Peltier Date: Wed, 14 Dec 2022 10:36:19 -0700 Subject: [PATCH 10/10] fix: DIDMethod refs in tests Signed-off-by: Micah Peltier --- .../protocols/connections/v1_0/tests/test_manager.py | 8 ++++---- .../protocols/didexchange/v1_0/tests/test_manager.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py index 6b0b6171f3..9d651c7f87 100644 --- a/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/connections/v1_0/tests/test_manager.py @@ -658,8 +658,8 @@ async def test_receive_request_public_did_conn_invite(self): recipient_did=self.test_did, recipient_did_public=True ) await session.wallet.create_local_did( - method=DIDMethod.SOV, - key_type=KeyType.ED25519, + method=SOV, + key_type=ED25519, seed=None, did=self.test_did, ) @@ -699,8 +699,8 @@ async def test_receive_request_public_did_unsolicited(self): recipient_did=self.test_did, recipient_did_public=True ) await session.wallet.create_local_did( - method=DIDMethod.SOV, - key_type=KeyType.ED25519, + method=SOV, + key_type=ED25519, seed=None, did=self.test_did, ) diff --git a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py index f912290daa..05641b86a4 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py @@ -988,8 +988,8 @@ async def test_receive_request_implicit_public_did_not_enabled(self): await mediation_record.save(session) await session.wallet.create_local_did( - method=DIDMethod.SOV, - key_type=KeyType.ED25519, + method=SOV, + key_type=ED25519, seed=None, did=TestConfig.test_did, ) @@ -1051,8 +1051,8 @@ async def test_receive_request_implicit_public_did(self): await mediation_record.save(session) await session.wallet.create_local_did( - method=DIDMethod.SOV, - key_type=KeyType.ED25519, + method=SOV, + key_type=ED25519, seed=None, did=TestConfig.test_did, )