Class: Types::BaseField
- Inherits:
-
GraphQL::Schema::Field
- Object
- GraphQL::Schema::Field
- Types::BaseField
- Defined in:
- app/graphql/types/base_field.rb
Direct Known Subclasses
Constant Summary collapse
- DEFAULT_COMPLEXITY =
1
Constants included from Gitlab::Graphql::Authorize::AuthorizeResource
Gitlab::Graphql::Authorize::AuthorizeResource::ConfigurationError, Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
Instance Attribute Summary collapse
-
#doc_reference ⇒ Object
readonly
Returns the value of attribute doc_reference.
-
#skip_type_authorization ⇒ Object
Returns the value of attribute skip_type_authorization.
Instance Method Summary collapse
-
#authorized?(object, args, ctx) ⇒ Boolean
By default fields authorize against the current object, but that is not how our resolvers work - they use declarative permissions to authorize fields manually (so we make them opt in).
- #base_complexity ⇒ Object
- #calls_gitaly? ⇒ Boolean
-
#complexity_for(child_complexity:, query:, lookahead:) ⇒ Object
This gets called from the gem’s ‘calculate_complexity` method, allowing us to ensure our complexity calculation is used even for connections.
- #constant_complexity? ⇒ Boolean
-
#initialize(**kwargs, &block) ⇒ BaseField
constructor
A new instance of BaseField.
- #may_call_gitaly? ⇒ Boolean
- #requires_argument? ⇒ Boolean
Methods included from Gitlab::Graphql::Authorize::AuthorizeResource
#authorize!, #authorized_find!, #authorized_resource?, #find_object, #raise_resource_not_available_error!
Methods included from Gitlab::Graphql::Deprecations
Constructor Details
#initialize(**kwargs, &block) ⇒ BaseField
Returns a new instance of BaseField.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'app/graphql/types/base_field.rb', line 15 def initialize(**kwargs, &block) @requires_argument = kwargs.delete(:requires_argument) @calls_gitaly = kwargs.delete(:calls_gitaly) @doc_reference = kwargs.delete(:see) given_complexity = kwargs[:complexity] || kwargs[:resolver_class].try(:complexity) @constant_complexity = given_complexity.is_a?(Integer) && given_complexity > 0 kwargs[:complexity] = field_complexity(kwargs[:resolver_class], given_complexity) @authorize = Array.wrap(kwargs.delete(:authorize)) @skip_type_authorization = Array.wrap(kwargs.delete(:skip_type_authorization)) @scopes = Array.wrap(kwargs.delete(:scopes) || %i[api read_api]) after_connection_extensions = kwargs.delete(:late_extensions) || [] super(**kwargs, &block) # We want to avoid the overhead of this in prod extension ::Gitlab::Graphql::CallsGitaly::FieldExtension if Gitlab.dev_or_test_env? extension ::Gitlab::Graphql::Present::FieldExtension extension ::Gitlab::Graphql::Authorize::FieldExtension after_connection_extensions.each { extension _1 } if after_connection_extensions.any? end |
Instance Attribute Details
#doc_reference ⇒ Object (readonly)
Returns the value of attribute doc_reference.
12 13 14 |
# File 'app/graphql/types/base_field.rb', line 12 def doc_reference @doc_reference end |
#skip_type_authorization ⇒ Object
Returns the value of attribute skip_type_authorization.
13 14 15 |
# File 'app/graphql/types/base_field.rb', line 13 def @skip_type_authorization end |
Instance Method Details
#authorized?(object, args, ctx) ⇒ Boolean
By default fields authorize against the current object, but that is not how our resolvers work - they use declarative permissions to authorize fields manually (so we make them opt in). TODO: gitlab.com/gitlab-org/gitlab/-/issues/300922
(separate out authorize into permissions on the object, and on the
resolved values)
We do not support argument authorization in our schema. If/when we do, we should call ‘super` here, to apply argument authorization checks. See: gitlab.com/gitlab-org/gitlab/-/issues/324647
57 58 59 |
# File 'app/graphql/types/base_field.rb', line 57 def (object, args, ctx) (object, ctx) && (object, ctx) end |
#base_complexity ⇒ Object
85 86 87 88 89 |
# File 'app/graphql/types/base_field.rb', line 85 def base_complexity complexity = DEFAULT_COMPLEXITY complexity += 1 if calls_gitaly? complexity end |
#calls_gitaly? ⇒ Boolean
91 92 93 |
# File 'app/graphql/types/base_field.rb', line 91 def calls_gitaly? !!(@calls_gitaly.nil? ? @resolver_class.try(:calls_gitaly?) : @calls_gitaly) end |
#complexity_for(child_complexity:, query:, lookahead:) ⇒ Object
This gets called from the gem’s ‘calculate_complexity` method, allowing us to ensure our complexity calculation is used even for connections. This code is actually a copy of the default case in `calculate_complexity` in `lib/graphql/schema/field.rb` (github.com/rmosolgo/graphql-ruby/blob/master/lib/graphql/schema/field.rb)
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'app/graphql/types/base_field.rb', line 66 def complexity_for(child_complexity:, query:, lookahead:) defined_complexity = complexity case defined_complexity when Proc arguments = query.arguments_for(lookahead.ast_nodes.first, self) if arguments.respond_to?(:keyword_arguments) defined_complexity.call(query.context, arguments.keyword_arguments, child_complexity) else child_complexity end when Numeric defined_complexity + child_complexity else raise("Invalid complexity: #{defined_complexity.inspect} on #{path} (#{inspect})") end end |
#constant_complexity? ⇒ Boolean
95 96 97 |
# File 'app/graphql/types/base_field.rb', line 95 def constant_complexity? @constant_complexity end |
#may_call_gitaly? ⇒ Boolean
39 40 41 |
# File 'app/graphql/types/base_field.rb', line 39 def may_call_gitaly? @constant_complexity || calls_gitaly? end |
#requires_argument? ⇒ Boolean
43 44 45 46 |
# File 'app/graphql/types/base_field.rb', line 43 def requires_argument? value = @requires_argument.nil? ? @resolver_class.try(:requires_argument?) : @requires_argument !!value || arguments.values.any? { |argument| argument.type.non_null? } end |