def test_generate_key():
    # Not much to test here in the current approach, this simply shadows PrivateKey()
    assert isinstance(Cryptographer.generate_key(), PrivateKey)

    # Making sure multiple calls to the function do not return the same key
    issued_keys = []
    for _ in range(100):
        sk = Cryptographer.generate_key()
        sk_der = sk.to_der()
        assert sk_der not in issued_keys
        issued_keys.append(sk_der)
Esempio n. 2
0
def test_get_users(teosd, rpc_client):
    _, teos_id = teosd

    # Create a fresh user
    tmp_user_id = Cryptographer.get_compressed_pk(Cryptographer.generate_key().public_key)

    users = json.loads(rpc_client.get_users())
    assert tmp_user_id not in users

    # Register the fresh user
    teos_client.register(tmp_user_id, teos_id, teos_base_endpoint)

    users = json.loads(rpc_client.get_users())
    assert tmp_user_id in users
Esempio n. 3
0
def main(config):
    setup_data_folder(config.get("DATA_DIR"))

    logging_server_ready = multiprocessing.Event()
    stop_logging_server = multiprocessing.Event()
    logging_port = multiprocessing.Value("i")
    logging_process = multiprocessing.Process(
        target=serve_logging,
        daemon=True,
        args=(config.get("LOG_FILE"), logging_port, config.get("DAEMON"),
              logging_server_ready, stop_logging_server),
    )
    logging_process.start()
    logging_server_ready.wait()

    setup_logging(logging_port.value)
    logger = get_logger(component="Daemon")

    if not os.path.exists(
            config.get("TEOS_SECRET_KEY")) or config.get("OVERWRITE_KEY"):
        logger.info("Generating a new key pair")
        sk = Cryptographer.generate_key()
        Cryptographer.save_key_file(sk.to_der(), "teos_sk",
                                    config.get("DATA_DIR"))

    else:
        logger.info("Tower identity found. Loading keys")
        secret_key_der = Cryptographer.load_key_file(
            config.get("TEOS_SECRET_KEY"))

        if not secret_key_der:
            raise IOError("TEOS private key cannot be loaded")
        sk = Cryptographer.load_private_key_der(secret_key_der)

    # Windows cannot run gunicorn
    if os.name == "nt" and config.get("WSGI") == "gunicorn":
        logger.warning(
            "Windows cannot run gunicorn as WSGI. Changing to waitress")
        config["WSGI"] = "waitress"

    try:
        TeosDaemon(config, sk, logger, logging_port.value, stop_logging_server,
                   logging_process).start()
    except Exception as e:
        logger.error("An error occurred: {}. Shutting down".format(e))
        stop_logging_server.set()
        logging_process.join()
        exit(1)
Esempio n. 4
0
def run_teosd():
    sk_file_path = os.path.join(config.get("DATA_DIR"), "teos_sk.der")
    if not os.path.exists(sk_file_path):
        # Generating teos sk so we can return the teos_id
        teos_sk = Cryptographer.generate_key()
        Cryptographer.save_key_file(teos_sk.to_der(), "teos_sk", config.get("DATA_DIR"))
    else:
        teos_sk = Cryptographer.load_private_key_der(Cryptographer.load_key_file(sk_file_path))

    teos_id = Cryptographer.get_compressed_pk(teos_sk.public_key)

    # Change the default WSGI for Windows
    if os.name == "nt":
        config["WSGI"] = "waitress"
    teosd_process = Process(target=main, kwargs={"config": config})
    teosd_process.start()

    # Give it some time to bootstrap
    # TODO: we should do better synchronization using an Event
    sleep(3)

    return teosd_process, teos_id
