Example #1
0
    async def find_inbound_connection(
            self, receipt: MessageReceipt) -> ConnectionRecord:
        """
        Deserialize an incoming message and further populate the request context.

        Args:
            receipt: The message receipt

        Returns:
            The `ConnectionRecord` associated with the expanded message, if any

        """

        cache_key = None
        connection = None
        resolved = False

        if receipt.sender_verkey and receipt.recipient_verkey:
            cache_key = (f"connection_by_verkey::{receipt.sender_verkey}"
                         f"::{receipt.recipient_verkey}")
            cache: BaseCache = await self.context.inject(BaseCache,
                                                         required=False)
            if cache:
                async with cache.acquire(cache_key) as entry:
                    if entry.result:
                        cached = entry.result
                        receipt.sender_did = cached["sender_did"]
                        receipt.recipient_did_public = cached[
                            "recipient_did_public"]
                        receipt.recipient_did = cached["recipient_did"]
                        connection = await ConnectionRecord.retrieve_by_id(
                            self.context, cached["id"])
                    else:
                        connection = await self.resolve_inbound_connection(
                            receipt)
                        if connection:
                            cache_val = {
                                "id":
                                connection.connection_id,
                                "sender_did":
                                receipt.sender_did,
                                "recipient_did":
                                receipt.recipient_did,
                                "recipient_did_public":
                                receipt.recipient_did_public,
                            }
                            await entry.set_result(cache_val, 3600)
                        resolved = True

        if not connection and not resolved:
            connection = await self.resolve_inbound_connection(receipt)
        return connection
Example #2
0
    async def test_handle(self):
        self.context.message_receipt = MessageReceipt(
            recipient_verkey=TEST_VERKEY)
        handler = test_module.ForwardHandler()

        responder = MockResponder()
        with async_mock.patch.object(
                test_module, "RoutingManager",
                autospec=True) as mock_mgr, async_mock.patch.object(
                    test_module, "ConnectionManager",
                    autospec=True) as mock_connection_mgr:
            mock_mgr.return_value.get_recipient = async_mock.CoroutineMock(
                return_value=RouteRecord(connection_id="dummy"))
            mock_connection_mgr.return_value.get_connection_targets = (
                async_mock.CoroutineMock(return_value=[
                    ConnectionTarget(recipient_keys=["recip_key"], )
                ]))

            await handler.handle(self.context, responder)

            messages = responder.messages
            assert len(messages) == 1
            (result, target) = messages[0]
            assert json.loads(result) == self.context.message.msg
            assert target["connection_id"] == "dummy"
Example #3
0
async def session():
    """Fixture for session used in tests."""
    # pylint: disable=W0621
    context = RequestContext.test_context()
    context.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY)
    context.connection_record = ConnRecord(connection_id=TEST_CONN_ID)
    yield await context.session()
Example #4
0
    async def resolve_inbound_connection(
            self, receipt: MessageReceipt) -> ConnectionRecord:
        """
        Populate the receipt DID information and find the related `ConnectionRecord`.

        Args:
            receipt: The message receipt

        Returns:
            The `ConnectionRecord` associated with the expanded message, if any

        """

        if receipt.sender_verkey:
            try:
                receipt.sender_did = await self.find_did_for_key(
                    receipt.sender_verkey)
            except StorageNotFoundError:
                self._logger.warning(
                    "No corresponding DID found for sender verkey: %s",
                    receipt.sender_verkey,
                )

        if receipt.recipient_verkey:
            try:
                wallet: BaseWallet = await self.context.inject(BaseWallet)
                my_info = await wallet.get_local_did_for_verkey(
                    receipt.recipient_verkey)
                receipt.recipient_did = my_info.did
                if "public" in my_info.metadata and my_info.metadata[
                        "public"] is True:
                    receipt.recipient_did_public = True
            except InjectorError:
                self._logger.warning(
                    "Cannot resolve recipient verkey, no wallet defined by "
                    "context: %s",
                    receipt.recipient_verkey,
                )
            except WalletNotFoundError:
                self._logger.warning(
                    "No corresponding DID found for recipient verkey: %s",
                    receipt.recipient_verkey,
                )

        return await self.find_connection(receipt.sender_did,
                                          receipt.recipient_did,
                                          receipt.recipient_verkey, True)
Example #5
0
 async def setUp(self):
     self.context = RequestContext(
         base_context=InjectionContext(enforce_typing=False)
     )
     self.context.connection_ready = True
     self.context.connection_record = ConnectionRecord(connection_id="conn-id")
     self.context.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY)
     self.context.injector.bind_instance(BaseStorage, BasicStorage())
 async def test_ping_not_ready(self, request_context):
     request_context.message_receipt = MessageReceipt()
     request_context.message = Ping(response_requested=False)
     request_context.connection_ready = False
     handler = PingHandler()
     responder = MockResponder()
     assert not await handler.handle(request_context, responder)
     messages = responder.messages
     assert len(messages) == 0
 async def setUp(self):
     self.context = RequestContext(base_context=InjectionContext(
         enforce_typing=False))
     self.context.message_receipt = MessageReceipt(
         sender_verkey=TEST_VERKEY)
     self.storage = BasicStorage()
     self.context.injector.bind_instance(BaseStorage, self.storage)
     self.manager = RoutingManager(self.context)
     assert self.manager.context
 async def test_ping(self, request_context):
     request_context.message_receipt = MessageReceipt()
     request_context.message = Ping(response_requested=False)
     request_context.settings["debug.monitor_ping"] = True
     request_context.connection_ready = True
     handler = PingHandler()
     responder = MockResponder()
     await handler.handle(request_context, responder)
     messages = responder.messages
     assert len(messages) == 0
 async def test_ping_response(self, request_context):
     request_context.message_receipt = MessageReceipt()
     request_context.message = Ping(response_requested=True)
     request_context.connection_ready = True
     handler = PingHandler()
     responder = MockResponder()
     await handler.handle(request_context, responder)
     messages = responder.messages
     assert len(messages) == 1
     result, target = messages[0]
     assert isinstance(result, PingResponse)
     assert result._thread_id == request_context.message._thread_id
     assert not target
Example #10
0
 async def test_problem_report(self, request_context):
     request_context.message_receipt = MessageReceipt()
     request_context.message = ProblemReport()
     request_context.connection_ready = True
     handler = ProblemReportHandler()
     responder = MockResponder()
     await handler.handle(request_context, responder)
     messages = responder.messages
     assert len(messages) == 0
     hooks = responder.webhooks
     assert len(hooks) == 1
     assert hooks[0] == ("problem_report",
                         request_context.message.serialize())
    async def test_handle_cannot_resolve_recipient(self):
        self.context.message_receipt = MessageReceipt(recipient_verkey=TEST_VERKEY)
        handler = test_module.ForwardHandler()

        responder = MockResponder()
        with async_mock.patch.object(
            test_module, "RoutingManager", autospec=True
        ) as mock_mgr:
            mock_mgr.return_value.get_recipient = async_mock.CoroutineMock(
                side_effect=test_module.RoutingManagerError()
            )

            await handler.handle(self.context, responder)

            messages = responder.messages
            assert not messages
Example #12
0
def request_context() -> RequestContext:
    ctx = RequestContext()
    ctx.message_receipt = MessageReceipt()
    yield ctx
 async def test_handle_receipt_no_recipient_verkey(self):
     self.context.message_receipt = MessageReceipt()
     handler = test_module.ForwardHandler()
     with self.assertRaises(HandlerException):
         await handler.handle(self.context, None)
Example #14
0
def manager() -> RoutingManager:
    ctx = RequestContext()
    ctx.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY)
    ctx.injector.bind_instance(BaseStorage, BasicStorage())
    return RoutingManager(ctx)
Example #15
0
def request_context() -> RequestContext:
    ctx = RequestContext()
    ctx.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY)
    ctx.injector.bind_instance(BaseStorage, BasicStorage())
    yield ctx