Class: Pebbles::Auth
- Inherits:
-
Object
show all
- Extended by:
- Helpers
- Defined in:
- lib/pebbles/auth.rb
Class Attribute Summary collapse
Class Method Summary
collapse
Methods included from Helpers
action, ask, confirm_command, create_git_remote, debug, debugging?, display, error, error_with_failure, error_with_failure=, flatten_hash, format_bytes, format_error, format_with_bang, git, has_git?, has_git_remote?, has_http_git_entry_in_netrc, home_directory, hputs, json_decode, launchy, line_formatter, longest, output_with_bang, running_on_a_mac?, running_on_windows?, styled_array, styled_error, styled_hash, styled_header, update_git_remote, with_tty
Class Attribute Details
.credentials ⇒ Object
Returns the value of attribute credentials.
11
12
13
|
# File 'lib/pebbles/auth.rb', line 11
def credentials
@credentials
end
|
Class Method Details
.api ⇒ Object
13
14
15
16
17
18
|
# File 'lib/pebbles/auth.rb', line 13
def api
@api ||= begin
debug "Using API with key: #{password[0,6]}..."
Pebbles::API.new(default_params.merge(:api_key => password))
end
end
|
.api_key(user = get_credentials[0], password = get_credentials[1]) ⇒ Object
66
67
68
69
70
71
|
# File 'lib/pebbles/auth.rb', line 66
def api_key(user=get_credentials[0], password=get_credentials[1])
@api ||= Pebbles::API.new(default_params)
api_key = @api.post_login(user, password).body["api_key"]
@api = nil
api_key
end
|
.ask_for_and_save_credentials ⇒ Object
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
# File 'lib/pebbles/auth.rb', line 188
def ask_for_and_save_credentials
@credentials = ask_for_credentials
debug "Logged in as #{@credentials[0]} with key: #{@credentials[1][0,6]}..."
write_credentials
check
@credentials
rescue Pebbles::API::Errors::Unauthorized => e
delete_credentials
display "Authentication failed."
warn "WARNING: PEBBLES_API_KEY is set to an invalid key." if ENV['PEBBLES_API_KEY']
retry if retry_login?
exit 1
rescue => e
delete_credentials
raise e
end
|
.ask_for_credentials ⇒ Object
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/pebbles/auth.rb', line 148
def ask_for_credentials
puts "Enter your Pebblescape 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
177
178
179
180
181
182
183
184
185
186
|
# File 'lib/pebbles/auth.rb', line 177
def ask_for_password
begin
echo_off
password = ask
puts
ensure
echo_on
end
return password
end
|
.ask_for_password_on_windows ⇒ Object
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/pebbles/auth.rb', line 159
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
255
256
257
258
259
260
261
262
263
|
# File 'lib/pebbles/auth.rb', line 255
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
# File 'lib/pebbles/auth.rb', line 205
def associate_or_generate_ssh_key
unless File.exists?("#{home_directory}/.ssh/id_rsa.pub")
display "Could not find an existing public key at ~/.ssh/id_rsa.pub"
display "Would you like to generate one? [Yn] ", false
unless ask.strip.downcase =~ /^n/
display "Generating new SSH public key."
generate_ssh_key("#{home_directory}/.ssh/id_rsa")
associate_key("#{home_directory}/.ssh/id_rsa.pub")
return
end
end
chosen = ssh_prompt
associate_key(chosen) if chosen
end
|
.base_host(host) ⇒ Object
271
272
273
274
275
|
# File 'lib/pebbles/auth.rb', line 271
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
30
31
32
|
# File 'lib/pebbles/auth.rb', line 30
def check
api.get_user
end
|
.default_host ⇒ Object
34
35
36
|
# File 'lib/pebbles/auth.rb', line 34
def default_host
"pebblesinspace.com"
end
|
.delete_credentials ⇒ Object
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/pebbles/auth.rb', line 77
def delete_credentials
return
if netrc
subdomains.each do |sub|
netrc.delete("#{sub}.#{host}")
end
netrc.save
end
@api, @credentials = nil, nil
end
|
.echo_off ⇒ Object
136
137
138
139
140
|
# File 'lib/pebbles/auth.rb', line 136
def echo_off
with_tty do
system "stty -echo"
end
end
|
.echo_on ⇒ Object
142
143
144
145
146
|
# File 'lib/pebbles/auth.rb', line 142
def echo_on
with_tty do
system "stty echo"
end
end
|
.full_host(host) ⇒ Object
277
278
279
280
|
# File 'lib/pebbles/auth.rb', line 277
def full_host(host)
scheme = debugging? ? 'http' : 'https'
(host =~ /^http/) ? host : "#{scheme}://api.#{host}"
end
|
.generate_ssh_key(keyfile) ⇒ Object
246
247
248
249
250
251
252
253
|
# File 'lib/pebbles/auth.rb', line 246
def generate_ssh_key(keyfile)
ssh_dir = File.dirname(keyfile)
FileUtils.mkdir_p ssh_dir, :mode => 0700
output = `ssh-keygen -t rsa -N "" -f \"#{keyfile}\" 2>&1`
if ! $?.success?
error("Could not generate key: #{output}")
end
end
|
.get_credentials ⇒ Object
73
74
75
|
# File 'lib/pebbles/auth.rb', line 73
def get_credentials @credentials ||= (read_credentials || ask_for_and_save_credentials)
end
|
.git_host ⇒ Object
42
43
44
|
# File 'lib/pebbles/auth.rb', line 42
def git_host
ENV['PEBBLES_GIT_HOST'] || host
end
|
.host ⇒ Object
46
47
48
|
# File 'lib/pebbles/auth.rb', line 46
def host
ENV['PEBBLES_HOST'] || default_host
end
|
.http_git_host ⇒ Object
38
39
40
|
# File 'lib/pebbles/auth.rb', line 38
def http_git_host
ENV['PEBBLES_HTTP_GIT_HOST'] || "git.#{host}"
end
|
.login ⇒ Object
20
21
22
23
|
# File 'lib/pebbles/auth.rb', line 20
def login
delete_credentials
get_credentials
end
|
.logout ⇒ Object
25
26
27
|
# File 'lib/pebbles/auth.rb', line 25
def logout
delete_credentials
end
|
.netrc ⇒ Object
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/pebbles/auth.rb', line 98
def netrc @netrc ||= begin
File.exists?(netrc_path) && Netrc.read(netrc_path)
rescue => error
case error.message
when /^Permission bits for/
abort("#{error.message}.\nYou should run `chmod 0600 #{netrc_path}` so that your credentials are NOT accessible by others.")
when /EACCES/
error("Error reading #{netrc_path}\n#{error.message}\nMake sure this user can read/write this file.")
else
error("Error reading #{netrc_path}\n#{error.message}\nYou may need to delete this file and run `pebbles login` to recreate it.")
end
end
end
|
.netrc_path ⇒ Object
88
89
90
91
92
93
94
95
96
|
# File 'lib/pebbles/auth.rb', line 88
def netrc_path
default = Netrc.default_path
encrypted = default + ".gpg"
if File.exists?(encrypted)
encrypted
else
default
end
end
|
.password ⇒ Object
62
63
64
|
# File 'lib/pebbles/auth.rb', line 62
def password get_credentials[1]
end
|
.read_credentials ⇒ Object
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/pebbles/auth.rb', line 113
def read_credentials
if ENV['PEBBLES_API_KEY']
['', ENV['PEBBLES_API_KEY']]
else
if netrc
netrc["api.#{host}"]
end
end
end
|
.reauthorize ⇒ Object
54
55
56
|
# File 'lib/pebbles/auth.rb', line 54
def reauthorize
@credentials = ask_for_and_save_credentials
end
|
.retry_login? ⇒ Boolean
265
266
267
268
269
|
# File 'lib/pebbles/auth.rb', line 265
def retry_login?
@login_attempts ||= 0
@login_attempts += 1
@login_attempts < 3
end
|
.ssh_prompt ⇒ Object
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
# File 'lib/pebbles/auth.rb', line 221
def ssh_prompt
public_keys = Dir.glob("#{home_directory}/.ssh/*.pub").sort
case public_keys.length
when 0
error("No SSH keys found")
return nil
when 1
display "Found an SSH public key at #{public_keys.first}"
display "Would you like to upload it to Pebblescape? [Yn] ", false
return ask.strip.downcase =~ /^n/ ? nil : 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 Pebblescape account? ", false
choice = ask.to_i - 1
chosen = public_keys[choice]
if choice == -1 || chosen.nil?
error("Invalid choice")
end
return chosen
end
end
|
.subdomains ⇒ Object
50
51
52
|
# File 'lib/pebbles/auth.rb', line 50
def subdomains
%w(api git)
end
|
.user ⇒ Object
58
59
60
|
# File 'lib/pebbles/auth.rb', line 58
def user get_credentials[0]
end
|
.verify_host?(host) ⇒ Boolean
282
283
284
285
|
# File 'lib/pebbles/auth.rb', line 282
def verify_host?(host)
return false if ENV["PEBBLES_SSL_VERIFY"] == "disable"
base_host(host) == "pebblesinspace.com"
end
|
.write_credentials ⇒ Object
124
125
126
127
128
129
130
131
132
133
134
|
# File 'lib/pebbles/auth.rb', line 124
def write_credentials
FileUtils.mkdir_p(File.dirname(netrc_path))
FileUtils.touch(netrc_path)
unless running_on_windows?
FileUtils.chmod(0600, netrc_path)
end
subdomains.each do |sub|
netrc["#{sub}.#{host}"] = self.credentials
end
netrc.save
end
|