Class: Heroku::Auth
- Inherits:
-
Object
show all
- Extended by:
- Helpers
- Defined in:
- lib/heroku/auth.rb
Class Attribute Summary collapse
Class Method Summary
collapse
Methods included from Helpers
action, ask, confirm, confirm_billing, confirm_command, create_git_remote, deprecate, display, display_header, display_object, display_row, display_table, error, error_with_failure, error_with_failure=, extended, extended_into, fail, format_bytes, format_date, format_error, format_with_bang, get_terminal_environment, git, has_git?, home_directory, host_name, hprint, hputs, included, included_into, json_decode, json_encode, launchy, line_formatter, longest, output_with_bang, quantify, redisplay, retry_on_exception, run_command, running_on_a_mac?, running_on_windows?, set_buffer, shell, spinner, status, string_distance, styled_array, styled_error, styled_hash, styled_header, suggestion, time_ago, truncate, with_tty
Class Attribute Details
.credentials ⇒ Object
Returns the value of attribute credentials.
12
13
14
|
# File 'lib/heroku/auth.rb', line 12
def credentials
@credentials
end
|
Class Method Details
.api ⇒ Object
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# File 'lib/heroku/auth.rb', line 14
def api
@api ||= begin
require("heroku-api")
api = Heroku::API.new(default_params.merge(:api_key => password))
def api.request(params, &block)
response = super
if response..has_key?('X-Heroku-Warning')
Heroku::Command.warnings.concat(response.['X-Heroku-Warning'].split("\n"))
end
response
end
api
end
end
|
.api_key(user = get_credentials[0], password = get_credentials[1]) ⇒ Object
77
78
79
80
81
|
# File 'lib/heroku/auth.rb', line 77
def api_key(user = get_credentials[0], password = get_credentials[1])
require("heroku-api")
api = Heroku::API.new(default_params)
api.post_login(user, password).body["api_key"]
end
|
.ask_for_and_save_credentials ⇒ Object
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/heroku/auth.rb', line 218
def ask_for_and_save_credentials
require("heroku-api") begin
@credentials = ask_for_credentials
write_credentials
check
rescue Heroku::API::Errors::NotFound, Heroku::API::Errors::Unauthorized => e
delete_credentials
display "Authentication failed."
retry if retry_login?
exit 1
rescue Exception => e
delete_credentials
raise e
end
check_for_associated_ssh_key unless Heroku::Command.current_command == "keys:add"
@credentials
end
|
.ask_for_credentials ⇒ Object
180
181
182
183
184
185
186
187
188
189
190
|
# File 'lib/heroku/auth.rb', line 180
def ask_for_credentials
puts "Enter your #{host_name} credentials."
print "Email: "
user = ask
print "Password (typing will be hidden): "
password = running_on_windows? ? ask_for_password_on_windows : ask_for_password
[user, api_key(user, password)]
end
|
.ask_for_password ⇒ Object
210
211
212
213
214
215
216
|
# File 'lib/heroku/auth.rb', line 210
def ask_for_password
echo_off
password = ask
puts
echo_on
return password
end
|
.ask_for_password_on_windows ⇒ Object
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
# File 'lib/heroku/auth.rb', line 192
def ask_for_password_on_windows
require "Win32API"
char = nil
password = ''
while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
break if char == 10 || char == 13 if char == 127 || char == 8 password.slice!(-1, 1)
else
(password << char.chr) rescue RangeError
end
end
puts
return password
end
|
.associate_key(key) ⇒ Object
287
288
289
290
291
292
293
294
295
|
# File 'lib/heroku/auth.rb', line 287
def associate_key(key)
action("Uploading SSH public key #{key}") do
if File.exists?(key)
api.post_key(File.read(key))
else
error("Could not upload SSH public key: key file '" + key + "' does not exist")
end
end
end
|
.associate_or_generate_ssh_key ⇒ Object
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
# File 'lib/heroku/auth.rb', line 243
def associate_or_generate_ssh_key
public_keys = Dir.glob("#{home_directory}/.ssh/*.pub").sort
case public_keys.length
when 0 then
display "Could not find an existing public key."
display "Would you like to generate one? [Yn] ", false
unless ask.strip.downcase == "n"
display "Generating new SSH public key."
generate_ssh_key("id_rsa")
associate_key("#{home_directory}/.ssh/id_rsa.pub")
end
when 1 then
display "Found existing public key: #{public_keys.first}"
associate_key(public_keys.first)
else
display "Found the following SSH public keys:"
public_keys.each_with_index do |key, index|
display "#{index+1}) #{File.basename(key)}"
end
display "Which would you like to use with your Pogoapp account? ", false
choice = ask.to_i - 1
chosen = public_keys[choice]
if choice == -1 || chosen.nil?
error("Invalid choice")
end
associate_key(chosen)
end
end
|
.base_host(host) ⇒ Object
307
308
309
310
311
|
# File 'lib/heroku/auth.rb', line 307
def base_host(host)
parts = URI.parse(full_host(host)).host.split(".")
return parts.first if parts.size == 1
parts[-2..-1].join(".")
end
|
.check ⇒ Object
just a stub; will raise if not authenticated
49
50
51
|
# File 'lib/heroku/auth.rb', line 49
def check
api.get_user
end
|
.check_for_associated_ssh_key ⇒ Object
237
238
239
240
241
|
# File 'lib/heroku/auth.rb', line 237
def check_for_associated_ssh_key
if api.get_keys.body.empty?
associate_or_generate_ssh_key
end
end
|
.client ⇒ Object
31
32
33
34
35
36
37
|
# File 'lib/heroku/auth.rb', line 31
def client
@client ||= begin
client = Heroku::Client.new(user, password, host)
client.on_warning { |msg| self.display("\n#{msg}\n\n") }
client
end
end
|
.default_host ⇒ Object
53
54
55
|
# File 'lib/heroku/auth.rb', line 53
def default_host
"heroku.com"
end
|
.delete_credentials ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/heroku/auth.rb', line 87
def delete_credentials
if File.exists?(legacy_credentials_path)
FileUtils.rm_f(legacy_credentials_path)
end
if netrc
netrc.delete("api.#{host}")
netrc.delete("code.#{host}")
netrc.save
end
@api, @client, @credentials = nil, nil
end
|
.echo_off ⇒ Object
168
169
170
171
172
|
# File 'lib/heroku/auth.rb', line 168
def echo_off
with_tty do
system "stty -echo"
end
end
|
.echo_on ⇒ Object
174
175
176
177
178
|
# File 'lib/heroku/auth.rb', line 174
def echo_on
with_tty do
system "stty echo"
end
end
|
.full_host(host) ⇒ Object
313
314
315
|
# File 'lib/heroku/auth.rb', line 313
def full_host(host)
(host =~ /^http/) ? host : "https://api.#{host}"
end
|
.generate_ssh_key(keyfile) ⇒ Object
273
274
275
276
277
278
279
280
281
282
283
284
285
|
# File 'lib/heroku/auth.rb', line 273
def generate_ssh_key(keyfile)
ssh_dir = File.join(home_directory, ".ssh")
unless File.exists?(ssh_dir)
FileUtils.mkdir_p ssh_dir
unless running_on_windows?
File.chmod(0700, ssh_dir)
end
end
output = `ssh-keygen -t rsa -N "" -f \"#{home_directory}/.ssh/#{keyfile}\" 2>&1`
if ! $?.success?
error("Could not generate key: #{output}")
end
end
|
.get_credentials ⇒ Object
83
84
85
|
# File 'lib/heroku/auth.rb', line 83
def get_credentials @credentials ||= (read_credentials || ask_for_and_save_credentials)
end
|
.git_host ⇒ Object
57
58
59
|
# File 'lib/heroku/auth.rb', line 57
def git_host
ENV['HEROKU_GIT_HOST'] || host
end
|
.host ⇒ Object
61
62
63
|
# File 'lib/heroku/auth.rb', line 61
def host
ENV['HEROKU_HOST'] || default_host
end
|
.legacy_credentials_path ⇒ Object
99
100
101
102
103
104
105
|
# File 'lib/heroku/auth.rb', line 99
def legacy_credentials_path
if host == default_host
"#{home_directory}/.heroku/credentials"
else
"#{home_directory}/.heroku/credentials.#{CGI.escape(host)}"
end
end
|
.login ⇒ Object
39
40
41
42
|
# File 'lib/heroku/auth.rb', line 39
def login
delete_credentials
get_credentials
end
|
.logout ⇒ Object
44
45
46
|
# File 'lib/heroku/auth.rb', line 44
def logout
delete_credentials
end
|
.netrc ⇒ Object
117
118
119
120
121
122
123
124
125
126
127
128
|
# File 'lib/heroku/auth.rb', line 117
def netrc @netrc ||= begin
File.exists?(netrc_path) && Netrc.read(netrc_path)
rescue => error
if error.message =~ /^Permission bits for/
perm = File.stat(netrc_path).mode & 0777
abort("Permissions #{perm} for '#{netrc_path}' are too open. You should run `chmod 0600 #{netrc_path}` so that your credentials are NOT accessible by others.")
else
raise error
end
end
end
|
.netrc_path ⇒ Object
107
108
109
110
111
112
113
114
115
|
# File 'lib/heroku/auth.rb', line 107
def netrc_path
default = Netrc.default_path
encrypted = default + ".gpg"
if File.exists?(encrypted)
encrypted
else
default
end
end
|
.password ⇒ Object
73
74
75
|
# File 'lib/heroku/auth.rb', line 73
def password get_credentials[1]
end
|
.read_credentials ⇒ Object
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/heroku/auth.rb', line 130
def read_credentials
if ENV['HEROKU_API_KEY']
['', ENV['HEROKU_API_KEY']]
else
if File.exists?(legacy_credentials_path)
@api, @client = nil
@credentials = File.read(legacy_credentials_path).split("\n")
write_credentials
FileUtils.rm_f(legacy_credentials_path)
end
if netrc
credentials = netrc["api.#{host}"]
if credentials && credentials[1].length > 40
@credentials = [ credentials[0], credentials[1][0,40] ]
write_credentials
end
netrc["api.#{host}"]
end
end
end
|
.reauthorize ⇒ Object
65
66
67
|
# File 'lib/heroku/auth.rb', line 65
def reauthorize
@credentials = ask_for_and_save_credentials
end
|
.retry_login? ⇒ Boolean
297
298
299
300
301
|
# File 'lib/heroku/auth.rb', line 297
def retry_login?
@login_attempts ||= 0
@login_attempts += 1
@login_attempts < 3
end
|
.user ⇒ Object
69
70
71
|
# File 'lib/heroku/auth.rb', line 69
def user get_credentials[0]
end
|
.verified_hosts ⇒ Object
303
304
305
|
# File 'lib/heroku/auth.rb', line 303
def verified_hosts
%w( heroku.com heroku-shadow.com )
end
|
.verify_host?(host) ⇒ Boolean
317
318
319
320
321
322
|
# File 'lib/heroku/auth.rb', line 317
def verify_host?(host)
hostname = base_host(host)
verified = verified_hosts.include?(hostname)
verified = false if ENV["HEROKU_SSL_VERIFY"] == "disable"
verified
end
|
.write_credentials ⇒ Object
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/heroku/auth.rb', line 157
def write_credentials
FileUtils.mkdir_p(File.dirname(netrc_path))
FileUtils.touch(netrc_path)
unless running_on_windows?
FileUtils.chmod(0600, netrc_path)
end
netrc["api.#{host}"] = self.credentials
netrc["code.#{host}"] = self.credentials
netrc.save
end
|