class GraphqlDevise::SchemaPlugin

Constants

DEFAULT_NOT_AUTHENTICATED
INTROSPECTION_FIELDS

NOTE: Based on GQL-Ruby docs graphql-ruby.org/schema/introspection.html

Attributes

public_introspection[R]

Public Class Methods

new(query: nil, mutation: nil, authenticate_default: true, public_introspection: !Rails.env.production?, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 9
def initialize(query: nil, mutation: nil, authenticate_default: true, public_introspection: !Rails.env.production?, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
  @query                = query
  @mutation             = mutation
  @resource_loaders     = resource_loaders
  @authenticate_default = authenticate_default
  @public_introspection = public_introspection
  @unauthenticated_proc = unauthenticated_proc

  # Must happen on initialize so operations are loaded before the types are added to the schema on GQL < 1.10
  load_fields
end

Public Instance Methods

trace(event, trace_data) { || ... } click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 25
    def trace(event, trace_data)
      # Authenticate only root level queries
      return yield unless event == 'execute_field' && path(trace_data).count == 1

      field         = traced_field(trace_data)
      auth_required = authenticate_option(field, trace_data)
      context       = context_from_data(trace_data)

      if context.key?(:resource_name)
        ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
          Providing `resource_name` as part of the GQL context, or doing so by using the `graphql_context(resource_name)`
          method on your controller is deprecated and will be removed in a future version of this gem.
          Please use `gql_devise_context` in you controller instead.

          EXAMPLE
          include GraphqlDevise::Concerns::SetUserByToken

          DummySchema.execute(params[:query], context: gql_devise_context(User))
          DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
        DEPRECATION
      end

      if auth_required && !(public_introspection && introspection_field?(field))
        context = set_current_resource(context)
        raise_on_missing_resource(context, field, auth_required)
      end

      yield
    end
use(schema_definition) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 21
def use(schema_definition)
  schema_definition.tracer(self)
end

Private Instance Methods

authenticate_option(field, trace_data) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 112
def authenticate_option(field, trace_data)
  auth_required = if trace_data[:context]
    field.metadata[:authenticate]
  else
    field.graphql_definition.metadata[:authenticate]
  end

  auth_required.nil? ? @authenticate_default : auth_required
end
context_from_data(trace_data) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 86
def context_from_data(trace_data)
  query = if trace_data[:context]
    trace_data[:context].query
  else
    trace_data[:query]
  end

  query.context
end
introspection_field?(field) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 130
def introspection_field?(field)
  INTROSPECTION_FIELDS.include?(field.name)
end
load_fields() click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 122
def load_fields
  @resource_loaders.each do |resource_loader|
    raise Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(GraphqlDevise::ResourceLoader)

    resource_loader.call(@query, @mutation)
  end
end
path(trace_data) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 96
def path(trace_data)
  if trace_data[:context]
    trace_data[:context].path
  else
    trace_data[:path]
  end
end
raise_on_missing_resource(context, field, auth_required) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 78
def raise_on_missing_resource(context, field, auth_required)
  @unauthenticated_proc.call(field.name) if context[:current_resource].blank?

  if auth_required.respond_to?(:call) && !auth_required.call(context[:current_resource])
    @unauthenticated_proc.call(field.name)
  end
end
set_current_resource(context) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 59
def set_current_resource(context)
  controller     = context[:controller]
  resource_names = Array(context[:resource_name])

  context[:current_resource] ||= resource_names.find do |resource_name|
    unless Devise.mappings.key?(resource_name)
      raise(
        GraphqlDevise::Error,
        "Invalid resource_name `#{resource_name}` provided to `graphql_context`. Possible values are: #{Devise.mappings.keys}."
      )
    end

    found = controller.set_resource_by_token(resource_name)
    break found if found
  end

  context
end
traced_field(trace_data) click to toggle source
# File lib/graphql_devise/schema_plugin.rb, line 104
def traced_field(trace_data)
  if trace_data[:context]
    trace_data[:context].field
  else
    trace_data[:field]
  end
end