async def test_agents_can_talk_both_ways(alice, bob):
    logger = logging.getLogger(__name__)
    await connect_alice_and_bob(alice, bob)

    alice.triggered = asyncio.Event()
    bob.triggered = asyncio.Event()

    @alice.route('test/protocol/1.0/test')
    async def alice_msg_handle(msg, alice):
        logger.debug('Alice got: %s', msg)
        alice.triggered.set()

    @bob.route('test/protocol/1.0/test')
    async def bob_msg_handle(msg, bob):
        logger.debug('Bob got: %s', msg)
        bob.triggered.set()

    logger.debug('Packing message to Alice: %s, %s', alice.did, alice.vk)
    await bob.send(
        Message({'@type': 'test/protocol/1.0/test'}),
        alice.vk,
        to_did=alice.did,
    )

    await alice.send(
        Message({'@type': 'test/protocol/1.0/test'}),
        bob.vk,
        to_did=bob.did,
    )

    await asyncio.wait_for(alice.triggered.wait(), 1)
    assert alice.triggered.is_set()
    await asyncio.wait_for(bob.triggered.wait(), 1)
    assert bob.triggered.is_set()
Esempio n. 2
0
async def test_simple_messaging(config, agent):
    """ Show simple messages being passed to and from tested agent """

    _my_did, my_vk, their_did, their_vk = \
        await static_connection(agent, config['static_connection'])

    expected_schema = MessageSchema({
        '@type': 'test/protocol/1.0/test',
        '@id': str,
        'msg': 'pong'
    })

    ping = Message({'@type': 'test/protocol/1.0/test', 'msg': 'ping'})
    print('Sending message:', ping.pretty_print())
    await agent.send(ping, their_vk, to_did=their_did, from_vk=my_vk)

    pong = await agent.expect_message('test/protocol/1.0/test', 1)
    print('Received message:', pong.pretty_print())

    assert pong.mtc[CONFIDENTIALITY | INTEGRITY | AUTHENTICATED_ORIGIN
                    | DESERIALIZE_OK]
    assert not pong.mtc[NONREPUDIATION]
    assert pong.mtc.ad['sender_vk'] == their_vk
    assert pong.mtc.ad['recip_vk'] == my_vk

    assert expected_schema.validate(pong)
    assert agent.ok()
async def test_module_routing_many():
    """ Test that routing to a module works. """
    dispatcher = Dispatcher()
    dispatcher.called_module = None
    routed_event = asyncio.Event()

    class TestModule1(Module):
        DOC_URI = ''
        PROTOCOL = 'test_protocol'
        VERSION = '1.0'

        async def testing_type(self, msg, *args, **kwargs):
            kwargs['dispatcher'].called_module = 1
            kwargs['event'].set()

    class TestModule2(Module):
        DOC_URI = ''
        PROTOCOL = 'test_protocol'
        VERSION = '2.0'

        async def testing_type(self, msg, *args, **kwargs):
            kwargs['dispatcher'].called_module = 2
            kwargs['event'].set()

    dispatcher.route_module(TestModule1())
    dispatcher.route_module(TestModule2())

    test_msg = Message({
        '@type': 'test_protocol/1.0/testing_type',
        'test': 'test'
    })
    await dispatcher.dispatch(test_msg,
                              event=routed_event,
                              dispatcher=dispatcher)
    await routed_event.wait()

    assert routed_event.is_set()
    assert dispatcher.called_module == 1

    routed_event.clear()

    test_msg = Message({
        '@type': 'test_protocol/2.0/testing_type',
        'test': 'test'
    })
    await dispatcher.dispatch(test_msg,
                              event=routed_event,
                              dispatcher=dispatcher)
    await routed_event.wait()

    assert routed_event.is_set()
    assert dispatcher.called_module == 2
Esempio n. 4
0
def build_invite(label: str, connection_key: str, endpoint: str) -> str:
    msg = Message({
        '@type': INVITE,
        'label': label,
        'recipientKeys': [connection_key],
        'serviceEndpoint': endpoint,
        'routingKeys': []
    })

    b64_invite = base64.urlsafe_b64encode(bytes(msg.serialize(),
                                                'utf-8')).decode('ascii')

    return '{}?c_i={}'.format(endpoint, b64_invite)
