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 +4 -4
- data/haveapi.gemspec +1 -1
- data/lib/haveapi/model_adapters/active_record.rb +7 -4
- data/lib/haveapi/parameters/resource.rb +3 -2
- data/lib/haveapi/version.rb +1 -1
- data/spec/model_adapters/active_record_spec.rb +48 -6
- data/spec/validators/inclusion_spec.rb +26 -24
- data/test_support/client_test_api.rb +47 -0
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 91faacf7a526f1d4a85e3ac834af09b31870084892a4fe423c89f788b785831f
|
|
4
|
+
data.tar.gz: 81ece8ab753c147e13401933bd8086e11c6a20f8e1991cb86ac80df6afbfccac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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)
|
data/lib/haveapi/version.rb
CHANGED
|
@@ -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
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
731
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
39
|
+
version: 0.29.5
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: i18n
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|