Пример #1
0
import os.path

from flask import Flask, render_template
from twisted.logger import globalLogPublisher

from hendrix.deploy.base import HendrixDeploy
from hendrix.experience import hey_joe
from nucypher.characters.base import Character
from nucypher.characters.lawful import Ursula
from nucypher.config.constants import GLOBAL_DOMAIN
from nucypher.network.middleware import RestMiddleware
from nucypher.network.nodes import FleetStateTracker
from nucypher.utilities.logging import SimpleObserver

websocket_service = hey_joe.WebSocketService("127.0.0.1", 9000)
globalLogPublisher.addObserver(SimpleObserver())

known_node = Ursula.from_seed_and_stake_info(seed_uri=sys.argv[1],
                                             federated_only=True,
                                             minimum_stake=0)

rest_app = Flask("fleet-monitor", root_path=os.path.dirname(__file__))


class MonitoringTracker(FleetStateTracker):
    def record_fleet_state(self, *args, **kwargs):
        new_state_or_none = super(MonitoringTracker,
                                  self).record_fleet_state(*args, **kwargs)
        if new_state_or_none:
            checksum, new_state = new_state_or_none
            hey_joe.send({checksum: self.abridged_state_details(new_state)},
Пример #2
0
def alicia_encrypt(data_fields):
    POLICY_FILENAME = "policy-metadata.json"
    globalLogPublisher.addObserver(SimpleObserver())
    TEMP_ALICE_DIR = "alicia-files".format(os.path.dirname(os.path.abspath(__file__)))
    SEEDNODE_URL = '40.122.164.26:9151'

    passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD"
    try:
        alice_config_file = os.path.join(TEMP_ALICE_DIR, "alice.config")
        new_alice_config = AliceConfiguration.from_configuration_file(
                filepath=alice_config_file,
                network_middleware=RestMiddleware(),
                start_learning_now=False,
                save_metadata=False,
            )
        alicia = new_alice_config(passphrase=passphrase)

    except:
        shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True)
        ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
                                                federated_only=True,
                                                minimum_stake=0)
        alice_config = AliceConfiguration(
            config_root=os.path.join(TEMP_ALICE_DIR),
            is_me=True,
            known_nodes={ursula},
            start_learning_now=False,
            federated_only=True,
            learn_on_same_thread=True,
        )

        alice_config.initialize(password=passphrase)

        alice_config.keyring.unlock(password=passphrase)
        alicia = alice_config.produce()
        alice_config_file = alice_config.to_configuration_file()

    alicia.start_learning_loop(now=True)
    label = "doctor"
    label = label.encode()
    policy_pubkey = alicia.get_policy_pubkey_from_label(label)

    print("The policy public key for "
        "label '{}' is {}".format(label.decode("utf-8"), policy_pubkey.to_bytes().hex()))

    import data_ipfs
    res = data_ipfs.encrypt_patient_data(policy_pubkey , data_fields, label=label,save_as_file=True)
    print(res)

    from doctor_keys import get_doctor_pubkeys
    doctor_pubkeys = get_doctor_pubkeys()

    powers_and_material = {
        DecryptingPower: doctor_pubkeys['enc'],
        SigningPower: doctor_pubkeys['sig']
    }

    doctor_strange = Bob.from_public_keys(powers_and_material=powers_and_material,
                                        federated_only=True)


    policy_end_datetime = maya.now() + datetime.timedelta(days=5)

    m, n = 2, 3
    print("Creating access policy for the Doctor...")
    policy = alicia.grant(bob=doctor_strange,
                        label=label,
                        m=m,
                        n=n,
                        expiration=policy_end_datetime)
    print("Done!")


    policy_info = {
        "policy_pubkey": policy.public_key.to_bytes().hex(),
        "alice_sig_pubkey": bytes(alicia.stamp).hex(),
        "label": label.decode("utf-8"),
    }

    filename = POLICY_FILENAME
    with open(filename, 'w') as f:
        json.dump(policy_info, f)
    
    return res
