haveapi 0.20.0 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +6 -6
  4. data/haveapi.gemspec +13 -13
  5. data/lib/haveapi/action.rb +153 -167
  6. data/lib/haveapi/action_state.rb +2 -6
  7. data/lib/haveapi/actions/default.rb +8 -10
  8. data/lib/haveapi/api.rb +2 -1
  9. data/lib/haveapi/authentication/base.rb +5 -8
  10. data/lib/haveapi/authentication/basic/provider.rb +4 -5
  11. data/lib/haveapi/authentication/chain.rb +19 -17
  12. data/lib/haveapi/authentication/oauth2/config.rb +12 -32
  13. data/lib/haveapi/authentication/oauth2/provider.rb +20 -30
  14. data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +1 -2
  15. data/lib/haveapi/authentication/token/action_config.rb +5 -3
  16. data/lib/haveapi/authentication/token/config.rb +5 -5
  17. data/lib/haveapi/authentication/token/provider.rb +33 -37
  18. data/lib/haveapi/authorization.rb +10 -4
  19. data/lib/haveapi/client_example.rb +11 -14
  20. data/lib/haveapi/client_examples/curl.rb +37 -37
  21. data/lib/haveapi/client_examples/fs_client.rb +29 -31
  22. data/lib/haveapi/client_examples/http.rb +35 -36
  23. data/lib/haveapi/client_examples/js_client.rb +62 -63
  24. data/lib/haveapi/client_examples/php_client.rb +77 -76
  25. data/lib/haveapi/client_examples/ruby_cli.rb +30 -30
  26. data/lib/haveapi/client_examples/ruby_client.rb +26 -26
  27. data/lib/haveapi/common.rb +3 -4
  28. data/lib/haveapi/context.rb +11 -10
  29. data/lib/haveapi/example.rb +9 -4
  30. data/lib/haveapi/example_list.rb +2 -2
  31. data/lib/haveapi/exceptions.rb +1 -1
  32. data/lib/haveapi/extensions/action_exceptions.rb +2 -2
  33. data/lib/haveapi/extensions/base.rb +1 -3
  34. data/lib/haveapi/extensions/exception_mailer.rb +260 -257
  35. data/lib/haveapi/hooks.rb +40 -39
  36. data/lib/haveapi/metadata.rb +1 -1
  37. data/lib/haveapi/model_adapter.rb +16 -27
  38. data/lib/haveapi/model_adapters/active_record.rb +59 -69
  39. data/lib/haveapi/output_formatter.rb +7 -7
  40. data/lib/haveapi/output_formatters/base.rb +2 -4
  41. data/lib/haveapi/parameters/resource.rb +7 -7
  42. data/lib/haveapi/parameters/typed.rb +6 -9
  43. data/lib/haveapi/params.rb +38 -45
  44. data/lib/haveapi/resource.rb +8 -8
  45. data/lib/haveapi/resources/action_state.rb +11 -19
  46. data/lib/haveapi/server.rb +102 -107
  47. data/lib/haveapi/spec/api_response.rb +1 -1
  48. data/lib/haveapi/spec/helpers.rb +1 -1
  49. data/lib/haveapi/spec/mock_action.rb +11 -10
  50. data/lib/haveapi/spec/spec_methods.rb +9 -8
  51. data/lib/haveapi/tasks/yard.rb +2 -2
  52. data/lib/haveapi/types.rb +0 -3
  53. data/lib/haveapi/validator.rb +6 -3
  54. data/lib/haveapi/validator_chain.rb +9 -8
  55. data/lib/haveapi/validators/acceptance.rb +6 -6
  56. data/lib/haveapi/validators/confirmation.rb +2 -3
  57. data/lib/haveapi/validators/exclusion.rb +1 -1
  58. data/lib/haveapi/validators/format.rb +1 -1
  59. data/lib/haveapi/validators/inclusion.rb +1 -1
  60. data/lib/haveapi/validators/length.rb +12 -11
  61. data/lib/haveapi/validators/numericality.rb +14 -13
  62. data/lib/haveapi/validators/presence.rb +4 -3
  63. data/lib/haveapi/version.rb +2 -2
  64. data/lib/haveapi.rb +2 -3
  65. data/spec/.rubocop.yml +4 -0
  66. data/spec/action/dsl_spec.rb +18 -18
  67. data/spec/authorization_spec.rb +8 -8
  68. data/spec/common_spec.rb +2 -1
  69. data/spec/documentation_spec.rb +2 -9
  70. data/spec/envelope_spec.rb +2 -2
  71. data/spec/hooks_spec.rb +12 -12
  72. data/spec/parameters/typed_spec.rb +6 -6
  73. data/spec/params_spec.rb +22 -24
  74. data/spec/resource_spec.rb +5 -7
  75. data/spec/spec_helper.rb +0 -1
  76. data/spec/validators/acceptance_spec.rb +1 -1
  77. data/spec/validators/confirmation_spec.rb +5 -5
  78. data/spec/validators/exclusion_spec.rb +3 -3
  79. data/spec/validators/format_spec.rb +2 -2
  80. data/spec/validators/inclusion_spec.rb +4 -4
  81. data/spec/validators/length_spec.rb +23 -23
  82. data/spec/validators/numericality_spec.rb +13 -13
  83. data/spec/validators/presence_spec.rb +3 -3
  84. metadata +49 -48
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0c14a9402fd2fd7ffef72fc2598c58b8682721c6166dd61acce339de6333e99
4
- data.tar.gz: 96b21deb3be038337ae86baa6a02a4ff3d5c61c04c8e5836f2bc86fbc0295d58
3
+ metadata.gz: 0e72ad9fd9ee5a7d0ada6b5985e28f51d6fe65423b290aae824f6ff55a067145
4
+ data.tar.gz: c6c35096b29c02199c3dd4ae46d2ee8ec6920e2f5d5436596e4cde1a133c80cf
5
5
  SHA512:
