base_mutation.rb 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Mutations
  3. # class BaseMutation < GraphQL::Schema::RelayClassicMutation
  4. class BaseMutation < GraphQL::Schema::Mutation
  5. include Gql::Concerns::HandlesAuthorization
  6. include Gql::Concerns::HasNestedGraphqlName
  7. # FIXME: Remove when all mutations are using services which are taking care of this flag.
  8. include Gql::Mutations::Concerns::HandlesCoreWorkflow
  9. argument_class Gql::Types::BaseArgument
  10. field_class Gql::Fields::BaseField
  11. object_class Gql::Types::BaseObject
  12. # input_object_class Gql::Types::BaseInputObject
  13. description 'Base class for all mutations'
  14. field :errors, [Gql::Types::UserErrorType], description: 'Errors encountered during execution of the mutation.'
  15. # Override this for mutations that don't need CSRF verification.
  16. def self.requires_csrf_verification?
  17. true
  18. end
  19. def self.before_authorize(*args)
  20. ctx = args[-1] # This may be called with 2 or 3 params, context is last.
  21. # CSRF - since this is expensive it is only called by mutations.
  22. verify_csrf_token(ctx) if requires_csrf_verification?
  23. end
  24. # Require authentication by default for mutations.
  25. def self.authorize(_obj, ctx)
  26. ctx.current_user
  27. end
  28. def self.verify_csrf_token(ctx)
  29. return true if ctx[:is_graphql_introspection_generator]
  30. # Support :graphql type tests that don't use HTTP.
  31. return true if Rails.env.test? && !ctx[:controller]
  32. # Support developer workflows that need to turn off CSRF.
  33. return true if Rails.env.development? && ctx[:controller].request.headers['SkipAuthenticityTokenCheck'] == 'true'
  34. ctx[:controller].send(:verify_csrf_token) # verify_csrf_token is private :(
  35. end
  36. def self.register_in_schema(schema)
  37. schema.field graphql_field_name, mutation: self
  38. end
  39. # Generate a response with user errors
  40. #
  41. # error_response({ message: 'Helpful error message.', field: 'error_field' }, ...)
  42. #
  43. def error_response(*errors)
  44. { errors: errors }
  45. end
  46. end
  47. end