haveapi 0.29.3 → 0.29.4

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: 0ea4a91d72110b964bf06310d13e19e2ac99629f842d8a7086b3ee8d1a060868
4
+ data.tar.gz: 26e7304458138efa50732b94f86c2de050e72539b07a7d6e6faa87ef4ecc5d5c
5
5
  SHA512:
6
- metadata.gz: 8b3cd3b9dabb84f88119dde487b150ea6694ab76450d24df1c8f7ff9309b5fcb91638d58f4794db0236de5d8a81c01693c3a5adfc9665200bdb24915599d131e
7
- data.tar.gz: c738c43d4cc3437124e9af50cd1ae70c84d3f5a91cb93f4c6d1b0966257e011f438f8ecf36639ba0da5044b0b06aa5c8b6072dce4793d4546df424ebdc50a1a9
6
+ metadata.gz: 38851b2f109fd4f502fd95237caa8c22a4bcb0c98171832ee88da356f61946234af9890a5c1565948db81a3186871b5c97eb68c2659ee9df5c28150f53e62b4a
7
+ data.tar.gz: 131e6a523d0147b10a1f0e7c399d2a879fbca04bf5b148eaf4639eff10abc0977c31323f7c74638dbb325440b9b1f32facf21986ec28e15eeb4bb1ab9d13b1d5
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.4'
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.4'.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
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.4
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.4
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.4
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: i18n
42
42
  requirement: !ruby/object:Gem::Requirement