6
- metadata.gz: 7ead70adaf53318e32eb048d8d4643e31b2c3e5bc6c4bd9b3cddf0e7449cefb4b1ff16c47d6eb97e88763ea0a9c0843c1f74b56304584799d6ef0c2b27b0cca3
7
- data.tar.gz: 1f8fd35c19dab55113f1702eacb323b5c86943c425279da4fa21f1de303164f7bd34bc9de134198458874ac09556e98de14de90f4d8f6d3b81b2b64785b001ea
6
+ metadata.gz: 722c8af5849aef6fe6dbbf48d53bb159c66a9dcd4decafcc4ba20a5f6fee441dbe0eb2d08a2f91283dd900869e1e36632281fcabc038a0ad8ed83dbc9255e053
7
+ data.tar.gz: b26b675cb2ce63c3d7f2723f3084bb7e7289d4ee896dfbdcf875ed841adedc9feb991b3ee76715586fc79d8b21657e537c446e2284aab24dd94361dfbbd78383
data/Gemfile CHANGED
@@ -4,8 +4,8 @@ gemspec
4
4
  gem 'haveapi-client', path: '../../clients/ruby'
5
5
 
6
6
  group :test do
7
- gem 'rspec'
8
7
  gem 'rack-test'
8
+ gem 'rspec'
9
9
  end
10
10
 
11
11
  group :activerecord do
data/Rakefile CHANGED
@@ -16,16 +16,16 @@ begin
16
16
  YARD::Rake::YardocTask.new do |t|
17
17
  t.files = ['lib/**/*.rb']
18
18
  t.options = [
19
- '--protected',
20
- '--output-dir=html_doc',
21
- '--files=doc/*.md',
22
- '--files=doc/*.html'
19
+ '--protected',
20
+ '--output-dir=html_doc',
21
+ '--files=doc/*.md',
22
+ '--files=doc/*.html'
23
23
  ]
24
- t.before = Proc.new do
24
+ t.before = proc do
25
25
  document_hooks.call
26
26
  render_doc_file('doc/json-schema.erb', 'doc/JSON-Schema.html').call
27
27
  end
28
28
  end
29
-
30
29
  rescue LoadError
30
+ # ignore
31
31
  end
data/haveapi.gemspec CHANGED
@@ -1,30 +1,30 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
1
+ lib = File.expand_path('lib', __dir__)
2
+ $:.unshift(lib) unless $:.include?(lib)
3
3
  require 'haveapi/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'haveapi'
7
7
  s.version = HaveAPI::VERSION
8
8
  s.summary =
9
- s.description = 'Framework for creating self-describing APIs'
9
+ s.description = 'Framework for creating self-describing APIs'
10
10
  s.authors = 'Jakub Skokan'
