base_field.rb 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # Copyright (C) 2012-2024 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. # relations extra attributes
  17. attr_reader :foreign_key, :through_key
  18. def initialize(*args, **kwargs, &)
  19. kwargs[:extensions] ||= []
  20. kwargs[:extensions].push(DependentFieldExension)
  21. # Method 1: pass in the flag directly.
  22. @is_dependent_field = kwargs.delete(:is_dependent_field)
  23. # extract relations extra attributes
  24. @foreign_key = kwargs.delete(:foreign_key)
  25. @through_key = kwargs.delete(:through_key)
  26. # Method 2: set the flag automatically for connection types.
  27. if kwargs[:type].respond_to?(:ancestors) && kwargs[:type] < Gql::Types::BaseConnection
  28. @is_dependent_field = true
  29. end
  30. super
  31. end
  32. end
  33. end
  34. # Field handling extensions that must be also available to interfaces.
  35. module GraphQL::Schema::Member::HasFields
  36. # Declare fields in passed block as 'ScopedField's.
  37. def scoped_fields(&)
  38. fields_with_class(Gql::Fields::ScopedField, &)
  39. end
  40. # Declare fields in passed block as 'InternalField's.
  41. def internal_fields(&)
  42. fields_with_class(Gql::Fields::InternalField, &)
  43. end
  44. def fields_with_class(type)
  45. field_class_orig = field_class
  46. field_class type
  47. yield
  48. field_class field_class_orig
  49. end
  50. end