Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
![blame-goto-line](assets/blame-goto-line.png)

### Added
* support x509 commit signing [[@kaden-l-nelson](https://github.com/kaden-l-nelson)] ([#2514](https://github.com/gitui-org/gitui/issues/2514))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to go into the unreleased section

* support choosing checkout branch method when status is not empty [[@fatpandac](https://github.com/fatpandac)] ([#2404](https://github.com/extrawurst/gitui/issues/2404))
* support pre-push hook [[@xlai89](https://github.com/xlai89)] ([#1933](https://github.com/extrawurst/gitui/issues/1933))
* message tab supports pageUp and pageDown [[@xlai89](https://github.com/xlai89)] ([#2623](https://github.com/extrawurst/gitui/issues/2623))
Expand Down
73 changes: 66 additions & 7 deletions asyncgit/src/sync/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,24 @@ impl SignBuilder {
// Variants are described in the git config documentation
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgformat
match format.as_str() {
"openpgp" => {
"openpgp" | "x509" => {
// Try to retrieve the gpg program from the git configuration,
// moving from the least to the most specific config key,
// defaulting to "gpg" if nothing is explicitly defined (per git's implementation)
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgprogram
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgprogram
let program = config
.get_string("gpg.openpgp.program")
.get_string(
format!("gpg.{format}.program").as_str(),
)
.or_else(|_| config.get_string("gpg.program"))
.unwrap_or_else(|_| "gpg".to_string());
.unwrap_or_else(|_| {
(if format == "x509" {
"gpgsm"
} else {
"gpg"
})
.to_string()
});

// Optional signing key.
// If 'user.signingKey' is not set, we'll use 'user.name' and 'user.email'
Expand Down Expand Up @@ -152,9 +160,6 @@ impl SignBuilder {
signing_key,
}))
}
"x509" => Err(SignBuilderError::MethodNotImplemented(
String::from("x509"),
)),
"ssh" => {
let ssh_signer = config
.get_string("user.signingKey")
Expand Down Expand Up @@ -439,4 +444,58 @@ mod tests {

Ok(())
}

#[test]
fn test_x509_program_defaults() -> Result<()> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are just config tests would you feel up to provide a linux only e2e test that actually setsup the tools and executes this whole flow?

let (_tmp_dir, repo) = repo_init_empty()?;

{
let mut config = repo.config()?;
config.set_str("gpg.format", "x509")?;
}

let sign =
SignBuilder::from_gitconfig(&repo, &repo.config()?)?;

// default x509 program should be gpgsm
assert_eq!("gpgsm", sign.program());
// default signing key should be "name <email>" when not specified
assert_eq!("name <email>", sign.signing_key());

Ok(())
}

#[test]
fn test_x509_program_configs() -> Result<()> {
let (_tmp_dir, repo) = repo_init_empty()?;

{
let mut config = repo.config()?;
config.set_str("gpg.format", "x509")?;
config.set_str("gpg.program", "GPG_PROGRAM_TEST")?;
}

let sign =
SignBuilder::from_gitconfig(&repo, &repo.config()?)?;

// we get gpg.program, because gpg.x509.program is not set
assert_eq!("GPG_PROGRAM_TEST", sign.program());

{
let mut config = repo.config()?;
config.set_str(
"gpg.x509.program",
"GPG_X509_PROGRAM_TEST",
)?;
}

let sign =
SignBuilder::from_gitconfig(&repo, &repo.config()?)?;

// since gpg.x509.program is now set as well, it is more specific than
// gpg.program and therefore takes precedence
assert_eq!("GPG_X509_PROGRAM_TEST", sign.program());

Ok(())
}
}
Loading