haveapi-client 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/haveapi-client.gemspec +1 -2
- data/lib/haveapi/cli/authentication/base.rb +7 -4
- data/lib/haveapi/cli/authentication/token.rb +40 -23
- data/lib/haveapi/cli/cli.rb +48 -48
- data/lib/haveapi/cli/utils.rb +28 -0
- data/lib/haveapi/client/action.rb +16 -16
- data/lib/haveapi/client/authentication/base.rb +3 -2
- data/lib/haveapi/client/authentication/token.rb +52 -15
- data/lib/haveapi/client/client.rb +2 -2
- data/lib/haveapi/client/communicator.rb +12 -7
- data/lib/haveapi/client/resource_instance.rb +5 -5
- data/lib/haveapi/client/version.rb +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0ef69654a1ce04be90ccdc628dd976c3c6b09d91c24455cce5a1bb9df008185
|
4
|
+
data.tar.gz: fd976abf5adb0366bb573bbef70074977b61accb2d37013aec3a8a8c30e485da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e600c0543471f31308f0d8c60fc3e36ae51f048e94a851c0889604b0c22eb97b5880f940903f19aad575a7f6bb73a2ddb9ca6d0313916ce6154f372763907f
|
7
|
+
data.tar.gz: d37e9baf1f316e2f4d5ea0e03af7b98aa6b010fbdb256cc263bd53da60d43359a5ccb6546e318947f80e883fa3a4c7ccdb75d51988c1ffcc5b689447d9a65b1f
|
data/haveapi-client.gemspec
CHANGED
@@ -6,7 +6,6 @@ require 'haveapi/client/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'haveapi-client'
|
8
8
|
spec.version = HaveAPI::Client::VERSION
|
9
|
-
spec.date = '2017-11-27'
|
10
9
|
spec.authors = ['Jakub Skokan']
|
11
10
|
spec.email = ['jakub.skokan@vpsfree.cz']
|
12
11
|
spec.summary =
|
@@ -19,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
19
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
19
|
spec.require_paths = ['lib']
|
21
20
|
|
22
|
-
spec.add_development_dependency 'bundler'
|
21
|
+
spec.add_development_dependency 'bundler'
|
23
22
|
spec.add_development_dependency 'rake'
|
24
23
|
|
25
24
|
spec.add_runtime_dependency 'activesupport', '>= 4.0'
|
@@ -12,9 +12,9 @@ module HaveAPI::CLI
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
def initialize(communicator, desc, opts = {})
|
16
|
+
@communicator = communicator
|
17
|
+
@desc = desc
|
18
18
|
opts ||= {}
|
19
19
|
|
20
20
|
opts.each do |k, v|
|
@@ -47,6 +47,9 @@ module HaveAPI::CLI
|
|
47
47
|
def save
|
48
48
|
@communicator.auth_save
|
49
49
|
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
attr_reader :communicator, :desc
|
50
53
|
end
|
51
54
|
end
|
52
|
-
end
|
55
|
+
end
|
@@ -1,16 +1,20 @@
|
|
1
1
|
require 'haveapi/cli/authentication/base'
|
2
|
+
require 'haveapi/cli/utils'
|
2
3
|
|
3
4
|
module HaveAPI::CLI::Authentication
|
4
5
|
class Token < Base
|
5
6
|
register :token
|
6
7
|
|
8
|
+
include HaveAPI::CLI::Utils
|
9
|
+
|
7
10
|
def options(opts)
|
8
|
-
|
9
|
-
@user = u
|
10
|
-
end
|
11
|
+
@credentials = {}
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
request_credentials.each do |name, desc|
|
14
|
+
opts.on(
|
15
|
+
param_option(name, desc),
|
16
|
+
desc[:label] || name.to_s
|
17
|
+
) { |v| @credentials[name] = v }
|
14
18
|
end
|
15
19
|
|
16
20
|
opts.on('--token TOKEN', 'Token') do |t|
|
@@ -44,31 +48,44 @@ module HaveAPI::CLI::Authentication
|
|
44
48
|
def validate
|
45
49
|
return if @token
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
q.echo = false
|
51
|
+
request_credentials.each do |name, desc|
|
52
|
+
if !@credentials.has_key?(name)
|
53
|
+
@credentials[name] = read_param(name, desc)
|
54
|
+
end
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
55
58
|
def authenticate
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
opts = {
|
60
|
+
token: @token,
|
61
|
+
lifetime: @lifetime || :renewable_auto,
|
62
|
+
interval: @interval,
|
63
|
+
valid_to: @valid_to,
|
64
|
+
via: @via,
|
65
|
+
}
|
66
|
+
|
67
|
+
opts.update(@credentials) if @credentials
|
68
|
+
|
69
|
+
@communicator.authenticate(:token, opts) do |action, params|
|
70
|
+
ret = {}
|
71
|
+
|
72
|
+
params.each do |name, desc|
|
73
|
+
ret[name] = read_param(name, desc)
|
74
|
+
end
|
75
|
+
|
76
|
+
ret
|
77
|
+
end
|
65
78
|
end
|
66
79
|
|
67
80
|
def save
|
68
|
-
super.update({
|
69
|
-
|
70
|
-
|
71
|
-
|
81
|
+
super.update({via: @via, interval: @interval})
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
def request_credentials
|
86
|
+
desc[:resources][:token][:actions][:request][:input][:parameters].reject do |name, _|
|
87
|
+
%i(lifetime interval).include?(name)
|
88
|
+
end
|
72
89
|
end
|
73
90
|
end
|
74
91
|
end
|
data/lib/haveapi/cli/cli.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'pp'
|
3
|
-
require 'highline/import'
|
4
3
|
require 'yaml'
|
5
4
|
require 'time'
|
6
5
|
require 'date'
|
6
|
+
require 'haveapi/cli/utils'
|
7
7
|
|
8
8
|
module HaveAPI::CLI
|
9
9
|
class Cli
|
@@ -29,12 +29,13 @@ module HaveAPI::CLI
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
include Utils
|
33
|
+
|
32
34
|
def initialize
|
33
35
|
@config = read_config || {}
|
34
36
|
args, @opts = options
|
35
37
|
|
36
|
-
|
37
|
-
@api.identity = $0.split('/').last
|
38
|
+
connect_api unless @api
|
38
39
|
|
39
40
|
if @action
|
40
41
|
method(@action.first).call( * @action[1..-1] )
|
@@ -53,7 +54,7 @@ module HaveAPI::CLI
|
|
53
54
|
if cmd = find_command(resources, args[1])
|
54
55
|
authenticate if @auth
|
55
56
|
c = cmd.new(@opts, HaveAPI::Client::Client.new(nil, communicator: @api))
|
56
|
-
|
57
|
+
|
57
58
|
cmd_opt = OptionParser.new do |opts|
|
58
59
|
opts.banner = "\nCommand options:"
|
59
60
|
c.options(opts)
|
@@ -64,13 +65,13 @@ module HaveAPI::CLI
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
end
|
67
|
-
|
68
|
+
|
68
69
|
if @opts[:help]
|
69
70
|
show_help do
|
70
71
|
puts cmd_opt.help
|
71
72
|
end
|
72
73
|
end
|
73
|
-
|
74
|
+
|
74
75
|
if sep = ARGV.index('--')
|
75
76
|
cmd_opt.parse!(ARGV[sep+1..-1])
|
76
77
|
end
|
@@ -106,7 +107,7 @@ module HaveAPI::CLI
|
|
106
107
|
@selected_params = @opts[:output] ? @opts[:output].split(',').uniq
|
107
108
|
: nil
|
108
109
|
|
109
|
-
@input_params = parameters(action)
|
110
|
+
@input_params = parameters(action)
|
110
111
|
|
111
112
|
includes = build_includes(action) if @selected_params
|
112
113
|
@input_params[:meta] = { includes: includes } if includes
|
@@ -174,7 +175,15 @@ module HaveAPI::CLI
|
|
174
175
|
|
175
176
|
opts.on('-a', '--auth METHOD', Cli.auth_methods.keys, 'Authentication method') do |m|
|
176
177
|
options[:auth] = m
|
177
|
-
|
178
|
+
connect_api(url: options[:client], version: options[:version])
|
179
|
+
|
180
|
+
@auth = Cli.auth_methods[m].new(
|
181
|
+
@api,
|
182
|
+
@api.describe_api(options[:version])[:authentication][m],
|
183
|
+
server_config(options[:client])[:auth][m]
|
184
|
+
)
|
185
|
+
|
186
|
+
opts.separator "\nAuthentication options:"
|
178
187
|
@auth.options(opts)
|
179
188
|
end
|
180
189
|
|
@@ -217,7 +226,7 @@ module HaveAPI::CLI
|
|
217
226
|
opts.on('-r', '--rows', 'Print output in rows') do
|
218
227
|
options[:layout] = :rows
|
219
228
|
end
|
220
|
-
|
229
|
+
|
221
230
|
opts.on('-s', '--sort PARAMETER', 'Sort output by parameter') do |p|
|
222
231
|
options[:sort] = p
|
223
232
|
end
|
@@ -225,7 +234,7 @@ module HaveAPI::CLI
|
|
225
234
|
opts.on('--save', 'Save credentials to config file for later use') do
|
226
235
|
options[:save] = true
|
227
236
|
end
|
228
|
-
|
237
|
+
|
229
238
|
opts.on('--raw', 'Print raw response as is') do
|
230
239
|
options[:raw] = true
|
231
240
|
end
|
@@ -249,7 +258,7 @@ module HaveAPI::CLI
|
|
249
258
|
opts.on('--[no-]block', 'Toggle action blocking mode') do |v|
|
250
259
|
options[:block] = v
|
251
260
|
end
|
252
|
-
|
261
|
+
|
253
262
|
opts.on(
|
254
263
|
'--timeout SEC',
|
255
264
|
Float,
|
@@ -265,11 +274,11 @@ module HaveAPI::CLI
|
|
265
274
|
opts.on('--client-version', 'Show client version') do
|
266
275
|
@action = [:show_version]
|
267
276
|
end
|
268
|
-
|
277
|
+
|
269
278
|
opts.on('--protocol-version', 'Show protocol version') do
|
270
279
|
@action = [:protocol_version]
|
271
280
|
end
|
272
|
-
|
281
|
+
|
273
282
|
opts.on('--check-compatibility', 'Check compatibility with API server') do
|
274
283
|
@action = [:check_compat]
|
275
284
|
end
|
@@ -293,8 +302,15 @@ module HaveAPI::CLI
|
|
293
302
|
|
294
303
|
unless options[:auth]
|
295
304
|
cfg = server_config(options[:client])
|
305
|
+
connect_api(url: options[:client], version: options[:version]) unless @api
|
296
306
|
|
297
|
-
|
307
|
+
if m = cfg[:last_auth]
|
308
|
+
@auth = Cli.auth_methods[m].new(
|
309
|
+
@api,
|
310
|
+
@api.describe_api(options[:version])[:authentication][m],
|
311
|
+
cfg[:auth][m],
|
312
|
+
)
|
313
|
+
end
|
298
314
|
end
|
299
315
|
|
300
316
|
[args, options]
|
@@ -356,29 +372,6 @@ module HaveAPI::CLI
|
|
356
372
|
options
|
357
373
|
end
|
358
374
|
|
359
|
-
def param_option(name, p)
|
360
|
-
ret = '--'
|
361
|
-
name = name.to_s.dasherize
|
362
|
-
|
363
|
-
if p[:type] == 'Boolean'
|
364
|
-
ret += "[no-]#{name}"
|
365
|
-
|
366
|
-
else
|
367
|
-
ret += "#{name} [#{name.underscore.upcase}]"
|
368
|
-
end
|
369
|
-
|
370
|
-
ret
|
371
|
-
end
|
372
|
-
|
373
|
-
def read_param(name, p)
|
374
|
-
prompt = "#{p[:label] || name}: "
|
375
|
-
|
376
|
-
ask(prompt) do |q|
|
377
|
-
q.default = nil
|
378
|
-
q.echo = !p[:protected]
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
375
|
def list_versions
|
383
376
|
desc = @api.available_versions
|
384
377
|
|
@@ -521,7 +514,7 @@ module HaveAPI::CLI
|
|
521
514
|
end
|
522
515
|
|
523
516
|
cols = []
|
524
|
-
|
517
|
+
|
525
518
|
(@selected_params || action.params.keys).each do |raw_name|
|
526
519
|
col = {}
|
527
520
|
name = nil
|
@@ -536,7 +529,7 @@ module HaveAPI::CLI
|
|
536
529
|
|
537
530
|
parts.each do |part|
|
538
531
|
fail "'#{part}' not found" unless top.has_key?(part)
|
539
|
-
|
532
|
+
|
540
533
|
if top[part][:type] == 'Resource'
|
541
534
|
param = top[part]
|
542
535
|
top = @api.get_action(top[part][:resource], :show, []).params
|
@@ -556,7 +549,7 @@ module HaveAPI::CLI
|
|
556
549
|
break if top[part].nil?
|
557
550
|
top = top[part]
|
558
551
|
end
|
559
|
-
|
552
|
+
|
560
553
|
case param[:type]
|
561
554
|
when 'Resource'
|
562
555
|
"#{top[ param[:value_label].to_sym ]} (##{top[ param[:value_id].to_sym ]})"
|
@@ -570,12 +563,12 @@ module HaveAPI::CLI
|
|
570
563
|
end
|
571
564
|
|
572
565
|
col[:label] = raw_name
|
573
|
-
|
566
|
+
|
574
567
|
else # directly accessible parameter
|
575
568
|
name = raw_name.to_sym
|
576
569
|
param = action.params[name]
|
577
570
|
fail "parameter '#{name}' does not exist" if param.nil?
|
578
|
-
|
571
|
+
|
579
572
|
if param[:type] == 'Resource'
|
580
573
|
col[:display] = Proc.new do |r|
|
581
574
|
next '' unless r
|
@@ -591,9 +584,9 @@ module HaveAPI::CLI
|
|
591
584
|
name: name,
|
592
585
|
align: %w(Integer Float).include?(param[:type]) ? 'right' : 'left',
|
593
586
|
})
|
594
|
-
|
587
|
+
|
595
588
|
col[:label] ||= param[:label] && !param[:label].empty? ? param[:label] : name.upcase
|
596
|
-
|
589
|
+
|
597
590
|
cols << col
|
598
591
|
end
|
599
592
|
|
@@ -618,7 +611,6 @@ module HaveAPI::CLI
|
|
618
611
|
|
619
612
|
def authenticate(action = nil)
|
620
613
|
if @auth
|
621
|
-
@auth.communicator = @api
|
622
614
|
@auth.validate
|
623
615
|
@auth.authenticate
|
624
616
|
|
@@ -669,6 +661,14 @@ module HaveAPI::CLI
|
|
669
661
|
@config[:servers].last
|
670
662
|
end
|
671
663
|
|
664
|
+
def connect_api(url: nil, version: nil)
|
665
|
+
@api = HaveAPI::Client::Communicator.new(
|
666
|
+
url || api_url,
|
667
|
+
version || (@opts && @opts[:version])
|
668
|
+
)
|
669
|
+
@api.identity = $0.split('/').last
|
670
|
+
end
|
671
|
+
|
672
672
|
def format_errors(action, msg, errors)
|
673
673
|
warn "Action failed: #{msg}"
|
674
674
|
|
@@ -701,7 +701,7 @@ module HaveAPI::CLI
|
|
701
701
|
# node.name => node
|
702
702
|
def build_includes(action)
|
703
703
|
ret = []
|
704
|
-
|
704
|
+
|
705
705
|
@selected_params.each do |param|
|
706
706
|
next unless param.index('.')
|
707
707
|
|
@@ -710,8 +710,8 @@ module HaveAPI::CLI
|
|
710
710
|
|
711
711
|
param.split('.').map! { |v| v.to_sym }.each do |part|
|
712
712
|
next unless top.has_key?(part)
|
713
|
-
next if top[part][:type] != 'Resource'
|
714
|
-
|
713
|
+
next if top[part][:type] != 'Resource'
|
714
|
+
|
715
715
|
includes << part
|
716
716
|
top = @api.get_action(top[part][:resource], :show, []).params
|
717
717
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
|
3
|
+
module HaveAPI::CLI
|
4
|
+
module Utils
|
5
|
+
def param_option(name, p)
|
6
|
+
ret = '--'
|
7
|
+
name = name.to_s.dasherize
|
8
|
+
|
9
|
+
if p[:type] == 'Boolean'
|
10
|
+
ret += "[no-]#{name}"
|
11
|
+
|
12
|
+
else
|
13
|
+
ret += "#{name} [#{name.underscore.upcase}]"
|
14
|
+
end
|
15
|
+
|
16
|
+
ret
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_param(name, p)
|
20
|
+
prompt = "#{p[:label] || name}: "
|
21
|
+
|
22
|
+
ask(prompt) do |q|
|
23
|
+
q.default = nil
|
24
|
+
q.echo = !p[:protected]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -14,10 +14,10 @@ module HaveAPI::Client
|
|
14
14
|
|
15
15
|
def execute(data, *_)
|
16
16
|
args = [self]
|
17
|
-
|
17
|
+
|
18
18
|
if input
|
19
19
|
params = Params.new(self, data)
|
20
|
-
|
20
|
+
|
21
21
|
unless params.valid?
|
22
22
|
raise ValidationError.new(self, params.errors)
|
23
23
|
end
|
@@ -98,8 +98,8 @@ module HaveAPI::Client
|
|
98
98
|
@spec[:meta][scope]
|
99
99
|
end
|
100
100
|
|
101
|
-
def
|
102
|
-
@spec[:
|
101
|
+
def path
|
102
|
+
@spec[:path]
|
103
103
|
end
|
104
104
|
|
105
105
|
def help
|
@@ -107,8 +107,8 @@ module HaveAPI::Client
|
|
107
107
|
end
|
108
108
|
|
109
109
|
# Url with resolved parameters.
|
110
|
-
def
|
111
|
-
@
|
110
|
+
def prepared_path
|
111
|
+
@prepared_path || @spec[:path]
|
112
112
|
end
|
113
113
|
|
114
114
|
def prepared_help
|
@@ -120,27 +120,27 @@ module HaveAPI::Client
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def unresolved_args?
|
123
|
-
|
123
|
+
prepared_path =~ /:[a-zA-Z\-_]+/
|
124
124
|
end
|
125
125
|
|
126
126
|
def provide_args(*args)
|
127
127
|
apply_args(args)
|
128
128
|
end
|
129
129
|
|
130
|
-
def
|
131
|
-
@
|
130
|
+
def provide_path(path, help)
|
131
|
+
@prepared_path = path
|
132
132
|
@prepared_help = help
|
133
133
|
end
|
134
134
|
|
135
135
|
def reset
|
136
|
-
@
|
136
|
+
@prepared_path = nil
|
137
137
|
@prepared_help = nil
|
138
138
|
end
|
139
139
|
|
140
140
|
def update_description(spec)
|
141
141
|
@spec = spec
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
# Block until the action is completed or timeout occurs. If the block is given,
|
145
145
|
# it is regularly called with the action's state.
|
146
146
|
# @param interval [Float] how often should the action state be checked
|
@@ -185,7 +185,7 @@ module HaveAPI::Client
|
|
185
185
|
cancel_block = state.cancel_block
|
186
186
|
|
187
187
|
ret = cancel(client, id)
|
188
|
-
|
188
|
+
|
189
189
|
if ret.is_a?(Response)
|
190
190
|
# The cancel is not a blocking operation, return immediately
|
191
191
|
raise ActionFailed, ret unless ret.ok?
|
@@ -203,7 +203,7 @@ module HaveAPI::Client
|
|
203
203
|
&cancel_block
|
204
204
|
)
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
return ret
|
208
208
|
end
|
209
209
|
|
@@ -232,12 +232,12 @@ module HaveAPI::Client
|
|
232
232
|
|
233
233
|
private
|
234
234
|
def apply_args(args)
|
235
|
-
@
|
235
|
+
@prepared_path ||= @spec[:path].dup
|
236
236
|
@prepared_help ||= @spec[:help].dup
|
237
237
|
|
238
238
|
args.each do |arg|
|
239
|
-
@
|
240
|
-
@prepared_help.sub!(
|
239
|
+
@prepared_path.sub!(/\{[a-zA-Z\-_]+\}/, arg.to_s)
|
240
|
+
@prepared_help.sub!(/\{[a-zA-Z\-_]+\}/, arg.to_s)
|
241
241
|
end
|
242
242
|
end
|
243
243
|
end
|
@@ -29,10 +29,11 @@ module HaveAPI::Client
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def initialize(communicator, description, opts)
|
32
|
+
def initialize(communicator, description, opts, &block)
|
33
33
|
@communicator = communicator
|
34
34
|
@desc = description
|
35
35
|
@opts = opts
|
36
|
+
@block = block
|
36
37
|
|
37
38
|
setup
|
38
39
|
end
|
@@ -48,7 +49,7 @@ module HaveAPI::Client
|
|
48
49
|
end
|
49
50
|
|
50
51
|
# Called for each request. Returns a hash of query parameters.
|
51
|
-
def
|
52
|
+
def request_query_params
|
52
53
|
{}
|
53
54
|
end
|
54
55
|
|
@@ -15,7 +15,7 @@ module HaveAPI::Client::Authentication
|
|
15
15
|
@configured = true
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def request_query_params
|
19
19
|
return {} unless @configured
|
20
20
|
check_validity
|
21
21
|
@via == :query_param ? {@desc[:query_parameter] => @token} : {}
|
@@ -65,25 +65,50 @@ module HaveAPI::Client::Authentication
|
|
65
65
|
|
66
66
|
protected
|
67
67
|
def request_token
|
68
|
+
input = {
|
69
|
+
lifetime: @opts[:lifetime],
|
70
|
+
interval: @opts[:interval] || 300,
|
71
|
+
}
|
72
|
+
request_credentials.each { |name| input[name] = @opts[name] }
|
73
|
+
|
74
|
+
cont, next_action, token = login_step(:request, input)
|
75
|
+
return if cont == :done
|
76
|
+
|
77
|
+
if @block.nil?
|
78
|
+
raise AuthenticationFailed.new('implement multi-factor authentication')
|
79
|
+
end
|
80
|
+
|
81
|
+
loop do
|
82
|
+
input = {token: token}
|
83
|
+
input.update(@block.call(next_action, auth_action_input(next_action)))
|
84
|
+
|
85
|
+
cont, next_action, token = login_step(next_action, input)
|
86
|
+
return if cont == :done
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def login_step(name, input)
|
68
91
|
a = HaveAPI::Client::Action.new(
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
92
|
+
nil,
|
93
|
+
@communicator,
|
94
|
+
name,
|
95
|
+
@desc[:resources][:token][:actions][name],
|
96
|
+
[]
|
74
97
|
)
|
75
|
-
ret = a.execute({
|
76
|
-
login: @opts[:user],
|
77
|
-
password: @opts[:password],
|
78
|
-
lifetime: @opts[:lifetime],
|
79
|
-
interval: @opts[:interval] || 300})
|
80
98
|
|
81
|
-
|
99
|
+
resp = HaveAPI::Client::Response.new(a, a.execute(input))
|
82
100
|
|
83
|
-
|
101
|
+
if resp.failed?
|
102
|
+
raise AuthenticationFailed.new(resp.message || 'invalid credentials')
|
103
|
+
end
|
84
104
|
|
85
|
-
|
86
|
-
|
105
|
+
if resp[:complete]
|
106
|
+
@token = resp[:token]
|
107
|
+
@valid_to = resp[:valid_to] && DateTime.iso8601(resp[:valid_to]).to_time
|
108
|
+
:done
|
109
|
+
else
|
110
|
+
[:continue, resp[:next_action].to_sym, resp[:token]]
|
111
|
+
end
|
87
112
|
end
|
88
113
|
|
89
114
|
def check_validity
|
@@ -95,5 +120,17 @@ module HaveAPI::Client::Authentication
|
|
95
120
|
end
|
96
121
|
end
|
97
122
|
end
|
123
|
+
|
124
|
+
def request_credentials
|
125
|
+
@desc[:resources][:token][:actions][:request][:input][:parameters].each_key.reject do |name|
|
126
|
+
%i(interval lifetime).include?(name)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def auth_action_input(name)
|
131
|
+
@desc[:resources][:token][:actions][name][:input][:parameters].reject do |k, _|
|
132
|
+
%i(token).include?(k)
|
133
|
+
end
|
134
|
+
end
|
98
135
|
end
|
99
136
|
end
|
@@ -41,10 +41,15 @@ module HaveAPI::Client
|
|
41
41
|
# Authenticate user with selected +auth_method+.
|
42
42
|
# +auth_method+ is a name of registered authentication provider.
|
43
43
|
# +options+ are specific for each authentication provider.
|
44
|
-
def authenticate(auth_method, options = {})
|
44
|
+
def authenticate(auth_method, options = {}, &block)
|
45
45
|
desc = describe_api(@version)
|
46
46
|
|
47
|
-
@auth = self.class.auth_methods[auth_method].new(
|
47
|
+
@auth = self.class.auth_methods[auth_method].new(
|
48
|
+
self,
|
49
|
+
desc[:authentication][auth_method],
|
50
|
+
options,
|
51
|
+
&block
|
52
|
+
)
|
48
53
|
@rest = @auth.resource || @rest
|
49
54
|
end
|
50
55
|
|
@@ -136,11 +141,11 @@ module HaveAPI::Client
|
|
136
141
|
|
137
142
|
end if meta
|
138
143
|
|
139
|
-
args << {params: get_params.update(@auth.
|
144
|
+
args << {params: get_params.update(@auth.request_query_params), accept: :json, user_agent: @identity}.update(@auth.request_headers)
|
140
145
|
end
|
141
146
|
|
142
147
|
begin
|
143
|
-
response = parse(@rest[action.
|
148
|
+
response = parse(@rest[action.prepared_path].method(action.http_method.downcase.to_sym).call(*args))
|
144
149
|
|
145
150
|
rescue RestClient::Forbidden
|
146
151
|
return error('Access forbidden. Bad user name or password? Not authorized?')
|
@@ -184,14 +189,14 @@ module HaveAPI::Client
|
|
184
189
|
|
185
190
|
def description_for(path, query_params={})
|
186
191
|
ret = parse(@rest[path].get_options({
|
187
|
-
params: @auth.request_payload.update(@auth.
|
192
|
+
params: @auth.request_payload.update(@auth.request_query_params).update(query_params),
|
188
193
|
user_agent: @identity
|
189
194
|
}.update(@auth.request_headers)))
|
190
|
-
|
195
|
+
|
191
196
|
@proto_version = ret[:version]
|
192
197
|
p_v = HaveAPI::Client::PROTOCOL_VERSION
|
193
198
|
return ret[:response] if ret[:version] == p_v
|
194
|
-
|
199
|
+
|
195
200
|
unless ret[:version]
|
196
201
|
raise ProtocolError,
|
197
202
|
"Incompatible protocol version: the client uses v#{p_v} "+
|
@@ -23,13 +23,13 @@ module HaveAPI::Client
|
|
23
23
|
if response
|
24
24
|
if response.is_a?(Hash)
|
25
25
|
@params = response
|
26
|
-
@prepared_args = response[:_meta][:
|
26
|
+
@prepared_args = response[:_meta][:path_params]
|
27
27
|
@meta = response[:_meta] unless @meta
|
28
28
|
|
29
29
|
else
|
30
30
|
@response = response
|
31
31
|
@params = response.response
|
32
|
-
@prepared_args = response.meta[:
|
32
|
+
@prepared_args = response.meta[:path_params]
|
33
33
|
@meta = response.meta unless @meta
|
34
34
|
end
|
35
35
|
|
@@ -81,14 +81,14 @@ module HaveAPI::Client
|
|
81
81
|
def resolve
|
82
82
|
return self if @resolved
|
83
83
|
|
84
|
-
@action.provide_args(*@meta[:
|
84
|
+
@action.provide_args(*@meta[:path_params])
|
85
85
|
@response = Response.new(@action, @action.execute({}))
|
86
86
|
@params = @response.response
|
87
87
|
|
88
88
|
setup_from_clone(@resource)
|
89
89
|
define_attributes
|
90
90
|
|
91
|
-
@prepared_args = @response.meta[:
|
91
|
+
@prepared_args = @response.meta[:path_params]
|
92
92
|
@resolved = true
|
93
93
|
self
|
94
94
|
end
|
@@ -133,7 +133,7 @@ module HaveAPI::Client
|
|
133
133
|
resolved: false,
|
134
134
|
# TODO: this will not work for nested resources, as they have
|
135
135
|
# multiple IDs
|
136
|
-
|
136
|
+
path_params: [id],
|
137
137
|
},
|
138
138
|
}
|
139
139
|
)
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haveapi-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Skokan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- lib/haveapi/cli/commands/action_state_wait.rb
|
148
148
|
- lib/haveapi/cli/example_formatter.rb
|
149
149
|
- lib/haveapi/cli/output_formatter.rb
|
150
|
+
- lib/haveapi/cli/utils.rb
|
150
151
|
- lib/haveapi/client.rb
|
151
152
|
- lib/haveapi/client/action.rb
|
152
153
|
- lib/haveapi/client/action_state.rb
|