Skip to content

Commit 90d871e

Browse files
author
Brett Walker
committed
Upgrade GraphQL gem to 1.8.17
- Due to exAspArk/batch-loader#32, we changed BatchLoader.for into BatchLoader::GraphQL.for - since our results are wrapped in a BatchLoader::GraphQL, calling `sync` during authorization is required to get real object - `graphql` now has it's own authorization system. Our `authorized?` method conflicted and required renaming
1 parent 1843502 commit 90d871e

27 files changed

+65
-54
lines changed

Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ gem 'grape-entity', '~> 0.7.1'
8383
gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
8484

8585
# GraphQL API
86-
gem 'graphql', '= 1.8.4'
86+
gem 'graphql', '= 1.8.17'
8787
gem 'graphiql-rails', '~> 1.4.10'
8888
gem 'apollo_upload_server', '~> 2.0.0.beta3'
8989
gem 'graphql-docs', '~> 1.6.0', group: [:development, :test]

Gemfile.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ GEM
375375
graphiql-rails (1.4.10)
376376
railties
377377
sprockets-rails
378-
graphql (1.8.4)
378+
graphql (1.8.17)
379379
graphql-docs (1.6.0)
380380
commonmarker (~> 0.16)
381381
escape_utils (~> 1.2)
@@ -1109,7 +1109,7 @@ DEPENDENCIES
11091109
grape-path-helpers (~> 1.1)
11101110
grape_logging (~> 1.7)
11111111
graphiql-rails (~> 1.4.10)
1112-
graphql (= 1.8.4)
1112+
graphql (= 1.8.17)
11131113
graphql-docs (~> 1.6.0)
11141114
grpc (~> 1.19.0)
11151115
haml_lint (~> 0.31.0)

app/graphql/mutations/notes/create/base.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ class Base < Mutations::Notes::Base
1818
required: true,
1919
description: copy_field_description(Types::Notes::NoteType, :body)
2020

21-
private
22-
2321
def resolve(args)
2422
noteable = authorized_find!(id: args[:noteable_id])
2523

@@ -37,6 +35,8 @@ def resolve(args)
3735
}
3836
end
3937

38+
private
39+
4040
def create_note_params(noteable, args)
4141
{
4242
noteable: noteable,

app/graphql/resolvers/full_path_resolver.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module FullPathResolver
1111
end
1212

1313
def model_by_full_path(model, full_path)
14-
BatchLoader.for(full_path).batch(key: model) do |full_paths, loader, args|
14+
BatchLoader::GraphQL.for(full_path).batch(key: model) do |full_paths, loader, args|
1515
# `with_route` avoids an N+1 calculating full_path
1616
args[:key].where_full_path_in(full_paths).with_route.each do |model_instance|
1717
loader.call(model_instance.full_path, model_instance)

app/graphql/resolvers/issues_resolver.rb

+1-3
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,11 @@ class IssuesResolver < BaseResolver
4141

4242
type Types::IssueType, null: true
4343

44-
alias_method :project, :object
45-
4644
def resolve(**args)
4745
# The project could have been loaded in batch by `BatchLoader`.
4846
# At this point we need the `id` of the project to query for issues, so
4947
# make sure it's loaded and not `nil` before continuing.
50-
project.sync if project.respond_to?(:sync)
48+
project = object.respond_to?(:sync) ? object.sync : object
5149
return Issue.none if project.nil?
5250

5351
# Will need to be be made group & namespace aware with

app/graphql/resolvers/merge_requests_resolver.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ def resolve(**args)
2525

2626
# rubocop: disable CodeReuse/ActiveRecord
2727
def batch_load(iid)
28-
BatchLoader.for(iid.to_s).batch(key: project) do |iids, loader, args|
29-
args[:key].merge_requests.where(iid: iids).each do |mr|
28+
BatchLoader::GraphQL.for(iid.to_s).batch(key: project) do |iids, loader, args|
29+
arg_key = args[:key].respond_to?(:sync) ? args[:key].sync : args[:key]
30+
31+
arg_key.merge_requests.where(iid: iids).each do |mr|
3032
loader.call(mr.iid.to_s, mr)
3133
end
3234
end

app/graphql/resolvers/namespace_projects_resolver.rb

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ class NamespaceProjectsResolver < BaseResolver
99

1010
type Types::ProjectType, null: true
1111

12-
alias_method :namespace, :object
13-
1412
def resolve(include_subgroups:)
1513
# The namespace could have been loaded in batch by `BatchLoader`.
1614
# At this point we need the `id` or the `full_path` of the namespace
1715
# to query for projects, so make sure it's loaded and not `nil` before continuing.
18-
namespace.sync if namespace.respond_to?(:sync)
16+
namespace = object.respond_to?(:sync) ? object.sync : object
1917
return Project.none if namespace.nil?
2018

2119
if include_subgroups

lib/gitlab/graphql/authorize/authorize_field_service.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ def authorize_against(parent_typed_object, resolved_type)
5454
# The field is a built-in/scalar type, or a list of scalars
5555
# authorize using the parent's object
5656
parent_typed_object.object
57-
elsif resolved_type.respond_to?(:object)
58-
# The field is a type representing a single object, we'll authorize
59-
# against the object directly
60-
resolved_type.object
6157
elsif @field.connection? || resolved_type.is_a?(Array)
6258
# The field is a connection or a list of non-built-in types, we'll
6359
# authorize each element when rendering
6460
nil
61+
elsif resolved_type.respond_to?(:object)
62+
# The field is a type representing a single object, we'll authorize
63+
# against the object directly
64+
resolved_type.object
6565
else
6666
# Resolved type is a single object that might not be loaded yet by
6767
# the batchloader, we'll authorize that

lib/gitlab/graphql/authorize/authorize_resource.rb

+7-2
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,24 @@ def find_object(*args)
2929

3030
def authorized_find!(*args)
3131
object = find_object(*args)
32+
object = object.sync if object.respond_to?(:sync)
33+
3234
authorize!(object)
3335

3436
object
3537
end
3638

3739
def authorize!(object)
38-
unless authorized?(object)
40+
unless authorized_resource?(object)
3941
raise Gitlab::Graphql::Errors::ResourceNotAvailable,
4042
"The resource that you are attempting to access does not exist or you don't have permission to perform this action"
4143
end
4244
end
4345

44-
def authorized?(object)
46+
# this was named `#authorized?`, however it conflicts with the native
47+
# graphql gem version
48+
# TODO consider adopting the gem's built in authorization system
49+
def authorized_resource?(object)
4550
# Sanity check. We don't want to accidentally allow a developer to authorize
4651
# without first adding permissions to authorize against
4752
if self.class.required_permissions.empty?

lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def initialize(repository, blob_id)
99
end
1010

1111
def find
12-
BatchLoader.for(blob_id).batch(key: repository) do |blob_ids, loader, batch_args|
12+
BatchLoader::GraphQL.for(blob_id).batch(key: repository) do |blob_ids, loader, batch_args|
1313
Gitlab::Git::Blob.batch_lfs_pointers(batch_args[:key], blob_ids).each do |loaded_blob|
1414
loader.call(loaded_blob.id, loaded_blob.lfs_oid)
1515
end

lib/gitlab/graphql/loaders/batch_model_loader.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def initialize(model_class, model_id)
1212

1313
# rubocop: disable CodeReuse/ActiveRecord
1414
def find
15-
BatchLoader.for({ model: model_class, id: model_id.to_i }).batch do |loader_info, loader|
15+
BatchLoader::GraphQL.for({ model: model_class, id: model_id.to_i }).batch do |loader_info, loader|
1616
per_model = loader_info.group_by { |info| info[:model] }
1717
per_model.each do |model, info|
1818
ids = info.map { |i| i[:id] }

lib/gitlab/graphql/loaders/batch_project_statistics_loader.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def initialize(project_id)
1111
end
1212

1313
def find
14-
BatchLoader.for(project_id).batch do |project_ids, loader|
14+
BatchLoader::GraphQL.for(project_id).batch do |project_ids, loader|
1515
ProjectStatistics.for_project_ids(project_ids).each do |statistics|
1616
loader.call(statistics.project_id, statistics)
1717
end

lib/gitlab/graphql/loaders/batch_root_storage_statistics_loader.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def initialize(namespace_id)
1111
end
1212

1313
def find
14-
BatchLoader.for(namespace_id).batch do |namespace_ids, loader|
14+
BatchLoader::GraphQL.for(namespace_id).batch do |namespace_ids, loader|
1515
Namespace::RootStorageStatistics.for_namespace_ids(namespace_ids).each do |statistics|
1616
loader.call(statistics.namespace_id, statistics)
1717
end

lib/gitlab/graphql/loaders/pipeline_for_sha_loader.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def initialize(project, sha)
1111
end
1212

1313
def find_last
14-
BatchLoader.for(sha).batch(key: project) do |shas, loader, args|
14+
BatchLoader::GraphQL.for(sha).batch(key: project) do |shas, loader, args|
1515
pipelines = args[:key].ci_pipelines.latest_for_shas(shas)
1616

1717
pipelines.each do |pipeline|

spec/graphql/gitlab_schema_spec.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@
129129

130130
result = described_class.object_from_id(user.to_global_id.to_s)
131131

132-
expect(result.__sync).to eq(user)
132+
expect(result.sync).to eq(user)
133133
end
134134

135135
it 'batchloads the queries' do
@@ -138,7 +138,7 @@
138138

139139
expect do
140140
[described_class.object_from_id(user1.to_global_id),
141-
described_class.object_from_id(user2.to_global_id)].map(&:__sync)
141+
described_class.object_from_id(user2.to_global_id)].map(&:sync)
142142
end.not_to exceed_query_limit(1)
143143
end
144144
end
@@ -149,7 +149,7 @@
149149

150150
result = described_class.object_from_id(note.to_global_id)
151151

152-
expect(result.__sync).to eq(note)
152+
expect(result.sync).to eq(note)
153153
end
154154

155155
it 'batchloads the queries' do
@@ -158,7 +158,7 @@
158158

159159
expect do
160160
[described_class.object_from_id(note1.to_global_id),
161-
described_class.object_from_id(note2.to_global_id)].map(&:__sync)
161+
described_class.object_from_id(note2.to_global_id)].map(&:sync)
162162
end.not_to exceed_query_limit(1)
163163
end
164164
end

spec/graphql/mutations/concerns/mutations/resolves_project_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
project = create(:project)
1515

1616
expect(Resolvers::ProjectResolver).to receive(:new).with(object: nil, context: context).and_call_original
17-
expect(mutation.resolve_project(full_path: project.full_path)).to eq(project)
17+
expect(mutation.resolve_project(full_path: project.full_path).sync).to eq(project)
1818
end
1919
end

spec/graphql/resolvers/group_resolver_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
it 'batch-resolves groups by full path' do
1313
paths = [group1.full_path, group2.full_path]
1414

15-
result = batch(max_queries: 1) do
15+
result = batch_sync(max_queries: 1) do
1616
paths.map { |path| resolve_group(path) }
1717
end
1818

1919
expect(result).to contain_exactly(group1, group2)
2020
end
2121

2222
it 'resolves an unknown full_path to nil' do
23-
result = batch { resolve_group('unknown/project') }
23+
result = batch_sync { resolve_group('unknown/project') }
2424

2525
expect(result).to be_nil
2626
end

spec/graphql/resolvers/issues_resolver_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110

111111
context "when passing a non existent, batch loaded project" do
112112
let(:project) do
113-
BatchLoader.for("non-existent-path").batch do |_fake_paths, loader, _|
113+
BatchLoader::GraphQL.for("non-existent-path").batch do |_fake_paths, loader, _|
114114
loader.call("non-existent-path", nil)
115115
end
116116
end

spec/graphql/resolvers/merge_requests_resolver_spec.rb

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@
1717

1818
describe '#resolve' do
1919
it 'batch-resolves by target project full path and individual IID' do
20-
result = batch(max_queries: 2) do
20+
result = batch_sync(max_queries: 2) do
2121
resolve_mr(project, iid: iid_1) + resolve_mr(project, iid: iid_2)
2222
end
2323

2424
expect(result).to contain_exactly(merge_request_1, merge_request_2)
2525
end
2626

2727
it 'batch-resolves by target project full path and IIDS' do
28-
result = batch(max_queries: 2) do
28+
result = batch_sync(max_queries: 2) do
2929
resolve_mr(project, iids: [iid_1, iid_2])
3030
end
3131

3232
expect(result).to contain_exactly(merge_request_1, merge_request_2)
3333
end
3434

3535
it 'can batch-resolve merge requests from different projects' do
36-
result = batch(max_queries: 3) do
36+
result = batch_sync(max_queries: 3) do
3737
resolve_mr(project, iid: iid_1) +
3838
resolve_mr(project, iid: iid_2) +
3939
resolve_mr(other_project, iid: other_iid)
@@ -43,13 +43,13 @@
4343
end
4444

4545
it 'resolves an unknown iid to be empty' do
46-
result = batch { resolve_mr(project, iid: -1) }
46+
result = batch_sync { resolve_mr(project, iid: -1) }
4747

48-
expect(result).to be_empty
48+
expect(result.compact).to be_empty
4949
end
5050

5151
it 'resolves empty iids to be empty' do
52-
result = batch { resolve_mr(project, iids: []) }
52+
result = batch_sync { resolve_mr(project, iids: []) }
5353

5454
expect(result).to be_empty
5555
end

spec/graphql/resolvers/namespace_projects_resolver_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
context "when passing a non existent, batch loaded namespace" do
4848
let(:namespace) do
49-
BatchLoader.for("non-existent-path").batch do |_fake_paths, loader, _|
49+
BatchLoader::GraphQL.for("non-existent-path").batch do |_fake_paths, loader, _|
5050
loader.call("non-existent-path", nil)
5151
end
5252
end

spec/graphql/resolvers/project_resolver_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
it 'batch-resolves projects by full path' do
1313
paths = [project1.full_path, project2.full_path]
1414

15-
result = batch(max_queries: 1) do
15+
result = batch_sync(max_queries: 1) do
1616
paths.map { |path| resolve_project(path) }
1717
end
1818

1919
expect(result).to contain_exactly(project1, project2)
2020
end
2121

2222
it 'resolves an unknown full_path to nil' do
23-
result = batch { resolve_project('unknown/project') }
23+
result = batch_sync { resolve_project('unknown/project') }
2424

2525
expect(result).to be_nil
2626
end

spec/lib/gitlab/graphql/authorize/authorize_resource_spec.rb

+6-6
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ def current_user
4646
end
4747
end
4848

49-
describe '#authorized?' do
49+
describe '#authorized_resource?' do
5050
it 'is true' do
51-
expect(loading_resource.authorized?(project)).to be(true)
51+
expect(loading_resource.authorized_resource?(project)).to be(true)
5252
end
5353
end
5454
end
@@ -72,9 +72,9 @@ def current_user
7272
end
7373
end
7474

75-
describe '#authorized?' do
75+
describe '#authorized_resource?' do
7676
it 'is false' do
77-
expect(loading_resource.authorized?(project)).to be(false)
77+
expect(loading_resource.authorized_resource?(project)).to be(false)
7878
end
7979
end
8080
end
@@ -121,9 +121,9 @@ def self.name
121121
end
122122
end
123123

124-
describe '#authorized?' do
124+
describe '#authorized_resource?' do
125125
it 'raises a comprehensive error message' do
126-
expect { loading_resource.authorized?(project) }.to raise_error(error)
126+
expect { loading_resource.authorized_resource?(project) }.to raise_error(error)
127127
end
128128
end
129129
end

spec/lib/gitlab/graphql/loaders/batch_lfs_oid_loader_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
it 'batch-resolves LFS blob IDs' do
1313
expect(Gitlab::Git::Blob).to receive(:batch_lfs_pointers).once.and_call_original
1414

15-
result = batch do
15+
result = batch_sync do
1616
[blob, otherblob].map { |b| described_class.new(repository, b.id).find }
1717
end
1818

spec/lib/gitlab/graphql/loaders/batch_model_loader_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
issue_result = described_class.new(Issue, issue.id).find
1010
user_result = described_class.new(User, user.id).find
1111

12-
expect(issue_result.__sync).to eq(issue)
13-
expect(user_result.__sync).to eq(user)
12+
expect(issue_result.sync).to eq(issue)
13+
expect(user_result.sync).to eq(user)
1414
end
1515

1616
it 'only queries once per model' do
@@ -21,7 +21,7 @@
2121
expect do
2222
[described_class.new(User, other_user.id).find,
2323
described_class.new(User, user.id).find,
24-
described_class.new(Issue, issue.id).find].map(&:__sync)
24+
described_class.new(Issue, issue.id).find].map(&:sync)
2525
end.not_to exceed_query_limit(2)
2626
end
2727
end

0 commit comments

Comments
 (0)