Пример #3
0
def run_doc():

    globalLogPublisher.addObserver(SimpleObserver())

    ######################
    # Boring setup stuff #
    ######################

    SEEDNODE_URL = 'localhost:11501'

    # TODO: path joins?
    TEMP_DOCTOR_DIR = "{}/doctor-files".format(
        os.path.dirname(os.path.abspath(__file__)))

    # Remove previous demo files and create new ones
    shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True)

    ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
                                             federated_only=True,
                                             minimum_stake=0)

    # To create a Bob, we need the doctor's private keys previously generated.

    doctor_keys = get_doctor_privkeys()

    bob_enc_keypair = DecryptingKeypair(private_key=doctor_keys["enc"])
    bob_sig_keypair = SigningKeypair(private_key=doctor_keys["sig"])
    enc_power = DecryptingPower(keypair=bob_enc_keypair)
    sig_power = SigningPower(keypair=bob_sig_keypair)
    power_ups = [enc_power, sig_power]

    print("Creating the Doctor ...")

    doctor = Bob(
        is_me=True,
        federated_only=True,
        crypto_power_ups=power_ups,
        start_learning_now=True,
        abort_on_learning_error=True,
        known_nodes=[ursula],
        save_metadata=False,
        network_middleware=RestMiddleware(),
    )

    print("Doctor = ", doctor)

    # Let's join the policy generated by Alicia. We just need some info about it.
    with open("policy-metadata.json", 'r') as f:
        policy_data = json.load(f)

    policy_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data["policy_pubkey"]))
    alices_sig_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data["alice_sig_pubkey"]))
    label = policy_data["label"].encode()

    print("The Doctor joins policy for label '{}'".format(
        label.decode("utf-8")))
    doctor.join_policy(label, alices_sig_pubkey)

    # Now that the Doctor joined the policy in the NuCypher network,
    # he can retrieve encrypted data which he can decrypt with his private key.
    # But first we need some encrypted data!
    # Let's read the file produced by the heart monitor and unpack the MessageKits,
    # which are the individual ciphertexts.
    data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False)
    message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])

    # The doctor also needs to create a view of the Data Source from its public keys
    data_source = Enrico.from_public_keys({SigningPower: data['data_source']},
                                          policy_encrypting_key=policy_pubkey)

    # Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit.
    for message_kit in message_kits:
        try:
            start = timer()
            retrieved_plaintexts = doctor.retrieve(
                label=label,
                message_kit=message_kit,
                data_source=data_source,
                alice_verifying_key=alices_sig_pubkey)
            end = timer()

            plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)

            # Now we can get the heart rate and the associated timestamp,
            # generated by the heart rate monitor.
            heart_rate = plaintext['heart_rate']
            timestamp = maya.MayaDT(plaintext['timestamp'])

            # This code block simply pretty prints the heart rate info
            terminal_size = shutil.get_terminal_size().columns
            max_width = min(terminal_size, 120)
            columns = max_width - 12 - 27
            scale = columns / 40
            scaled_heart_rate = int(scale * (heart_rate - 60))
            retrieval_time = "Retrieval time: {:8.2f} ms".format(1000 *
                                                                 (end - start))
            line = ("-" * scaled_heart_rate) + "❤︎ ({} BPM)".format(heart_rate)
            line = line.ljust(max_width - 27, " ") + retrieval_time
            print(line)
        except Exception as e:
            # We just want to know what went wrong and continue the demo
            traceback.print_exc()
Пример #4
0
def doctor_decrypt(hash_key):
    globalLogPublisher.addObserver(SimpleObserver())
    SEEDNODE_URL = 'localhost:11501'

    TEMP_DOCTOR_DIR = "{}/doctor-files".format(
        os.path.dirname(os.path.abspath(__file__)))
    shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True)

    ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
                                             federated_only=True,
                                             minimum_stake=0)

    from doctor_keys import get_doctor_privkeys

    doctor_keys = get_doctor_privkeys()

    bob_enc_keypair = DecryptingKeypair(private_key=doctor_keys["enc"])
    bob_sig_keypair = SigningKeypair(private_key=doctor_keys["sig"])
    enc_power = DecryptingPower(keypair=bob_enc_keypair)
    sig_power = SigningPower(keypair=bob_sig_keypair)
    power_ups = [enc_power, sig_power]

    print("Creating the Doctor ...")

    doctor = Bob(
        is_me=True,
        federated_only=True,
        crypto_power_ups=power_ups,
        start_learning_now=True,
        abort_on_learning_error=True,
        known_nodes=[ursula],
        save_metadata=False,
        network_middleware=RestMiddleware(),
    )

    print("Doctor = ", doctor)

    with open("policy-metadata.json", 'r') as f:
        policy_data = json.load(f)

    policy_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data["policy_pubkey"]))
    alices_sig_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data["alice_sig_pubkey"]))
    label = policy_data["label"].encode()

    print("The Doctor joins policy for label '{}'".format(
        label.decode("utf-8")))
    doctor.join_policy(label, alices_sig_pubkey)

    ipfs_api = ipfsapi.connect()
    file = ipfs_api.get(hash_key)
    print(file)
    os.rename(hash_key, 'patient_details.msgpack')
    data = msgpack.load(open("patient_details.msgpack", "rb"), raw=False)
    message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])

    data_source = DataSource.from_public_keys(
        policy_public_key=policy_pubkey,
        datasource_public_key=data['data_source'],
        label=label)
    complete_message = []
    for message_kit in message_kits:
        print(message_kit)
        try:
            start = timer()
            retrieved_plaintexts = doctor.retrieve(
                message_kit=message_kit,
                data_source=data_source,
                alice_verifying_key=alices_sig_pubkey)
            end = timer()
            plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)
            complete_message.append(plaintext)
            print(plaintext)
            #with open("details.json", "w") as write_file:
            #               json.dump(plaintext, write_file)
        except Exception as e:
            traceback.print_exc()
    with open("details.json", "w") as write_file:
        json.dump(complete_message, write_file)
    return complete_message
Пример #5
0
def ursula(
        click_config,
        action,
        debug,
        dev,
        quiet,
        dry_run,
        force,
        lonely,
        network,
        teacher_uri,
        min_stake,
        rest_host,
        rest_port,
        db_filepath,
        checksum_address,
        federated_only,
        poa,
        config_root,
        config_file,
        metadata_dir,  # TODO: Start nodes from an additional existing metadata dir
        provider_uri,
        no_registry,
        registry_filepath) -> None:
    """
    Manage and run an Ursula node.

    \b
    Actions
    -------------------------------------------------
    \b
    run            Run an "Ursula" node.
    init           Create a new Ursula node configuration.
    view           View the Ursula node's configuration.
    forget         Forget all known nodes.
    save-metadata  Manually write node metadata to disk without running
    destroy        Delete Ursula node configuration.

    """

    #
    # Boring Setup Stuff
    #
    if not quiet:
        log = Logger('ursula.cli')

    if debug and quiet:
        raise click.BadOptionUsage(
            option_name="quiet",
            message="--debug and --quiet cannot be used at the same time.")

    if debug:
        click_config.log_to_sentry = False
        click_config.log_to_file = True
        globalLogPublisher.removeObserver(logToSentry)  # Sentry
        globalLogPublisher.addObserver(
            SimpleObserver(log_level_name='debug'))  # Print

    elif quiet:
        globalLogPublisher.removeObserver(logToSentry)
        globalLogPublisher.removeObserver(SimpleObserver)
        globalLogPublisher.removeObserver(getJsonFileObserver())

    #
    # Pre-Launch Warnings
    #
    if not quiet:
        if dev:
            click.secho("WARNING: Running in development mode", fg='yellow')
        if force:
            click.secho("WARNING: Force is enabled", fg='yellow')

    #
    # Unauthenticated Configurations
    #
    if action == "init":
        """Create a brand-new persistent Ursula"""

        if dev and not quiet:
            click.secho("WARNING: Using temporary storage area", fg='yellow')

        if not config_root:  # Flag
            config_root = click_config.config_file  # Envvar

        if not rest_host:
            rest_host = click.prompt(
                "Enter Ursula's public-facing IPv4 address")

        ursula_config = UrsulaConfiguration.generate(
            password=click_config.get_password(confirm=True),
            config_root=config_root,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath,
            domains={network} if network else None,
            federated_only=federated_only,
            checksum_public_address=checksum_address,
            no_registry=federated_only or no_registry,
            registry_filepath=registry_filepath,
            provider_uri=provider_uri,
            poa=poa)

        if not quiet:
            click.secho("Generated keyring {}".format(
                ursula_config.keyring_dir),
                        fg='green')
            click.secho("Saved configuration file {}".format(
                ursula_config.config_file_location),
                        fg='green')

            # Give the use a suggestion as to what to do next...
            how_to_run_message = "\nTo run an Ursula node from the default configuration filepath run: \n\n'{}'\n"
            suggested_command = 'nucypher ursula run'
            if config_root is not None:
                config_file_location = os.path.join(
                    config_root, config_file
                    or UrsulaConfiguration.CONFIG_FILENAME)
                suggested_command += ' --config-file {}'.format(
                    config_file_location)
            click.secho(how_to_run_message.format(suggested_command),
                        fg='green')
            return  # FIN

        else:
            click.secho("OK")

    elif action == "destroy":
        """Delete all configuration files from the disk"""

        if dev:
            message = "'nucypher ursula destroy' cannot be used in --dev mode"
            raise click.BadOptionUsage(option_name='--dev', message=message)

        try:
            ursula_config = UrsulaConfiguration.from_configuration_file(
                filepath=config_file, domains={network})

        except FileNotFoundError:
            config_root = config_root or DEFAULT_CONFIG_ROOT
            config_file_location = config_file or UrsulaConfiguration.DEFAULT_CONFIG_FILE_LOCATION

            if not force:
                message = "No configuration file found at {}; \n" \
                          "Destroy top-level configuration directory: {}?".format(config_file_location, config_root)
                click.confirm(message, abort=True)  # ABORT

            shutil.rmtree(config_root, ignore_errors=False)

        else:
            if not force:
                click.confirm('''
*Permanently and irreversibly delete all* nucypher files including
    - Private and Public Keys
    - Known Nodes
    - TLS certificates
    - Node Configurations
    - Log Files

Delete {}?'''.format(ursula_config.config_root),
                              abort=True)

            try:
                ursula_config.destroy(force=force)
            except FileNotFoundError:
                message = 'Failed: No nucypher files found at {}'.format(
                    ursula_config.config_root)
                click.secho(message, fg='red')
                log.debug(message)
                raise click.Abort()
            else:
                message = "Deleted configuration files at {}".format(
                    ursula_config.config_root)
                click.secho(message, fg='green')
                log.debug(message)

        if not quiet:
            click.secho("Destroyed {}".format(config_root))

        return

    # Development Configuration
    if dev:
        ursula_config = UrsulaConfiguration(
            dev_mode=True,
            domains={TEMPORARY_DOMAIN},
            poa=poa,
            registry_filepath=registry_filepath,
            provider_uri=provider_uri,
            checksum_public_address=checksum_address,
            federated_only=federated_only,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath)
    # Authenticated Configurations
    else:

        # Deserialize network domain name if override passed
        if network:
            domain_constant = getattr(constants, network.upper())
            domains = {domain_constant}
        else:
            domains = None

        ursula_config = UrsulaConfiguration.from_configuration_file(
            filepath=config_file,
            domains=domains,
            registry_filepath=registry_filepath,
            provider_uri=provider_uri,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath,

            # TODO: Handle Boolean overrides
            # poa=poa,
            # federated_only=federated_only,
        )

        try:  # Unlock Keyring
            if not quiet:
                click.secho('Decrypting keyring...', fg='blue')
            ursula_config.keyring.unlock(password=click_config.get_password()
                                         )  # Takes ~3 seconds, ~1GB Ram
        except CryptoError:
            raise ursula_config.keyring.AuthenticationFailed

    if not ursula_config.federated_only:
        try:
            ursula_config.connect_to_blockchain(recompile_contracts=False)
            ursula_config.connect_to_contracts()
        except EthereumContractRegistry.NoRegistry:
            message = "Cannot configure blockchain character: No contract registry found; " \
                      "Did you mean to pass --federated-only?"
            raise EthereumContractRegistry.NoRegistry(message)

    click_config.ursula_config = ursula_config  # Pass Ursula's config onto staking sub-command

    #
    # Launch Warnings
    #
    if not quiet:
        if ursula_config.federated_only:
            click.secho("WARNING: Running in Federated mode", fg='yellow')

    #
    # Action Switch
    #
    if action == 'run':
        """Seed, Produce, Run!"""

        #
        # Seed - Step 1
        #
        teacher_nodes = list()
        if teacher_uri:
            node = Ursula.from_teacher_uri(
                teacher_uri=teacher_uri,
                min_stake=min_stake,
                federated_only=ursula_config.federated_only)
            teacher_nodes.append(node)

        #
        # Produce - Step 2
        #
        ursula = ursula_config(known_nodes=teacher_nodes, lonely=lonely)

        # GO!
        try:

            #
            # Run - Step 3
            #
            click.secho("Connecting to {}".format(','.join(
                str(d) for d in ursula_config.domains)),
                        fg='blue',
                        bold=True)
            click.secho("Running Ursula {} on {}".format(
                ursula, ursula.rest_interface),
                        fg='green',
                        bold=True)
            if not debug:
                stdio.StandardIO(UrsulaCommandProtocol(ursula=ursula))

            if dry_run:
                # That's all folks!
                return

            ursula.get_deployer().run()  # <--- Blocking Call (Reactor)

        except Exception as e:
            ursula_config.log.critical(str(e))
            click.secho("{} {}".format(e.__class__.__name__, str(e)), fg='red')
            raise  # Crash :-(

        finally:
            if not quiet:
                click.secho("Stopping Ursula")
            ursula_config.cleanup()
            if not quiet:
                click.secho("Ursula Stopped", fg='red')

        return

    elif action == "save-metadata":
        """Manually save a node self-metadata file"""

        ursula = ursula_config.produce(ursula_config=ursula_config)
        metadata_path = ursula.write_node_metadata(node=ursula)
        if not quiet:
            click.secho("Successfully saved node metadata to {}.".format(
                metadata_path),
                        fg='green')
        return

    elif action == "view":
        """Paint an existing configuration to the console"""
        paint_configuration(
            config_filepath=config_file or ursula_config.config_file_location)
        return

    elif action == "forget":
        """Forget all known nodes via storages"""
        click.confirm("Permanently delete all known node data?", abort=True)
        ursula_config.forget_nodes()
        message = "Removed all stored node node metadata and certificates"
        click.secho(message=message, fg='red')
        return

    else:
        raise click.BadArgumentUsage("No such argument {}".format(action))
Пример #6
0
def subscribe_and_grant_permission_to(username):

    globalLogPublisher.addObserver(SimpleObserver())

    # Reinitialize Alice from our config file

    ALICE_CONFIG_DIR = os.path.join(settings.BASE_DIR, 'nucypher_utils',
                                    'nucypher_data', 'nucypher_char_configs',
                                    'stridon-demo-alice')

    ALICE_CONFIG_FILE = os.path.join(ALICE_CONFIG_DIR, "alice.config")

    passphrase = "TEST_ALICE_PASSWORD"

    new_alice_config = AliceConfiguration.from_configuration_file(
        filepath=ALICE_CONFIG_FILE,
        network_middleware=RestMiddleware(),
        start_learning_now=False,
        save_metadata=False,
    )
    new_alice_config.keyring.unlock(password=passphrase)

    alice = new_alice_config()

    # Now onto Bob

    SEEDNODE_URL = 'localhost:11500'

    BOB_CONFIG_DIR = os.path.join(settings.BASE_DIR, 'nucypher_utils',
                                  'nucypher_data', 'nucypher_char_configs',
                                  username)

    ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
                                             federated_only=True,
                                             minimum_stake=0)

    bob_config = BobConfiguration(
        config_root=os.path.join(BOB_CONFIG_DIR),
        is_me=True,
        known_nodes={ursula},
        start_learning_now=False,
        federated_only=True,
        learn_on_same_thread=True,
    )

    bob_config.initialize(password=passphrase)
    bob_config.keyring.unlock(password=passphrase)
    bob_config_file = bob_config.to_configuration_file()

    premium_user = bob_config.produce()

    policy_end_datetime = maya.now() + datetime.timedelta(days=5)

    label = b'stridon-premium-service'

    policy_pubkey = alice.get_policy_pubkey_from_label(label)

    alice.start_learning_loop(now=True)

    policy = alice.grant(bob=premium_user,
                         label=label,
                         m=1,
                         n=1,
                         expiration=policy_end_datetime)

    assert policy.public_key == policy_pubkey
    alices_pubkey_bytes = bytes(alice.stamp)

    premium_user.join_policy(label, alices_pubkey_bytes)

    from nucypher.crypto.powers import SigningPower, DecryptingPower
    print("ALICE")
    print(alice.public_keys(SigningPower))
    print(alice.public_keys(DecryptingPower))
    print("PREMIUM_USER")
    print(premium_user.public_keys(SigningPower))
    print(premium_user.public_keys(DecryptingPower))

    return policy.public_key == policy_pubkey