async def test_module_routing_explicit_def():
    """ Test that routing to a module works. """

    dispatcher = Dispatcher()
    called_event = asyncio.Event()

    class TestModule(Module):
        DOC_URI = ''
        PROTOCOL = 'test_protocol'
        VERSION = '1.0'

        routes = {}

        @route_def(routes, 'test_protocol/1.0/testing_type')
        async def route_gets_called(self, msg, **kwargs):
            kwargs['event'].set()

    mod = TestModule()
    dispatcher.route_module(mod)

    test_msg = Message({
        '@type': 'test_protocol/1.0/testing_type',
        'test': 'test'
    })
    await dispatcher.dispatch(test_msg, event=called_event)

    assert called_event.is_set()
Esempio n. 6
0
def build_request(label: str, my_did: str, my_vk: str,
                  endpoint: str) -> Message:
    """ Construct a connection request. """
    return Message({
        '@type': REQUEST,
        '@id': str(uuid.uuid4()),
        'label': label,
        'connection': {
            'DID': my_did,
            'DIDDoc': {
                "@context":
                "https://w3id.org/did/v1",
                "id":
                my_did,
                "publicKey": [{
                    "id": my_did + "#keys-1",
                    "type": "Ed25519VerificationKey2018",
                    "controller": my_did,
                    "publicKeyBase58": my_vk
                }],
                "service": [{
                    "id": my_did + ";indy",
                    "type": "IndyAgent",
                    "recipientKeys": [my_vk],
                    "routingKeys": [],
                    "serviceEndpoint": endpoint,
                }],
            }
        }
    })
Esempio n. 7
0
def build_response(req_id: str, my_did: str, my_vk: str,
                   endpoint: str) -> Message:
    return Message({
        '@type': RESPONSE,
        '@id': str(uuid.uuid4()),
        '~thread': {
            'thid': req_id,
            'sender_order': 0
        },
        'connection': {
            'DID': my_did,
            'DIDDoc': {
                "@context":
                "https://w3id.org/did/v1",
                "id":
                my_did,
                "publicKey": [{
                    "id": my_did + "#keys-1",
                    "type": "Ed25519VerificationKey2018",
                    "controller": my_did,
                    "publicKeyBase58": my_vk
                }],
                "service": [{
                    "id": my_did + ";indy",
                    "type": "IndyAgent",
                    "recipientKeys": [my_vk],
                    "routingKeys": [],
                    "serviceEndpoint": endpoint,
                }],
            }
        }
    })
Esempio n. 8
0
async def packed_message_anonymous(wallet_handle, loopback_relationship):
    """ Get a packed message """
    _, a_vk = loopback_relationship
    yield await crypto.pack_message(
        wallet_handle,
        Message({'@type': 'test/protocol/1.0/test'}).serialize(),
        [a_vk]
    )
Esempio n. 9
0
def parse_invite(invite_url: str) -> Message:
    """ Parse an invite url """
    matches = re.match('(.+)?c_i=(.+)', invite_url)
    assert matches, 'Improperly formatted invite url!'

    invite_msg = Message.deserialize(
        base64.urlsafe_b64decode(matches.group(2)).decode('ascii'))

    INVITE_SCHEMA.validate(invite_msg)

    return invite_msg
def test_valid_message_no_doc_uri():
    """ Test basic message creation and member access. """
    id_ = '12345'

    msg = Message({'@type': TEST_TYPE_NO_DOC, '@id': id_})
    assert msg.type == TEST_TYPE_NO_DOC
    assert msg.id == id_
    assert msg.doc_uri == ''
    assert msg.protocol == 'protocol'
    assert msg.version == '1.0'
    assert msg.short_type == 'test'
    assert msg.version_info == Semver(1, 0, 0)
