Exemple #1
0
def test_list_credentials(tmpdir, capsys):
    with patch("hop.auth.load_auth", MagicMock(return_value=[])):
        auth.list_credentials()
        captured = capsys.readouterr()
        assert len(captured.out) == 0

    # lie about output going to a TTY to check more user-friendly message used then
    with patch("hop.auth.load_auth", MagicMock(return_value=[])), \
            patch("os.isatty", MagicMock(return_value=True)):
        auth.list_credentials()
        captured = capsys.readouterr()
        assert "No credentials" in captured.out

    short_cred = auth.Auth("user1", "pass1")
    long_cred = auth.Auth("user2", "pass2", "host2")

    with patch("hop.auth.load_auth", MagicMock(return_value=[short_cred])):
        auth.list_credentials()
        captured = capsys.readouterr()
        assert short_cred.username in captured.out
        assert short_cred.password not in captured.out
        assert "for" not in captured.out

    with patch("hop.auth.load_auth",
               MagicMock(return_value=[short_cred, long_cred])):
        auth.list_credentials()
        captured = capsys.readouterr()
        assert short_cred.username in captured.out
        assert long_cred.username in captured.out
        assert long_cred.password not in captured.out
        assert long_cred.hostname in captured.out
Exemple #2
0
def test_auth_ca_location():
    a = auth.Auth("foo", "bar", ssl=False)
    assert not a.ssl
    assert a.ssl_ca_location is None
    a = auth.Auth("foo", "bar", ssl_ca_location="foo/bar")
    assert a.ssl
    assert a.ssl_ca_location == "foo/bar"
Exemple #3
0
def test_auth_protocol():
    a = auth.Auth("foo", "bar")  # use default security
    assert a.ssl
    assert a.protocol == "SASL_SSL"
    a = auth.Auth("foo", "bar", ssl=False)
    assert not a.ssl
    assert a.protocol == "SASL_PLAINTEXT"
Exemple #4
0
def test_delete_credential_ambiguous_creds_without_hosts(tmpdir):
    creds = [auth.Auth("user1", "pass1"), auth.Auth("user1", "pass2")]
    with temp_environ(HOME=str(tmpdir)), \
            patch("hop.auth.load_auth", MagicMock(return_value=creds)), \
            pytest.raises(RuntimeError) as err:
        auth.delete_credential("user1")
    assert "Ambiguous credentials found" in err.value.args[0]
    assert creds[0].username in err.value.args[0]
Exemple #5
0
def test_add_credential_to_nonempty(auth_config, tmpdir):
    old_cred = auth.Auth("username", "password")
    new_cred = auth.Auth("other_user", "other_pass")

    with temp_config(tmpdir, auth_config) as config_dir, temp_environ(HOME=config_dir), \
            patch("hop.auth.read_new_credential", MagicMock(return_value=new_cred)):
        args = MagicMock()
        args.cred_file = None
        args.force = False
        auth.add_credential(args)
        check_credential_file(configure.get_config_path("auth"), old_cred)
        check_credential_file(configure.get_config_path("auth"), new_cred)
Exemple #6
0
def test_add_credential_to_nonempty_hostname_no_conflict(tmpdir):
    # unfortunately, we must permit duplicate usernames if one has a hostname and the other does not
    old_cred = auth.Auth("username", "password")
    new_cred = auth.Auth("username", "other_pass", "example.com")

    with temp_environ(HOME=str(tmpdir)), \
            patch("hop.auth.load_auth", MagicMock(return_value=[old_cred])), \
            patch("hop.auth.read_new_credential", MagicMock(return_value=new_cred)):
        args = MagicMock()
        args.cred_file = None
        args.force = False
        auth.add_credential(args)
        check_credential_file(configure.get_config_path("auth"), old_cred)
        check_credential_file(configure.get_config_path("auth"), new_cred)
Exemple #7
0
def test_add_credential_conflict_no_host(tmpdir, caplog):
    old_cred = auth.Auth("username", "password")
    new_cred = auth.Auth("username", "other_pass")

    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])
        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)
Exemple #8
0
def test_add_credential_to_empty(tmpdir):
    new_cred = auth.Auth("user", "pass")

    with temp_environ(HOME=str(tmpdir)), \
            patch("hop.auth.read_new_credential", MagicMock(return_value=new_cred)):
        args = MagicMock()
        args.cred_file = None
        args.force = False
        auth.add_credential(args)
        check_credential_file(configure.get_config_path("auth"), new_cred)
