Class: Azuki::Auth
- Inherits:
-
Object
show all
- Extended by:
- Helpers
- Defined in:
- lib/azuki/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, 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/azuki/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/azuki/auth.rb', line 14
def api
@api ||= begin
require("azuki-api")
api = Azuki::API.new(default_params.merge(:api_key => password))
def api.request(params, &block)
response = super
if response..has_key?('X-Azuki-Warning')
Azuki::Command.warnings.concat(response.['X-Azuki-Warning'].split("\n"))
end
response
end
api
end
end
|
.api_key(user = get_credentials[0], password = get_credentials[1]) ⇒ Object
81
82
83
84
85
|
# File 'lib/azuki/auth.rb', line 81
def api_key(user = get_credentials[0], password = get_credentials[1])
require("azuki-api")
api = Azuki::API.new(default_params)
api.post_login(user, password).body["api_key"]
end
|
.ask_for_and_save_credentials ⇒ Object
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
# File 'lib/azuki/auth.rb', line 222
def ask_for_and_save_credentials
require("azuki-api") begin
@credentials = ask_for_credentials
write_credentials
check
rescue Azuki::API::Errors::NotFound, Azuki::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 Azuki::Command.current_command == "keys:add"
@credentials
end
|
.ask_for_credentials ⇒ Object
184
185
186
187
188
189
190
191
192
193
194
|
# File 'lib/azuki/auth.rb', line 184
def ask_for_credentials
puts "Enter your Azuki 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
214
215
216
217
218
219
220
|
# File 'lib/azuki/auth.rb', line 214
def ask_for_password
echo_off
password = ask
puts
echo_on
return password
end
|
.ask_for_password_on_windows ⇒ Object
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
# File 'lib/azuki/auth.rb', line 196
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
291
292
293
294
295
296
297
298
299
|
# File 'lib/azuki/auth.rb', line 291
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
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
272
273
274
275
|
# File 'lib/azuki/auth.rb', line 247
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 Azuki 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
311
312
313
314
315
|
# File 'lib/azuki/auth.rb', line 311
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/azuki/auth.rb', line 49
def check
api.get_user
end
|
.check_for_associated_ssh_key ⇒ Object
241
242
243
244
245
|
# File 'lib/azuki/auth.rb', line 241
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/azuki/auth.rb', line 31
def client
@client ||= begin
client = Azuki::Client.new(user, password, host)
client.on_warning { |msg| self.display("\n#{msg}\n\n") }
client
end
end
|
.default_git ⇒ Object
57
58
59
|
# File 'lib/azuki/auth.rb', line 57
def default_git
"git.azukiapp.com"
end
|
.default_host ⇒ Object
53
54
55
|
# File 'lib/azuki/auth.rb', line 53
def default_host
"azukiapp.com"
end
|
.delete_credentials ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/azuki/auth.rb', line 91
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
172
173
174
175
176
|
# File 'lib/azuki/auth.rb', line 172
def echo_off
with_tty do
system "stty -echo"
end
end
|
.echo_on ⇒ Object
178
179
180
181
182
|
# File 'lib/azuki/auth.rb', line 178
def echo_on
with_tty do
system "stty echo"
end
end
|
.full_host(host) ⇒ Object
317
318
319
|
# File 'lib/azuki/auth.rb', line 317
def full_host(host)
(host =~ /^http/) ? host : "https://api.#{host}"
end
|
.generate_ssh_key(keyfile) ⇒ Object
277
278
279
280
281
282
283
284
285
286
287
288
289
|
# File 'lib/azuki/auth.rb', line 277
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
87
88
89
|
# File 'lib/azuki/auth.rb', line 87
def get_credentials @credentials ||= (read_credentials || ask_for_and_save_credentials)
end
|
.git_host ⇒ Object
61
62
63
|
# File 'lib/azuki/auth.rb', line 61
def git_host
ENV['AZUKI_GIT_HOST'] || default_git
end
|
.host ⇒ Object
65
66
67
|
# File 'lib/azuki/auth.rb', line 65
def host
ENV['AZUKI_HOST'] || default_host
end
|
.legacy_credentials_path ⇒ Object
103
104
105
106
107
108
109
|
# File 'lib/azuki/auth.rb', line 103
def legacy_credentials_path
if host == default_host
"#{home_directory}/.azuki/credentials"
else
"#{home_directory}/.azuki/credentials.#{CGI.escape(host)}"
end
end
|
.login ⇒ Object
39
40
41
42
|
# File 'lib/azuki/auth.rb', line 39
def login
delete_credentials
get_credentials
end
|
.logout ⇒ Object
44
45
46
|
# File 'lib/azuki/auth.rb', line 44
def logout
delete_credentials
end
|
.netrc ⇒ Object
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/azuki/auth.rb', line 121
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
111
112
113
114
115
116
117
118
119
|
# File 'lib/azuki/auth.rb', line 111
def netrc_path
default = Netrc.default_path
encrypted = default + ".gpg"
if File.exists?(encrypted)
encrypted
else
default
end
end
|
.password ⇒ Object
77
78
79
|
# File 'lib/azuki/auth.rb', line 77
def password get_credentials[1]
end
|
.read_credentials ⇒ Object
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/azuki/auth.rb', line 134
def read_credentials
if ENV['AZUKI_API_KEY']
['', ENV['AZUKI_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
69
70
71
|
# File 'lib/azuki/auth.rb', line 69
def reauthorize
@credentials = ask_for_and_save_credentials
end
|
.retry_login? ⇒ Boolean
301
302
303
304
305
|
# File 'lib/azuki/auth.rb', line 301
def retry_login?
@login_attempts ||= 0
@login_attempts += 1
@login_attempts < 3
end
|
.user ⇒ Object
73
74
75
|
# File 'lib/azuki/auth.rb', line 73
def user get_credentials[0]
end
|
.verified_hosts ⇒ Object
307
308
309
|
# File 'lib/azuki/auth.rb', line 307
def verified_hosts
%w( azukiapp.com azuki-shadow.com )
end
|
.verify_host?(host) ⇒ Boolean
321
322
323
324
325
326
|
# File 'lib/azuki/auth.rb', line 321
def verify_host?(host)
hostname = base_host(host)
verified = verified_hosts.include?(hostname)
verified = false if ENV["AZUKI_SSL_VERIFY"] == "disable"
verified
end
|
.write_credentials ⇒ Object
161
162
163
164
165
166
167
168
169
170
|
# File 'lib/azuki/auth.rb', line 161
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
|