Esempio n. 5
0
def main(command, args, config):
    setup_data_folder(config.get("DATA_DIR"))

    # Set the teos url
    teos_url = "{}:{}".format(config.get("API_CONNECT"),
                              config.get("API_PORT"))
    # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http.
    if not teos_url.startswith("http"):
        teos_url = "http://" + teos_url

    try:
        if os.path.exists(config.get("USER_PRIVATE_KEY")):
            logger.debug("Client id found. Loading keys")
            user_sk, user_id = load_keys(config.get("USER_PRIVATE_KEY"))

        else:
            logger.info("Client id not found. Generating new keys")
            user_sk = Cryptographer.generate_key()
            Cryptographer.save_key_file(user_sk.to_der(), "user_sk",
                                        config.get("DATA_DIR"))
            user_id = Cryptographer.get_compressed_pk(user_sk.public_key)

        if command == "register":
            if not args:
                raise InvalidParameter(
                    "Cannot register. No tower id was given")
            else:
                teos_id = args.pop(0)
                if not is_compressed_pk(teos_id):
                    raise InvalidParameter(
                        "Cannot register. Tower id has invalid format")

                available_slots, subscription_expiry = register(
                    user_id, teos_id, teos_url)
                logger.info(
                    "Registration succeeded. Available slots: {}".format(
                        available_slots))
                logger.info("Subscription expires at block {}".format(
                    subscription_expiry))

                teos_id_file = os.path.join(config.get("DATA_DIR"), "teos_pk")
                Cryptographer.save_key_file(bytes.fromhex(teos_id),
                                            teos_id_file,
                                            config.get("DATA_DIR"))

        if command == "add_appointment":
            teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY"))
            appointment_data = parse_add_appointment_args(args)
            appointment = create_appointment(appointment_data)
            start_block, signature = add_appointment(appointment, user_sk,
                                                     teos_id, teos_url)
            save_appointment_receipt(appointment.to_dict(), start_block,
                                     signature,
                                     config.get("APPOINTMENTS_FOLDER_NAME"))

        elif command == "get_appointment":
            if not args:
                logger.error("No arguments were given")

            else:
                arg_opt = args.pop(0)

                if arg_opt in ["-h", "--help"]:
                    sys.exit(help_get_appointment())

                teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY"))
                appointment_data = get_appointment(arg_opt, user_sk, teos_id,
                                                   teos_url)
                if appointment_data:
                    logger.info(json.dumps(appointment_data, indent=4))

        elif command == "get_subscription_info":
            if args:
                arg_opt = args.pop(0)

                if arg_opt in ["-h", "--help"]:
                    sys.exit(help_get_subscription_info())

            teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY"))
            subscription_info = get_subscription_info(user_sk, teos_id,
                                                      teos_url)
            if subscription_info:
                logger.info(json.dumps(subscription_info, indent=4))

        elif command == "help":
            if args:
                command = args.pop(0)

                if command == "register":
                    sys.exit(help_register())

                if command == "add_appointment":
                    sys.exit(help_add_appointment())

                if command == "get_subscription_info":
                    sys.exit(help_get_subscription_info())

                elif command == "get_appointment":
                    sys.exit(help_get_appointment())

                else:
                    logger.error(
                        "Unknown command. Use help to check the list of available commands"
                    )

            else:
                sys.exit(show_usage())

    except (
            FileNotFoundError,
            IOError,
            ConnectionError,
            ValueError,
            BasicException,
    ) as e:
        logger.error(str(e))
    except Exception as e:
        logger.error("Unknown error occurred", error=str(e))
Esempio n. 6
0
from common.exceptions import InvalidParameter
from common.cryptographer import Cryptographer

from teos.cli.rpc_client import RPCClient

from test.teos.conftest import (
    create_txs,
    generate_block_with_transactions,
    generate_blocks,
    config,
)
from test.teos.e2e.conftest import build_appointment_data

teos_base_endpoint = "http://{}:{}".format(config.get("API_BIND"), config.get("API_PORT"))

user_sk = Cryptographer.generate_key()
user_id = Cryptographer.get_compressed_pk(user_sk.public_key)


@pytest.fixture
def rpc_client():
    return RPCClient(config.get("RPC_BIND"), config.get("RPC_PORT"))


def get_appointment_info(teos_id, locator, sk=user_sk):
    sleep(1)  # Let's add a bit of delay so the state can be updated
    return teos_client.get_appointment(locator, sk, teos_id, teos_base_endpoint)


def add_appointment(teos_id, appointment_data, sk=user_sk):
    return teos_client.add_appointment(appointment_data, sk, teos_id, teos_base_endpoint)