action_policy 0.3.0 → 0.3.1
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/.github/FUNDING.yml +1 -0
- data/.rubocop.yml +1 -1
- data/.tidelift.yml +6 -0
- data/CHANGELOG.md +6 -0
- data/README.md +11 -0
- data/Rakefile +0 -1
- data/action_policy.gemspec +10 -2
- data/docs/README.md +3 -1
- data/docs/_sidebar.md +1 -0
- data/docs/aliases.md +5 -1
- data/docs/graphql.md +252 -0
- data/docs/reasons.md +2 -1
- data/gemfiles/railsmaster.gemfile +1 -1
- data/lib/action_policy.rb +2 -2
- data/lib/action_policy/behaviour.rb +2 -2
- data/lib/action_policy/behaviours/policy_for.rb +14 -0
- data/lib/action_policy/behaviours/scoping.rb +1 -1
- data/lib/action_policy/policy/core.rb +2 -1
- data/lib/action_policy/policy/scoping.rb +0 -4
- data/lib/action_policy/version.rb +1 -1
- metadata +16 -9
- data/lib/action_policy/ext/proc_case_eq.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e593d4567bab1e7fec960db2d67d7d659d4b4df92159741b7db715b35b75c790
|
4
|
+
data.tar.gz: efdc9d9815936a6dcbb0e94b0098050bc30fddae20a3d06f35bf03b91787d500
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c58c58e14c25f4daadc890ab67de43781f33f28485811b05458568b9003b9037911fbaade9332dca0b458dec811138df87fa094564574cd55fae948a09379be8
|
7
|
+
data.tar.gz: 12db66ef181fa94ec6ac2c48feeb7fe49d12a3b66a9a554c925594b9b622ec3cec94412e48db13406d71733d0ae001f7dece5fedfe56ca11216f6e027754765f
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
tidelift: "rubygems/action_policy"
|
data/.rubocop.yml
CHANGED
data/.tidelift.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## 0.3.1 (2019-05-30)
|
4
|
+
|
5
|
+
- Fixed bug with missing implicit target and hash like scoping data. ([@palkan][])
|
6
|
+
|
7
|
+
Fixes [#70](https://github.com/palkan/action_policy/issues/70).
|
8
|
+
|
3
9
|
## 0.3.0 (2019-04-02)
|
4
10
|
|
5
11
|
- Added ActiveSupport-based instrumentation. ([@palkan][])
|
data/README.md
CHANGED
@@ -13,9 +13,15 @@ Action Policy is an authorization framework for Ruby and Rails applications.
|
|
13
13
|
|
14
14
|
## Resources
|
15
15
|
|
16
|
+
- Seattle.rb, 2019 "A Denial!" talk [[slides](https://speakerdeck.com/palkan/seattle-dot-rb-2019-a-denial)]
|
17
|
+
|
16
18
|
- RailsConf, 2018 "Access Denied" talk [[video](https://www.youtube.com/watch?v=NVwx0DARDis), [slides](https://speakerdeck.com/palkan/railsconf-2018-access-denied-the-missing-guide-to-authorization-in-rails)]
|
17
19
|
|
18
20
|
|
21
|
+
## Integrations
|
22
|
+
|
23
|
+
- GraphQL Ruby ([`action_policy-graphql`](https://github.com/palkan/action_policy-graphql))
|
24
|
+
|
19
25
|
## Installation
|
20
26
|
|
21
27
|
Add this line to your application's `Gemfile`:
|
@@ -107,3 +113,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/palkan
|
|
107
113
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
108
114
|
|
109
115
|
[Documentation]: http://actionpolicy.evilmartians.io
|
116
|
+
|
117
|
+
## Security Contact
|
118
|
+
|
119
|
+
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
|
120
|
+
|
data/Rakefile
CHANGED
data/action_policy.gemspec
CHANGED
@@ -19,6 +19,14 @@ Gem::Specification.new do |spec|
|
|
19
19
|
f.match(%r{^(test|spec|features)/})
|
20
20
|
end
|
21
21
|
|
22
|
+
spec.metadata = {
|
23
|
+
"bug_tracker_uri" => "http://github.com/palkan/action_policy/issues",
|
24
|
+
"changelog_uri" => "https://github.com/palkan/action_policy/blob/master/CHANGELOG.md",
|
25
|
+
"documentation_uri" => "https://actionpolicy.evilmartians.io/",
|
26
|
+
"homepage_uri" => "https://actionpolicy.evilmartians.io/",
|
27
|
+
"source_code_uri" => "http://github.com/palkan/action_policy"
|
28
|
+
}
|
29
|
+
|
22
30
|
spec.require_paths = ["lib"]
|
23
31
|
|
24
32
|
spec.required_ruby_version = ">= 2.4.0"
|
@@ -27,9 +35,9 @@ Gem::Specification.new do |spec|
|
|
27
35
|
spec.add_development_dependency "minitest", "~> 5.0"
|
28
36
|
spec.add_development_dependency "rake", "~> 10.0"
|
29
37
|
spec.add_development_dependency "rspec", "~> 3.3"
|
30
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
38
|
+
spec.add_development_dependency "rubocop", "~> 0.67.0"
|
31
39
|
spec.add_development_dependency "rubocop-md", "~> 0.2"
|
32
|
-
spec.add_development_dependency "standard", "~> 0.0.
|
40
|
+
spec.add_development_dependency "standard", "~> 0.0.39"
|
33
41
|
spec.add_development_dependency "benchmark-ips", "~> 2.7.0"
|
34
42
|
spec.add_development_dependency "i18n"
|
35
43
|
end
|
data/docs/README.md
CHANGED
@@ -22,7 +22,7 @@ Action Policy provides flexible tools to build an _authorization layer_ for your
|
|
22
22
|
|
23
23
|
## Project State
|
24
24
|
|
25
|
-
The project is in
|
25
|
+
The project is being used in production since mid 2018. Major features have been implemented, API has been stabilized. Check out our [development board](https://github.com/palkan/action_policy/projects/1) to see what's coming next.
|
26
26
|
|
27
27
|
## History
|
28
28
|
|
@@ -58,6 +58,8 @@ Learn more about the motivation behind the Action Policy and its features by wat
|
|
58
58
|
|
59
59
|
## Resources
|
60
60
|
|
61
|
+
- Seattle.rb, 2019 "A Denial!" talk [[slides](https://speakerdeck.com/palkan/seattle-dot-rb-2019-a-denial)]
|
62
|
+
|
61
63
|
- RailsConf, 2018 "Access Denied" talk [[video](https://www.youtube.com/watch?v=NVwx0DARDis), [slides](https://speakerdeck.com/palkan/railsconf-2018-access-denied-the-missing-guide-to-authorization-in-rails)]
|
62
64
|
|
63
65
|
<a href="https://evilmartians.com/?utm_source=action_policy">
|
data/docs/_sidebar.md
CHANGED
data/docs/aliases.md
CHANGED
@@ -41,15 +41,19 @@ You can add a _default_ rule–the rule that would be applied if the rule specif
|
|
41
41
|
|
42
42
|
```ruby
|
43
43
|
class PostPolicy < ApplicationPolicy
|
44
|
+
# For an ApplicationPolicy, makes :manage? match anything that is
|
45
|
+
# not :index?, :create? or :new?
|
44
46
|
default_rule :manage?
|
45
47
|
|
48
|
+
# If you want manage? to catch really everything, place this alias
|
49
|
+
#alias_rule :index?, :create?, :new?, to: :manage?
|
46
50
|
def manage?
|
47
51
|
# ...
|
48
52
|
end
|
49
53
|
end
|
50
54
|
```
|
51
55
|
|
52
|
-
Now when you call `authorize! post` with any rule not
|
56
|
+
Now when you call `authorize! post` with any rule not defined in the policy class, the `manage?` rule is applied. Note that `index?` `create?` and `new?` are already defined in the [superclass by default](custom_policy.md) (returning `false`) - if you want the same behaviour for *all* actions, define aliases like in the example above (commented out).
|
53
57
|
|
54
58
|
By default, `ActionPolicy::Base` sets `manage?` as a default rule.
|
55
59
|
|
data/docs/graphql.md
ADDED
@@ -0,0 +1,252 @@
|
|
1
|
+
# GraphQL integration
|
2
|
+
|
3
|
+
You can use Action Policy as an authorization library for you [GraphQL Ruby](https://graphql-ruby.org/) application via the [`action_policy-graphql` gem](https://github.com/palkan/action_policy-graphql).
|
4
|
+
|
5
|
+
This integration provides the following features:
|
6
|
+
- Fields & mutations authorization
|
7
|
+
- List and connections scoping
|
8
|
+
- [**Exposing permissions/authorization rules in the API**](https://dev.to/evilmartians/exposing-permissions-in-graphql-apis-with-action-policy-1mfh).
|
9
|
+
|
10
|
+
## Getting Started
|
11
|
+
|
12
|
+
First, add `action_policy-graphql` gem to your Gemfile (see [installation instructions](https://github.com/palkan/action_policy-graphql#installation)).
|
13
|
+
|
14
|
+
Then, include `ActionPolicy::GraphQL::Behaviour` to your base type (or any other type/mutation where you want to use authorization features):
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
# For fields authorization, lists scoping and rules exposing
|
18
|
+
class Types::BaseObject < GraphQL::Schema::Object
|
19
|
+
include ActionPolicy::GraphQL::Behaviour
|
20
|
+
end
|
21
|
+
|
22
|
+
# For using authorization helpers in mutations
|
23
|
+
class Types::BaseMutation < GraphQL::Schema::Mutation
|
24
|
+
include ActionPolicy::GraphQL::Behaviour
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
## Authorization Context
|
29
|
+
|
30
|
+
By default, Action Policy use `context[:current_user]` as the `user` [authorization context](./authoriation_context.md).
|
31
|
+
|
32
|
+
**NOTE:** see below for more information on what's included into `ActionPolicy::GraphQL::Behaviour`.
|
33
|
+
|
34
|
+
## Authorizing Fields
|
35
|
+
|
36
|
+
You can add `authorize: true` option to any field (=underlying object) to protect the access (it's equal to calling `authorize! object, to: :show?`):
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# authorization could be useful for find-like methods,
|
40
|
+
# where the object is resolved from the provided params (e.g., ID)
|
41
|
+
field :home, Home, null: false, authorize: true do
|
42
|
+
argument :id, ID, required: true
|
43
|
+
end
|
44
|
+
|
45
|
+
def home(id:)
|
46
|
+
Home.find(id)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Without `authorize: true` the code would look like this
|
50
|
+
def home(id:)
|
51
|
+
Home.find(id).tap { |home| authorize! home, to: :show? }
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
You can use authorization options to customize the behaviour, e.g. `authorize: {to: :preview?, with: CustomPolicy}`.
|
56
|
+
|
57
|
+
By default, if a user is not authorized to access the field, an `ActionPolicy::Unauthorized` exception is raised.
|
58
|
+
|
59
|
+
If you want to return a `nil` instead, you should add `raise: false` to the options:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# NOTE: don't forget to mark your field as nullable
|
63
|
+
field :home, Home, null: true, authorize: {raise: false}
|
64
|
+
```
|
65
|
+
|
66
|
+
You can make non-raising behaviour a default by setting a configuration option:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
ActionPolicy::GraphQL.authorize_raise_exception = false
|
70
|
+
```
|
71
|
+
|
72
|
+
You can also change the default `show?` rule globally:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
ActionPolicy::GraphQL.default_authorize_rule = :show_graphql_field?
|
76
|
+
```
|
77
|
+
|
78
|
+
### Class-level authorization
|
79
|
+
|
80
|
+
You can use Action Policy in the class-level [authorization hooks](https://graphql-ruby.org/authorization/authorization.html) (`self.authorized?`) like this:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
class Types::Friendship < Types::BaseObject
|
84
|
+
def self.authorized?(object, context)
|
85
|
+
super &&
|
86
|
+
object.allowed_to?(
|
87
|
+
:show?,
|
88
|
+
object,
|
89
|
+
context: {user: context[:current_user]}
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## Authorizing Mutations
|
96
|
+
|
97
|
+
Mutation is just a Ruby class with a single API method. There is nothing specific in authorizing mutations: from the Action Policy point of view, they are just [_behaviours_](./behaviour.md).
|
98
|
+
|
99
|
+
If you want to authorize the mutation, you call `authorize!` method. For example:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class Mutations::DestroyUser < Types::BaseMutation
|
103
|
+
argument :id, ID, required: true
|
104
|
+
|
105
|
+
def resolve(id:)
|
106
|
+
user = User.find(id)
|
107
|
+
|
108
|
+
# Raise an exception if the user has not enough permissions
|
109
|
+
authorize! user, to: :destroy?
|
110
|
+
# Or check without raising and do what you want
|
111
|
+
#
|
112
|
+
# if allowed_to?(:destroy?, user)
|
113
|
+
|
114
|
+
user.destroy!
|
115
|
+
|
116
|
+
{deleted_id: user.id}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
121
|
+
## Handling exceptions
|
122
|
+
|
123
|
+
The query would fail with `ActionPolicy::Unauthorized` exception when using `authorize: true` (in raising mode) or calling `authorize!` explicitly.
|
124
|
+
|
125
|
+
That could be useful to handle this exception and send a more detailed error message to the client, for example:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
# in your schema file
|
129
|
+
rescue_from(ActionPolicy::Unauthorized) do |exp|
|
130
|
+
raise GraphQL::ExecutionError.new(
|
131
|
+
# use result.message (backed by i18n) as an error message
|
132
|
+
exp.result.message,
|
133
|
+
# use GraphQL error extensions to provide more context
|
134
|
+
extensions: {
|
135
|
+
code: :unauthorized,
|
136
|
+
fullMessages: exp.result.reasons.full_messages,
|
137
|
+
details: exp.result.reasons.details
|
138
|
+
}
|
139
|
+
)
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
## Scoping Data
|
144
|
+
|
145
|
+
You can add `authorized_scope: true` option to a field (list or [_connection_](https://graphql-ruby.org/relay/connections.html)) to apply the corresponding policy rules to the data:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class CityType < ::Common::Graphql::Type
|
149
|
+
# It would automatically apply the relation scope from the EventPolicy to
|
150
|
+
# the relation (city.events)
|
151
|
+
field :events, EventType.connection_type,
|
152
|
+
null: false,
|
153
|
+
authorized_scope: true
|
154
|
+
|
155
|
+
# you can specify the policy explicitly
|
156
|
+
field :events, EventType.connection_type,
|
157
|
+
null: false,
|
158
|
+
authorized_scope: {with: CustomEventPolicy}
|
159
|
+
|
160
|
+
# without the option you would write the following code
|
161
|
+
def events
|
162
|
+
authorized_scope object.events
|
163
|
+
# or if `with` option specified
|
164
|
+
authorized_scope object.events, with: CustomEventPolicy
|
165
|
+
end
|
166
|
+
end
|
167
|
+
```
|
168
|
+
|
169
|
+
See the documenation on [scoping](./scoping.md).
|
170
|
+
|
171
|
+
## Exposing Authorization Rules
|
172
|
+
|
173
|
+
With `action_policy-graphql` gem, you can easily expose your authorization logic to the client in a standardized way.
|
174
|
+
|
175
|
+
For example, if you want to "tell" the client which actions could be performed against the object you
|
176
|
+
can use the `expose_authorization_rules` macro to add authorization-related fields to your type:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class ProfileType < Types::BaseType
|
180
|
+
# Adds can_edit, can_destroy fields with
|
181
|
+
# AuthorizationResult type.
|
182
|
+
|
183
|
+
# NOTE: prefix "can_" is used by default, no need to specify it explicitly
|
184
|
+
expose_authorization_rules :edit?, :destroy?, prefix: "can_"
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
**NOTE:** you can use [aliases](./aliases.md) here as well as defined rules.
|
189
|
+
|
190
|
+
**NOTE:** This feature relies the [_failure reasons_](./reasons.md) and
|
191
|
+
the [i18n integration](./i18n.md) extensions. If your policies don't include any of these,
|
192
|
+
you won't be able to use it.
|
193
|
+
|
194
|
+
Then the client could perform the following query:
|
195
|
+
|
196
|
+
```gql
|
197
|
+
{
|
198
|
+
post(id: $id) {
|
199
|
+
canEdit {
|
200
|
+
# (bool) true|false; not null
|
201
|
+
value
|
202
|
+
# top-level decline message ("Not authorized" by default); null if value is true
|
203
|
+
message
|
204
|
+
# detailed information about the decline reasons; null if value is true or you don't have "failure reasons" extension enabled
|
205
|
+
reasons {
|
206
|
+
details # JSON-encoded hash of the form { "event" => [:privacy_off?] }
|
207
|
+
fullMessages # Array of human-readable reasons
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
canDestroy {
|
212
|
+
# ...
|
213
|
+
}
|
214
|
+
}
|
215
|
+
}
|
216
|
+
```
|
217
|
+
|
218
|
+
You can override a custom authorization field prefix (`can_`):
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
ActionPolicy::GraphQL.default_authorization_field_prefix = "allowed_to_"
|
222
|
+
```
|
223
|
+
|
224
|
+
## Custom Behaviour
|
225
|
+
|
226
|
+
Including the default `ActionPolicy::GraphQL::Behaviour` is equal to adding the following to your base class:
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
class Types::BaseObject < GraphQL::Schema::Object
|
230
|
+
# include Action Policy behaviour and its extensions
|
231
|
+
include ActionPolicy::Behaviour
|
232
|
+
include ActionPolicy::Behaviours::ThreadMemoized
|
233
|
+
include ActionPolicy::Behaviours::Memoized
|
234
|
+
include ActionPolicy::Behaviours::Namespaced
|
235
|
+
|
236
|
+
# define authorization context
|
237
|
+
authorize :user, through: :current_user
|
238
|
+
|
239
|
+
# add a method helper to get the current_user from the context
|
240
|
+
def current_user
|
241
|
+
context[:current_user]
|
242
|
+
end
|
243
|
+
|
244
|
+
# extend the field class to add `authorize` and `authorized_scope` options
|
245
|
+
field_class.prepend(ActionPolicy::GraphQL::AuthorizedField)
|
246
|
+
|
247
|
+
# add `expose_authorization_rules` macro
|
248
|
+
include ActionPolicy::GraphQL::Fields
|
249
|
+
end
|
250
|
+
```
|
251
|
+
|
252
|
+
Feel free to create your own behaviour by adding only the functionality you need.
|
data/docs/reasons.md
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
When you have complex policy rules, it could be helpful to have an ability to define an exact reason for why a specific authorization was rejected.
|
4
4
|
|
5
|
-
It is especially helpful when you compose policies (i.e., use one policy within another)
|
5
|
+
It is especially helpful when you compose policies (i.e., use one policy within another) or want
|
6
|
+
to expose permissions to client applications (see [GraphQL](./graphql)).
|
6
7
|
|
7
8
|
Action Policy allows you to track failed `allowed_to?` checks in your rules.
|
8
9
|
|
data/lib/action_policy.rb
CHANGED
@@ -11,9 +11,9 @@ module ActionPolicy
|
|
11
11
|
class NotFound < Error
|
12
12
|
attr_reader :target, :message
|
13
13
|
|
14
|
-
def initialize(target)
|
14
|
+
def initialize(target, message = nil)
|
15
15
|
@target = target
|
16
|
-
@message = "Couldn't find policy class for #{target.inspect}"
|
16
|
+
@message = message || "Couldn't find policy class for #{target.inspect}"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -35,7 +35,7 @@ module ActionPolicy
|
|
35
35
|
#
|
36
36
|
# Raises `ActionPolicy::Unauthorized` if check failed.
|
37
37
|
def authorize!(record = :__undef__, to:, **options)
|
38
|
-
record = implicit_authorization_target if record == :__undef__
|
38
|
+
record = implicit_authorization_target! if record == :__undef__
|
39
39
|
raise ArgumentError, "Record must be specified" if record.nil?
|
40
40
|
|
41
41
|
policy = policy_for(record: record, **options)
|
@@ -47,7 +47,7 @@ module ActionPolicy
|
|
47
47
|
#
|
48
48
|
# Returns true of false.
|
49
49
|
def allowed_to?(rule, record = :__undef__, **options)
|
50
|
-
record = implicit_authorization_target if record == :__undef__
|
50
|
+
record = implicit_authorization_target! if record == :__undef__
|
51
51
|
raise ArgumentError, "Record must be specified" if record.nil?
|
52
52
|
|
53
53
|
policy = policy_for(record: record, **options)
|
@@ -27,6 +27,20 @@ module ActionPolicy
|
|
27
27
|
def implicit_authorization_target
|
28
28
|
# no-op
|
29
29
|
end
|
30
|
+
|
31
|
+
# Return implicit authorization target or raises an exception if it's nil
|
32
|
+
def implicit_authorization_target!
|
33
|
+
implicit_authorization_target || raise(
|
34
|
+
NotFound,
|
35
|
+
[
|
36
|
+
self,
|
37
|
+
"Couldn't find implicit authorization target " \
|
38
|
+
"for #{self.class}. " \
|
39
|
+
"Please, provide policy class explicitly using `with` option or " \
|
40
|
+
"define the `implicit_authorization_target` method."
|
41
|
+
]
|
42
|
+
)
|
43
|
+
end
|
30
44
|
end
|
31
45
|
end
|
32
46
|
end
|
@@ -12,7 +12,7 @@ module ActionPolicy
|
|
12
12
|
# - use `implicit_authorization_target` if none of the above works.
|
13
13
|
def authorized_scope(target, type: nil, as: :default, scope_options: nil, **options)
|
14
14
|
policy = policy_for(record: target, allow_nil: true, **options)
|
15
|
-
policy ||= policy_for(record: implicit_authorization_target
|
15
|
+
policy ||= policy_for(record: implicit_authorization_target!, **options)
|
16
16
|
|
17
17
|
type ||= authorization_scope_type_for(policy, target)
|
18
18
|
|
@@ -4,10 +4,6 @@ require "action_policy/behaviours/scoping"
|
|
4
4
|
|
5
5
|
require "action_policy/utils/suggest_message"
|
6
6
|
|
7
|
-
require "action_policy/ext/proc_case_eq"
|
8
|
-
|
9
|
-
using ActionPolicy::Ext::ProcCaseEq
|
10
|
-
|
11
7
|
module ActionPolicy
|
12
8
|
class UnknownScopeType < Error # :nodoc:
|
13
9
|
include ActionPolicy::SuggestMessage
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_policy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.67.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.67.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop-md
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.0.
|
103
|
+
version: 0.0.39
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.0.
|
110
|
+
version: 0.0.39
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: benchmark-ips
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,10 +144,12 @@ extensions: []
|
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
146
|
- ".gitattributes"
|
147
|
+
- ".github/FUNDING.yml"
|
147
148
|
- ".github/ISSUE_TEMPLATE.md"
|
148
149
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
149
150
|
- ".gitignore"
|
150
151
|
- ".rubocop.yml"
|
152
|
+
- ".tidelift.yml"
|
151
153
|
- ".travis.yml"
|
152
154
|
- CHANGELOG.md
|
153
155
|
- Gemfile
|
@@ -183,6 +185,7 @@ files:
|
|
183
185
|
- docs/debugging.md
|
184
186
|
- docs/decorators.md
|
185
187
|
- docs/favicon.ico
|
188
|
+
- docs/graphql.md
|
186
189
|
- docs/i18n.md
|
187
190
|
- docs/index.html
|
188
191
|
- docs/instrumentation.md
|
@@ -214,7 +217,6 @@ files:
|
|
214
217
|
- lib/action_policy/ext/hash_transform_keys.rb
|
215
218
|
- lib/action_policy/ext/module_namespace.rb
|
216
219
|
- lib/action_policy/ext/policy_cache_key.rb
|
217
|
-
- lib/action_policy/ext/proc_case_eq.rb
|
218
220
|
- lib/action_policy/ext/string_constantize.rb
|
219
221
|
- lib/action_policy/ext/string_match.rb
|
220
222
|
- lib/action_policy/ext/string_underscore.rb
|
@@ -253,7 +255,12 @@ files:
|
|
253
255
|
homepage: https://github.com/palkan/action_policy
|
254
256
|
licenses:
|
255
257
|
- MIT
|
256
|
-
metadata:
|
258
|
+
metadata:
|
259
|
+
bug_tracker_uri: http://github.com/palkan/action_policy/issues
|
260
|
+
changelog_uri: https://github.com/palkan/action_policy/blob/master/CHANGELOG.md
|
261
|
+
documentation_uri: https://actionpolicy.evilmartians.io/
|
262
|
+
homepage_uri: https://actionpolicy.evilmartians.io/
|
263
|
+
source_code_uri: http://github.com/palkan/action_policy
|
257
264
|
post_install_message:
|
258
265
|
rdoc_options: []
|
259
266
|
require_paths:
|
@@ -269,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
269
276
|
- !ruby/object:Gem::Version
|
270
277
|
version: '0'
|
271
278
|
requirements: []
|
272
|
-
rubygems_version: 3.0.
|
279
|
+
rubygems_version: 3.0.3
|
273
280
|
signing_key:
|
274
281
|
specification_version: 4
|
275
282
|
summary: Authorization framework for Ruby/Rails application
|