diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2019-06-14 17:46:31 +0300 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2019-06-14 17:46:31 +0300 |
commit | 6b3de25996e32f9b78cf4dbbad6dfeba346758fd (patch) | |
tree | ce3f22d9f77be086eaa136ff559b0ec6f6db7262 /spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb | |
parent | ba6e134e2814e6d7616990c7f9aa3a521b4082b3 (diff) | |
parent | c449e35b33c55e2a0c8c3b7c08d0d68870e41ec4 (diff) |
Merge branch 'master' into 59532-danger-css59532-danger-css
* master: (1920 commits)
Upgrade gitlab-ui and migrate gl-pagination
New translations gitlab.pot (Danish) [skip ci]
Fix missing deployment rockets in monitor dashboard
Add basic support for AsciiDoc include directive
Improve the gitea importer test
Backport of EE changes from MR 13763
Clarify ED25519 SSH key support
Exclude preexisting lint issues for i18n
Add back sidekiq metrics exporter
Breakup first pass
Use scoped routes for labels and milestones
AutoDevops fix ensure_namespace() does not explicitly test namespace
Speed up commit loads by disabling BatchLoader replace_methods
Speed up merge request loads by disabling BatchLoader replace_methods
Remove unused selector
Disable unnecessary ESLint i18n offences
Unquarantine spec in user_edits_files_spec.rb
Refactor for cleaner caching in dashboards
Update height of -tabs-height
Change SLA to target SLO for bugs and defects
...
Diffstat (limited to 'spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb')
-rw-r--r-- | spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb | 142 |
1 files changed, 84 insertions, 58 deletions
diff --git a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb index 6114aca0616..aec9c4baf0a 100644 --- a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb +++ b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb @@ -5,92 +5,118 @@ require 'spec_helper' # Also see spec/graphql/features/authorization_spec.rb for # integration tests of AuthorizeFieldService describe Gitlab::Graphql::Authorize::AuthorizeFieldService do - describe '#build_checker' do - let(:current_user) { double(:current_user) } - let(:abilities) { [double(:first_ability), double(:last_ability)] } - - context 'when authorizing against the object' do - let(:checker) do - service = described_class.new(double(resolve_proc: proc {})) - allow(service).to receive(:authorizations).and_return(abilities) - service.__send__(:build_checker, current_user, nil) - end + def type(type_authorizations = []) + Class.new(Types::BaseObject) do + graphql_name "TestType" - it 'returns a checker which checks for a single object' do - object = double(:object) + authorize type_authorizations + end + end - abilities.each do |ability| - spy_ability_check_for(ability, object, passed: true) - end + def type_with_field(field_type, field_authorizations = [], resolved_value = "Resolved value") + Class.new(Types::BaseObject) do + graphql_name "TestTypeWithField" + field :test_field, field_type, null: true, authorize: field_authorizations, resolve: -> (_, _, _) { resolved_value} + end + end - expect(checker.call(object)).to eq(object) - end + let(:current_user) { double(:current_user) } + subject(:service) { described_class.new(field) } - it 'returns a checker which checks for all objects' do - objects = [double(:first), double(:last)] + describe "#authorized_resolve" do + let(:presented_object) { double("presented object") } + let(:presented_type) { double("parent type", object: presented_object) } + subject(:resolved) { service.authorized_resolve.call(presented_type, {}, { current_user: current_user }) } - abilities.each do |ability| - objects.each do |object| - spy_ability_check_for(ability, object, passed: true) + context "scalar types" do + shared_examples "checking permissions on the presented object" do + it "checks the abilities on the object being presented and returns the value" do + expected_permissions.each do |permission| + spy_ability_check_for(permission, presented_object, passed: true) end + + expect(resolved).to eq("Resolved value") end - expect(checker.call(objects)).to eq(objects) + it "returns nil if the value wasn't authorized" do + allow(Ability).to receive(:allowed?).and_return false + + expect(resolved).to be_nil + end end - context 'when some objects would not pass the check' do - it 'returns nil when it is single object' do - disallowed = double(:object) + context "when the field is a built-in scalar type" do + let(:field) { type_with_field(GraphQL::STRING_TYPE, :read_field).fields["testField"].to_graphql } + let(:expected_permissions) { [:read_field] } - spy_ability_check_for(abilities.first, disallowed, passed: false) + it_behaves_like "checking permissions on the presented object" + end - expect(checker.call(disallowed)).to be_nil - end + context "when the field is a list of scalar types" do + let(:field) { type_with_field([GraphQL::STRING_TYPE], :read_field).fields["testField"].to_graphql } + let(:expected_permissions) { [:read_field] } + + it_behaves_like "checking permissions on the presented object" + end - it 'returns only objects which passed when there are more than one' do - allowed = double(:allowed) - disallowed = double(:disallowed) + context "when the field is sub-classed scalar type" do + let(:field) { type_with_field(Types::TimeType, :read_field).fields["testField"].to_graphql } + let(:expected_permissions) { [:read_field] } - spy_ability_check_for(abilities.first, disallowed, passed: false) + it_behaves_like "checking permissions on the presented object" + end - abilities.each do |ability| - spy_ability_check_for(ability, allowed, passed: true) - end + context "when the field is a list of sub-classed scalar types" do + let(:field) { type_with_field([Types::TimeType], :read_field).fields["testField"].to_graphql } + let(:expected_permissions) { [:read_field] } - expect(checker.call([disallowed, allowed])).to contain_exactly(allowed) - end + it_behaves_like "checking permissions on the presented object" end end - context 'when authorizing against another object' do - let(:authorizing_obj) { double(:object) } + context "when the field is a specific type" do + let(:custom_type) { type(:read_type) } + let(:object_in_field) { double("presented in field") } + let(:field) { type_with_field(custom_type, :read_field, object_in_field).fields["testField"].to_graphql } - let(:checker) do - service = described_class.new(double(resolve_proc: proc {})) - allow(service).to receive(:authorizations).and_return(abilities) - service.__send__(:build_checker, current_user, authorizing_obj) - end + it "checks both field & type permissions" do + spy_ability_check_for(:read_field, object_in_field, passed: true) + spy_ability_check_for(:read_type, object_in_field, passed: true) - it 'returns a checker which checks for a single object' do - object = double(:object) + expect(resolved).to eq(object_in_field) + end - abilities.each do |ability| - spy_ability_check_for(ability, authorizing_obj, passed: true) - end + it "returns nil if viewing was not allowed" do + spy_ability_check_for(:read_field, object_in_field, passed: false) + spy_ability_check_for(:read_type, object_in_field, passed: true) - expect(checker.call(object)).to eq(object) + expect(resolved).to be_nil end - it 'returns a checker which checks for all objects' do - objects = [double(:first), double(:last)] + context "when the field is a list" do + let(:object_1) { double("presented in field 1") } + let(:object_2) { double("presented in field 2") } + let(:presented_types) { [double(object: object_1), double(object: object_2)] } + let(:field) { type_with_field([custom_type], :read_field, presented_types).fields["testField"].to_graphql } - abilities.each do |ability| - objects.each do |object| - spy_ability_check_for(ability, authorizing_obj, passed: true) - end + it "checks all permissions" do + allow(Ability).to receive(:allowed?) { true } + + spy_ability_check_for(:read_field, object_1, passed: true) + spy_ability_check_for(:read_type, object_1, passed: true) + spy_ability_check_for(:read_field, object_2, passed: true) + spy_ability_check_for(:read_type, object_2, passed: true) + + expect(resolved).to eq(presented_types) end - expect(checker.call(objects)).to eq(objects) + it "filters out objects that the user cannot see" do + allow(Ability).to receive(:allowed?) { true } + + spy_ability_check_for(:read_type, object_1, passed: false) + + expect(resolved.map(&:object)).to contain_exactly(object_2) + end end end end |