Exemple #9
0
def test_write_config_data(tmpdir):
    config_file = tmpdir + "/config"
    username = "******"
    password = "******"
    auth.write_auth_data(config_file, [auth.Auth(username, password)])
    check_credential_file(config_file, auth.Auth(username, password))

    credential_write_read_round_trip(auth.Auth(username, password),
                                     config_file)
    credential_write_read_round_trip(
        auth.Auth(username, password, host="example.com"), config_file)
    credential_write_read_round_trip(auth.Auth(username, password, ssl=False),
                                     config_file)
    credential_write_read_round_trip(
        auth.Auth(username, password, method=auth.SASLMethod.SCRAM_SHA_256),
        config_file)
    credential_write_read_round_trip(
        auth.Auth(username, password, ssl_ca_location="ca.cert"), config_file)
Exemple #10
0
def test_auth_mechanism():
    a = auth.Auth("foo", "bar")  # use default mechanism
    assert a.mechanism == str(auth.SASLMethod.SCRAM_SHA_512)
    a = auth.Auth("foo", "bar", method=auth.SASLMethod.SCRAM_SHA_256)
    assert a.mechanism == str(auth.SASLMethod.SCRAM_SHA_256)
Exemple #11
0
def test_auth_hostname():
    a = auth.Auth("foo", "bar")  # use default hostname
    assert a.hostname == ""
    a = auth.Auth("foo", "bar", "example.com")
    assert a.hostname == "example.com"
Exemple #12
0
def test_select_auth_ambiguity():
    too_many = "Ambiguous credentials found"

    two_vague_creds = [
        auth.Auth("user1", "pass1"),
        auth.Auth("user2", "pass2"),
    ]

    # given two credetials with no associated hostnames, any lookup which does not specify the
    # username will be ambiguous
    with pytest.raises(RuntimeError) as err:
        selected = auth.select_matching_auth(two_vague_creds, "example.com")
    assert f"{too_many} for hostname 'example.com' with no username specified" in err.value.args[
        0]
    assert "user1 which has no associated hostname" in err.value.args[0]
    assert "user2 which has no associated hostname" in err.value.args[0]

    # specifying a valid username should resolve the ambiguity
    for username in ["user1", "user2"]:
        selected = auth.select_matching_auth(two_vague_creds, "example.com",
                                             username)
        assert selected.username == username

    two_vague_creds = [
        auth.Auth("user1", "pass1"),
        auth.Auth("user3", "pass3", host="example.com"),
    ]
    # given a credential with no hostname and one with, a request which matches the one with a
    # hostname should _not_ be ambiguous
    selected = auth.select_matching_auth(two_vague_creds, "example.com")
    assert selected.username == "user3"

    two_specific_creds = [
        auth.Auth("user3", "pass3", host="example.com"),
        auth.Auth("user4", "pass4", host="example.com"),
    ]

    # given two credentials which both exactly match the requested hostname there should again be
    # an ambiguity
    with pytest.raises(RuntimeError) as err:
        selected = auth.select_matching_auth(two_specific_creds, "example.com")
    assert f"{too_many} for hostname 'example.com'" in err.value.args[0]
    assert "user3 for example.com" in err.value.args[0]
    assert "user4 for example.com" in err.value.args[0]

    # specifying a valid username should again resolve the ambiguity
    for username in ["user3", "user4"]:
        selected = auth.select_matching_auth(two_specific_creds, "example.com",
                                             username)
        assert selected.username == username

    # No single source of credentials should issue two credentials with the same username, however,
    # two separate issuers could issue ones with the same name, and if neither specifies a hostname
    # they will be ambiguous.
    # (Duplicate usernames with matching hostnames should be impossible, as there should not be two
    # issuers for the same hostname)
    duplicate_users = [
        auth.Auth("user", "pass5"),
        auth.Auth("user", "pass6"),
    ]
    with pytest.raises(RuntimeError) as err:
        selected = auth.select_matching_auth(duplicate_users, "example.com")
    assert f"{too_many} for hostname 'example.com'" in err.value.args[0]
    assert "user which has no associated hostname" in err.value.args[0]
    assert "user which has no associated hostname" in err.value.args[0]

    # specifying a username woun't help, since they are duplicates
    with pytest.raises(RuntimeError) as err:
        selected = auth.select_matching_auth(duplicate_users, "example.com",
                                             "user")
    assert f"{too_many} for hostname 'example.com'" in err.value.args[0]
    assert "user which has no associated hostname" in err.value.args[0]
    assert "user which has no associated hostname" in err.value.args[0]
Exemple #13
0
def test_auth_password():
    a = auth.Auth("foo", "bar")
    assert a.password == "bar"
Exemple #14
0
def test_auth_username():
    a = auth.Auth("foo", "bar")
    assert a.username == "foo"
Exemple #15
0
        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


delete_input_creds = [
    auth.Auth("user1", "pass1"),
    auth.Auth("user2", "pass2"),
    auth.Auth("user3", "pass3", "example.com"),
    auth.Auth("user3", "pass3-alt", "example.net"),
]


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)