Example #1
0
def test_bob_can_follow_treasure_map_even_if_he_only_knows_of_one_node(
        enacted_federated_policy, federated_ursulas, certificates_tempdir):
    """
    Similar to above, but this time, we'll show that if Bob can connect to a single node, he can
    learn enough to follow the TreasureMap.

    Also, we'll get the TreasureMap from the hrac alone (ie, not via a side channel).
    """

    from nucypher.characters.lawful import Bob

    bob = Bob(network_middleware=MockRestMiddleware(),
              domain=TEMPORARY_DOMAIN,
              start_learning_now=False,
              abort_on_learning_error=True,
              federated_only=True)

    # Again, let's assume that he received the TreasureMap via a side channel.
    hrac, treasure_map = enacted_federated_policy.hrac(
    ), enacted_federated_policy.treasure_map
    map_id = treasure_map.public_id()
    bob.treasure_maps[map_id] = treasure_map

    # Now, let's create a scenario in which Bob knows of only one node.
    assert len(bob.known_nodes) == 0
    first_ursula = list(federated_ursulas).pop(0)
    bob.remember_node(first_ursula)
    assert len(bob.known_nodes) == 1

    # This time, when he follows the TreasureMap...
    unknown_nodes, known_nodes = bob.peek_at_treasure_map(map_id=map_id)

    # Bob already knew about one node; the rest are unknown.
    assert len(unknown_nodes) == len(treasure_map) - 1

    # He needs to actually follow the treasure map to get the rest.
    bob.follow_treasure_map(map_id=map_id)

    # The nodes in the learning loop are now his top target, but he's not learning yet.
    assert not bob._learning_task.running

    # ...so he hasn't learned anything (ie, Bob still knows of just one node).
    assert len(bob.known_nodes) == 1

    # Now, we'll start his learning loop.
    bob.start_learning_loop()

    # ...and block until the unknown_nodes have all been found.
    d = threads.deferToThread(bob.block_until_specific_nodes_are_known,
                              unknown_nodes)
    yield d

    # ...and he now has no more unknown_nodes.
    assert len(bob.known_nodes) == len(treasure_map)
    bob.disenchant()
Example #2
0
def make_bob_control(drone_bob: Bob, teacher_node: Ursula):
    bob_control = Flask('bob-control')

    teacher_node.verify_node(drone_bob.network_middleware)
    drone_bob.remember_node(teacher_node)
    drone_bob.start_learning_loop(now=True)

    @bob_control.route('/join_policy', methods=['POST'])
    def join_policy():
        """
        Character control endpoint for joining a policy on the network.

        This is an unfinished endpoint. You're probably looking for retrieve.
        """
        try:
            request_data = json.loads(request.data)

            label = b64decode(request_data['label'])
            alice_pubkey_sig = bytes.fromhex(
                request_data['alice_signing_pubkey'])
        except (KeyError, JSONDecodeError) as e:
            return Response(e, status=400)

        drone_bob.join_policy(label=label, alice_pubkey_sig=alice_pubkey_sig)

        return Response('Policy joined!', status=200)

    @bob_control.route('/retrieve', methods=['POST'])
    def retrieve():
        """
        Character control endpoint for re-encrypting and decrypting policy
        data.
        """
        try:
            request_data = json.loads(request.data)

            label = b64decode(request_data['label'])
            policy_pubkey_enc = bytes.fromhex(
                request_data['policy_encrypting_pubkey'])
            alice_pubkey_sig = bytes.fromhex(
                request_data['alice_signing_pubkey'])
            datasource_pubkey_sig = bytes.fromhex(
                request_data['datasource_signing_pubkey'])
            message_kit = b64decode(request_data['message_kit'])
        except (KeyError, JSONDecodeError) as e:
            return Response(e, status=400)

        policy_pubkey_enc = UmbralPublicKey.from_bytes(policy_pubkey_enc)
        alice_pubkey_sig = UmbralPublicKey.from_bytes(alice_pubkey_sig)
        message_kit = UmbralMessageKit.from_bytes(message_kit)

        data_source = DataSource.from_public_keys(policy_pubkey_enc,
                                                  datasource_pubkey_sig,
                                                  label=label)
        drone_bob.join_policy(label=label, alice_pubkey_sig=alice_pubkey_sig)
        plaintexts = drone_bob.retrieve(message_kit=message_kit,
                                        data_source=data_source,
                                        alice_verifying_key=alice_pubkey_sig)

        plaintexts = [
            b64encode(plaintext).decode() for plaintext in plaintexts
        ]
        response_data = {
            'result': {
                'plaintext': plaintexts,
            }
        }

        return Response(json.dumps(response_data), status=200)

    return bob_control