Beispiel #1
0
def test_select_auth_no_match(auth_config, tmpdir):
    no_match = "No matching credential found"

    # no credentials at all
    with pytest.raises(RuntimeError) as err:
        selected = auth.select_matching_auth([], "example.com", "nosuchuser")
    assert "No matching credential found for hostname 'example.com'" in err.value.args[
        0]

    # no match for requested hostname
    with_host = """auth = [{
        username = "******",
        password = "******",
        hostname = "example.com"
        }]"""
    with temp_config(tmpdir, with_host) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(RuntimeError) as err:
        creds = auth.load_auth()
        selected = auth.select_matching_auth(creds, "example.net")
    assert f"{no_match} for hostname 'example.net'" in err.value.args[0]

    # no match for requested username
    with temp_config(tmpdir, auth_config) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(RuntimeError) as err:
        creds = auth.load_auth()
        selected = auth.select_matching_auth(creds, "example.com",
                                             "nosuchuser")
    assert f"{no_match} for hostname 'example.com' with username 'nosuchuser'" in err.value.args[
        0]
Beispiel #2
0
def test_load_auth_bad_perms(auth_config, tmpdir):
    for bad_perm in [
            stat.S_IRGRP, stat.S_IWGRP, stat.S_IXGRP, stat.S_IROTH,
            stat.S_IWOTH, stat.S_IXOTH
    ]:
        with temp_config(tmpdir, auth_config, bad_perm) as config_dir, \
                temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(RuntimeError):
            auth.load_auth()
Beispiel #3
0
def test_load_auth_options(auth_config, tmpdir):
    # SSL should be used by default
    # The default mechanism should be SCRAM_SHA_512
    with temp_config(tmpdir, auth_config) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(ssl=True)
        from adc.auth import SASLMethod
        assert auth_mock.called_with(mechanism=SASLMethod.SCRAM_SHA_512)

    # But it should be possible to disable SSL
    use_plaintext = """auth = [{
                       username = "******",
                       password = "******",
                       protocol = "SASL_PLAINTEXT"
                       }]"""
    with temp_config(tmpdir, use_plaintext) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(ssl=False)

    # An SSL CA data path should be honored
    with_ca_data = """auth = [{
                   username = "******",
                   password = "******",
                   ssl_ca_location = "/foo/bar/baz"
                   }]"""
    with temp_config(tmpdir, with_ca_data) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(ssl_ca_location="/foo/bar/baz")

    # Alternate mechanisms should be honored
    plain_mechanism = """auth = [{
                      username = "******",
                      password = "******",
                      mechanism = "PLAIN"
                      }]"""
    with temp_config(tmpdir, plain_mechanism) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(mechanism=SASLMethod.PLAIN)

    # Associated hostnames should be included
    with_host = """auth = [{
                username = "******",
                password = "******",
                hostname = "example.com"
                }]"""
    with temp_config(tmpdir, with_host) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir):
        creds = auth.load_auth()
        assert len(creds) == 1
        assert creds[0].hostname == "example.com"
Beispiel #4
0
def test_load_auth_malformed(tmpdir):
    missing_username = """
        auth = [{extra="stuff",
            password="******"}]
        """
    with temp_config(tmpdir, missing_username) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(RuntimeError):
        auth.load_auth()

    missing_password = """
    auth = [{username="******",
        extra="stuff"}]
    """
    with temp_config(tmpdir, missing_password) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(RuntimeError):
        auth.load_auth()
Beispiel #5
0
def _main(args):
    """Stream TNS objects to Hopskotch.
    """
    # set up logging
    logging.basicConfig(
        level=utils.get_log_level(args.verbose),
        format="%(asctime)s | tns2hop : %(levelname)s : %(message)s",
    )
    # lower verbosity of schedule logger
    logging.getLogger('schedule').setLevel(logging.WARNING)

    # load parameters file
    with open(args.params_file, "r") as f:
        parameters_list = json.load(f)["data"]

    # open stream to hop
    stream = io.Stream(auth=auth.load_auth(args.config))
    sink = stream.open(args.hop_url + "tns", "w")

    # schedule everyday
    exact_time = "23:00"
    schedule.every().day.at(exact_time).do(job, sink, args.api_key,
                                           parameters_list)
    try:
        while True:
            schedule.run_pending()
            time.sleep(1)
    except KeyboardInterrupt:
        pass
    except Exception:
        raise
    finally:
        sink.close()
