• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

graphql-devise / graphql_devise / e89003cd-fd46-4bd3-aad7-2304cef122b5

13 May 2026 04:15PM UTC coverage: 96.324% (-1.1%) from 97.426%
e89003cd-fd46-4bd3-aad7-2304cef122b5

push

circleci

web-flow
Merge pull request #292 from graphql-devise/mcelicalderon-support-gql-2.6.0

Support graphql 2.6

786 of 816 relevant lines covered (96.32%)

964.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.93
/lib/graphql_devise/schema_plugin.rb
1
# frozen_string_literal: true
2

3
module GraphqlDevise
45✔
4
  class SchemaPlugin
45✔
5
    # NOTE: Based on GQL-Ruby docs  https://graphql-ruby.org/schema/introspection.html
6
    INTROSPECTION_FIELDS = ['__schema', '__type', '__typename']
45✔
7
    DEFAULT_NOT_AUTHENTICATED = ->(field) { raise AuthenticationError, "#{field} field requires authentication" }
495✔
8

9
    def initialize(query: nil, mutation: nil, authenticate_default: true, public_introspection: !Rails.env.production?, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
45✔
10
      @query                = query
180✔
11
      @mutation             = mutation
180✔
12
      @resource_loaders     = resource_loaders
180✔
13
      @authenticate_default = authenticate_default
180✔
14
      @public_introspection = public_introspection
180✔
15
      @unauthenticated_proc = unauthenticated_proc
180✔
16

17
      # Must happen on initialize so operations are loaded before the types are added to the schema on GQL < 1.10
18
      load_fields
180✔
19
    end
20

21
    def use(schema_definition)
45✔
22
      if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.3')
90✔
23
        schema_definition.trace_with(
48✔
24
          FieldAuthTracer,
25
          authenticate_default: @authenticate_default,
26
          public_introspection: public_introspection,
27
          unauthenticated_proc: @unauthenticated_proc
28
        )
29
      else
30
        schema_definition.tracer(self)
42✔
31
      end
32
    end
33

34
    def trace(event, trace_data)
45✔
35
      # Authenticate only root level queries
36
      return yield unless event == 'execute_field' && path(trace_data).count == 1
131,153✔
37

38
      field         = traced_field(trace_data)
777✔
39
      auth_required = authenticate_option(field, trace_data)
777✔
40
      context       = context_from_data(trace_data)
777✔
41

42
      if auth_required && !(public_introspection && introspection_field?(field))
777✔
43
        raise_on_missing_resource(context, field, auth_required)
483✔
44
      end
45

46
      yield
567✔
47
    end
48

49
    private
45✔
50

51
    attr_reader :public_introspection
45✔
52

53
    def raise_on_missing_resource(context, field, auth_required)
45✔
54
      @unauthenticated_proc.call(field.name) if context[:current_resource].blank?
483✔
55

56
      if auth_required.respond_to?(:call) && !auth_required.call(context[:current_resource])
315✔
57
        @unauthenticated_proc.call(field.name)
42✔
58
      end
59
    end
60

61
    def context_from_data(trace_data)
45✔
62
      query = if trace_data[:context]
777✔
63
        trace_data[:context].query
×
64
      else
65
        trace_data[:query]
777✔
66
      end
67

68
      query.context
777✔
69
    end
70

71
    def path(trace_data)
45✔
72
      if trace_data[:context]
100,392✔
73
        trace_data[:context].path
×
74
      else
75
        trace_data[:path]
100,392✔
76
      end
77
    end
78

79
    def traced_field(trace_data)
45✔
80
      if trace_data[:context]
777✔
81
        trace_data[:context].field
×
82
      else
83
        trace_data[:field]
777✔
84
      end
85
    end
86

87
    def authenticate_option(field, trace_data)
45✔
88
      auth_required = if trace_data[:context]
777✔
89
        field.metadata[:authenticate]
×
90
      else
91
        if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
777✔
92
          # authenticate will only be defined if "field_class GraphqlDevise::Types::BaseField" is added to the type
93
          # returning nil here will use the default value used when mounting the plugin
94
          field.try(:authenticate)
777✔
95
        elsif Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.13.1')
×
96
          field.graphql_definition(silence_deprecation_warning: true).metadata[:authenticate]
×
97
        else
98
          field.graphql_definition.metadata[:authenticate]
×
99
        end
100
      end
101

102
      auth_required.nil? ? @authenticate_default : auth_required
777✔
103
    end
104

105
    def load_fields
45✔
106
      @resource_loaders.each do |resource_loader|
180✔
107
        raise ::GraphqlDevise::Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(ResourceLoader)
180✔
108

109
        resource_loader.call(@query, @mutation)
135✔
110
      end
111
    end
112

113
    def introspection_field?(field)
45✔
114
      INTROSPECTION_FIELDS.include?(field.name)
504✔
115
    end
116
  end
117
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc