Class: Travis::Tools::Github

Inherits:
Object
  • Object
show all
Defined in:
lib/travis/tools/github.rb

Constant Summary collapse

TOKEN_SIZE =
40
GITHUB_API =
'api.github.com'
GITHUB_HOST =
'github.com'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) {|_self| ... } ⇒ Github

Returns a new instance of Github.

Yields:

  • (_self)

Yield Parameters:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/travis/tools/github.rb', line 16

def initialize(options = nil)
  @check_token     = true
  @manual_login    = true
  @ask_login       = proc { raise "ask_login callback not set" }
  @after_tokens    = proc { }
  @ask_password    = proc { |_| raise "ask_password callback not set" }
  @ask_otp         = proc { |_| raise "ask_otp callback not set" }
  @debug           = proc { |_| }
  @netrc_path      = '~/.netrc'
  @hub_path        = ENV['HUB_CONFIG'] || '~/.config/hub'
  @oauth_paths     = ['~/.github-oauth-token']
  @composer_path   = "~/.composer/config.json"
  @note            = 'temporary token'
  @git_config_keys = %w[github.token github.oauth-token]
  @scopes          = ['user', 'user:email', 'repo'] # overridden by value from /config
  options.each_pair { |k,v| send("#{k}=", v) if respond_to? "#{k}=" } if options
  yield self if block_given?
end

Instance Attribute Details

#after_tokensObject

Returns the value of attribute after_tokens.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def after_tokens
  @after_tokens
end

#api_urlObject

Returns the value of attribute api_url.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def api_url
  @api_url
end

#ask_loginObject

Returns the value of attribute ask_login.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def 
  @ask_login
end

#ask_otpObject

Returns the value of attribute ask_otp.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def ask_otp
  @ask_otp
end

#ask_passwordObject

Returns the value of attribute ask_password.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def ask_password
  @ask_password
end

#auto_passwordObject

Returns the value of attribute auto_password.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def auto_password
  @auto_password
end

#auto_tokenObject

Returns the value of attribute auto_token.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def auto_token
  @auto_token
end

#callbackObject

Returns the value of attribute callback.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def callback
  @callback
end

#check_tokenObject

Returns the value of attribute check_token.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def check_token
  @check_token
end

#composer_pathObject

Returns the value of attribute composer_path.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def composer_path
  @composer_path
end

#debug=(value) ⇒ Object

Sets the attribute debug

Parameters:

  • value

    the value to set the attribute debug to.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def debug=(value)
  @debug = value
end

#drop_tokenObject

Returns the value of attribute drop_token.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def drop_token
  @drop_token
end

#explodeObject

Returns the value of attribute explode.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def explode
  @explode
end

#git_config_keysObject

Returns the value of attribute git_config_keys.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def git_config_keys
  @git_config_keys
end

#github_loginObject

Returns the value of attribute github_login.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def 
  @github_login
end

#github_tokenObject

Returns the value of attribute github_token.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def github_token
  @github_token
end

#hub_pathObject

Returns the value of attribute hub_path.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def hub_path
  @hub_path
end

#login_headerObject

Returns the value of attribute login_header.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def 
  @login_header
end

#manual_loginObject

Returns the value of attribute manual_login.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def 
  @manual_login
end

#netrc_pathObject

Returns the value of attribute netrc_path.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def netrc_path
  @netrc_path
end

#no_tokenObject

Returns the value of attribute no_token.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def no_token
  @no_token
end

#noteObject

Returns the value of attribute note.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def note
  @note
end

#oauth_pathsObject

Returns the value of attribute oauth_paths.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def oauth_paths
  @oauth_paths
end

#scopesObject

Returns the value of attribute scopes.



12
13
14
# File 'lib/travis/tools/github.rb', line 12

def scopes
  @scopes
end

Instance Method Details

#acceptable?(token) ⇒ Boolean

Returns:

  • (Boolean)


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/travis/tools/github.rb', line 210

def acceptable?(token)
  return true unless check_token
  gh   = GH.with(:token => token)
  user = gh['user']

  if  and  != user['login']
    debug "token is not acceptable: identifies %p instead of %p" % [user['login'], ]
    false
  else
    true
  end
rescue GH::Error => error
  debug "token is not acceptable: #{gh_error(error)}"
  false
end

#api_hostObject



189
190
191
192
# File 'lib/travis/tools/github.rb', line 189

def api_host
  return GITHUB_API unless api_url
  api_url[%r{^(?:https?://)?([^/]+)}, 1]
end

#composer_tokenObject



107
108
109
110
111
112
# File 'lib/travis/tools/github.rb', line 107

def composer_token
  file(composer_path) do |content|
    token = JSON.parse(content)['config'].fetch('github-oauth', {})[host]
    yield token if token
  end
end

#each_tokenObject



39
40
41
42
43
44
45
# File 'lib/travis/tools/github.rb', line 39

def each_token
  require 'gh' unless defined? GH
  possible_tokens { |t| yield(t) if acceptable?(t) }
ensure
  callback, self.callback = self.callback, nil
  callback.call if callback
end

#git_tokensObject



97
98
99
100
101
102
103
104
105
# File 'lib/travis/tools/github.rb', line 97

def git_tokens
  return unless System.has? 'git'
  git_config_keys.each do |key|
    `git config --get-all #{key}`.each_line do |line|
      token = line.strip
      yield token unless token.empty?
    end
  end
end

#github_for_mac_token(&block) ⇒ Object



179
180
181
182
183
# File 'lib/travis/tools/github.rb', line 179

def github_for_mac_token(&block)
  command = '-s "github.com/mac"'
  command << " -a #{}" if 
  security(:internet, :w, command, "GitHub for Mac token", &block) if host == 'github.com'
end

#hostObject



185
186
187
# File 'lib/travis/tools/github.rb', line 185

def host
  api_host == GITHUB_API ? GITHUB_HOST : api_host
end

#hubObject



169
170
171
172
173
# File 'lib/travis/tools/github.rb', line 169

def hub
  file(hub_path, {}) do |contents|
    YAML.load(contents)
  end
end

#hub_loginsObject



138
139
140
141
142
143
# File 'lib/travis/tools/github.rb', line 138

def hub_logins
  hub.fetch(host, []).each do |entry|
    next if  and  != entry["user"]
    yield entry["user"], entry["password"] if entry["user"] and entry["password"]
  end
end

#hub_tokensObject



114
115
116
117
118
119
# File 'lib/travis/tools/github.rb', line 114

def hub_tokens
  hub.fetch(host, []).each do |entry|
    next if  and  != entry["user"]
    yield entry["oauth_token"] if entry["oauth_token"]
  end
end

#issuepost_token(&block) ⇒ Object



175
176
177
# File 'lib/travis/tools/github.rb', line 175

def issuepost_token(&block)
  security(:generic, :w, "-l issuepost.github.access_token",  "issuepost token", &block) if host == 'github.com'
end

#keychain_loginObject



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/travis/tools/github.rb', line 145

def 
  if 
    security(:internet, :w, "-s #{host} -a #{}", "#{host} password for #{}") do |password|
      yield , password if password and not password.empty?
    end
  else
    security(:internet, :g, "-s #{host}", "#{host} login and password") do |data|
      username = data[/^\s+"acct"<blob>="(.*)"$/, 1].to_s
      password = data[/^password: "(.*)"$/, 1].to_s
      yield username, password unless username.empty? or password.empty?
    end
  end
end

#login(user, password, die = true, otp = nil) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/travis/tools/github.rb', line 194

def (user, password, die = true, otp = nil)
  opt           = { :username => user, :password => password }
  opt[:headers] = { "X-GitHub-OTP" => otp } if otp
  gh            = GH.with(opt)
  reply         = gh.post('/authorizations', :scopes => scopes, :note => note)
  self.callback = proc { gh.delete reply['_links']['self']['href'] } if drop_token
  reply['token']
rescue GH::Error => error
  if error.info[:response_status] == 401 and error.info[:response_headers]['x-github-otp'].to_s =~ /required/
    otp = ask_otp.arity == 0 ? ask_otp.call : ask_otp.call(user)
    (user, password, die, otp)
  elsif die
    raise gh_error(error)
  end
end

#netrcObject



159
160
161
162
163
164
165
166
167
# File 'lib/travis/tools/github.rb', line 159

def netrc
  file(netrc_path, []) do |contents|
    contents.scan(/^\s*(\S+)\s+(\S+)\s*$/).inject([]) do |mapping, (key, value)|
      mapping << {} if key == "machine"
      mapping.last[key] = value if mapping.last
      mapping
    end
  end
end

#netrc_loginsObject



130
131
132
133
134
135
136
# File 'lib/travis/tools/github.rb', line 130

def netrc_logins
  netrc.each do |entry|
    next unless entry["machine"] == api_host or entry["machine"] == host
    next if  and  != entry["login"]
    yield entry["login"], entry["password"] if entry["login"] and entry["password"]
  end
end

#netrc_tokensObject



86
87
88
89
90
91
92
93
94
95
# File 'lib/travis/tools/github.rb', line 86

def netrc_tokens
  netrc.each do |entry|
    next unless entry["machine"] == api_host or entry["machine"] == host
    entry.values_at("token", "login", "password").each do |entry|
      next if entry.to_s.size != TOKEN_SIZE
      debug "found oauth token in netrc"
      yield entry
    end
  end
end

#oauth_file_tokens(&block) ⇒ Object



121
122
123
124
125
126
127
128
# File 'lib/travis/tools/github.rb', line 121

def oauth_file_tokens(&block)
  oauth_paths.each do |path|
    file(path) do |content|
      token = content.strip
      yield token unless token.empty?
    end
  end
end

#possible_logins(&block) ⇒ Object



80
81
82
83
84
# File 'lib/travis/tools/github.rb', line 80

def possible_logins(&block)
  netrc_logins(&block)
  hub_logins(&block)
  (&block)
end

#possible_tokens(&block) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/travis/tools/github.rb', line 51

def possible_tokens(&block)
  return block[github_token] if github_token

  if auto_token
    netrc_tokens(&block)
    git_tokens(&block)
    hub_tokens(&block)
    oauth_file_tokens(&block)
    github_for_mac_token(&block)
    issuepost_token(&block)
    composer_token(&block)
  end

  if auto_password
    possible_logins do |user, password|
      yield (user, password, false)
    end
  end

  if 
    .call if 
    user     =  || .call
    password = ask_password.arity == 0 ? ask_password.call : ask_password.call(user)
    yield (user, password, true)
  end

  after_tokens.call
end

#with_session(&block) ⇒ Object



47
48
49
# File 'lib/travis/tools/github.rb', line 47

def with_session(&block)
  with_token { |t| GH.with(:token => t) { yield(t) } }
end

#with_tokenObject



35
36
37
# File 'lib/travis/tools/github.rb', line 35

def with_token
  each_token { |t| break yield(t) }
end