graphql-guard 0.4.0 → 1.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/CHANGELOG.md +40 -1
- data/README.md +13 -15
- data/lib/graphql/guard/testing.rb +9 -8
- data/lib/graphql/guard/version.rb +1 -1
- data/lib/graphql/guard.rb +8 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fee7151ba4f1b935f9bb185bc1ecef61920d0bc
|
4
|
+
data.tar.gz: d5286b90482d2e5a99827f05a3587d9f596a0669
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36f519bf2ed0879655eced44f1a8062e13fcfc01d08565c7c92d33ee50cef08278e430054cc42ed9834a629dc16d3512b19cf14ef2c395a19f37929c615488c0
|
7
|
+
data.tar.gz: c9873f1af3b37a07398e853871f661bb45d232d79cc833aa6f0bc2aca1104e961b8e2ecf2bda3a38950de7ad91181918dbe62447cb2267ac88966b88df9c3c26
|
data/CHANGELOG.md
CHANGED
@@ -8,10 +8,49 @@ 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/v1.0.0...HEAD)
|
12
12
|
|
13
13
|
* WIP
|
14
14
|
|
15
|
+
#### [v1.0.0](https://github.com/exAspArk/graphql-guard/compare/v0.4.0...v1.0.0) – 2017-07-31
|
16
|
+
|
17
|
+
* `Changed`: guards for every `*` field also accepts arguments: `->(object, arguments, context) { ... }`:
|
18
|
+
|
19
|
+
* Before:
|
20
|
+
|
21
|
+
<pre>
|
22
|
+
GraphQL::ObjectType.define do
|
23
|
+
name "Post"
|
24
|
+
guard ->(obj, ctx) { ... }
|
25
|
+
...
|
26
|
+
end
|
27
|
+
</pre>
|
28
|
+
|
29
|
+
* After:
|
30
|
+
|
31
|
+
<pre>
|
32
|
+
GraphQL::ObjectType.define do
|
33
|
+
name "Post"
|
34
|
+
guard ->(obj, <b>args</b>, ctx) { ... }
|
35
|
+
...
|
36
|
+
end
|
37
|
+
</pre>
|
38
|
+
|
39
|
+
* `Changed`: `.field_with_guard` from `graphql/guard/testing` module accepts policy object as a second argument:
|
40
|
+
|
41
|
+
* Before:
|
42
|
+
|
43
|
+
<pre>
|
44
|
+
guard_object = GraphQL::Guard.new(policy_object: GraphqlPolicy)
|
45
|
+
posts_field = QueryType.field_with_guard('posts', <b>guard_object</b>)
|
46
|
+
</pre>
|
47
|
+
|
48
|
+
* After:
|
49
|
+
|
50
|
+
<pre>
|
51
|
+
posts_field = QueryType.field_with_guard('posts', <b>GraphqlPolicy</b>)
|
52
|
+
</pre>
|
53
|
+
|
15
54
|
#### [v0.4.0](https://github.com/exAspArk/graphql-guard/compare/v0.3.0...v0.4.0) – 2017-07-25
|
16
55
|
|
17
56
|
* `Added`: ability to test `guard` lambdas via field.
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
[](https://rubygems.org/gems/graphql-guard)
|
7
7
|
[](https://rubygems.org/gems/graphql-guard)
|
8
8
|
|
9
|
-
This
|
9
|
+
This gem provides a field-level authorization for [graphql-ruby](https://github.com/rmosolgo/graphql-ruby).
|
10
10
|
|
11
11
|
## Contents
|
12
12
|
|
@@ -44,7 +44,7 @@ QueryType = GraphQL::ObjectType.define do
|
|
44
44
|
|
45
45
|
field :posts, !types[PostType] do
|
46
46
|
argument :user_id, !types.ID
|
47
|
-
resolve ->(
|
47
|
+
resolve ->(obj, args, ctx) { Post.where(user_id: args[:user_id]) }
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -82,12 +82,12 @@ QueryType = GraphQL::ObjectType.define do
|
|
82
82
|
end
|
83
83
|
</pre>
|
84
84
|
|
85
|
-
You can also define `guard`, which will be executed for every
|
85
|
+
You can also define `guard`, which will be executed for every `*` field in the type:
|
86
86
|
|
87
87
|
<pre>
|
88
88
|
PostType = GraphQL::ObjectType.define do
|
89
89
|
name "Post"
|
90
|
-
<b>guard ->(obj, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
90
|
+
<b>guard ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
91
91
|
...
|
92
92
|
end
|
93
93
|
</pre>
|
@@ -105,7 +105,7 @@ class <b>GraphqlPolicy</b>
|
|
105
105
|
<b>posts: ->(obj, args, ctx) {</b> args[:user_id] == ctx[:current_user].id <b>}</b>
|
106
106
|
},
|
107
107
|
PostType => {
|
108
|
-
<b>'*': ->(obj, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
108
|
+
<b>'*': ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>
|
109
109
|
}
|
110
110
|
}
|
111
111
|
|
@@ -137,8 +137,8 @@ end
|
|
137
137
|
class <b>GraphqlPolicy</b>
|
138
138
|
RULES = {
|
139
139
|
PostType => {
|
140
|
-
<b>'*': ->(
|
141
|
-
<b>title: ->(
|
140
|
+
<b>'*': ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b>, # <=== <b>4</b>
|
141
|
+
<b>title: ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>2</b>
|
142
142
|
}
|
143
143
|
}
|
144
144
|
|
@@ -149,8 +149,8 @@ end
|
|
149
149
|
|
150
150
|
PostType = GraphQL::ObjectType.define do
|
151
151
|
name "Post"
|
152
|
-
<b>guard ->(
|
153
|
-
<b>field :title</b>, !types.String, <b>guard: ->(
|
152
|
+
<b>guard ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>3</b>
|
153
|
+
<b>field :title</b>, !types.String, <b>guard: ->(obj, args, ctx) {</b> ctx[:current_user].admin? <b>}</b> # <=== <b>1</b>
|
154
154
|
end
|
155
155
|
|
156
156
|
Schema = GraphQL::Schema.define do
|
@@ -211,7 +211,7 @@ end
|
|
211
211
|
# Use the ability in your guard
|
212
212
|
PostType = GraphQL::ObjectType.define do
|
213
213
|
name "Post"
|
214
|
-
<b>guard ->(post, ctx) { ctx[:current_ability].can?(:read, post) }</b>
|
214
|
+
<b>guard ->(post, args, ctx) { ctx[:current_ability].can?(:read, post) }</b>
|
215
215
|
...
|
216
216
|
end
|
217
217
|
|
@@ -232,7 +232,7 @@ end
|
|
232
232
|
# Use the ability in your guard
|
233
233
|
PostType = GraphQL::ObjectType.define do
|
234
234
|
name "Post"
|
235
|
-
<b>guard ->(post, ctx) { PostPolicy.new(ctx[:current_user], post).show? }</b>
|
235
|
+
<b>guard ->(post, args, ctx) { PostPolicy.new(ctx[:current_user], post).show? }</b>
|
236
236
|
...
|
237
237
|
end
|
238
238
|
|
@@ -288,16 +288,14 @@ end
|
|
288
288
|
# Your policy object
|
289
289
|
class <b>GraphqlPolicy</b>
|
290
290
|
def self.<b>guard</b>(type, field)
|
291
|
-
<b>->(
|
291
|
+
<b>->(obj, args, ctx) {</b> ... <b>}</b>
|
292
292
|
end
|
293
293
|
end
|
294
294
|
|
295
295
|
# Your test
|
296
296
|
<b>require "graphql/guard/testing"</b>
|
297
297
|
|
298
|
-
|
299
|
-
|
300
|
-
posts = QueryType.<b>field_with_guard('posts', guard_object)</b>
|
298
|
+
posts = QueryType.<b>field_with_guard('posts', GraphqlPolicy)</b>
|
301
299
|
result = posts.<b>guard(obj, args, ctx)</b>
|
302
300
|
expect(result).to eq(true)
|
303
301
|
</pre>
|
@@ -5,29 +5,30 @@ 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
|
-
guard_proc = @
|
10
|
-
raise NoGuardError.new("Guard lambda does not exist for #{@
|
8
|
+
raise NoGuardError.new("Get your field by calling: Type.field_with_guard('#{name}')") unless @__guard_type
|
9
|
+
guard_proc = @__guard_object.guard_proc(@__guard_type, self)
|
10
|
+
raise NoGuardError.new("Guard lambda does not exist for #{@__guard_type}.#{name}") unless guard_proc
|
11
11
|
|
12
12
|
guard_proc.call(*args)
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
@
|
15
|
+
def __policy_object=(policy_object)
|
16
|
+
@__policy_object = policy_object
|
17
|
+
@__guard_object = GraphQL::Guard.new(policy_object: policy_object)
|
17
18
|
end
|
18
19
|
|
19
20
|
def __guard_type=(guard_type)
|
20
|
-
@
|
21
|
+
@__guard_type = guard_type
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
class ObjectType
|
25
|
-
def field_with_guard(field_name,
|
26
|
+
def field_with_guard(field_name, policy_object = nil)
|
26
27
|
field = get_field(field_name)
|
27
28
|
return unless field
|
28
29
|
|
29
30
|
field.clone.tap do |f|
|
30
|
-
f.
|
31
|
+
f.__policy_object = policy_object
|
31
32
|
f.__guard_type = self
|
32
33
|
end
|
33
34
|
end
|
data/lib/graphql/guard.rb
CHANGED
@@ -25,18 +25,12 @@ module GraphQL
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def instrument(type, field)
|
28
|
-
|
29
|
-
|
30
|
-
return field if !field_guard_proc && !type_guard_proc
|
28
|
+
guard_proc = guard_proc(type, field)
|
29
|
+
return field unless guard_proc
|
31
30
|
|
32
31
|
old_resolve_proc = field.resolve_proc
|
33
32
|
new_resolve_proc = ->(object, arguments, context) do
|
34
|
-
authorized =
|
35
|
-
if field_guard_proc
|
36
|
-
field_guard_proc.call(object, arguments, context)
|
37
|
-
elsif type_guard_proc
|
38
|
-
type_guard_proc.call(object, context)
|
39
|
-
end
|
33
|
+
authorized = guard_proc.call(object, arguments, context)
|
40
34
|
|
41
35
|
if authorized
|
42
36
|
old_resolve_proc.call(object, arguments, context)
|
@@ -48,12 +42,11 @@ module GraphQL
|
|
48
42
|
field.redefine { resolve(new_resolve_proc) }
|
49
43
|
end
|
50
44
|
|
51
|
-
def
|
52
|
-
inline_field_guard(field) ||
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
inline_type_guard(type) || policy_object_guard(type, ANY_FIELD_NAME)
|
45
|
+
def guard_proc(type, field)
|
46
|
+
inline_field_guard(field) ||
|
47
|
+
policy_object_guard(type, field.name.to_sym) ||
|
48
|
+
inline_type_guard(type) ||
|
49
|
+
policy_object_guard(type, ANY_FIELD_NAME)
|
57
50
|
end
|
58
51
|
|
59
52
|
private
|
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: 0.
|
4
|
+
version: 1.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: 2017-07-
|
11
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|