MuranoCLI 3.1.0 → 3.2.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/.trustme.sh +6 -2
- data/lib/MrMurano/Account.rb +8 -262
- data/lib/MrMurano/AccountBase.rb +214 -0
- data/lib/MrMurano/Business.rb +3 -19
- data/lib/MrMurano/Config-Migrate.rb +0 -4
- data/lib/MrMurano/Config.rb +159 -70
- data/lib/MrMurano/Content.rb +3 -2
- data/lib/MrMurano/Exchange.rb +3 -1
- data/lib/MrMurano/Gateway.rb +3 -2
- data/lib/MrMurano/HttpAuthed.rb +287 -0
- data/lib/MrMurano/Passwords.rb +82 -35
- data/lib/MrMurano/ReCommander.rb +2 -0
- data/lib/MrMurano/Solution.rb +3 -2
- data/lib/MrMurano/SyncRoot.rb +2 -0
- data/lib/MrMurano/Webservice.rb +3 -2
- data/lib/MrMurano/commands/business.rb +2 -2
- data/lib/MrMurano/commands/globals.rb +41 -0
- data/lib/MrMurano/commands/init.rb +1 -1
- data/lib/MrMurano/commands/login.rb +30 -6
- data/lib/MrMurano/commands/logs.rb +1 -6
- data/lib/MrMurano/commands/password.rb +15 -11
- data/lib/MrMurano/commands/show.rb +1 -1
- data/lib/MrMurano/commands/token.rb +209 -0
- data/lib/MrMurano/commands.rb +1 -0
- data/lib/MrMurano/http.rb +13 -24
- data/lib/MrMurano/version.rb +1 -1
- data/lib/MrMurano.rb +1 -0
- data/spec/Account_spec.rb +8 -8
- data/spec/Http_spec.rb +0 -1
- data/spec/cmd_token_spec.rb +56 -0
- data/spec/fixtures/websocket/README.rst +2 -2
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb061c736e0642412756d2b964e8dc05a5955863beaa0c94cd5b9cd1f77fd7a6
|
4
|
+
data.tar.gz: d94b914a08a3679c09332d9ade3533d6e9bc350ba9b84656f50890834cf34dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccfa0f6a460dd6510919cc82d5482485dc16c88ccf0feb9af2f06408dd07ab6b22526f215aa4f63445264a866f08cad15c4ded3c7b75d8e179ce7d2a60e4900e
|
7
|
+
data.tar.gz: c684535687d90509380929e5e5f014d7e2e1706f20b25560d077e8e58e19c457d7ff027de9c3d0b4ebb72a1e4d5646d2abb3c5e3c9ac477ae6828a0a6c25c9ce
|
data/.rubocop.yml
CHANGED
@@ -119,6 +119,7 @@ Style/FileName:
|
|
119
119
|
- 'lib/MrMurano.rb'
|
120
120
|
- 'lib/MrMurano/makePretty.rb'
|
121
121
|
- 'lib/MrMurano/Account.rb'
|
122
|
+
- 'lib/MrMurano/AccountBase.rb'
|
122
123
|
- 'lib/MrMurano/Business.rb'
|
123
124
|
- 'lib/MrMurano/Commander-Entry.rb'
|
124
125
|
- 'lib/MrMurano/Config-Migrate.rb'
|
@@ -127,6 +128,7 @@ Style/FileName:
|
|
127
128
|
- 'lib/MrMurano/Exchange.rb'
|
128
129
|
- 'lib/MrMurano/Exchange-Element.rb'
|
129
130
|
- 'lib/MrMurano/Gateway.rb'
|
131
|
+
- 'lib/MrMurano/HttpAuthed.rb'
|
130
132
|
- 'lib/MrMurano/Keystore.rb'
|
131
133
|
- 'lib/MrMurano/Logs.rb'
|
132
134
|
- 'lib/MrMurano/Mock.rb'
|
data/.trustme.sh
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
# to open them, the BufEnter event doesn't trigger properly.
|
33
33
|
# E.g.,
|
34
34
|
#
|
35
|
-
# MURANO_CLI=/exo/clients/exosite/MuranoCLI filter=".* *" in=".trustme.vim" {
|
35
|
+
# MURANO_CLI=/exo/clients/exosite/MuranoCLIs/active+MuranoCLI filter=".* *" in=".trustme.vim" {
|
36
36
|
# .agignore
|
37
37
|
# # ...
|
38
38
|
# }
|
@@ -217,9 +217,13 @@ build_it() {
|
|
217
217
|
echo "- rubocop -v: $(rubocop -v)" >> ${OUT_FILE}
|
218
218
|
#echo "- cmd rubocop: $(command -v rubocop)" >> ${OUT_FILE}
|
219
219
|
|
220
|
+
local projpath="/exo/clients/exosite/MuranoCLIs"
|
220
221
|
rake build &>> ${OUT_FILE} && \
|
221
222
|
gem install -i $(ruby -rubygems -e 'puts Gem.dir') \
|
222
|
-
pkg/MuranoCLI-$(
|
223
|
+
pkg/MuranoCLI-$( \
|
224
|
+
ruby -e "require \"${projpath}/active+MuranoCLI/lib/MrMurano/version.rb\"; \
|
225
|
+
puts MrMurano::VERSION"\
|
226
|
+
).gem \
|
223
227
|
&>> ${OUT_FILE}
|
224
228
|
}
|
225
229
|
|
data/lib/MrMurano/Account.rb
CHANGED
@@ -5,273 +5,17 @@
|
|
5
5
|
# vim:tw=0:ts=2:sw=2:et:ai
|
6
6
|
# Unauthorized copying of this file is strictly prohibited.
|
7
7
|
|
8
|
-
require 'json'
|
9
|
-
require 'net/http'
|
10
|
-
require 'uri'
|
11
|
-
require 'yaml'
|
12
8
|
require 'MrMurano/hash'
|
13
|
-
require 'MrMurano/http'
|
14
9
|
require 'MrMurano/verbosing'
|
10
|
+
require 'MrMurano/AccountBase'
|
15
11
|
require 'MrMurano/Business'
|
16
|
-
require 'MrMurano/
|
17
|
-
require 'MrMurano/Passwords'
|
18
|
-
require 'MrMurano/Solution'
|
12
|
+
require 'MrMurano/HttpAuthed'
|
19
13
|
|
20
14
|
module MrMurano
|
21
15
|
class Account
|
22
|
-
|
23
|
-
# token multiple times (and to avoid having to pass an Account
|
24
|
-
# object around), we make the class a singleton.
|
25
|
-
include Singleton
|
26
|
-
|
27
|
-
include Http
|
16
|
+
include AccountBase
|
28
17
|
include Verbose
|
29
18
|
|
30
|
-
def initialize
|
31
|
-
@token = nil
|
32
|
-
@twofactor_token = nil
|
33
|
-
end
|
34
|
-
|
35
|
-
def host
|
36
|
-
$cfg['net.host'].to_s
|
37
|
-
end
|
38
|
-
|
39
|
-
def user
|
40
|
-
$cfg['user.name'].to_s
|
41
|
-
end
|
42
|
-
|
43
|
-
def endpoint(path)
|
44
|
-
URI($cfg['net.protocol'] + '://' + host + '/api:1/' + path.to_s)
|
45
|
-
end
|
46
|
-
|
47
|
-
# ---------------------------------------------------------------------
|
48
|
-
|
49
|
-
LOGIN_ADVICE = %(
|
50
|
-
Please login using `murano login` or `murano init`.
|
51
|
-
Or set your password with `murano password set <username>`.
|
52
|
-
).strip
|
53
|
-
LOGIN_NOTICE = 'Please login.'
|
54
|
-
|
55
|
-
def login_info
|
56
|
-
warned_once = false
|
57
|
-
|
58
|
-
if user.empty?
|
59
|
-
prologue = 'No Murano user account found.'
|
60
|
-
unless $cfg.prompt_if_logged_off
|
61
|
-
MrMurano::Verbose.whirly_stop
|
62
|
-
error("#{prologue}\n#{LOGIN_ADVICE}")
|
63
|
-
exit 2
|
64
|
-
end
|
65
|
-
MrMurano::Verbose.whirly_pause
|
66
|
-
error("#{prologue} #{LOGIN_NOTICE}")
|
67
|
-
warned_once = true
|
68
|
-
username = ask('User name: ')
|
69
|
-
$cfg.set('user.name', username, :user)
|
70
|
-
$project.refresh_user_name
|
71
|
-
MrMurano::Verbose.whirly_unpause
|
72
|
-
end
|
73
|
-
|
74
|
-
pwd_file = pwd_file_load
|
75
|
-
user_pass = pwd_file.get(host, user)
|
76
|
-
if user_pass.nil?
|
77
|
-
prologue = "No Murano password found for #{user}."
|
78
|
-
unless $cfg.prompt_if_logged_off
|
79
|
-
MrMurano::Verbose.whirly_stop
|
80
|
-
error("#{prologue}\n#{LOGIN_ADVICE}")
|
81
|
-
exit 2
|
82
|
-
end
|
83
|
-
MrMurano::Verbose.whirly_pause
|
84
|
-
error(%(#{prologue} #{LOGIN_NOTICE}).strip) unless warned_once
|
85
|
-
user_pass = ask('Password: ') { |q| q.echo = '*' }
|
86
|
-
pwd_file.set(host, user, user_pass)
|
87
|
-
pwd_file.set(host, user + '/twofactor', nil)
|
88
|
-
pwd_file.save
|
89
|
-
MrMurano::Verbose.whirly_unpause
|
90
|
-
else
|
91
|
-
@twofactor_token = token_twofactor_lookup(pwd_file)
|
92
|
-
end
|
93
|
-
|
94
|
-
{
|
95
|
-
email: user,
|
96
|
-
password: user_pass,
|
97
|
-
}
|
98
|
-
end
|
99
|
-
|
100
|
-
def pwd_file_load
|
101
|
-
pwd_path = $cfg.file_at('passwords', :user)
|
102
|
-
pwd_file = MrMurano::Passwords.new(pwd_path)
|
103
|
-
pwd_file.load
|
104
|
-
pwd_file
|
105
|
-
end
|
106
|
-
|
107
|
-
def token_twofactor_lookup(pwd_file)
|
108
|
-
twoftoken = pwd_file.lookup(host, user + '/twofactor')
|
109
|
-
if twoftoken.to_s.empty?
|
110
|
-
nil
|
111
|
-
elsif twoftoken !~ /^[a-fA-F0-9]+$/
|
112
|
-
warning "Malformed twofactor token: #{twoftoken}"
|
113
|
-
nil
|
114
|
-
else
|
115
|
-
twoftoken
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
# ---------------------------------------------------------------------
|
120
|
-
|
121
|
-
def token
|
122
|
-
return '' if defined?(@logging_on) && @logging_on
|
123
|
-
token_fetch if @token.to_s.empty?
|
124
|
-
@token
|
125
|
-
end
|
126
|
-
|
127
|
-
def token_reset(value=nil)
|
128
|
-
@token = value
|
129
|
-
end
|
130
|
-
|
131
|
-
def token_fetch
|
132
|
-
@logging_on = true
|
133
|
-
creds = login_info
|
134
|
-
@token = nil
|
135
|
-
|
136
|
-
# If 2fa token found, verify it works.
|
137
|
-
unless @twofactor_token.nil?
|
138
|
-
get('token/' + @twofactor_token) do |request, http|
|
139
|
-
http.request(request) do |response|
|
140
|
-
if response.is_a?(Net::HTTPSuccess)
|
141
|
-
# response.body is, e.g., "{\"email\":\"xxx@yyy.zzz\",\"ttl\":172800}"
|
142
|
-
@token = @twofactor_token
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
unless @token.nil?
|
147
|
-
@logging_on = false
|
148
|
-
return
|
149
|
-
end
|
150
|
-
@twofactor_token = nil
|
151
|
-
end
|
152
|
-
|
153
|
-
MrMurano::Verbose.whirly_start('Logging in...')
|
154
|
-
post('token/', creds) do |request, http|
|
155
|
-
http.request(request) do |response|
|
156
|
-
reply = JSON.parse(response.body, json_opts)
|
157
|
-
if response.is_a?(Net::HTTPSuccess)
|
158
|
-
@token = reply[:token]
|
159
|
-
elsif response.is_a?(Net::HTTPConflict) && reply[:message] == 'twofactor'
|
160
|
-
MrMurano::Verbose.whirly_interject do
|
161
|
-
# Prompt user for emailed code.
|
162
|
-
token_twofactor_fetch(creds)
|
163
|
-
end
|
164
|
-
else
|
165
|
-
showHttpError(request, response)
|
166
|
-
error 'Check to see if username and password are correct.'
|
167
|
-
unless ENV['MURANO_PASSWORD'].to_s.empty?
|
168
|
-
pwd_path = $cfg.file_at('passwords', :user)
|
169
|
-
warning "NOTE: MURANO_PASSWORD specifies the password; it was not read from #{pwd_path}"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
MrMurano::Verbose.whirly_stop
|
175
|
-
@logging_on = false
|
176
|
-
end
|
177
|
-
|
178
|
-
def token_twofactor_fetch(creds)
|
179
|
-
error 'Two-factor Authentication'
|
180
|
-
warning 'A verification code has been sent to your email.'
|
181
|
-
code = ask('Please enter the code here to continue: ').strip
|
182
|
-
unless code =~ /^[a-fA-F0-9]+$/
|
183
|
-
error 'Expected token to contain only numbers and hexadecimal letters.'
|
184
|
-
exit 1
|
185
|
-
end
|
186
|
-
MrMurano::Verbose.whirly_start('Verifying code...')
|
187
|
-
|
188
|
-
path = 'key/' + code
|
189
|
-
|
190
|
-
response = get(path)
|
191
|
-
# Response is, e.g., {
|
192
|
-
# purpose: "twofactor",
|
193
|
-
# status: "exists",
|
194
|
-
# email: "xxx@yyy.zzz",
|
195
|
-
# bizid: null,
|
196
|
-
# businessName: null, }
|
197
|
-
return if response.nil?
|
198
|
-
|
199
|
-
response = post(path, password: creds[:password])
|
200
|
-
# Response is, e.g., { "token": "..." }
|
201
|
-
return if response.nil?
|
202
|
-
|
203
|
-
@twofactor_token = response[:token]
|
204
|
-
pwd_file = pwd_file_load
|
205
|
-
pwd_file.set(host, user + '/twofactor', @twofactor_token)
|
206
|
-
pwd_file.save
|
207
|
-
@token = @twofactor_token
|
208
|
-
MrMurano::Verbose.whirly_stop
|
209
|
-
|
210
|
-
warning 'Please run `murano logout --token` to clear your two-factor token when finished.'
|
211
|
-
end
|
212
|
-
|
213
|
-
def logout(token_delete_only)
|
214
|
-
@logging_on = true
|
215
|
-
|
216
|
-
pwd_file = pwd_file_load
|
217
|
-
twoftoken = token_twofactor_lookup(pwd_file)
|
218
|
-
|
219
|
-
# First, delete/invalidate the remote token.
|
220
|
-
unless twoftoken.to_s.empty?
|
221
|
-
verbose 'Removing two-factor token.'
|
222
|
-
@suppress_error = true
|
223
|
-
delete('token/' + twoftoken)
|
224
|
-
# The response is nil if the token was not recognized, otherwise it's
|
225
|
-
# {}. We don't really care, since we're going to forget our copy of
|
226
|
-
# the token, anyway.
|
227
|
-
@suppress_error = false
|
228
|
-
end
|
229
|
-
|
230
|
-
net_host = verify_set('net.host')
|
231
|
-
user_name = verify_set('user.name')
|
232
|
-
if net_host && user_name
|
233
|
-
pwd_file = MrMurano::Passwords.new
|
234
|
-
pwd_file.load
|
235
|
-
pwd_file.remove(net_host, user_name) unless token_delete_only
|
236
|
-
pwd_file.remove(net_host, user_name + '/twofactor')
|
237
|
-
pwd_file.save
|
238
|
-
else
|
239
|
-
verbose 'Skipping password scrub: need both net.host and user.name to remove.'
|
240
|
-
end
|
241
|
-
|
242
|
-
clear_from_config(net_host, user_name) unless token_delete_only
|
243
|
-
|
244
|
-
@logging_on = false
|
245
|
-
end
|
246
|
-
|
247
|
-
def clear_from_config(net_host, user_name)
|
248
|
-
user_net_host = $cfg.get('net.host', :user)
|
249
|
-
user_net_host = $cfg.get('net.host', :defaults) if user_net_host.nil?
|
250
|
-
user_user_name = $cfg.get('user.name', :user)
|
251
|
-
# Only clear user name from the user config if the net.host
|
252
|
-
# or user.name did not come from a different config, like the
|
253
|
-
# --project config.
|
254
|
-
unless (user_net_host == net_host) && (user_user_name == user_name)
|
255
|
-
verbose 'Skipping config scrub: net.host and/or user.name do not match.'
|
256
|
-
return
|
257
|
-
end
|
258
|
-
$cfg.set('user.name', nil, :user)
|
259
|
-
$cfg.set('business.id', nil, :user)
|
260
|
-
$cfg.set('business.name', nil, :user)
|
261
|
-
end
|
262
|
-
|
263
|
-
def verify_set(cfg_key)
|
264
|
-
cfg_val = $cfg.get(cfg_key)
|
265
|
-
if cfg_val.to_s.empty?
|
266
|
-
cfg_val = nil
|
267
|
-
cfg_key_q = MrMurano::Verbose.fancy_ticks(cfg_key)
|
268
|
-
MrMurano::Verbose.warning("No config key #{cfg_key_q}: no password to delete")
|
269
|
-
end
|
270
|
-
cfg_val
|
271
|
-
end
|
272
|
-
|
273
|
-
# ---------------------------------------------------------------------
|
274
|
-
|
275
19
|
def businesses(bid: nil, name: nil, fuzzy: nil)
|
276
20
|
# Ask user for name and password, if not saved to config and password files.
|
277
21
|
login_info if user.empty?
|
@@ -294,7 +38,9 @@ Or set your password with `murano password set <username>`.
|
|
294
38
|
match_bid.include?(biz[:bizid]) ||
|
295
39
|
match_name.include?(biz[:name]) ||
|
296
40
|
match_fuzzy.any? do |term|
|
297
|
-
biz[:name] =~
|
41
|
+
biz[:name] =~ (
|
42
|
+
/#{Regexp.escape(term)}/i || biz[:bizid] =~ /#{Regexp.escape(term)}/i
|
43
|
+
)
|
298
44
|
end
|
299
45
|
)
|
300
46
|
end
|
@@ -313,7 +59,7 @@ Or set your password with `murano password set <username>`.
|
|
313
59
|
|
314
60
|
def new_account(email, name, company='')
|
315
61
|
# this is a kludge. If we're gonna support this, do it better.
|
316
|
-
|
62
|
+
token_reset
|
317
63
|
post('key/', email: email, name: name, company: company, source: 'signup')
|
318
64
|
end
|
319
65
|
|
@@ -323,7 +69,7 @@ Or set your password with `murano password set <username>`.
|
|
323
69
|
|
324
70
|
def accept_account(token, password)
|
325
71
|
# this is a kludge. If we're gonna support this, do it better.
|
326
|
-
|
72
|
+
token_reset
|
327
73
|
post("key/#{token}", password: password)
|
328
74
|
end
|
329
75
|
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
6
|
+
# Unauthorized copying of this file is strictly prohibited.
|
7
|
+
|
8
|
+
require 'json'
|
9
|
+
require 'net/http'
|
10
|
+
require 'uri'
|
11
|
+
require 'MrMurano/http'
|
12
|
+
require 'MrMurano/verbosing'
|
13
|
+
require 'MrMurano/HttpAuthed'
|
14
|
+
|
15
|
+
module MrMurano
|
16
|
+
module AccountBase
|
17
|
+
include Http
|
18
|
+
include Verbose
|
19
|
+
|
20
|
+
def initialize(authless: false)
|
21
|
+
super()
|
22
|
+
# Set up the HttpAuthed instance. If 'authless', caller wants an
|
23
|
+
# Account object but does not want to ask user for name and password,
|
24
|
+
# nor does caller want credentials added to any HTTP requests. This
|
25
|
+
# is so far only useful for the `murano token delete` command.
|
26
|
+
login_info unless authless
|
27
|
+
@authless = false
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_headers(request)
|
31
|
+
super
|
32
|
+
MrMurano::HttpAuthed.instance.add_headers(request) unless @authless
|
33
|
+
request
|
34
|
+
end
|
35
|
+
|
36
|
+
def token
|
37
|
+
token_biz = MrMurano::HttpAuthed.instance.token_biz
|
38
|
+
return token_biz unless token_biz.to_s.empty?
|
39
|
+
MrMurano::HttpAuthed.instance.ensure_token!
|
40
|
+
end
|
41
|
+
|
42
|
+
def token_reset
|
43
|
+
MrMurano::HttpAuthed.instance.token_reset
|
44
|
+
end
|
45
|
+
|
46
|
+
# ---------------------------------------------------------------------
|
47
|
+
|
48
|
+
LOGIN_NOTICE = 'Please login.'
|
49
|
+
|
50
|
+
LOGIN_ADVICE = %(
|
51
|
+
Please login using `murano login` or `murano init`.
|
52
|
+
Or set your password with `murano password set <username>`.
|
53
|
+
).strip.gsub(/^\s+/, '')
|
54
|
+
|
55
|
+
def login_info
|
56
|
+
# (lb): This is a little hokey, but someone has to init the Singleton,
|
57
|
+
# so we make sure it's ready anytime a new AccountBase instance is created.
|
58
|
+
email_pwd = MrMurano::HttpAuthed.instance.login_info
|
59
|
+
return email_pwd unless email_pwd.nil?
|
60
|
+
verify_cfg_auth!
|
61
|
+
@warned_once = false
|
62
|
+
ask_for_user! if user.empty?
|
63
|
+
# Do not prompt for password if using token.
|
64
|
+
if !@logging_on && $cfg['auth.scheme-token']
|
65
|
+
token = MrMurano::HttpAuthed.instance.token_resolve
|
66
|
+
return unless token.to_s.empty?
|
67
|
+
end
|
68
|
+
password = MrMurano::HttpAuthed.instance.password_get_or_ask(
|
69
|
+
host, user
|
70
|
+
) { ask_for_password! }
|
71
|
+
email_pwd = { email: user, password: password }
|
72
|
+
email_pwd['ttl'] = $cfg.get('auth.ttl') unless $cfg.get('auth.ttl').to_s.empty?
|
73
|
+
MrMurano::HttpAuthed.instance.login_info = email_pwd
|
74
|
+
end
|
75
|
+
|
76
|
+
def ask_for_user!
|
77
|
+
prologue = 'No Murano user account found.'
|
78
|
+
must_prompt_if_logged_off!(prologue)
|
79
|
+
MrMurano::Verbose.whirly_pause
|
80
|
+
error("#{prologue} #{LOGIN_NOTICE}")
|
81
|
+
@warned_once = true
|
82
|
+
username = ask('User name: ')
|
83
|
+
$cfg.set('user.name', username, :user)
|
84
|
+
$project.refresh_user_name
|
85
|
+
MrMurano::Verbose.whirly_unpause
|
86
|
+
username
|
87
|
+
end
|
88
|
+
|
89
|
+
def ask_for_password!
|
90
|
+
prologue = "No Murano password found for #{user}."
|
91
|
+
must_prompt_if_logged_off!(prologue)
|
92
|
+
MrMurano::Verbose.whirly_pause
|
93
|
+
error(%(#{prologue} #{LOGIN_NOTICE}).strip) unless @warned_once
|
94
|
+
password = ask('Password: ') { |q| q.echo = '*' }
|
95
|
+
MrMurano::Verbose.whirly_unpause
|
96
|
+
password
|
97
|
+
end
|
98
|
+
|
99
|
+
def must_prompt_if_logged_off!(prologue)
|
100
|
+
return if $cfg.prompt_if_logged_off
|
101
|
+
MrMurano::Verbose.whirly_stop
|
102
|
+
error("#{prologue}\n#{LOGIN_ADVICE}")
|
103
|
+
exit 2
|
104
|
+
end
|
105
|
+
|
106
|
+
def verify_cfg_auth!
|
107
|
+
verify_cfg_auth_scheme!
|
108
|
+
verify_cfg_auth_persist
|
109
|
+
verify_cfg_auth_ttl
|
110
|
+
end
|
111
|
+
|
112
|
+
def verify_cfg_auth_scheme!
|
113
|
+
if $cfg['auth.scheme-token'] && $cfg['auth.scheme-basic']
|
114
|
+
error(%(Please only specify 'token' or 'basic' authentication))
|
115
|
+
exit 1
|
116
|
+
elsif !($cfg['auth.scheme-token'] || $cfg['auth.scheme-basic'])
|
117
|
+
if $cfg['auth.scheme-token'].nil?
|
118
|
+
# Default to token auth.
|
119
|
+
# E.g., user ran `murano cmd`, or `murano cmd --no-basic`.
|
120
|
+
$cfg['auth.scheme-token'] = true
|
121
|
+
else
|
122
|
+
# $cfg['auth.scheme-token'] is false(y), so use basic auth.
|
123
|
+
# E.g., user ran `cmd --no-token`, or `cmd --no-token --basic`.
|
124
|
+
$cfg['auth.scheme-basic'] = true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def verify_cfg_auth_persist
|
130
|
+
return unless $cfg['auth.persist-token'].nil? && $cfg['auth.persist-basic'].nil?
|
131
|
+
# User did not specify either --[no-]login or --[no-]cache.
|
132
|
+
# Default to caching the token.
|
133
|
+
$cfg['auth.persist-token'] = true
|
134
|
+
end
|
135
|
+
|
136
|
+
def verify_cfg_auth_ttl
|
137
|
+
return unless $cfg['auth.ttl'].nil? && !$cfg['auth.persist-token']
|
138
|
+
# User did not specify TTL, and token *not* being cached,
|
139
|
+
# so set a low time-to-live (2018-03-07: currently 60 secs).
|
140
|
+
$cfg['auth.ttl'] = MrMurano::Config::CFG_AUTH_DEFAULT_TTL
|
141
|
+
# Otherwise, user overrode the value; or
|
142
|
+
# token being persisted, so leave nil and let BizAPI set default.
|
143
|
+
end
|
144
|
+
|
145
|
+
# ---------------------------------------------------------------------
|
146
|
+
|
147
|
+
def logout(keep_user: false, keep_password: false, no_invalidate: false)
|
148
|
+
@logging_on = true
|
149
|
+
|
150
|
+
token = MrMurano::HttpAuthed.instance.token_lookup
|
151
|
+
invalidate_token(token) unless no_invalidate
|
152
|
+
|
153
|
+
net_host = verify_set('net.host')
|
154
|
+
user_name = verify_set('user.name')
|
155
|
+
if net_host && user_name
|
156
|
+
MrMurano::HttpAuthed.instance.token_forget(
|
157
|
+
net_host, user_name, keep_password: keep_password,
|
158
|
+
)
|
159
|
+
else
|
160
|
+
verbose 'Skipping password scrub: need both host and username to remove.'
|
161
|
+
end
|
162
|
+
|
163
|
+
cfg_clear_user_and_business(net_host, user_name) unless keep_user
|
164
|
+
|
165
|
+
@logging_on = false
|
166
|
+
end
|
167
|
+
|
168
|
+
def invalidate_token(tok)
|
169
|
+
# Delete/invalidate the remote tok.
|
170
|
+
return if tok.to_s.empty?
|
171
|
+
verbose 'Removing token.'
|
172
|
+
@suppress_error = true
|
173
|
+
# (lb): This is a bit of a kludge. The DELETE token/ call does not need
|
174
|
+
# authentication creds (like username and password). So tell our
|
175
|
+
# add_headers method not to call HttpAuthed.add_headers, which would
|
176
|
+
# otherwise add Authentication headers to the HTTP request.
|
177
|
+
@authless = true
|
178
|
+
delete('token/' + tok)
|
179
|
+
@authless = false
|
180
|
+
# The response is nil if token was not recognized, else it's {}.
|
181
|
+
# We don't care, because we'll forget our copy of the token.
|
182
|
+
@suppress_error = false
|
183
|
+
end
|
184
|
+
|
185
|
+
def cfg_clear_user_and_business(net_host, user_name)
|
186
|
+
user_net_host = $cfg.get('net.host', :user)
|
187
|
+
user_net_host = $cfg.get('net.host', :defaults) if user_net_host.nil?
|
188
|
+
user_user_name = $cfg.get('user.name', :user)
|
189
|
+
# Only clear user name from the user config if the net.host
|
190
|
+
# or user.name did not come from a different config, like the
|
191
|
+
# --project config.
|
192
|
+
unless (user_net_host == net_host) && (user_user_name == user_name)
|
193
|
+
verbose 'Skipping config scrub: net.host and/or user.name do not match.'
|
194
|
+
return
|
195
|
+
end
|
196
|
+
$cfg.set('user.name', nil, :user)
|
197
|
+
$cfg.set('business.id', nil, :user)
|
198
|
+
$cfg.set('business.name', nil, :user)
|
199
|
+
end
|
200
|
+
|
201
|
+
# ---------------------------------------------------------------------
|
202
|
+
|
203
|
+
def verify_set(cfg_key)
|
204
|
+
cfg_val = $cfg.get(cfg_key)
|
205
|
+
if cfg_val.to_s.empty?
|
206
|
+
cfg_val = nil
|
207
|
+
cfg_key_q = MrMurano::Verbose.fancy_ticks(cfg_key)
|
208
|
+
MrMurano::Verbose.warning("No config key #{cfg_key_q}: no password to delete")
|
209
|
+
end
|
210
|
+
cfg_val
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
data/lib/MrMurano/Business.rb
CHANGED
@@ -12,16 +12,15 @@ require 'rainbow'
|
|
12
12
|
require 'uri'
|
13
13
|
require 'yaml'
|
14
14
|
require 'MrMurano/hash'
|
15
|
-
require 'MrMurano/http'
|
16
15
|
require 'MrMurano/verbosing'
|
16
|
+
require 'MrMurano/AccountBase'
|
17
17
|
require 'MrMurano/Config'
|
18
18
|
require 'MrMurano/Solution'
|
19
|
-
require 'MrMurano/Passwords'
|
20
19
|
|
21
20
|
module MrMurano
|
22
21
|
# The Business class represents an end user's solutions.
|
23
22
|
class Business
|
24
|
-
include
|
23
|
+
include AccountBase
|
25
24
|
include Verbose
|
26
25
|
|
27
26
|
attr_writer :bid
|
@@ -31,6 +30,7 @@ module MrMurano
|
|
31
30
|
attr_reader :ometa
|
32
31
|
|
33
32
|
def initialize(data=nil)
|
33
|
+
super()
|
34
34
|
@bid = nil
|
35
35
|
@name = nil
|
36
36
|
@valid = false
|
@@ -85,22 +85,6 @@ module MrMurano
|
|
85
85
|
self
|
86
86
|
end
|
87
87
|
|
88
|
-
# MAYBE: Check that ADC is enabled on the business. If not, tell
|
89
|
-
# user to run Murano 2.x. [lb] is not sure which value from
|
90
|
-
# Murano to check. Is it :enableMurano or :enableProjects?
|
91
|
-
# See the overview method.
|
92
|
-
#def adc_compat_check
|
93
|
-
# unless $cfg['business.id'].nil?
|
94
|
-
# unless projects?($cfg['business.id'])
|
95
|
-
# # This is 3.x which does not support projects!
|
96
|
-
# warning('!'*80)
|
97
|
-
# warning "Your business requires Murano CLI 2.x"
|
98
|
-
# warning "Some features may not work correctly."
|
99
|
-
# warning('!'*80)
|
100
|
-
# end
|
101
|
-
# end
|
102
|
-
#end
|
103
|
-
|
104
88
|
def must_business_id!
|
105
89
|
raise MrMurano::ConfigError.new(Business.missing_business_id_msg) if bid.to_s.empty?
|
106
90
|
end
|
@@ -5,12 +5,8 @@
|
|
5
5
|
# vim:tw=0:ts=2:sw=2:et:ai
|
6
6
|
# Unauthorized copying of this file is strictly prohibited.
|
7
7
|
|
8
|
-
require 'fileutils'
|
9
8
|
require 'pathname'
|
10
9
|
require 'yaml'
|
11
|
-
require 'MrMurano/verbosing'
|
12
|
-
require 'MrMurano/Account'
|
13
|
-
require 'MrMurano/Config'
|
14
10
|
|
15
11
|
module MrMurano
|
16
12
|
class ConfigMigrate
|