class R10K::Git::Rugged::Credentials

Generate credentials for secured remote connections.

@api private

Public Class Methods

new(repository) click to toggle source

@param repository [R10K::Git::Rugged::BaseRepository]

# File lib/r10k/git/rugged/credentials.rb, line 13
def initialize(repository)
  @repository = repository
  @called = 0
end

Public Instance Methods

call(url, username_from_url, allowed_types) click to toggle source
# File lib/r10k/git/rugged/credentials.rb, line 18
def call(url, username_from_url, allowed_types)
  @called += 1

  # Break out of infinite HTTP auth retry loop introduced in libgit2/rugged 0.24.0, libssh
  # auth seems to already abort after ~50 attempts.
  if @called > 50
    raise R10K::Git::GitError.new(_("Authentication failed for Git remote %{url}.") % {url: url.inspect} )
  end

  if allowed_types.include?(:ssh_key)
    get_ssh_key_credentials(url, username_from_url)
  elsif allowed_types.include?(:plaintext)
    get_plaintext_credentials(url, username_from_url)
  else
    get_default_credentials(url, username_from_url)
  end
end
get_default_credentials(url, username_from_url) click to toggle source
# File lib/r10k/git/rugged/credentials.rb, line 69
def get_default_credentials(url, username_from_url)
  Rugged::Credentials::Default.new
end
get_git_username(url, username_from_url) click to toggle source
# File lib/r10k/git/rugged/credentials.rb, line 73
def get_git_username(url, username_from_url)
  git_user = R10K::Git.settings[:username]

  user = nil

  if !username_from_url.nil?
    user = username_from_url
    logger.debug2 _("URL %{url} includes the username %{username}, using that user for authentication.") % {url: url.inspect, username: username_from_url}
  elsif git_user
    user = git_user
    logger.debug2 _("URL %{url} did not specify a user, using %{user} from configuration") % {url: url.inspect, user: user.inspect}
  else
    user = Etc.getlogin
    logger.debug2 _("URL %{url} did not specify a user, using current user %{user}") % {url: url.inspect, user: user.inspect}
  end

  user
end
get_plaintext_credentials(url, username_from_url) click to toggle source
# File lib/r10k/git/rugged/credentials.rb, line 63
def get_plaintext_credentials(url, username_from_url)
  user = get_git_username(url, username_from_url)
  password = URI.parse(url).password || ''
  Rugged::Credentials::UserPassword.new(username: user, password: password)
end
get_ssh_key_credentials(url, username_from_url) click to toggle source
# File lib/r10k/git/rugged/credentials.rb, line 36
def get_ssh_key_credentials(url, username_from_url)
  user = get_git_username(url, username_from_url)

  per_repo_private_key = nil
  if per_repo_settings = R10K::Git.get_repo_settings(url)
    per_repo_private_key = per_repo_settings[:private_key]
  end

  global_private_key = R10K::Git.settings[:private_key]

  if per_repo_private_key
    private_key = per_repo_private_key
    logger.debug2 _("Using per-repository private key %{key} for URL %{url}") % {key: private_key, url: url.inspect}
  elsif global_private_key
    private_key = global_private_key
    logger.debug2 _("URL %{url} has no per-repository private key using '%{key}'." ) % {key: private_key, url: url.inspect}
  else
    raise R10K::Git::GitError.new(_("Git remote %{url} uses the SSH protocol but no private key was given") % {url: url.inspect}, :git_dir => @repository.path.to_s)
  end

  if !File.readable?(private_key)
    raise R10K::Git::GitError.new(_("Unable to use SSH key auth for %{url}: private key %{private_key} is missing or unreadable") % {url: url.inspect, private_key: private_key.inspect}, :git_dir => @repository.path.to_s)
  end

  Rugged::Credentials::SshKey.new(:username => user, :privatekey => private_key)
end