base_field.rb 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Fields
  3. class BaseField < GraphQL::Schema::Field
  4. include Gql::Concerns::HandlesAuthorization
  5. argument_class Gql::Types::BaseArgument
  6. # Make sure that on field resultion infrormation about 'is_dependent_field' is
  7. # set (with a scope) in the context so that nested object types can access it as well.
  8. class DependentFieldExension < GraphQL::Schema::FieldExtension
  9. def resolve(object:, arguments:, context:, **_rest)
  10. context.scoped_set!(:is_dependent_field, true) if field.is_dependent_field
  11. yield(object, arguments)
  12. end
  13. end
  14. # Identify if this field is a nested member of an already authorized object.
  15. attr_reader :is_dependent_field
  16. def initialize(*args, **kwargs, &)
  17. kwargs[:extensions] ||= []
  18. kwargs[:extensions].push(DependentFieldExension)
  19. # Method 1: pass in the flag directly.
  20. @is_dependent_field = kwargs.delete(:is_dependent_field)
  21. # Method 2: set the flag automatically for connection types.
  22. if kwargs[:type].respond_to?(:ancestors) && kwargs[:type] < Gql::Types::BaseConnection
  23. @is_dependent_field = true
  24. end
  25. super
  26. end
  27. end
  28. end
  29. # Field handling extensions that must be also available to interfaces.
  30. module GraphQL::Schema::Member::HasFields
  31. # Declare fields in passed block as 'ScopedField's.
  32. def scoped_fields(&)
  33. fields_with_class(Gql::Fields::ScopedField, &)
  34. end
  35. # Declare fields in passed block as 'InternalField's.
  36. def internal_fields(&)
  37. fields_with_class(Gql::Fields::InternalField, &)
  38. end
  39. def fields_with_class(type)
  40. field_class_orig = field_class
  41. field_class type
  42. yield
  43. field_class field_class_orig
  44. end
  45. end