Skip to content

Commit

Permalink
Fix issue where approved credentials were not sent to git credential …
Browse files Browse the repository at this point in the history
…helpers (#40161)

Due to the bug in the `GitCredential` constructor we were never writing
credential data to the credential helper effectively making our use of
git credential helpers read-only.
  • Loading branch information
omus authored Mar 29, 2021
1 parent 6e4ea5b commit ac50ac6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
7 changes: 6 additions & 1 deletion stdlib/LibGit2/src/gitcredential.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ function GitCredential(cfg::GitConfig, url::AbstractString)
fill!(cfg, parse(GitCredential, url))
end

GitCredential(cred::UserPasswordCredential, url::AbstractString) = parse(GitCredential, url)
function GitCredential(user_pass_cred::UserPasswordCredential, url::AbstractString)
cred = parse(GitCredential, url)
cred.username = user_pass_cred.user
cred.password = deepcopy(user_pass_cred.pass)
return cred
end

Base.:(==)(c1::GitCredential, c2::GitCredential) = (c1.protocol, c1.host, c1.path, c1.username, c1.password, c1.use_http_path) ==
(c2.protocol, c2.host, c2.path, c2.username, c2.password, c2.use_http_path)
Expand Down
61 changes: 61 additions & 0 deletions stdlib/LibGit2/test/libgit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,23 @@ end
github_regex_test("ssh://[email protected]/$user/$repo", user, repo)
@test !occursin(LibGit2.GITHUB_REGEX, "[email protected]/$user/$repo.git")
end

@testset "UserPasswordCredential/url constructor" begin
user_pass_cred = LibGit2.UserPasswordCredential("user", "*******")
url = "https://github.com"
expected_cred = LibGit2.GitCredential("https", "github.com", nothing, "user", "*******")

cred = LibGit2.GitCredential(user_pass_cred, url)
@test cred == expected_cred

# Shredding the UserPasswordCredential shouldn't result in information being lost
# inside of a GitCredential.
Base.shred!(user_pass_cred)
@test cred == expected_cred

Base.shred!(cred)
Base.shred!(expected_cred)
end
end

mktempdir() do dir
Expand Down Expand Up @@ -2133,6 +2150,50 @@ mktempdir() do dir
end
end
end

@testset "approve/reject with UserPasswordCredential" begin
# In order to use the "store" credential helper `git` needs to be installed and
# on the path.
if GIT_INSTALLED
config_path = joinpath(dir, config_file)
isfile(config_path) && rm(config_path)

credential_path = joinpath(dir, ".git-credentials")
isfile(credential_path) && rm(credential_path)

LibGit2.with(LibGit2.GitConfig(config_path, LibGit2.Consts.CONFIG_LEVEL_APP)) do cfg
query = LibGit2.GitCredential("https", "mygithost")
filled = LibGit2.GitCredential("https", "mygithost", nothing, "alice", "1234")
user_pass_cred = LibGit2.UserPasswordCredential("alice", "1234")
url = "https://mygithost"

# Requires `git` to be installed and available on the path.
LibGit2.set!(cfg, "credential.helper", "store --file \"$credential_path\"")
helper = only(LibGit2.credential_helpers(cfg, query))

@test !isfile(credential_path)

Base.shred!(LibGit2.fill!(helper, deepcopy(query))) do result
@test result == query
end

LibGit2.approve(cfg, user_pass_cred, url)
@test isfile(credential_path)
Base.shred!(LibGit2.fill!(helper, deepcopy(query))) do result
@test result == filled
end

LibGit2.reject(cfg, user_pass_cred, url)
Base.shred!(LibGit2.fill!(helper, deepcopy(query))) do result
@test result == query
end

Base.shred!(query)
Base.shred!(filled)
Base.shred!(user_pass_cred)
end
end
end
end

# The following tests require that we can fake a TTY so that we can provide passwords
Expand Down

0 comments on commit ac50ac6

Please sign in to comment.