11
11
  s.email = 'jakub.skokan@vpsfree.cz'
12
12
  s.files = `git ls-files -z`.split("\x0") + Dir.glob('doc/*')
13
13
  s.license = 'MIT'
14
14
 
15
- s.required_ruby_version = '>= 2.0.0'
15
+ s.required_ruby_version = ">= #{File.read('../../.ruby-version').strip}"
16
16
 
17
- s.add_runtime_dependency 'require_all', '~> 2.0.0'
18
- s.add_runtime_dependency 'json'
19
17
  s.add_runtime_dependency 'activesupport', '>= 7.1'
20
- s.add_runtime_dependency 'sinatra', '~> 3.1.0'
21
- s.add_runtime_dependency 'sinatra-contrib', '~> 3.1.0'
22
- s.add_runtime_dependency 'tilt', '~> 2.3.0'
23
- s.add_runtime_dependency 'redcarpet', '~> 3.6'
24
- s.add_runtime_dependency 'rake'
25
18
  s.add_runtime_dependency 'github-markdown'
26
- s.add_runtime_dependency 'nesty', '~> 1.0'
27
- s.add_runtime_dependency 'haveapi-client', '~> 0.20.0'
19
+ s.add_runtime_dependency 'haveapi-client', '~> 0.21.1'
20
+ s.add_runtime_dependency 'json'
28
21
  s.add_runtime_dependency 'mail'
22
+ s.add_runtime_dependency 'nesty', '~> 1.0'
29
23
  s.add_runtime_dependency 'rack-oauth2', '~> 2.2.0'
24
+ s.add_runtime_dependency 'rake'
25
+ s.add_runtime_dependency 'redcarpet', '~> 3.6'
26
+ s.add_runtime_dependency 'require_all', '~> 2.0.0'
27
+ s.add_runtime_dependency 'sinatra', '~> 3.1.0'
28
+ s.add_runtime_dependency 'sinatra-contrib', '~> 3.1.0'
29
+ s.add_runtime_dependency 'tilt', '~> 2.3.0'
30
30
  end
@@ -17,29 +17,26 @@ module HaveAPI
17
17
  include Hookable
18
18
 
19
19
  has_hook :pre_authorize,
20
- desc: 'Called to provide additional authorization blocks. These blocks are '+
21
- 'called before action\'s own authorization block. Note that if any '+
22
- 'of the blocks uses allow/deny rule, it will be the final authorization '+
23
- 'decision and even action\'s own authorization block will not be called.',
24
- args: {
25
- context: 'HaveAPI::Context instance',
26
- },
27
- ret: {
28
- blocks: 'array of authorization blocks',
29
- }
20
+ desc: "Called to provide additional authorization blocks. These blocks are called before action's own authorization block. Note that if any of the blocks uses allow/deny rule, it will be the final authorization decision and even action's own authorization block will not be called.",
21
+ args: {
22
+ context: 'HaveAPI::Context instance'
23
+ },
24
+ ret: {
25
+ blocks: 'array of authorization blocks'
26
+ }
30
27
 
31
28
  has_hook :exec_exception,
32
- desc: 'Called when unhandled exceptions occurs during Action.exec',
33
- args: {
34
- context: 'HaveAPI::Context instance',
35
- exception: 'exception instance',
36
- },
37
- ret: {
38
- status: 'true or false, indicating whether error should be reported',
39
- message: 'error message sent to the user',
40
- }
41
-
42
- attr_reader :message, :errors, :version
29
+ desc: 'Called when unhandled exceptions occurs during Action.exec',
30
+ args: {
31
+ context: 'HaveAPI::Context instance',
32
+ exception: 'exception instance'
33
+ },
34
+ ret: {
35
+ status: 'true or false, indicating whether error should be reported',
36
+ message: 'error message sent to the user'
37
+ }
38
+
39
+ attr_reader :message, :errors, :version, :current_user, :request
43
40
  attr_accessor :flags
44
41
 
45
42
  class << self
@@ -48,13 +45,13 @@ module HaveAPI
48
45
 
49
46
  def inherited(subclass)
50
47
  # puts "Action.inherited called #{subclass} from #{to_s}"
51
-
48
+ super
52
49
  subclass.instance_variable_set(:@obj_type, obj_type)
53
50
 
54
- if subclass.name
55
- # not an anonymouse class
56
- delayed_inherited(subclass)
57
- end
51
+ return unless subclass.name
52
+
53
+ # not an anonymouse class
54
+ delayed_inherited(subclass)
58
55
  end
59
56
 
60
57
  def delayed_inherited(subclass)
@@ -71,9 +68,10 @@ module HaveAPI
71
68
 
72
69
  m = {}
73
70
 
74
- @meta.each do |k,v|
71
+ @meta.each do |k, v|
75
72
  m[k] = v && v.clone
76
73
  next unless v
74
+
77
75
  m[k].action = subclass
78
76
  end
79
77
 
@@ -86,11 +84,11 @@ module HaveAPI
86
84
  subclass.instance_variable_set(:@model, resource.model)
87
85
  resource.action_defined(subclass)
88
86
  rescue NoMethodError
89
- return
87
+ nil
90
88
  end
91
89
  end
92
90
 
93
- def initialize
91
+ def initialize # rubocop:disable Lint/MissingSuper
94
92
  return if @initialized
95
93
 
96
94
  check_build("#{self}.input") do
@@ -109,9 +107,9 @@ module HaveAPI
109
107
  meta(:global) do
110
108
  output do
111
109
  integer :action_state_id,
112
- label: 'Action state ID',
113
- desc: 'ID of ActionState object for state querying. When null, the action '+
114
- 'is not blocking for the current invocation.'
110
+ label: 'Action state ID',
111
+ desc: 'ID of ActionState object for state querying. When null, the action ' \
112
+ 'is not blocking for the current invocation.'
115
113
  end
116
114
  end
117
115
  end
@@ -171,7 +169,7 @@ module HaveAPI
171
169
 
172
170
  def meta(type = :object, &block)
173
171
  if block
174
- @meta ||= {object: nil, global: nil}
172
+ @meta ||= { object: nil, global: nil }
175
173
  @meta[type] ||= Metadata::ActionMetadata.new
176
174
  @meta[type].action = self
177
175
  @meta[type].instance_exec(&block)
@@ -180,14 +178,14 @@ module HaveAPI
180
178
  end
181
179
  end
182
180
 
183
- def authorize(&block)
184
- @authorization = Authorization.new(&block)
181
+ def authorize(&)
182
+ @authorization = Authorization.new(&)
185
183
  end
186
184
 
187
- def example(title = '', &block)
185
+ def example(title = '', &)
188
186
  @examples ||= ExampleList.new
189
187
  e = Example.new(title)
190
- e.instance_eval(&block)
188
+ e.instance_eval(&)
191
189
  @examples << e
192
190
  end
193
191
 
@@ -195,29 +193,28 @@ module HaveAPI
195
193
  (@action_name ? @action_name.to_s : to_s).demodulize
196
194
  end
197
195
 
198
- def action_name=(name)
199
- @action_name = name
200
- end
196
+ attr_writer :action_name
201
197
 
202
198
  def build_route(prefix)
203
199
  route = @route || action_name.underscore
204
- if @route
205
- @route
206
- elsif action_name
207
- action_name.to_s.demodulize.underscore
208
- else
209
- to_s.demodulize.underscore
210
- end
200
+ if @route
201
+ @route
202
+ elsif action_name
203
+ action_name.to_s.demodulize.underscore
204
+ else
205
+ to_s.demodulize.underscore
206
+ end
211
207
 
212
208
  if !route.is_a?(String) && route.respond_to?(:call)
213
- route = route.call(self.resource)
209
+ route = route.call(resource)
214
210
  end
215
211
 
216
- prefix + route % {resource: self.resource.resource_name.underscore}
212
+ prefix + format(route, resource: resource.resource_name.underscore)
217
213
  end
218
214
 
219
215
  def describe(context)
220
216
  authorization = (@authorization && @authorization.clone) || Authorization.new
217
+ add_pre_authorize_blocks(authorization, context)
221
218
 
222
219
  if (context.endpoint || context.current_user) \
223
220
  && !authorization.authorized?(context.current_user, context.path_params_from_args)
@@ -242,14 +239,14 @@ module HaveAPI
242
239
  description: @desc,
243
240
  aliases: @aliases,
244
241
  blocking: @blocking ? true : false,
