Class: ReleaseManager::Git::Credentials

Inherits:
Object
  • Object
show all
Includes:
Logger
Defined in:
lib/release_manager/git/credentials.rb

Instance Method Summary collapse

Methods included from Logger

#color, #log_level, #logger

Constructor Details

#initialize(repository = nil) ⇒ Credentials

Returns a new instance of Credentials.

Parameters:

  • repository (Rugged::BaseRepository) (defaults to: nil)


11
12
13
14
# File 'lib/release_manager/git/credentials.rb', line 11

def initialize(repository = nil)
  @repository = repository
  @called = 0
end

Instance Method Details

#call(url, username_from_url = 'git', allowed_types = [:ssh_key]) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/release_manager/git/credentials.rb', line 20

def call(url, username_from_url = 'git', allowed_types = [:ssh_key])
  @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 Exception.new("Authentication failed for Git remote %{url}.") % {url: url.inspect}
  end
  if allowed_types.include?(:ssh_key)
    # should also check to see if process is still alive
    begin
      if ENV['SSH_AUTH_SOCK'] or (ENV['SSH_AGENT_PID'] and Process.getpgid( ENV['SSH_AGENT_PID'].to_i ))
        ssh_agent_credentials
      else
        logger.warn("Could not find ssh-agent running, falling back to ssh key")
        ssh_key_credentials
      end
    rescue Errno::ESRCH
      ssh_key_credentials
    end
  else
    default_credentials
  end
end

#default_credentialsObject



86
87
88
# File 'lib/release_manager/git/credentials.rb', line 86

def default_credentials
  Rugged::Credentials::Default.new
end

#git_usernameObject



90
91
92
# File 'lib/release_manager/git/credentials.rb', line 90

def git_username
  'git'
end

#global_private_keyObject

this assumes the user has the private key in their home folder we should be smarter about getting this, maybe consulting ssh directory to find out which key is for the host if using an ssh config file additionally if the key is password protected how do we prompt for the password?



53
54
55
56
57
58
59
# File 'lib/release_manager/git/credentials.rb', line 53

def global_private_key
  unless @global_private_key
    @global_private_key = ENV['SSH_PRIVATE_KEY'] || File.expand_path(File.join(ENV['HOME'], '.ssh', 'id_rsa'))
    logger.info("Using ssh private key #{@global_private_key}")
  end
  @global_private_key
end

#global_public_keyObject



61
62
63
64
65
66
67
# File 'lib/release_manager/git/credentials.rb', line 61

def global_public_key
  unless @global_public_key
    @global_public_key = ENV['SSH_PUBLIC_KEY'] || File.expand_path(File.join(ENV['HOME'], '.ssh', 'id_rsa.pub'))
    logger.info("Using ssh public key #{@global_public_key}")
  end
  @global_public_key
end

#needs_auth?(url) ⇒ Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/release_manager/git/credentials.rb', line 16

def needs_auth?(url)
  url =~ /\Agit@/
end

#prompt_for_passwordObject



44
45
46
47
# File 'lib/release_manager/git/credentials.rb', line 44

def prompt_for_password
  print "Enter password for #{global_private_key}: "
  STDIN.noecho(&:gets).chomp
end

#ssh_agent_credentialsObject

SSH_AGENT_SOCK must be set



70
71
72
# File 'lib/release_manager/git/credentials.rb', line 70

def ssh_agent_credentials
  Rugged::Credentials::SshKeyFromAgent.new(username: git_username)
end

#ssh_key_credentials(url = nil) ⇒ Object

this method does currently now work



75
76
77
78
79
80
81
82
83
84
# File 'lib/release_manager/git/credentials.rb', line 75

def ssh_key_credentials(url = nil)
  logger.error("Must use ssh-agent, please run ssh-agent zsh, then ssh-add to load your ssh key")
  unless File.readable?(global_private_key)
    raise Exception.new("Unable to use SSH key auth for %{url}: private key %{private_key} is missing or unreadable" % {url: url.inspect, private_key: global_private_key.inspect} )
  end
  Rugged::Credentials::SshKey.new(:username => git_username,
                                  :privatekey => global_private_key,
                                  :publickey => global_public_key,
                                  :passphrase => prompt_for_password)
end