graphql-guard 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +9 -27
- data/CHANGELOG.md +59 -1
- data/Gemfile +3 -2
- data/README.md +53 -69
- data/graphql-guard.gemspec +3 -3
- data/lib/graphql/guard.rb +56 -48
- data/lib/graphql/guard/testing.rb +6 -21
- data/lib/graphql/guard/version.rb +1 -1
- metadata +8 -11
- data/.ruby-version +0 -1
- data/graphql-1.7.gemfile +0 -8
- data/graphql-latest.gemfile +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d5d87291a11cec745bf06b4b4ca13362123da9408167d788128393b3283c389
|
4
|
+
data.tar.gz: ad81005c01967b319d6439b36878497917a7bc48d573f4fe9cb3ba1c26e32d05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '095a399709be67e31b09fc1bac0031a28323b173b8b2f4242aebf230fce6044a8bd321c85b0a6a6aa0119f889f7476720d259c6c4dad3904a251cb62dd13073d'
|
7
|
+
data.tar.gz: e573f57903edfe4b6ec5157eea5264423f81cf217d527d0cea73307cc3f95eabda9297295b570e2b6f4576e771340cc973269c2b3636d3f9548d053603ae887d
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,29 +1,11 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
|
-
before_install: gem install bundler -v 1.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
- gemfile: graphql-1.7.gemfile
|
13
|
-
env: GRAPHQL_RUBY_VERSION=1_7 CI=true
|
14
|
-
rvm: 2.4.5
|
15
|
-
- gemfile: graphql-latest.gemfile
|
16
|
-
env: GRAPHQL_RUBY_VERSION=LATEST CI=true
|
17
|
-
rvm: 2.4.5
|
18
|
-
- gemfile: graphql-1.7.gemfile
|
19
|
-
env: GRAPHQL_RUBY_VERSION=1_7 CI=true
|
20
|
-
rvm: 2.5.7
|
21
|
-
- gemfile: graphql-latest.gemfile
|
22
|
-
env: GRAPHQL_RUBY_VERSION=LATEST CI=true
|
23
|
-
rvm: 2.5.7
|
24
|
-
- gemfile: graphql-1.7.gemfile
|
25
|
-
env: GRAPHQL_RUBY_VERSION=1_7 CI=true
|
26
|
-
rvm: 2.6.5
|
27
|
-
- gemfile: graphql-latest.gemfile
|
28
|
-
env: GRAPHQL_RUBY_VERSION=LATEST CI=true
|
29
|
-
rvm: 2.6.5
|
3
|
+
before_install: gem install bundler -v 2.1.4
|
4
|
+
rvm:
|
5
|
+
- 2.3.8
|
6
|
+
- 2.4.9
|
7
|
+
- 2.5.7
|
8
|
+
- 2.6.5
|
9
|
+
- 2.7.0
|
10
|
+
env:
|
11
|
+
- CI=true
|
data/CHANGELOG.md
CHANGED
@@ -8,10 +8,68 @@ one of the following labels: `Added`, `Changed`, `Deprecated`,
|
|
8
8
|
to manage the versions of this gem so
|
9
9
|
that you can set version constraints properly.
|
10
10
|
|
11
|
-
#### [Unreleased](https://github.com/exAspArk/graphql-guard/compare/
|
11
|
+
#### [Unreleased](https://github.com/exAspArk/graphql-guard/compare/v2.0.0...HEAD)
|
12
12
|
|
13
13
|
* WIP
|
14
14
|
|
15
|
+
#### [v2.0.0](https://github.com/exAspArk/graphql-guard/compare/v1.3.1...v2.0.0) – 2020-04-20
|
16
|
+
|
17
|
+
* `Added`: support for `graphql` gem version `>= 1.10` with `Interpreter`. [#39](https://github.com/exAspArk/graphql-guard/pull/39)
|
18
|
+
* `Removed`: support for previous `graphql` gem versions. [#39](https://github.com/exAspArk/graphql-guard/pull/39)
|
19
|
+
|
20
|
+
**Breaking changes**:
|
21
|
+
|
22
|
+
* Requires using `graphql` gem version `>= 1.10.0` with [Interpreter](https://graphql-ruby.org/queries/interpreter.html).
|
23
|
+
|
24
|
+
Before:
|
25
|
+
|
26
|
+
```rb
|
27
|
+
class Schema < GraphQL::Schema
|
28
|
+
query QueryType
|
29
|
+
mutation MutationType
|
30
|
+
|
31
|
+
use GraphQL::Guard.new
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
After:
|
36
|
+
|
37
|
+
```rb
|
38
|
+
class Schema < GraphQL::Schema
|
39
|
+
use GraphQL::Execution::Interpreter
|
40
|
+
use GraphQL::Analysis::AST
|
41
|
+
|
42
|
+
query QueryType
|
43
|
+
mutation MutationType
|
44
|
+
|
45
|
+
use GraphQL::Guard.new
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
|
50
|
+
* Use the actual type in the Policy object without `type.metadata[:type_class]`.
|
51
|
+
|
52
|
+
Before (with `graphql` gem version `>= 1.8` and class-based type definitions):
|
53
|
+
|
54
|
+
```rb
|
55
|
+
class GraphqlPolicy
|
56
|
+
def self.guard(type, field)
|
57
|
+
RULES.dig(type.metadata[:type_class], field)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
After:
|
63
|
+
|
64
|
+
```rb
|
65
|
+
class GraphqlPolicy
|
66
|
+
def self.guard(type, field)
|
67
|
+
RULES.dig(type, field)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
|
15
73
|
#### [v1.3.1](https://github.com/exAspArk/graphql-guard/compare/v1.3.0...v1.3.1) – 2020-01-22
|
16
74
|
|
17
75
|
* `Fixed`: compatibility with `graphql` gem version 1.10. [#36](https://github.com/exAspArk/graphql-guard/pull/36)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -26,40 +26,37 @@ This gem provides a field-level authorization for [graphql-ruby](https://github.
|
|
26
26
|
* [License](#license)
|
27
27
|
* [Code of Conduct](#code-of-conduct)
|
28
28
|
|
29
|
-
<a href="https://www.hyrestaff.com/" target="_blank" rel="noopener noreferrer">
|
30
|
-
<img src="images/hyre.png" height="39" width="137" alt="Sponsored by Hyre" style="max-width:100%;">
|
31
|
-
</a>
|
32
|
-
|
33
29
|
## Usage
|
34
30
|
|
35
31
|
Define a GraphQL schema:
|
36
32
|
|
37
33
|
```ruby
|
38
34
|
# Define a type
|
39
|
-
PostType
|
40
|
-
|
41
|
-
|
42
|
-
field :id, !types.ID
|
43
|
-
field :title, types.String
|
35
|
+
class PostType < GraphQL::Schema::Object
|
36
|
+
field :id, ID, null: false
|
37
|
+
field :title, String, null: true
|
44
38
|
end
|
45
39
|
|
46
40
|
# Define a query
|
47
|
-
QueryType
|
48
|
-
|
41
|
+
class QueryType < GraphQL::Schema::Object
|
42
|
+
field :posts, [PostType], null: false do
|
43
|
+
argument :user_id, ID, required: true
|
44
|
+
end
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
resolve ->(obj, args, ctx) { Post.where(user_id: args[:user_id]) }
|
46
|
+
def posts(user_id:)
|
47
|
+
Post.where(user_id: user_id)
|
53
48
|
end
|
54
49
|
end
|
55
50
|
|
56
51
|
# Define a schema
|
57
|
-
Schema
|
52
|
+
class Schema < GraphQL::Schema
|
53
|
+
use GraphQL::Execution::Interpreter
|
54
|
+
use GraphQL::Analysis::AST
|
58
55
|
query QueryType
|
59
56
|
end
|
60
57
|
|
61
58
|
# Execute query
|
62
|
-
Schema.execute(query, variables: {
|
59
|
+
Schema.execute(query, variables: { userId: 1 }, context: { current_user: current_user })
|
63
60
|
```
|
64
61
|
|
65
62
|
### Inline policies
|
@@ -67,7 +64,9 @@ Schema.execute(query, variables: { user_id: 1 }, context: { current_user: curren
|
|
67
64
|
Add `GraphQL::Guard` to your schema:
|
68
65
|
|
69
66
|
<pre>
|
70
|
-
Schema
|
67
|
+
class Schema < GraphQL::Schema
|
68
|
+
use GraphQL::Execution::Interpreter
|
69
|
+
use GraphQL::Analysis::AST
|
71
70
|
query QueryType
|
72
71
|
<b>use GraphQL::Guard.new</b>
|
73
72
|
end
|
@@ -76,22 +75,19 @@ end
|
|
76
75
|
Now you can define `guard` for a field, which will check permissions before resolving the field:
|
77
76
|
|
78
77
|
<pre>
|
79
|
-
QueryType
|
80
|
-
|
81
|
-
|
82
|
-
<b>field :posts</b>, !types[!PostType] do
|
83
|
-
argument :user_id, !types.ID
|
78
|
+
class QueryType < GraphQL::Schema::Object
|
79
|
+
<b>field :posts</b>, [PostType], null: false do
|
80
|
+
argument :user_id, ID, required: true
|
84
81
|
<b>guard ->(obj, args, ctx) {</b> args[:user_id] == ctx[:current_user].id <b>}</b>
|
85
|
-
...
|
86
82
|
end
|
83
|
+
...
|
87
84
|
end
|
88
85
|
</pre>
|
89
86
|
|
90
87
|
You can also define `guard`, which will be executed for every `*` field in the type:
|
91
88
|
|
92
89
|
<pre>
|
93
|
-
PostType
|
94
|
-
name "Post"
|
90
|
+
class PostType < GraphQL::Schema::Object
|
95
91
|
<b>guard ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
96
92
|
...
|
97
93
|
end
|
@@ -120,27 +116,12 @@ class <b>GraphqlPolicy</b>
|
|
120
116
|
end
|
121
117
|
</pre>
|
122
118
|
|
123
|
-
With `graphql-ruby` gem version >= 1.8 and class-based type definitions, use `camelCased` field names in the policy object.
|
124
|
-
You'd also need to use `type.metadata` (related to [rmosolgo/graphql-ruby#1429](https://github.com/rmosolgo/graphql-ruby/issues/1429)) to get the type class:
|
125
|
-
|
126
|
-
<pre>
|
127
|
-
class GraphqlPolicy
|
128
|
-
RULES = {
|
129
|
-
MutationType => {
|
130
|
-
<b>createPost</b>: ->(obj, args, cts) { ctx[:current_user].admin? }
|
131
|
-
}
|
132
|
-
}
|
133
|
-
|
134
|
-
def self.guard(type, field)
|
135
|
-
RULES.dig(<b>type.metadata[:type_class]</b>, field)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
</pre>
|
139
|
-
|
140
119
|
Pass this object to `GraphQL::Guard`:
|
141
120
|
|
142
121
|
<pre>
|
143
|
-
Schema
|
122
|
+
class Schema < GraphQL::Schema
|
123
|
+
use GraphQL::Execution::Interpreter
|
124
|
+
use GraphQL::Analysis::AST
|
144
125
|
query QueryType
|
145
126
|
use GraphQL::Guard.new(<b>policy_object: GraphqlPolicy</b>)
|
146
127
|
end
|
@@ -167,8 +148,8 @@ end
|
|
167
148
|
class <b>GraphqlPolicy</b>
|
168
149
|
RULES = {
|
169
150
|
PostType => {
|
170
|
-
<b>'*': ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>,
|
171
|
-
<b>title: ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
151
|
+
<b>'*': ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>, # <=== <b>4</b>
|
152
|
+
<b>title: ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>2</b>
|
172
153
|
}
|
173
154
|
}
|
174
155
|
|
@@ -177,13 +158,14 @@ class <b>GraphqlPolicy</b>
|
|
177
158
|
end
|
178
159
|
end
|
179
160
|
|
180
|
-
PostType
|
181
|
-
|
182
|
-
<b>guard ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
183
|
-
<b>field :title</b>, !types.String, <b>guard: ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>1</b>
|
161
|
+
class PostType < GraphQL::Schema::Object
|
162
|
+
<b>guard ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>3</b>
|
163
|
+
field :title, String, null: true, <b>guard: ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>1</b>
|
184
164
|
end
|
185
165
|
|
186
|
-
Schema
|
166
|
+
class Schema < GraphQL::Schema
|
167
|
+
use GraphQL::Execution::Interpreter
|
168
|
+
use GraphQL::Analysis::AST
|
187
169
|
query QueryType
|
188
170
|
use GraphQL::Guard.new(<b>policy_object: GraphqlPolicy</b>)
|
189
171
|
end
|
@@ -211,8 +193,7 @@ class <b>Ability</b>
|
|
211
193
|
end
|
212
194
|
|
213
195
|
# Use the ability in your guard
|
214
|
-
PostType
|
215
|
-
name "Post"
|
196
|
+
class PostType < GraphQL::Schema::Object
|
216
197
|
guard ->(post, args, ctx) { <b>ctx[:current_ability].can?(:read, post)</b> }
|
217
198
|
...
|
218
199
|
end
|
@@ -232,8 +213,7 @@ class <b>PostPolicy</b> < ApplicationPolicy
|
|
232
213
|
end
|
233
214
|
|
234
215
|
# Use the ability in your guard
|
235
|
-
PostType
|
236
|
-
name "Post"
|
216
|
+
class PostType < GraphQL::Schema::Object
|
237
217
|
guard ->(post, args, ctx) { <b>PostPolicy.new(ctx[:current_user], post).show?</b> }
|
238
218
|
...
|
239
219
|
end
|
@@ -248,14 +228,20 @@ By default `GraphQL::Guard` raises a `GraphQL::Guard::NotAuthorizedError` except
|
|
248
228
|
You can change this behavior, by passing custom `not_authorized` lambda. For example:
|
249
229
|
|
250
230
|
<pre>
|
251
|
-
SchemaWithErrors
|
231
|
+
class SchemaWithErrors < GraphQL::Schema
|
232
|
+
use GraphQL::Execution::Interpreter
|
233
|
+
use GraphQL::Analysis::AST
|
252
234
|
query QueryType
|
253
235
|
use GraphQL::Guard.new(
|
254
236
|
# By default it raises an error
|
255
|
-
# not_authorized: ->(type, field)
|
237
|
+
# not_authorized: ->(type, field) do
|
238
|
+
# raise GraphQL::Guard::NotAuthorizedError.new("#{type}.#{field}")
|
239
|
+
# end
|
256
240
|
|
257
241
|
# Returns an error in the response
|
258
|
-
<b>not_authorized: ->(type, field)
|
242
|
+
<b>not_authorized: ->(type, field) do
|
243
|
+
GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
|
244
|
+
end</b>
|
259
245
|
)
|
260
246
|
end
|
261
247
|
</pre>
|
@@ -300,7 +286,9 @@ class <b>GraphqlPolicy</b>
|
|
300
286
|
end
|
301
287
|
end
|
302
288
|
|
303
|
-
Schema
|
289
|
+
class Schema < GraphQL::Schema
|
290
|
+
use GraphQL::Execution::Interpreter
|
291
|
+
use GraphQL::Analysis::AST
|
304
292
|
query QueryType
|
305
293
|
mutation MutationType
|
306
294
|
|
@@ -319,11 +307,9 @@ end
|
|
319
307
|
It's possible to hide fields from being introspectable and accessible based on the context. For example:
|
320
308
|
|
321
309
|
<pre>
|
322
|
-
PostType
|
323
|
-
|
324
|
-
|
325
|
-
field :id, !types.ID
|
326
|
-
field :title, types.String do
|
310
|
+
class PostType < GraphQL::Schema::Object
|
311
|
+
field :id, ID, null: false
|
312
|
+
field :title, String, null: true do
|
327
313
|
# The field "title" is accessible only for beta testers
|
328
314
|
<b>mask ->(ctx) {</b> ctx[:current_user].beta_tester? <b>}</b>
|
329
315
|
end
|
@@ -352,9 +338,8 @@ It's possible to test fields with `guard` in isolation:
|
|
352
338
|
|
353
339
|
<pre>
|
354
340
|
# Your type
|
355
|
-
QueryType
|
356
|
-
|
357
|
-
<b>field :posts</b>, !types[!PostType], <b>guard ->(obj, args, ctx) {</b> ... <b>}</b>
|
341
|
+
class QueryType < GraphQL::Schema::Object
|
342
|
+
field :posts, [PostType], null: false, <b>guard ->(obj, args, ctx) {</b> ... <b>}</b>
|
358
343
|
end
|
359
344
|
|
360
345
|
# Your test
|
@@ -370,9 +355,8 @@ If you would like to test your fields with policy objects:
|
|
370
355
|
|
371
356
|
<pre>
|
372
357
|
# Your type
|
373
|
-
QueryType
|
374
|
-
|
375
|
-
<b>field :posts</b>, !types[!PostType]
|
358
|
+
class QueryType < GraphQL::Schema::Object
|
359
|
+
field :posts, [PostType], null: false
|
376
360
|
end
|
377
361
|
|
378
362
|
# Your policy object
|
data/graphql-guard.gemspec
CHANGED
@@ -23,9 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.required_ruby_version = '>= 2.1.0' # keyword args
|
25
25
|
|
26
|
-
spec.add_runtime_dependency "graphql", ">= 1.
|
26
|
+
spec.add_runtime_dependency "graphql", ">= 1.10.0", "< 2"
|
27
27
|
|
28
|
-
spec.add_development_dependency "bundler", "~> 1
|
29
|
-
spec.add_development_dependency "rake", "~>
|
28
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
29
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
30
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
31
|
end
|
data/lib/graphql/guard.rb
CHANGED
@@ -5,10 +5,18 @@ require "graphql/guard/version"
|
|
5
5
|
|
6
6
|
module GraphQL
|
7
7
|
class Guard
|
8
|
+
NotAuthorizedError = Class.new(StandardError)
|
9
|
+
|
8
10
|
ANY_FIELD_NAME = :'*'
|
9
|
-
DEFAULT_NOT_AUTHORIZED = ->(type, field) { raise NotAuthorizedError.new("Not authorized to access: #{type}.#{field}") }
|
10
11
|
|
11
|
-
|
12
|
+
DEFAULT_NOT_AUTHORIZED = ->(type, field) do
|
13
|
+
raise NotAuthorizedError.new("Not authorized to access: #{type}.#{field}")
|
14
|
+
end
|
15
|
+
|
16
|
+
MASKING_FILTER = ->(schema_member, ctx) do
|
17
|
+
mask = schema_member.graphql_definition.metadata[:mask]
|
18
|
+
mask ? mask.call(ctx) : true
|
19
|
+
end
|
12
20
|
|
13
21
|
attr_reader :policy_object, :not_authorized
|
14
22
|
|
@@ -18,75 +26,75 @@ module GraphQL
|
|
18
26
|
end
|
19
27
|
|
20
28
|
def use(schema_definition)
|
21
|
-
schema_definition.
|
29
|
+
if schema_definition.interpreter?
|
30
|
+
schema_definition.tracer(self)
|
31
|
+
else
|
32
|
+
raise "Please use the graphql gem version >= 1.10 with GraphQL::Execution::Interpreter"
|
33
|
+
end
|
34
|
+
|
22
35
|
add_schema_masking!(schema_definition)
|
23
36
|
end
|
24
37
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
new_resolve_proc = ->(object, arguments, context) do
|
31
|
-
authorized = guard_proc.call(object, arguments, context)
|
32
|
-
|
33
|
-
if authorized
|
34
|
-
old_resolve_proc.call(object, arguments, context)
|
35
|
-
else
|
36
|
-
not_authorized.call(type, field.name.to_sym)
|
37
|
-
end
|
38
|
+
def trace(event, trace_data)
|
39
|
+
if event == 'execute_field'
|
40
|
+
ensure_guarded(trace_data) { yield }
|
41
|
+
else
|
42
|
+
yield
|
38
43
|
end
|
39
|
-
|
40
|
-
field.redefine { resolve(new_resolve_proc) }
|
41
44
|
end
|
42
45
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
policy_object_guard(type,
|
46
|
+
def find_guard_proc(type, field)
|
47
|
+
return unless type.respond_to?(:type_class)
|
48
|
+
|
49
|
+
inline_guard(field) ||
|
50
|
+
policy_object_guard(type.type_class, field.name.to_sym) ||
|
51
|
+
inline_guard(type) ||
|
52
|
+
policy_object_guard(type.type_class, ANY_FIELD_NAME)
|
48
53
|
end
|
49
54
|
|
50
55
|
private
|
51
56
|
|
52
57
|
def add_schema_masking!(schema_definition)
|
53
|
-
|
54
|
-
def default_filter
|
55
|
-
GraphQL::Filter.new(except: default_mask).merge(only:
|
56
|
-
schema_member.metadata[:mask] ? schema_member.metadata[:mask].call(ctx) : true
|
57
|
-
})
|
58
|
+
schema_definition.class_eval do
|
59
|
+
def self.default_filter
|
60
|
+
GraphQL::Filter.new(except: default_mask).merge(only: MASKING_FILTER)
|
58
61
|
end
|
59
62
|
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def ensure_guarded(trace_data)
|
66
|
+
field = trace_data[:field]
|
67
|
+
guard_proc = find_guard_proc(field.owner, field)
|
68
|
+
return yield unless guard_proc
|
60
69
|
|
61
|
-
if
|
62
|
-
|
70
|
+
if guard_proc.call(trace_data[:object], args(trace_data), trace_data[:query].context)
|
71
|
+
yield
|
63
72
|
else
|
64
|
-
|
73
|
+
not_authorized.call(field.owner.graphql_definition, field.name.to_sym)
|
65
74
|
end
|
66
75
|
end
|
67
76
|
|
68
|
-
def
|
69
|
-
|
77
|
+
def args(trace_data)
|
78
|
+
if trace_data[:arguments].key?(:input) && !trace_data[:arguments][:input].is_a?(Hash)
|
79
|
+
return trace_data[:arguments][:input] # Relay mutation input
|
80
|
+
end
|
81
|
+
|
82
|
+
trace_data[:arguments]
|
70
83
|
end
|
71
84
|
|
72
|
-
def
|
73
|
-
|
85
|
+
def policy_object_guard(type, field_name)
|
86
|
+
@policy_object && @policy_object.guard(type, field_name)
|
74
87
|
end
|
75
88
|
|
76
|
-
def
|
77
|
-
|
89
|
+
def inline_guard(type_or_field)
|
90
|
+
type_or_field.graphql_definition.metadata[:guard]
|
78
91
|
end
|
79
92
|
end
|
80
93
|
end
|
81
94
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
if defined?(GraphQL::Schema::Object) && GraphQL::Schema::Object.respond_to?(:accepts_definition) # GraphQL-Ruby version >= 1.8
|
89
|
-
GraphQL::Schema::Object.accepts_definition(:guard)
|
90
|
-
GraphQL::Schema::Field.accepts_definition(:guard)
|
91
|
-
GraphQL::Schema::Field.accepts_definition(:mask)
|
92
|
-
end
|
95
|
+
GraphQL::ObjectType.accepts_definitions(guard: GraphQL::Define.assign_metadata_key(:guard))
|
96
|
+
GraphQL::Field.accepts_definitions(guard: GraphQL::Define.assign_metadata_key(:guard))
|
97
|
+
GraphQL::Field.accepts_definitions(mask: GraphQL::Define.assign_metadata_key(:mask))
|
98
|
+
GraphQL::Schema::Object.accepts_definition(:guard)
|
99
|
+
GraphQL::Schema::Field.accepts_definition(:guard)
|
100
|
+
GraphQL::Schema::Field.accepts_definition(:mask)
|
@@ -5,32 +5,18 @@ module GraphQL
|
|
5
5
|
NoGuardError = Class.new(StandardError)
|
6
6
|
|
7
7
|
def guard(*args)
|
8
|
-
raise NoGuardError.new("Get your field by calling: Type.field_with_guard('#{name}')") unless @
|
9
|
-
|
8
|
+
raise NoGuardError.new("Get your field by calling: Type.field_with_guard('#{name}')") unless @__guard_instance
|
9
|
+
|
10
|
+
guard_proc = @__guard_instance.find_guard_proc(@__guard_type, self)
|
10
11
|
raise NoGuardError.new("Guard lambda does not exist for #{@__guard_type}.#{name}") unless guard_proc
|
11
12
|
|
12
13
|
guard_proc.call(*args)
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
+
def __set_guard_instance(policy_object, guard_type)
|
16
17
|
@__policy_object = policy_object
|
17
|
-
@__guard_object = GraphQL::Guard.new(policy_object: policy_object)
|
18
|
-
end
|
19
|
-
|
20
|
-
def __guard_type=(guard_type)
|
21
18
|
@__guard_type = guard_type
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
class ObjectType
|
26
|
-
def field_with_guard(field_name, policy_object = nil)
|
27
|
-
field = get_field(field_name)
|
28
|
-
return unless field
|
29
|
-
|
30
|
-
field.clone.tap do |f|
|
31
|
-
f.__policy_object = policy_object
|
32
|
-
f.__guard_type = self
|
33
|
-
end
|
19
|
+
@__guard_instance = GraphQL::Guard.new(policy_object: policy_object)
|
34
20
|
end
|
35
21
|
end
|
36
22
|
|
@@ -41,8 +27,7 @@ module GraphQL
|
|
41
27
|
return unless field
|
42
28
|
|
43
29
|
field.to_graphql.clone.tap do |f|
|
44
|
-
f.
|
45
|
-
f.__guard_type = self.to_graphql
|
30
|
+
f.__set_guard_instance(policy_object, self.to_graphql)
|
46
31
|
end
|
47
32
|
end
|
48
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-guard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- exAspArk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.10.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.
|
29
|
+
version: 1.10.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2'
|
@@ -36,28 +36,28 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '1
|
39
|
+
version: '2.1'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '1
|
46
|
+
version: '2.1'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '13.0'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '13.0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rspec
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,7 +81,6 @@ extra_rdoc_files: []
|
|
81
81
|
files:
|
82
82
|
- ".gitignore"
|
83
83
|
- ".rspec"
|
84
|
-
- ".ruby-version"
|
85
84
|
- ".travis.yml"
|
86
85
|
- CHANGELOG.md
|
87
86
|
- CODE_OF_CONDUCT.md
|
@@ -91,9 +90,7 @@ files:
|
|
91
90
|
- Rakefile
|
92
91
|
- bin/console
|
93
92
|
- bin/setup
|
94
|
-
- graphql-1.7.gemfile
|
95
93
|
- graphql-guard.gemspec
|
96
|
-
- graphql-latest.gemfile
|
97
94
|
- lib/graphql/guard.rb
|
98
95
|
- lib/graphql/guard/testing.rb
|
99
96
|
- lib/graphql/guard/version.rb
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.6.5
|
data/graphql-1.7.gemfile
DELETED