245
- input: @input ? @input.describe(context) : {parameters: {}},
246
- output: @output ? @output.describe(context) : {parameters: {}},
242
+ input: @input ? @input.describe(context) : { parameters: {} },
243
+ output: @output ? @output.describe(context) : { parameters: {} },
247
244
  meta: @meta ? @meta.merge(@meta) { |_, v| v && v.describe(context) } : nil,
248
245
  examples: @examples ? @examples.describe(context) : [],
249
246
  scope: context.action_scope,
250
247
  path: context.resolved_path,
251
248
  method: route_method,
252
- help: "#{context.path}?method=#{route_method}",
249
+ help: "#{context.path}?method=#{route_method}"
253
250
  }
254
251
  end
255
252
 
@@ -257,7 +254,6 @@ module HaveAPI
257
254
  def inherit_attrs_from_resource(action, r, attrs)
258
255
  begin
259
256
  return unless r.obj_type == :resource
260
-
261
257
  rescue NoMethodError
262
258
  return
263
259
  end
@@ -279,16 +275,29 @@ module HaveAPI
279
275
  end
280
276
 
281
277
  def resolve_path_params(object)
282
- if self.resolve
283
- self.resolve.call(object)
278
+ if resolve
279
+ resolve.call(object)
284
280
 
285
281
  else
286
282
  object.respond_to?(:id) ? object.id : nil
287
283
  end
288
284
  end
285
+
286
+ def add_pre_authorize_blocks(authorization, context)
287
+ ret = Action.call_hooks(
288
+ :pre_authorize,
289
+ args: [context],
290
+ initial: { blocks: [] }
291
+ )
292
+
293
+ ret[:blocks].reverse_each do |block|
294
+ authorization.prepend_block(block)
295
+ end
296
+ end
289
297
  end
290
298
 
291
299
  def initialize(request, version, params, body, context)
300
+ super()
292
301
  @request = request
293
302
  @version = version
294
303
  @params = params
@@ -297,35 +306,24 @@ module HaveAPI
297
306
  @context.action = self.class
298
307
  @context.action_instance = self
299
308
  @metadata = {}
300
- @reply_meta = {object: {}, global: {}}
309
+ @reply_meta = { object: {}, global: {} }
301
310
  @flags = {}
302
311
 
303
312
  class_auth = self.class.authorization
304
313
 
305
- if class_auth
306
- @authorization = class_auth.clone
307
- else
308
- @authorization = Authorization.new {}
309
- end
310
-
311
- ret = call_class_hooks_as_for(
312
- Action,
313
- :pre_authorize,
314
- args: [@context],
315
- initial: {blocks: []},
316
- )
314
+ @authorization = if class_auth
315
+ class_auth.clone
316
+ else
317
+ Authorization.new {}
318
+ end
317
319
 
318
- ret[:blocks].reverse_each do |block|
319
- @authorization.prepend_block(block)
320
- end
320
+ self.class.add_pre_authorize_blocks(@authorization, @context)
321
321
  end
322
322
 
323
323
  def validate!
324
- begin
325
- @params = validate
326
- rescue ValidationError => e
327
- error(e.message, e.to_hash)
328
- end
324
+ @params = validate
325
+ rescue ValidationError => e
326
+ error(e.message, e.to_hash)
329
327
  end
330
328
 
331
329
  def authorized?(user)
@@ -333,20 +331,12 @@ module HaveAPI
333
331
  @authorization.authorized?(user, extract_path_params)
334
332
  end
335
333
 
336
- def current_user
337
- @current_user
338
- end
339
-
340
334
  def params
341
335
  @safe_params
342
336
  end
343
337
 
344
338
  def input
345
- @safe_params[ self.class.input.namespace ] if self.class.input
346
- end
347
-
348
- def request
349
- @request
339
+ @safe_params[self.class.input.namespace] if self.class.input
350
340
  end
351
341
 
352
342
  def meta
@@ -364,13 +354,9 @@ module HaveAPI
364
354
  # --
365
355
  # FIXME: is this correct behaviour?
366
356
  # ++
367
- def prepare
357
+ def prepare; end
368
358
 
369
- end
370
-
371
- def pre_exec
372
-
373
- end
359
+ def pre_exec; end
374
360
 
375
361
  # This method must be reimplemented in every action.
376
362
  # It must not be invoked directly, only via safe_exec, which restricts output.
@@ -383,29 +369,27 @@ module HaveAPI
383
369
  # Return array +[status, data|error, errors]+
384
370
  def safe_exec
385
371
  exec_ret = catch(:return) do
386
- begin
387
- validate!
388
- prepare
389
- pre_exec
390
- exec
391
- rescue Exception => e
392
- tmp = call_class_hooks_as_for(Action, :exec_exception, args: [@context, e])
393
-
394
- if tmp.empty?
395
- p e.message
396
- puts e.backtrace
397
- error('Server error occurred')
398
- end
372
+ validate!
373
+ prepare
374
+ pre_exec
375
+ exec
376
+ rescue Exception => e # rubocop:disable Lint/RescueException
377
+ tmp = call_class_hooks_as_for(Action, :exec_exception, args: [@context, e])
399
378
 
400
- unless tmp[:status]
401
- error(tmp[:message], {}, http_status: tmp[:http_status] || 500)
402
- end
379
+ if tmp.empty?
380
+ p e.message
381
+ puts e.backtrace
382
+ error('Server error occurred')
383
+ end
384
+
385
+ unless tmp[:status]
386
+ error(tmp[:message], {}, http_status: tmp[:http_status] || 500)
403
387
  end
404
388
  end
405
389
 
406
390
  begin
407
391
  output_ret = safe_output(exec_ret)
408
- rescue Exception => e
392
+ rescue Exception => e # rubocop:disable Lint/RescueException
409
393
  tmp = call_class_hooks_as_for(Action, :exec_exception, args: [@context, e])
410
394
 
411
395
  p e.message
@@ -415,7 +399,7 @@ module HaveAPI
415
399
  tmp[:status] || false,
416
400
  tmp[:message] || 'Server error occurred',
417
401
  {},
418
- tmp[:http_status] || 500,
402
+ tmp[:http_status] || 500
419
403
  ]
420
404
  end
421
405
 
@@ -436,55 +420,55 @@ module HaveAPI
436
420
  out_params = self.class.output.params
437
421
 
438
422
  case output.layout
439
- when :object
440
- out = adapter.output(@context, ret)
441
- safe_ret = @authorization.filter_output(
423
+ when :object
424
+ out = adapter.output(@context, ret)
425
+ safe_ret = @authorization.filter_output(
426
+ out_params,
427
+ out,
428
+ true
429
+ )
430
+ @reply_meta[:global].update(out.meta)
431
+
432
+ when :object_list
433
+ safe_ret = []
434
+
435
+ ret.each do |obj|
436
+ out = adapter.output(@context, obj)
437
+
438
+ safe_ret << @authorization.filter_output(
442
439
  out_params,
443
440
  out,
444
441
  true
445
442
  )
446
- @reply_meta[:global].update(out.meta)
447
-
448
- when :object_list
449
- safe_ret = []
450
-
451
- ret.each do |obj|
452
- out = adapter.output(@context, obj)
443
+ safe_ret.last.update({ Metadata.namespace => out.meta }) unless meta[:no]
444
+ end
453
445
 
454
- safe_ret << @authorization.filter_output(
455
- out_params,
456
- out,
457
- true
458
- )
459
- safe_ret.last.update({Metadata.namespace => out.meta}) unless meta[:no]
460
- end
446
+ when :hash
447
+ safe_ret = @authorization.filter_output(
448
+ out_params,
449
+ adapter.output(@context, ret),
450
+ true
451
+ )
461
452
 
462
- when :hash
463
- safe_ret = @authorization.filter_output(
453
+ when :hash_list
454
+ safe_ret = ret
455
+ safe_ret.map! do |hash|
456
+ @authorization.filter_output(
464
457
  out_params,
465
- adapter.output(@context, ret),
458
+ adapter.output(@context, hash),
466
459
  true
467
460
  )
461
+ end
468
462
 
469
- when :hash_list
470
- safe_ret = ret
471
- safe_ret.map! do |hash|
472
- @authorization.filter_output(
473
- out_params,
474
- adapter.output(@context, hash),
475
- true
476
- )
477
- end
478
-
479
- else
480
- safe_ret = ret
463
+ else
464
+ safe_ret = ret
481
465
  end
482
466
 
483
467
  if self.class.blocking
484
468
  @reply_meta[:global][:action_state_id] = state_id
485
469
  end
486
470
 
487
- ns = {output.namespace => safe_ret}
471
+ ns = { output.namespace => safe_ret }
488
472
  ns[Metadata.namespace] = @reply_meta[:global] unless meta[:no]
489
473
 
490
474
  [true, ns]
@@ -507,6 +491,7 @@ module HaveAPI
507
491
  end
508
492
 
509
493
  protected
494
+
510
495
  def with_restricted(**kwargs)
511
496
  if kwargs.empty?
512
497
  @authorization.restrictions
@@ -517,7 +502,7 @@ module HaveAPI
517
502
 
518
503
  # Convert parameter names to corresponding DB names.
519
504
  # By default, input parameters are used for the translation.
520
- def to_db_names(hash, src=:input)
505
+ def to_db_names(hash, src = :input)
521
506
  return {} unless hash
522
507
 
523
508
  params = self.class.method(src).call.params
@@ -528,11 +513,11 @@ module HaveAPI
528
513
  hit = false
529
514
 
530
515
  params.each do |p|
531
- if k == p.name
532
- ret[p.db_name] = v
533
- hit = true
534
- break
535
- end
516
+ next unless k == p.name
517
+
518
+ ret[p.db_name] = v
519
+ hit = true
520
+ break
536
521
  end
537
522
 
538
523
  ret[k] = v unless hit
@@ -543,7 +528,7 @@ module HaveAPI
543
528
 
544
529
  # Convert DB names to corresponding parameter names.
545
530
  # By default, output parameters are used for the translation.
546
- def to_param_names(hash, src=:output)
531
+ def to_param_names(hash, src = :output)
547
532
  return {} unless hash
548
533
 
549
534
  params = self.class.method(src).call.params
@@ -554,11 +539,11 @@ module HaveAPI
554
539
  hit = false
555
540
 
556
541
  params.each do |p|
557
- if k == p.db_name
558
- ret[p.name] = v
559
- hit = true
560
- break
561
- end
542
+ next unless k == p.db_name
543
+
544
+ ret[p.name] = v
545
+ hit = true
546
+ break
562
547
  end
563
548
 
564
549
  ret[k] = v unless hit
@@ -587,6 +572,7 @@ module HaveAPI
587
572
  end
588
573
 
589
574
  private
575
+
590
576
  def validate
591
577
  # Validate standard input
592
578
  @safe_params = @params.dup
@@ -598,19 +584,19 @@ module HaveAPI
598
584
 
599
585
  # Then filter allowed params
600
586
  case input.layout
601
- when :object_list, :hash_list
602
- @safe_params[input.namespace].map! do |obj|
603
- @authorization.filter_input(
604
- self.class.input.params,
605
- self.class.model_adapter(self.class.input.layout).input(obj)
606
- )
607
- end
608
-
609
- else
610
- @safe_params[input.namespace] = @authorization.filter_input(
587
+ when :object_list, :hash_list
588
+ @safe_params[input.namespace].map! do |obj|
589
+ @authorization.filter_input(
611
590
  self.class.input.params,
612
- self.class.model_adapter(self.class.input.layout).input(@safe_params[input.namespace])
591
+ self.class.model_adapter(self.class.input.layout).input(obj)
613
592
  )
593
+ end
594
+
595
+ else
596
+ @safe_params[input.namespace] = @authorization.filter_input(
597
+ self.class.input.params,
598
+ self.class.model_adapter(self.class.input.layout).input(@safe_params[input.namespace])
599
+ )
614
600
  end
615
601
 
616
602
  # Now check required params, convert types and set defaults
@@ -621,9 +607,9 @@ module HaveAPI
621
607
  auth = Authorization.new { allow }
622
608
  @metadata = {}
623
609
 
624
- return if input && %i(object_list hash_list).include?(input.layout)
610
+ return if input && %i[object_list hash_list].include?(input.layout)
625
611
 
626
- [:object, :global].each do |v|
612
+ %i[object global].each do |v|
627
613
  meta = self.class.meta(v)
628
614
  next unless meta
629
615
 
@@ -65,14 +65,10 @@ module HaveAPI
65
65
  end
66
66
 
67
67
  # @return [Time]
68
- def created_at
69
-
70
- end
68
+ def created_at; end
71
69
 
72
70
  # @return [Time]
73
- def updated_at
74
-
75
- end
71
+ def updated_at; end
76
72
 
77
73
  # @return [Boolean] true if the action can be cancelled
78
74
  def can_cancel?