action_policy 0.2.2 → 0.2.3
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/.rubocop.yml +0 -1
- data/CHANGELOG.md +13 -0
- data/docs/aliases.md +60 -0
- data/docs/namespaces.md +8 -0
- data/docs/quick_start.md +2 -0
- data/lib/action_policy/lookup_chain.rb +7 -3
- data/lib/action_policy/policy/aliases.rb +13 -3
- data/lib/action_policy/railtie.rb +10 -1
- data/lib/action_policy/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c211ebea84e0d55fb6691b9abd897cfd2f594299cd72b1f346b904af99eb192c
|
4
|
+
data.tar.gz: b56a427246d7ebd7d5b96660791af5254880ada1c8dc29566ce4114f97f9aac7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f2deff9d0ff76e5966e0a4abafc75772730369ac46d033636c26a2cfa236b113c6544ccd2338cdd9813177905f58b97fa6111515b27a3ba7e862fbf7845953d
|
7
|
+
data.tar.gz: be2bc03196ac2de3e2ede2d3ea9c995e29352fdf269f9814d1bfe0d8dd9e9a1a4429a10e68631030fd749492888b30de607ebd1748a1656a6e12e0e7fb8ccb14
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## 0.2.3 (2018-07-03)
|
4
|
+
|
5
|
+
- [Fix [#16](https://github.com/palkan/action_policy/issues/16)] Add ability to disable namespace resolution cache. ([@palkan][])
|
6
|
+
|
7
|
+
We cache namespaced policy resolution for better performance (it could affect performance when we look up a policy from a deeply nested module context).
|
8
|
+
|
9
|
+
It could be disabled by setting `ActionPolicy::LookupChain.namespace_cache_enabled = false`. It's enabled by default unless `RACK_ENV` env var is specified and is not equal to `"production"` (e.g. when `RACK_ENV=test` the cache is disabled).
|
10
|
+
|
11
|
+
When using Rails it's enabled only in production mode but could be configured through setting the `config.config.action_policy.namespace_cache_enabled` parameter.
|
12
|
+
|
13
|
+
- [Fix [#18](https://github.com/palkan/action_policy/issues/18)] Clarify documentation around, and fix the way `resolve_rule` resolves rules and rule aliases when subclasses are involved. ([@brendon][])
|
14
|
+
|
3
15
|
## 0.2.2 (2018-07-01)
|
4
16
|
|
5
17
|
- [Fix [#29](https://github.com/palkan/action_policy/issues/29)] Fix loading cache middleware. ([@palkan][])
|
6
18
|
|
19
|
+
|
7
20
|
- Use `send` instead of `public_send` to get the `authorization_context` so that contexts such as
|
8
21
|
`current_user` can be `private` in the controller. ([@brendon][])
|
9
22
|
|
data/docs/aliases.md
CHANGED
@@ -52,3 +52,63 @@ end
|
|
52
52
|
Now when you call `authorize! post` with any rule not explicitly defined in policy class, the `manage?` rule is applied.
|
53
53
|
|
54
54
|
By default, `ActionPolicy::Base` sets `manage?` as a default rule.
|
55
|
+
|
56
|
+
## Aliases and Private Methods
|
57
|
+
|
58
|
+
Rules in `action_policy` can only be public methods. Trying to use a private method as a rule will raise an error. Thus, aliases can also only point to public methods.
|
59
|
+
|
60
|
+
## Rule resolution with subclasses
|
61
|
+
|
62
|
+
Here's the order in which aliases and concrete rule methods are resolved in regards to subclasses:
|
63
|
+
|
64
|
+
1. If there is a concrete rule method on the subclass, this is called, else
|
65
|
+
2. If there is a matching alias then this is called, else
|
66
|
+
* When aliases are defined on the subclass they will overwrite matching aliases on the superclass.
|
67
|
+
3. If there is a concrete rule method on the superclass, then this is called, else
|
68
|
+
4. If there is a default rule defined, then this is called, else
|
69
|
+
5. `ActionPolicy::UnknownRule` is raised.
|
70
|
+
|
71
|
+
Here's an example with the expected results:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class SuperPolicy < ApplicationPolicy
|
75
|
+
default_rule :manage?
|
76
|
+
|
77
|
+
alias_rule :update?, :destroy?, :create?, to: :edit?
|
78
|
+
|
79
|
+
def manage?; end
|
80
|
+
|
81
|
+
def edit?; end
|
82
|
+
|
83
|
+
def index?; end
|
84
|
+
end
|
85
|
+
|
86
|
+
class SubPolicy < AbstractPolicy
|
87
|
+
default_rule nil
|
88
|
+
|
89
|
+
alias_rule :index?, :update?, to: :manage?
|
90
|
+
|
91
|
+
def create?; end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
Authorizing against the SuperPolicy:
|
96
|
+
|
97
|
+
* `update?` will resolve to `edit?`
|
98
|
+
* `destroy?` will resolve to `edit?`
|
99
|
+
* `create?` will resolve to `edit?`
|
100
|
+
* `manage?` will resolve to `manage?`
|
101
|
+
* `edit?` will resolve to `edit?`
|
102
|
+
* `index?` will resolve to `index?`
|
103
|
+
* `something?` will resolve to `manage?`
|
104
|
+
|
105
|
+
Authorizing against the SuBPolicy:
|
106
|
+
|
107
|
+
* `index?` will resolve to `manage?`
|
108
|
+
* `update?` will resolve to `manage?`
|
109
|
+
* `create?` will resolve to `create?`
|
110
|
+
* `destroy?` will resolve to `edit?`
|
111
|
+
* `manage?` will resolve to `manage?`
|
112
|
+
* `edit?` will resolve to `edit?`
|
113
|
+
* `index?` will resolve to `manage?`
|
114
|
+
* `something?` will raise `ActionPolicy::UnknownRule`
|
data/docs/namespaces.md
CHANGED
@@ -67,3 +67,11 @@ end
|
|
67
67
|
```
|
68
68
|
|
69
69
|
**NOTE**: namespace support is an extension for `ActionPolicy::Behaviour` and could be included with `ActionPolicy::Behaviours::Namespaced` (included into Rails controllers and channel integrations by default).
|
70
|
+
|
71
|
+
## Namespace resultion cache
|
72
|
+
|
73
|
+
We cache namespaced policy resolution for better performance (it could affect performance when we look up a policy from a deeply nested module context, see the [benchmark](https://github.com/palkan/action_policy/blob/master/benchmarks/namespaced_lookup_cache.rb)).
|
74
|
+
|
75
|
+
It could be disabled by setting `ActionPolicy::LookupChain.namespace_cache_enabled = false`. It's enabled by default unless `RACK_ENV` env var is specified and is not equal to `"production"` (e.g. when `RACK_ENV=test` the cache is disabled).
|
76
|
+
|
77
|
+
When using Rails it's enabled only in production mode but could be configured through setting the `config.config.action_policy.namespace_cache_enabled` parameter.
|
data/docs/quick_start.md
CHANGED
@@ -36,6 +36,8 @@ end
|
|
36
36
|
|
37
37
|
**NOTE:** it is not necessary to inherit from `ActionPolicy::Base`; instead, you can [construct basic policy](custom_policy.md) choosing only the components you need.
|
38
38
|
|
39
|
+
Rules must be public methods on the class. Using private methods as rules will raise an error.
|
40
|
+
|
39
41
|
Consider a simple example:
|
40
42
|
|
41
43
|
```ruby
|
@@ -22,7 +22,7 @@ module ActionPolicy
|
|
22
22
|
attr_reader :store
|
23
23
|
|
24
24
|
def fetch(namespace, policy)
|
25
|
-
return yield unless LookupChain.namespace_cache_enabled
|
25
|
+
return yield unless LookupChain.namespace_cache_enabled?
|
26
26
|
return store[namespace][policy] if store[namespace].key?(policy)
|
27
27
|
store[namespace][policy] ||= yield
|
28
28
|
end
|
@@ -38,6 +38,8 @@ module ActionPolicy
|
|
38
38
|
class << self
|
39
39
|
attr_accessor :chain, :namespace_cache_enabled
|
40
40
|
|
41
|
+
alias namespace_cache_enabled? namespace_cache_enabled
|
42
|
+
|
41
43
|
def call(record, **opts)
|
42
44
|
chain.each do |probe|
|
43
45
|
val = probe.call(record, opts)
|
@@ -76,8 +78,10 @@ module ActionPolicy
|
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
# Enable namespace cache by default
|
80
|
-
|
81
|
+
# Enable namespace cache by default or
|
82
|
+
# if RACK_ENV provided and equal to "production"
|
83
|
+
self.namespace_cache_enabled =
|
84
|
+
!ENV["RACK_ENV"].nil? ? ENV["RACK_ENV"] == "production" : true
|
81
85
|
|
82
86
|
# By self `policy_class` method
|
83
87
|
INSTANCE_POLICY_CLASS = ->(record, _) {
|
@@ -29,8 +29,10 @@ module ActionPolicy
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def resolve_rule(activity)
|
32
|
-
|
33
|
-
|
32
|
+
self.class.lookup_alias(activity) ||
|
33
|
+
(activity if respond_to?(activity)) ||
|
34
|
+
self.class.lookup_default_rule ||
|
35
|
+
super
|
34
36
|
end
|
35
37
|
|
36
38
|
module ClassMethods # :nodoc:
|
@@ -45,7 +47,11 @@ module ActionPolicy
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def lookup_alias(rule)
|
48
|
-
rules_aliases
|
50
|
+
rules_aliases[rule]
|
51
|
+
end
|
52
|
+
|
53
|
+
def lookup_default_rule
|
54
|
+
rules_aliases[DEFAULT]
|
49
55
|
end
|
50
56
|
|
51
57
|
def rules_aliases
|
@@ -58,6 +64,10 @@ module ActionPolicy
|
|
58
64
|
{}
|
59
65
|
end
|
60
66
|
end
|
67
|
+
|
68
|
+
def method_added(name)
|
69
|
+
rules_aliases.delete(name) if public_method_defined?(name)
|
70
|
+
end
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
@@ -25,6 +25,11 @@ module ActionPolicy # :nodoc:
|
|
25
25
|
# the default authorization context in channels
|
26
26
|
attr_accessor :channel_authorize_current_user
|
27
27
|
|
28
|
+
# Define whether to cache namespaced policy resolution
|
29
|
+
# result (e.g. in controllers).
|
30
|
+
# Enabled only in production by default.
|
31
|
+
attr_accessor :namespace_cache_enabled
|
32
|
+
|
28
33
|
def cache_store=(store, *args)
|
29
34
|
if store.is_a?(Symbol)
|
30
35
|
store = ActiveSupport::Cache.lookup_store(
|
@@ -40,6 +45,7 @@ module ActionPolicy # :nodoc:
|
|
40
45
|
self.controller_authorize_current_user = true
|
41
46
|
self.auto_inject_into_channel = true
|
42
47
|
self.channel_authorize_current_user = true
|
48
|
+
self.namespace_cache_enabled = Rails.env.production?
|
43
49
|
end
|
44
50
|
|
45
51
|
config.action_policy = Config
|
@@ -50,11 +56,14 @@ module ActionPolicy # :nodoc:
|
|
50
56
|
app.executor.to_complete { ActionPolicy::PerThreadCache.clear_all }
|
51
57
|
else
|
52
58
|
require "action_policy/cache_middleware"
|
53
|
-
|
59
|
+
app.middleware.use ActionPolicy::CacheMiddleware
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
57
63
|
config.to_prepare do |_app|
|
64
|
+
ActionPolicy::LookupChain.namespace_cache_enabled =
|
65
|
+
Rails.application.config.action_policy.namespace_cache_enabled
|
66
|
+
|
58
67
|
ActiveSupport.on_load(:action_controller) do
|
59
68
|
next unless Rails.application.config.action_policy.auto_inject_into_controller
|
60
69
|
|
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.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|