action_policy 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5aa63f362aa8606be7d0ba77e1c78be9ed8c811eb57b06c38835ec4df24c9bf1
4
- data.tar.gz: 9c704fda90d4735827eddfb78be38a6f2ea2a293f71165df1955cdd78a3e803d
3
+ metadata.gz: c211ebea84e0d55fb6691b9abd897cfd2f594299cd72b1f346b904af99eb192c
4
+ data.tar.gz: b56a427246d7ebd7d5b96660791af5254880ada1c8dc29566ce4114f97f9aac7
5
5
  SHA512:
6
- metadata.gz: a0cd9a62e04d0dbf1263d5c30ba0e860930877e63dd5c3c93f0be327e204b5e66265b8d9ce264278e9b16bef1bff7924331c66f11f88012c0a26dca445ad51bd
7
- data.tar.gz: eb7b6b92a10869ab50f71656b446d26199d339891f5336ca28f87918cfd8dad467498e0262011703662944f82c49927e0c26dc24c871c456813ca87397cc4786
6
+ metadata.gz: 4f2deff9d0ff76e5966e0a4abafc75772730369ac46d033636c26a2cfa236b113c6544ccd2338cdd9813177905f58b97fa6111515b27a3ba7e862fbf7845953d
7
+ data.tar.gz: be2bc03196ac2de3e2ede2d3ea9c995e29352fdf269f9814d1bfe0d8dd9e9a1a4429a10e68631030fd749492888b30de607ebd1748a1656a6e12e0e7fb8ccb14
@@ -9,7 +9,6 @@ AllCops:
9
9
  Exclude:
10
10
  - 'bin/**/*'
11
11
  - 'gemfiles/**/*'
12
- - 'test/dummy/**/*'
13
12
  - 'vendor/**/*'
14
13
  - 'tmp/**/*'
15
14
  DisplayCopNames: true
@@ -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
 
@@ -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`
@@ -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.
@@ -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
- self.namespace_cache_enabled = true
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
- return activity if respond_to?(activity)
33
- self.class.lookup_alias(activity) || super
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.fetch(rule, rules_aliases[DEFAULT])
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
- app_middleware.use ActionPolicy::CacheMiddleware
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.3"
5
5
  end
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.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-01 00:00:00.000000000 Z
11
+ date: 2018-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler