summaryrefslogtreecommitdiff
path: root/app/graphql/gitlab_schema.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/gitlab_schema.rb')
-rw-r--r--app/graphql/gitlab_schema.rb84
1 files changed, 84 insertions, 0 deletions
diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb
index 06d26309b5b..2e5bdbd79c8 100644
--- a/app/graphql/gitlab_schema.rb
+++ b/app/graphql/gitlab_schema.rb
@@ -1,13 +1,97 @@
# frozen_string_literal: true
class GitlabSchema < GraphQL::Schema
+ # Currently an IntrospectionQuery has a complexity of 179.
+ # These values will evolve over time.
+ DEFAULT_MAX_COMPLEXITY = 200
+ AUTHENTICATED_COMPLEXITY = 250
+ ADMIN_COMPLEXITY = 300
+
+ DEFAULT_MAX_DEPTH = 10
+ AUTHENTICATED_MAX_DEPTH = 15
+
use BatchLoader::GraphQL
use Gitlab::Graphql::Authorize
use Gitlab::Graphql::Present
use Gitlab::Graphql::Connections
+ use Gitlab::Graphql::GenericTracing
+
+ query_analyzer Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer.new
query(Types::QueryType)
default_max_page_size 100
+
+ max_complexity DEFAULT_MAX_COMPLEXITY
+ max_depth DEFAULT_MAX_DEPTH
+
mutation(Types::MutationType)
+
+ class << self
+ def multiplex(queries, **kwargs)
+ kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context])
+
+ queries.each do |query|
+ query[:max_depth] = max_query_depth(kwargs[:context])
+ end
+
+ super(queries, **kwargs)
+ end
+
+ def execute(query_str = nil, **kwargs)
+ kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context])
+ kwargs[:max_depth] ||= max_query_depth(kwargs[:context])
+
+ super(query_str, **kwargs)
+ end
+
+ def id_from_object(object)
+ unless object.respond_to?(:to_global_id)
+ # This is an error in our schema and needs to be solved. So raise a
+ # more meaningfull error message
+ raise "#{object} does not implement `to_global_id`. "\
+ "Include `GlobalID::Identification` into `#{object.class}"
+ end
+
+ object.to_global_id
+ end
+
+ def object_from_id(global_id)
+ gid = GlobalID.parse(global_id)
+
+ unless gid
+ raise Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab id."
+ end
+
+ if gid.model_class < ApplicationRecord
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(gid.model_class, gid.model_id).find
+ else
+ gid.find
+ end
+ end
+
+ private
+
+ def max_query_complexity(ctx)
+ current_user = ctx&.fetch(:current_user, nil)
+
+ if current_user&.admin
+ ADMIN_COMPLEXITY
+ elsif current_user
+ AUTHENTICATED_COMPLEXITY
+ else
+ DEFAULT_MAX_COMPLEXITY
+ end
+ end
+
+ def max_query_depth(ctx)
+ current_user = ctx&.fetch(:current_user, nil)
+
+ if current_user
+ AUTHENTICATED_MAX_DEPTH
+ else
+ DEFAULT_MAX_DEPTH
+ end
+ end
+ end
end