11module GraphqlDevise
22 class SchemaPlugin
3- def initialize ( query :, mutation : nil , resource_loaders : [ ] )
4- @query = query
5- @mutation = mutation
6- @resource_loaders = resource_loaders
3+ DEFAULT_NOT_AUTHENTICATED = -> ( field ) { raise GraphqlDevise ::UserError , "#{ field } field requires authentication" }
4+
5+ def initialize ( query :, mutation : nil , authenticate_default : true , resource_loaders : [ ] , unauthenticated_proc : DEFAULT_NOT_AUTHENTICATED )
6+ @query = query
7+ @mutation = mutation
8+ @resource_loaders = resource_loaders
9+ @authenticate_default = authenticate_default
10+ @unauthenticated_proc = unauthenticated_proc
711
812 # Must happen on initialize so operations are loaded before the types are added to the schema on GQL < 1.10
913 load_fields
1014 end
1115
16+ def use ( schema_definition )
17+ schema_definition . tracer ( self )
18+ end
19+
20+ def trace ( event , trace_data )
21+ # Authenticate only root level queries
22+ return yield unless event == 'execute_field' && path ( trace_data ) . count == 1
23+
24+ field = traced_field ( trace_data )
25+ provided_value = authenticate_option ( field , trace_data )
26+
27+ if ( !provided_value . nil? && provided_value ) || @authenticate_default
28+ raise_on_missing_resource (
29+ context ( trace_data ) ,
30+ field
31+ )
32+ end
33+
34+ yield
35+ end
36+
1237 private
1338
39+ def raise_on_missing_resource ( context , field )
40+ @unauthenticated_proc . call ( field . name ) if context [ :current_resource ] . blank?
41+ end
42+
43+ def context ( trace_data )
44+ query = if trace_data [ :context ]
45+ trace_data [ :context ] . query
46+ else
47+ trace_data [ :query ]
48+ end
49+
50+ query . context
51+ end
52+
53+ def path ( trace_data )
54+ if trace_data [ :context ]
55+ trace_data [ :context ] . path
56+ else
57+ trace_data [ :path ]
58+ end
59+ end
60+
61+ def traced_field ( trace_data )
62+ if trace_data [ :context ]
63+ trace_data [ :context ] . field
64+ else
65+ trace_data [ :field ]
66+ end
67+ end
68+
69+ def authenticate_option ( field , trace_data )
70+ if trace_data [ :context ]
71+ field . metadata [ :authenticate ]
72+ else
73+ field . graphql_definition . metadata [ :authenticate ]
74+ end
75+ end
76+
1477 def load_fields
1578 @resource_loaders . each do |resource_loader |
1679 raise Error , 'Invalid resource loader instance' unless resource_loader . instance_of? ( GraphqlDevise ::ResourceLoader )
@@ -20,3 +83,6 @@ def load_fields
2083 end
2184 end
2285end
86+
87+ GraphQL ::Field . accepts_definitions ( authenticate : GraphQL ::Define . assign_metadata_key ( :authenticate ) )
88+ GraphQL ::Schema ::Field . accepts_definition ( :authenticate )
0 commit comments