def test_message_serialization():
    """ Test deserializing and serializing a message """
    msg = Message.deserialize('{"@type": "%s"}' % TEST_TYPE)
    assert msg.type == TEST_TYPE
    assert msg.id is not None
    assert msg.doc_uri == 'test_type/'
    assert msg.protocol == 'protocol'
    assert msg.version == '1.0'
    assert msg.short_type == 'test'
    assert msg.version_info == Semver(1, 0, 0)

    assert msg.serialize() == \
        '{"@type": "%s", "@id": "%s"}' % (TEST_TYPE, msg.id)
Esempio n. 12
0
async def test_send(conductor, loopback_relationship):
    """ Test that conductor can send a message """
    a_did, a_vk = loopback_relationship
    send_task = create_task(conductor.send(
        Message({'@type': 'test/protocol/1.0/test'}),
        a_vk,
        to_did=a_did,
        from_key=a_vk
    ))
    conn = await conductor.connection_queue.get()
    await conductor.message_reader(conn)
    msg = await asyncio.wait_for(conductor.recv(), 5)
    assert msg.type == 'test/protocol/1.0/test'
    send_task.cancel()
Esempio n. 13
0
async def test_unpack_plaintext(conductor):
    """ Test unpack behavior for plaintext """
    msg = await conductor.unpack(
        Message({'@type': 'test/protocol/1.0/test'}).serialize()
    )

    assert msg.mtc[DESERIALIZE_OK]
    assert not msg.mtc[
        AUTHENTICATED_ORIGIN |
        CONFIDENTIALITY |
        INTEGRITY |
        LIMITED_SCOPE |
        NONREPUDIATION
    ]
async def test_agents_can_talk(alice, bob):
    logger = logging.getLogger(__name__)
    await connect_alice_and_bob(alice, bob)

    alice.triggered = asyncio.Event()

    @alice.route('test/protocol/1.0/test')
    async def alice_msg_handle(msg, alice):
        alice.triggered.set()

    await bob.send(Message({'@type': 'test/protocol/1.0/test'}),
                   alice.vk,
                   to_did=alice.did)

    assert alice.triggered.is_set()
async def test_module_routing_no_matching_version():
    """ Test that routing to a module works. """
    dispatcher = Dispatcher()
    called_event = asyncio.Event()

    class TestModule(Module):
        DOC_URI = ''
        PROTOCOL = 'test_protocol'
        VERSION = '1.0'

        async def testing_type(self, msg, *args, **kwargs):
            kwargs['event'].set()

    mod = TestModule()
    dispatcher.route_module(mod)

    test_msg = Message({
        '@type': 'test_protocol/3.0/testing_type',
        'test': 'test'
    })
    with pytest.raises(NoRegisteredRouteException):
        await dispatcher.dispatch(test_msg, event=called_event)
async def test_module_routing_minor_version_different():
    """ Test that routing to a module works. """
    dispatcher = Dispatcher()
    called_event = asyncio.Event()

    class TestModule(Module):
        DOC_URI = ''
        PROTOCOL = 'test_protocol'
        VERSION = '1.4'

        async def testing_type(self, msg, *args, **kwargs):
            kwargs['event'].set()

    mod = TestModule()
    dispatcher.route_module(mod)

    test_msg = Message({
        '@type': 'test_protocol/1.0/testing_type',
        'test': 'test'
    })
    await dispatcher.dispatch(test_msg, event=called_event)

    assert called_event.is_set()
 def validate(self, msg: Message):
     """ Validate message, storing defaults inserted by validation. """
     msg.update(self._schema.validate(dict(msg)))
     return msg
def test_bad_message_type(type_str):
    """ Test bad message types raise InvalidMessage """
    with pytest.raises(InvalidMessage):
        Message({'@type': type_str})
def test_bad_message_id(id_):
    """ Test message with bad message id """
    with pytest.raises(InvalidMessage):
        Message({'@type': TEST_TYPE, '@id': id_})
def test_id_generated():
    """ Test ID is generated for message where one is not specified. """
    msg = Message({'@type': TEST_TYPE})
    assert msg.type == TEST_TYPE
    assert msg.id is not None