haveapi 0.29.3 → 0.29.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 885ac3cc2e4b40ee6595f9beadad79e75f371d607dd0d49d02f67a01cece7d7f
4
- data.tar.gz: 8c8b186ae1299655f952bedf5cd857042df97b060a0fda7e43ef6b9bc0ec6393
3
+ metadata.gz: 91faacf7a526f1d4a85e3ac834af09b31870084892a4fe423c89f788b785831f
4
+ data.tar.gz: 81ece8ab753c147e13401933bd8086e11c6a20f8e1991cb86ac80df6afbfccac
5
5
  SHA512:
6
- metadata.gz: 8b3cd3b9dabb84f88119dde487b150ea6694ab76450d24df1c8f7ff9309b5fcb91638d58f4794db0236de5d8a81c01693c3a5adfc9665200bdb24915599d131e
7
- data.tar.gz: c738c43d4cc3437124e9af50cd1ae70c84d3f5a91cb93f4c6d1b0966257e011f438f8ecf36639ba0da5044b0b06aa5c8b6072dce4793d4546df424ebdc50a1a9
6
+ metadata.gz: 4d2c6c8cc96b841f645193d248023ea939f36a55af8e7dc2ed710ed770a15de89c34897cd9f3db969c4e1867b4e70ebcbcdf0c15f702d8acf917cee3cbc543a2
7
+ data.tar.gz: c7ff9c297474a183ba391e8567088494c0b98456f1cbb37b6a36599a955a4b6aca30ec2d5f631fc8d9fdc2c18319059eb5fda188fe75d2574d3875a52dda4544
data/haveapi.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.required_ruby_version = ">= #{File.read('../../.ruby-version').strip}"
16
16
 
17
17
  s.add_dependency 'activesupport', '>= 7.1'
18
- s.add_dependency 'haveapi-client', '~> 0.29.3'
18
+ s.add_dependency 'haveapi-client', '~> 0.29.5'
19
19
  s.add_dependency 'i18n', '>= 1.6', '< 2'
20
20
  s.add_dependency 'json'
21
21
  s.add_dependency 'mail'
@@ -362,7 +362,7 @@ module HaveAPI::ModelAdapters
362
362
  resolve_assoc = includes_include?(param.name)
363
363
  pass_includes = includes_pass_on_to(param.name) if resolve_assoc
364
364
 
365
- with_association_context(res_show, args) do |show|
365
+ with_association_context(param, res_show, args) do |show|
366
366
  # Tell the child action it is being checked as a nested association.
367
367
  show.flags[:inner_assoc] = true
368
368
 
@@ -393,15 +393,17 @@ module HaveAPI::ModelAdapters
393
393
  end
394
394
  end
395
395
 
396
- def with_association_context(res_show, args)
396
+ def with_association_context(param, res_show, args)
397
397
  push_cls = @context.action
398
398
  push_ins = @context.action_instance
399
399
  push_path = @context.path
400
400
  push_path_params = @context.path_params
401
+ push_resource_path = @context.resource_path
401
402
  path = @context.action_path_for(res_show)
402
403
  path_params = @context.path_params_for(res_show, args)
403
404
  @context.path = path
404
405
  @context.path_params = path_params
406
+ @context.resource_path = param.resource_path
405
407
 
406
408
  res_show.new(
407
409
  push_ins.request,
@@ -412,14 +414,15 @@ module HaveAPI::ModelAdapters
412
414
  )
413
415
  yield @context.action_instance
414
416
  ensure
415
- restore_context(push_cls, push_ins, push_path, push_path_params)
417
+ restore_context(push_cls, push_ins, push_path, push_path_params, push_resource_path)
416
418
  end
417
419
 
418
- def restore_context(action, action_instance, path, path_params)
420
+ def restore_context(action, action_instance, path, path_params, resource_path)
419
421
  @context.action = action
420
422
  @context.action_instance = action_instance
421
423
  @context.path = path
422
424
  @context.path_params = path_params
425
+ @context.resource_path = resource_path
423
426
  end
424
427
 
425
428
  def show_prepared?(show)
@@ -5,7 +5,7 @@ module HaveAPI::Parameters
5
5
  include MetadataI18n
6
6
 
7
7
  attr_reader :name, :resource, :label, :desc, :type, :value_id, :value_label,
8
- :choices, :value_params
8
+ :choices, :value_params, :resource_path
9
9
 
10
10
  def initialize(resource, name: nil, label: nil, desc: nil,
11
11
  choices: nil, value_id: :id, value_label: :label, required: nil,
@@ -177,7 +177,8 @@ module HaveAPI::Parameters
177
177
  path_params:,
178
178
  input: {},
179
179
  user: context.current_user,
180
- endpoint: context.endpoint
180
+ endpoint: context.endpoint,
181
+ resource_path: @resource_path
181
182
  )
182
183
  action = show_action.new(context.request, context.version, path_params, {}, child_context)
183
184
  return if action.authorized?(context.current_user)
@@ -1,4 +1,4 @@
1
1
  module HaveAPI
2
2
  PROTOCOL_VERSION = '2.0'.freeze
3
- VERSION = '0.29.3'.freeze
3
+ VERSION = '0.29.5'.freeze
4
4
  end
@@ -572,6 +572,18 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
572
572
  validators[klass] || validators[short_name.to_sym] || validators[short_name.to_s]
573
573
  end
574
574
 
575
+ def with_pre_authorize(listener)
576
+ hooks = HaveAPI::Hooks.hooks
577
+ action_hooks = hooks[HaveAPI::Action][:pre_authorize]
578
+ original = action_hooks[:listeners].dup
579
+
580
+ HaveAPI::Action.connect_hook(:pre_authorize, &listener)
581
+
582
+ yield
583
+ ensure
584
+ action_hooks[:listeners] = original
585
+ end
586
+
575
587
  it 'translates ActiveModel validators to HaveAPI validators' do
576
588
  app
577
589
  create_action = action_class(:User, :create)
@@ -644,6 +656,27 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
644
656
  expect(group_data).not_to have_key(:note)
645
657
  end
646
658
 
659
+ it 'uses the associated resource scope when authorizing output records' do
660
+ group = ARAdapterSpec::Group.create!(label: 'grp', note: 'GRP_NOTE')
661
+ user = create_user(name: 'user', group:)
662
+ group_show = action_class(:Group, :show)
663
+ scopes = []
664
+
665
+ with_pre_authorize(proc do |ret, context|
666
+ if context.action == group_show
667
+ scopes << context.action_scope
668
+ end
669
+ ret
670
+ end) do
671
+ get "/v1/users/#{user.id}", {}, input: ''
672
+ end
673
+
674
+ expect(api_response).to be_ok
675
+ expect(api_response[:user][:group][:id]).to eq(group.id)
676
+ expect(scopes.length).to eq(1)
677
+ expect(scopes.first).to end_with('.group#show')
678
+ end
679
+
647
680
  it 'resolves direct associations when included' do
648
681
  environment = ARAdapterSpec::Environment.create!(label: 'env', note: 'ENV_NOTE')
649
682
  group = ARAdapterSpec::Group.create!(label: 'grp', note: 'GRP_NOTE', environment: environment)
@@ -723,16 +756,25 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
723
756
 
724
757
  it 'uses full nested paths when authorizing resource input records' do
725
758
  _dataset, snapshot, link = create_snapshot_link
726
-
727
- put "/v1/snapshot_links/#{link.id}", {
728
- snapshot_link: {
729
- snapshot: snapshot.id
730
- }
731
- }.to_json, 'CONTENT_TYPE' => 'application/json'
759
+ scopes = []
760
+
761
+ with_pre_authorize(proc do |ret, context|
762
+ scopes << context.action_scope
763
+ ret[:blocks] << proc { deny if context.action_scope == '#show' }
764
+ ret
765
+ end) do
766
+ put "/v1/snapshot_links/#{link.id}", {
767
+ snapshot_link: {
768
+ snapshot: snapshot.id
769
+ }
770
+ }.to_json, 'CONTENT_TYPE' => 'application/json'
771
+ end
732
772
 
733
773
  expect(last_response.status).to eq(200)
734
774
  expect(api_response).to be_ok
735
775
  expect(api_response[:snapshot_link]).to eq(assigned: true)
776
+ expect(scopes).to include(a_string_ending_with('dataset.snapshot#show'))
777
+ expect(scopes).not_to include('#show')
736
778
  end
737
779
 
738
780
  it 'drops invalid nested include paths from requests' do
@@ -12,30 +12,32 @@ describe HaveAPI::Validators::Inclusion do
12
12
  end
13
13
  end
14
14
 
15
- [
16
- %w[one two three],
17
- {
18
- one: 'Fancy one',
19
- two: 'Fancy two',
20
- three: 'Fancy three'
21
- }
22
- ].each do |include|
23
- context "with include as a '#{include.class}'" do
24
- context 'with short form' do
25
- let(:validator) { described_class.new(:include, %w[one two three]) }
26
-
27
- it_behaves_like 'all'
28
- end
29
-
30
- context 'with full form' do
31
- let(:validator) do
32
- described_class.new(:include, {
33
- values: %w[one two three]
34
- })
35
- end
36
-
37
- it_behaves_like 'all'
38
- end
15
+ context 'with include as an Array' do
16
+ let(:values) { %w[one two three] }
17
+
18
+ context 'with short form' do
19
+ let(:validator) { described_class.new(:include, values) }
20
+
21
+ it_behaves_like 'all'
22
+ end
23
+
24
+ context 'with full form' do
25
+ let(:validator) { described_class.new(:include, { values: }) }
26
+
27
+ it_behaves_like 'all'
39
28
  end
40
29
  end
30
+
31
+ context 'with include as a Hash' do
32
+ let(:values) do
33
+ {
34
+ one: 'Fancy one',
35
+ two: 'Fancy two',
36
+ three: 'Fancy three'
37
+ }
38
+ end
39
+ let(:validator) { described_class.new(:include, { values: }) }
40
+
41
+ it_behaves_like 'all'
42
+ end
41
43
  end
@@ -519,6 +519,31 @@ module HaveAPI
519
519
  end
520
520
  end
521
521
 
522
+ define_action(:EchoChoice) do
523
+ extend DocFilter
524
+
525
+ route 'echo_choice'
526
+ http_method :post
527
+ input(:hash) do
528
+ string :format,
529
+ required: true,
530
+ choices: {
531
+ values: {
532
+ archive: 'Archive',
533
+ stream: 'Stream'
534
+ }
535
+ }
536
+ end
537
+ output(:hash) do
538
+ string :format
539
+ end
540
+ authorize { allow }
541
+
542
+ def exec
543
+ input
544
+ end
545
+ end
546
+
522
547
  define_action(:EchoOptional) do
523
548
  extend DocFilter
524
549
 
@@ -692,10 +717,32 @@ module HaveAPI
692
717
  HaveAPI.implicit_version = '1.0'
693
718
 
694
719
  reset!
720
+ ::I18n.backend.store_translations(
721
+ :cs,
722
+ client_test: {
723
+ resources: {
724
+ test: {
725
+ actions: {
726
+ echo_choice: {
727
+ input: {
728
+ format: {
729
+ choices: {
730
+ archive: { label: 'Archiv' },
731
+ stream: { label: 'Proud' }
732
+ }
733
+ }
734
+ }
735
+ }
736
+ }
737
+ }
738
+ }
739
+ }
740
+ )
695
741
 
696
742
  api = HaveAPI::Server.new(Resources)
697
743
  api.use_version(:all)
698
744
  api.default_version = '1.0'
745
+ api.parameter_i18n_scope = 'client_test'
699
746
  api.auth_chain << BasicProvider
700
747
  api.auth_chain << TokenProvider
701
748
  api.action_state = ActionStateBackend
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haveapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.29.3
4
+ version: 0.29.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Skokan
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.29.3
32
+ version: 0.29.5
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.29.3
39
+ version: 0.29.5
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: i18n
42
42
  requirement: !ruby/object:Gem::Requirement