Implement SSH identity authentication
This commit is contained in:
@@ -701,7 +701,7 @@ url = "https://example.test/team/store.git"
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_remote_configuration_round_trips_without_https_credentials() -> TestResult {
|
||||
fn ssh_remote_configuration_round_trips_with_secret_free_authentication() -> TestResult {
|
||||
let fixture = ConfigurationFixture::new()?;
|
||||
fixture.write_explicit(
|
||||
r#"
|
||||
@@ -712,12 +712,27 @@ key_material = "keys"
|
||||
[[git.remotes]]
|
||||
name = "origin"
|
||||
url = "git@example.test:team/store.git"
|
||||
ssh_identity_file = "keys/id_ed25519"
|
||||
ssh_known_hosts_file = "known_hosts"
|
||||
"#,
|
||||
)?;
|
||||
let config = fixture.loader().load(Some(&fixture.explicit_path()))?;
|
||||
let remote = &config.git_remotes()[0];
|
||||
assert_eq!(remote.url(), "git@example.test:team/store.git");
|
||||
assert!(remote.https_credentials().is_none());
|
||||
let authentication = remote.ssh_authentication().expect("SSH authentication");
|
||||
assert_eq!(
|
||||
authentication.identity().key_file(),
|
||||
Some(
|
||||
fs::canonicalize(fixture.temporary.path())?
|
||||
.join("cwd/config/keys/id_ed25519")
|
||||
.as_path()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
authentication.known_hosts_file(),
|
||||
fs::canonicalize(fixture.temporary.path())?.join("cwd/config/known_hosts")
|
||||
);
|
||||
|
||||
config.update_git_identity(&GitIdentity::new("Alice", "alice@example.test")?)?;
|
||||
let reloaded = fixture.loader().load(Some(&fixture.explicit_path()))?;
|
||||
@@ -725,6 +740,70 @@ url = "git@example.test:team/store.git"
|
||||
let persisted = fs::read_to_string(fixture.explicit_path())?;
|
||||
assert!(!persisted.contains("server_id"));
|
||||
assert!(!persisted.contains("application_id"));
|
||||
assert!(!persisted.contains("passphrase"));
|
||||
assert!(persisted.contains("ssh_identity_file"));
|
||||
assert!(persisted.contains("ssh_known_hosts_file"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_authentication_requires_exactly_one_identity_source() -> TestResult {
|
||||
let fixture = ConfigurationFixture::new()?;
|
||||
fixture.write_explicit(
|
||||
r#"
|
||||
vault = "vault"
|
||||
default_key = "alice"
|
||||
key_material = "keys"
|
||||
|
||||
[[git.remotes]]
|
||||
name = "origin"
|
||||
url = "ssh://git@example.test/team/store.git"
|
||||
"#,
|
||||
)?;
|
||||
assert_eq!(
|
||||
fixture
|
||||
.loader()
|
||||
.load(Some(&fixture.explicit_path()))
|
||||
.expect_err("SSH identity is required"),
|
||||
ConfigError::InvalidField {
|
||||
field: "git.remotes.ssh_authentication"
|
||||
}
|
||||
);
|
||||
|
||||
fixture.write_explicit(
|
||||
r#"
|
||||
vault = "vault"
|
||||
default_key = "alice"
|
||||
key_material = "keys"
|
||||
|
||||
[[git.remotes]]
|
||||
name = "origin"
|
||||
url = "ssh://git@example.test/team/store.git"
|
||||
ssh_agent_fingerprint = "SHA256:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
ssh_agent_socket = "agent.sock"
|
||||
ssh_known_hosts_file = "known_hosts"
|
||||
"#,
|
||||
)?;
|
||||
let config = fixture.loader().load(Some(&fixture.explicit_path()))?;
|
||||
let authentication = config.git_remotes()[0]
|
||||
.ssh_authentication()
|
||||
.expect("SSH authentication");
|
||||
assert_eq!(
|
||||
authentication
|
||||
.identity()
|
||||
.agent_fingerprint()
|
||||
.expect("agent fingerprint")
|
||||
.as_str(),
|
||||
"SHA256:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
);
|
||||
assert_eq!(
|
||||
authentication.identity().agent_socket(),
|
||||
Some(
|
||||
fs::canonicalize(fixture.temporary.path())?
|
||||
.join("cwd/config/agent.sock")
|
||||
.as_path()
|
||||
)
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user