Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Commit

Permalink
Auto merge of #3898 - frsyuki:git-http-configured-auth, r=indirect
Browse files Browse the repository at this point in the history
Private access credentials for private git repositories

Pull-request #2825 added support for authorization credentials provided by bundle-config for rubygems source. This change adds the same support for HTTP(S) URL of git source.

Users can provide username and password as following:

    bundle config https://github.com/bundler/bundler.git username:password

or

    export BUNDLE_GITHUB__COM=username:password

Especially for private repositories on Github, users can use personal OAuth tokens:

    export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x-oauth-basic

This enables us to easily deploy ruby code hosted on github private repositories to production servers where storing shared password in plain text at `~/.git-credentials` is security risk.
  • Loading branch information
homu committed Aug 3, 2015
2 parents 69475cb + 832dedd commit 7cad928
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
23 changes: 18 additions & 5 deletions lib/bundler/source/git/git_proxy.rb
Expand Up @@ -68,12 +68,12 @@ def checkout
return if has_revision_cached?
Bundler.ui.confirm "Updating #{uri}"
in_path do
git_retry %|fetch --force --quiet --tags #{uri_escaped} "refs/heads/*:refs/heads/*"|
git_retry %|fetch --force --quiet --tags #{uri_escaped_with_configured_credentials} "refs/heads/*:refs/heads/*"|
end
else
Bundler.ui.info "Fetching #{uri}"
FileUtils.mkdir_p(path.dirname)
git_retry %|clone #{uri_escaped} "#{path}" --bare --no-hardlinks --quiet|
git_retry %|clone #{uri_escaped_with_configured_credentials} "#{path}" --bare --no-hardlinks --quiet|
end
end

Expand Down Expand Up @@ -136,15 +136,28 @@ def has_revision_cached?
end

# Escape the URI for git commands
def uri_escaped
def uri_escaped_with_configured_credentials
remote = configured_uri_for(uri)
if Bundler::WINDOWS
# Windows quoting requires double quotes only, with double quotes
# inside the string escaped by being doubled.
'"' + uri.gsub('"') { '""' } + '"'
'"' + remote.gsub('"') { '""' } + '"'
else
# Bash requires single quoted strings, with the single quotes escaped
# by ending the string, escaping the quote, and restarting the string.
"'" + uri.gsub("'") { "'\\''" } + "'"
"'" + remote.gsub("'") { "'\\''" } + "'"
end
end

# Adds credentials to the URI as Fetcher#configured_uri_for does
def configured_uri_for(uri)
if /https?:/ =~ uri
remote = URI(uri)
config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
remote.userinfo ||= config_auth
remote.to_s
else
uri
end
end

Expand Down
34 changes: 34 additions & 0 deletions spec/bundler/source/git/git_proxy_spec.rb
@@ -0,0 +1,34 @@
require "spec_helper"

describe Bundler::Source::Git::GitProxy do
let(:uri) { "https://github.com/bundler/bundler.git" }
subject { described_class.new(Pathname("path"), uri, "HEAD") }

context "with configured credentials" do
it "adds username and password to URI" do
Bundler.settings[uri] = "u:p"
expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/bundler/bundler.git"))
subject.checkout
end

it "adds username and password to URI for host" do
Bundler.settings["github.com"] = "u:p"
expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/bundler/bundler.git"))
subject.checkout
end

it "does not add username and password to mismatched URI" do
Bundler.settings["https://u:p@github.com/bundler/bundler-mismatch.git"] = "u:p"
expect(subject).to receive(:git_retry).with(match(uri))
subject.checkout
end

it "keeps original userinfo" do
Bundler.settings["github.com"] = "u:p"
original = "https://orig:info@github.com/bundler/bundler.git"
subject = described_class.new(Pathname("path"), original, "HEAD")
expect(subject).to receive(:git_retry).with(match(original))
subject.checkout
end
end
end

0 comments on commit 7cad928

Please sign in to comment.