Beispiel #6
0
def _main(args):
    """Stream GCN alerts to Hopskotch.
    """
    # set up logging
    logging.basicConfig(
        level=utils.get_log_level(args.verbose),
        format="%(asctime)s | gcn2hop : %(levelname)s : %(message)s",
    )

    # Line buffer stdout and stderr
    sys.stdout = os.fdopen(sys.stdout.fileno(), "w", buffering=1)
    sys.stderr = os.fdopen(sys.stderr.fileno(), "w", buffering=1)

    hop_url = args.hop_url + "gcn"
    hop_conf_file = os.path.expanduser(args.config)
    host = tuple(args.hosts.split(","))
    port = args.port

    logger.info("starting up")
    logger.info(f"GCN host list: {repr(host)}")
    logger.info(f"GCN port: {port}")
    logger.info(f"Hop server URL: {hop_url}")
    logger.info(f"Hop config file: {hop_conf_file}")

    # open stream to hop
    stream = io.Stream(auth=auth.load_auth(hop_conf_file))
    sink = stream.open(hop_url, "w")
    try:
        gcn.voeventclient.listen(host=host, port=port, handler=write_to_hop(sink))
    except KeyboardInterrupt:
        pass
    except Exception:
        raise
    finally:
        sink.close()
Beispiel #7
0
def test_load_auth_malformed(tmpdir):
    missing_username = """
                       [auth]
                       password = "******"
                       extra = "stuff"
                       """
    with temp_config(tmpdir, missing_username) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(KeyError):
        auth.load_auth()

    missing_password = """
                       [auth]
                       username = "******"
                       extra = "stuff"
                   """
    with temp_config(tmpdir, missing_password) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(KeyError):
        auth.load_auth()
Beispiel #8
0
def test_auth_location_fallback(tmpdir):
    valid_auth = "auth = [{username=\"user\",password=\"pass\"}]"
    other_auth = "auth = [{username=\"other-user\",password=\"other-pass\"}]"

    config_dir = f"{tmpdir}/hop"
    os.makedirs(config_dir, exist_ok=True)

    def write_file(name: str, data: str):
        file_path = f"{config_dir}/{name}"
        with open(file_path, 'w') as file:
            os.chmod(file_path, stat.S_IRUSR | stat.S_IWUSR)
            file.write(data)

    with temp_environ(XDG_CONFIG_HOME=str(tmpdir)):
        # If both auth.toml and config.toml contain auth data, only auth.toml should be read
        write_file("auth.toml", valid_auth)
        write_file("config.toml", other_auth)
        creds = auth.load_auth()
        assert len(creds) == 1
        assert creds[0].username == "user"

        # If auth.toml does not exist and config.toml contains valid auth data, it should be read
        os.remove(f"{config_dir}/auth.toml")
        creds = auth.load_auth()
        assert len(creds) == 1
        assert creds[0].username == "other-user"

        # If auth.toml does not exist and config.toml exists but contains no valid auth data, the
        # resulting error should be about auth.toml
        write_file("config.toml", "")
        with pytest.raises(FileNotFoundError) as err:
            creds = auth.load_auth()
        assert "auth.toml" in err.value.filename

        # If neither auth.toml nor config.toml exixts, the error should be about auth.toml
        os.remove(f"{config_dir}/config.toml")
        with pytest.raises(FileNotFoundError) as err:
            creds = auth.load_auth()
        assert "auth.toml" in err.value.filename
Beispiel #9
0
def check_credential_deletion(config_file, removed_index):
    """Check that a particular credential is not in a config file after removal,
       and that all other are still present.

    Args:
        config_file: Path to the file to check.
        removed_index: Index of the credential in delete_input_creds which should not be present.
    """
    observed = auth.load_auth(config_file)
    for idx, cred in enumerate(delete_input_creds):
        if idx == removed_index:
            assert cred not in observed
        else:
            assert cred in observed
Beispiel #10
0
def test_load_auth_options(auth_config, tmpdir):
    # SSL should be used by default
    # The default mechanism should be SCRAM_SHA_512
    with temp_config(tmpdir, auth_config) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(ssl=True)
        from adc.auth import SASLMethod
        assert auth_mock.called_with(mechanism=SASLMethod.SCRAM_SHA_512)

    # But it should be possible to disable SSL
    use_plaintext = """
                       [auth]
                       username = "******"
                       password = "******"
                       protocol = "SASL_PLAINTEXT"
                       """
    with temp_config(tmpdir, use_plaintext) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(ssl=False)

    # An SSL CA data path should be honored
    with_ca_data = """
                   [auth]
                   username = "******"
                   password = "******"
                   ssl_ca_location = "/foo/bar/baz"
                   """
    with temp_config(tmpdir, with_ca_data) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(ssl_ca_location="/foo/bar/baz")

    # Alternate mechanisms should be honored
    plain_mechanism = """
                      [auth]
                      username = "******"
                      password = "******"
                      mechanism = "PLAIN"
                      """
    with temp_config(tmpdir, plain_mechanism) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), patch("hop.auth.Auth") as auth_mock:
        auth.load_auth()
        assert auth_mock.called_with(mechanism=SASLMethod.PLAIN)
Beispiel #11
0
def test_add_credential_conflict_with_host(tmpdir, caplog):
    old_cred = auth.Auth("username", "password", "example.com")
    new_cred = auth.Auth("username", "other_pass", "example.com")
    unrelated_cred = auth.Auth("username", "unrelated_pass", "example.org")

    with temp_environ(HOME=str(tmpdir)), \
            patch("hop.auth.read_new_credential", MagicMock(return_value=new_cred)):
        auth.write_auth_data(configure.get_config_path("auth"),
                             [old_cred, unrelated_cred])
        args = MagicMock()
        args.cred_file = None
        args.force = False
        auth.add_credential(args)
        # without the force option, the old credential should not be overwritten
        check_credential_file(configure.get_config_path("auth"), old_cred)
        assert "Credential already exists; overwrite with --force" in caplog.text

        args.force = True
        auth.add_credential(args)
        # with the force option, the old credential should be overwritten
        check_credential_file(configure.get_config_path("auth"), new_cred)
        # also check that unrelated credentials haven't been removed
        creds = auth.load_auth(configure.get_config_path("auth"))
        assert unrelated_cred in creds
Beispiel #12
0
def test_load_auth_muliple_creds(tmpdir):
    two_creds = """auth = [
                    {
                        username = "******",
                        password = "******",
                        hostname = "host1"
                    },
                    {
                        username = "******",
                        password = "******",
                        hostname = "host2"
                    },
                ]"""
    with temp_config(
            tmpdir,
            two_creds) as config_dir, temp_environ(XDG_CONFIG_HOME=config_dir):
        creds = auth.load_auth()
        assert len(creds) == 2
        assert creds[0].username == "user1"
        assert creds[0].password == "pass1"
        assert creds[0].hostname == "host1"
        assert creds[1].username == "user2"
        assert creds[1].password == "pass2"
        assert creds[1].hostname == "host2"
Beispiel #13
0
def test_load_auth_invalid_toml(tmpdir):
    garbage = "KHFBGKJSBVJKbdfb ,s ,msb vks bs"
    with temp_config(tmpdir, garbage) as config_dir, \
            temp_environ(XDG_CONFIG_HOME=config_dir), pytest.raises(RuntimeError):
        auth.load_auth()
Beispiel #14
0
def test_load_auth_non_existent(auth_config, tmpdir):
    with temp_environ(XDG_CONFIG_HOME=str(tmpdir)), \
            pytest.raises(FileNotFoundError):
        auth.load_auth()
Beispiel #15
0
def test_load_auth(auth_config, tmpdir):
    with temp_config(tmpdir, auth_config) as config_dir, temp_environ(
            XDG_CONFIG_HOME=config_dir):
        auth_data = auth.load_auth()
        assert len(auth_data) == 1
        assert auth_data[0].username == "username"
Beispiel #16
0
def credential_write_read_round_trip(orig_cred, file_path):
    auth.write_auth_data(file_path, [orig_cred])
    read_creds = auth.load_auth(file_path)
    assert len(read_creds) == 1
    assert read_creds[0] == orig_cred