From 8207f7877fea6987cbd8ef26e6f01feca6608bd2 Mon Sep 17 00:00:00 2001 From: Luke Duncalfe Date: Mon, 4 Mar 2019 15:30:32 +1300 Subject: GraphQL Type authorization Enables authorizations to be defined on GraphQL Types. module Types class ProjectType < BaseObject authorize :read_project end end If a field has authorizations defined on it, and the return type of the field also has authorizations defined on it. then all of the combined permissions in the authorizations will be checked and must pass. Connection fields are checked by "digging" to find the type class of the "node" field in the expected location of edges->node. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/54417 --- .../authorize/authorize_field_service_spec.rb | 73 ++++++++++++++++++++++ .../graphql/authorize/instrumentation_spec.rb | 67 -------------------- 2 files changed, 73 insertions(+), 67 deletions(-) create mode 100644 spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb delete mode 100644 spec/lib/gitlab/graphql/authorize/instrumentation_spec.rb (limited to 'spec/lib') diff --git a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb new file mode 100644 index 00000000000..ce320a2bdb0 --- /dev/null +++ b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +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)] } + + 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) + end + + it 'returns a checker which checks for a single object' do + object = double(:object) + + abilities.each do |ability| + spy_ability_check_for(ability, object, passed: true) + end + + expect(checker.call(object)).to eq(object) + end + + it 'returns a checker which checks for all objects' do + objects = [double(:first), double(:last)] + + abilities.each do |ability| + objects.each do |object| + spy_ability_check_for(ability, object, passed: true) + end + end + + expect(checker.call(objects)).to eq(objects) + end + + context 'when some objects would not pass the check' do + it 'returns nil when it is single object' do + disallowed = double(:object) + + spy_ability_check_for(abilities.first, disallowed, passed: false) + + expect(checker.call(disallowed)).to be_nil + end + + it 'returns only objects which passed when there are more than one' do + allowed = double(:allowed) + disallowed = double(:disallowed) + + spy_ability_check_for(abilities.first, disallowed, passed: false) + + abilities.each do |ability| + spy_ability_check_for(ability, allowed, passed: true) + end + + expect(checker.call([disallowed, allowed])) + .to contain_exactly(allowed) + end + end + end + + private + + def spy_ability_check_for(ability, object, passed: true) + expect(Ability) + .to receive(:allowed?) + .with(current_user, ability, object) + .and_return(passed) + end +end diff --git a/spec/lib/gitlab/graphql/authorize/instrumentation_spec.rb b/spec/lib/gitlab/graphql/authorize/instrumentation_spec.rb deleted file mode 100644 index cf3a8bcc8b4..00000000000 --- a/spec/lib/gitlab/graphql/authorize/instrumentation_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Graphql::Authorize::Instrumentation do - describe '#build_checker' do - let(:current_user) { double(:current_user) } - let(:abilities) { [double(:first_ability), double(:last_ability)] } - - let(:checker) do - described_class.new.__send__(:build_checker, current_user, abilities) - end - - it 'returns a checker which checks for a single object' do - object = double(:object) - - abilities.each do |ability| - spy_ability_check_for(ability, object, passed: true) - end - - expect(checker.call(object)).to eq(object) - end - - it 'returns a checker which checks for all objects' do - objects = [double(:first), double(:last)] - - abilities.each do |ability| - objects.each do |object| - spy_ability_check_for(ability, object, passed: true) - end - end - - expect(checker.call(objects)).to eq(objects) - end - - context 'when some objects would not pass the check' do - it 'returns nil when it is single object' do - disallowed = double(:object) - - spy_ability_check_for(abilities.first, disallowed, passed: false) - - expect(checker.call(disallowed)).to be_nil - end - - it 'returns only objects which passed when there are more than one' do - allowed = double(:allowed) - disallowed = double(:disallowed) - - spy_ability_check_for(abilities.first, disallowed, passed: false) - - abilities.each do |ability| - spy_ability_check_for(ability, allowed, passed: true) - end - - expect(checker.call([disallowed, allowed])) - .to contain_exactly(allowed) - end - end - - def spy_ability_check_for(ability, object, passed: true) - expect(Ability) - .to receive(:allowed?) - .with(current_user, ability, object) - .and_return(passed) - end - end -end -- cgit v1.2.3