ii_policy 1.0.0 → 1.1.0

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: f4b0ae3047d7ec960796e3bc2cb0fec29584717eb19e23035337121b17b0f66e
4
- data.tar.gz: 2d0e5696b4a5888f062ae7b9240eff50f7d94e5ee0f4bf49c461c037e4006619
3
+ metadata.gz: 62f7efd3ac2e7db1c4c9532e987e3ed592083cec2e00f5cca700c5c5a5bab4e6
4
+ data.tar.gz: e6df72f0fae98ff640ff6f87bc8bf3a1297c4470c64c45e5449b9ab439c96bdc
5
5
  SHA512:
6
- metadata.gz: caec6ed0fba367ae7f425afc1c427acef1ec1260e5e0b5057f106a95f237a65d598daadd75156875a4f282d7a606c0616fb7caeccc25b8147e4edc9f7e08adde
7
- data.tar.gz: a49b1a52334ce402ea35a11055a76823713564d84b9d6105e42ec931973acf67dd15d6a85f0e3c98c8d06631ac1369323b8b862883000300d275fef062fb33bf
6
+ metadata.gz: 928646d051e6296eff7dcb3330f8080c36fba6949ffd706165e598f8849d1cf5d6084a4eaf15daab013f289783087a1406c3417c6fb096c963ffd858e4f0c8dc
7
+ data.tar.gz: e21fbbf89718aa908b42acd332b85178cfe7ab8ca9c5b11525b1c0454f6475df77820e4604bc3c275f46359ac32ac9d800107444973b95bc785593d72a6d37a2
@@ -39,4 +39,4 @@ jobs:
39
39
  bundler-cache: true
40
40
  - name: Run test
41
41
  run: |
42
- bundle exec rspec
42
+ DEBUG=1 bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.1.0
4
+
5
+ * Support method and block for `chain`.
6
+ * Include `IIPolicy::Chain` by default.
7
+ * Add log subscriber.
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  * First release.
data/README.md CHANGED
@@ -177,7 +177,7 @@ end
177
177
 
178
178
  #### Policy chain
179
179
 
180
- You can chain shared policies to base policy by including `IIPolicy::Chain` as follows:
180
+ You can chain shared policies to base policy by using `chain` as follows:
181
181
 
182
182
  ```ruby
183
183
  # shared policy
@@ -189,8 +189,6 @@ end
189
189
 
190
190
  # base policy
191
191
  class ItemPolicy < IIPolicy::Base
192
- include IIPolicy::Chain
193
-
194
192
  chain SharedPolicy
195
193
 
196
194
  def show?
@@ -205,6 +203,23 @@ policy.allowed(:show?)
205
203
 
206
204
  In this example, `policy.allowed(:show?)` is evaluated by `SharedPolicy#show? && ItemPolicy#show?`.
207
205
 
206
+ You can also use method or block to find policy class dynamically:
207
+
208
+ ```ruby
209
+ class ItemPolicy < IIPolicy::Base
210
+ chain -> { SharedPolicy }
211
+ end
212
+
213
+ class ItemPolicy < IIPolicy::Base
214
+ chain :chain_policy
215
+
216
+ def chain_policy
217
+ SharedPolicy
218
+ end
219
+ end
220
+ ```
221
+
222
+
208
223
  ### Lookup for policy
209
224
 
210
225
  `authorize` and `policy` lookups policy class if the first argument of them is not a policy class.
@@ -250,6 +265,21 @@ IIPolicy::Base.lookup(InheritedItem.new)
250
265
  #=> ItemPolicy
251
266
  ```
252
267
 
268
+ ### Logging
269
+
270
+ Policy supports instrumentation hook supplied by `ActiveSupport::Notifications`.
271
+ You can enable log subscriber as follows:
272
+
273
+ ```ruby
274
+ IIPolicy::LogSubscriber.attach_to :ii_policy
275
+ ```
276
+
277
+ This subscriber will write logs in debug mode as the following example:
278
+
279
+ ```
280
+ Called ItemPolicy#index? for Item#1 and return true (Duration: 0.1ms, Allocations: 9)
281
+ ```
282
+
253
283
  ## Contributing
254
284
 
255
285
  Bug reports and pull requests are welcome at https://github.com/kanety/ii_policy.
data/lib/ii_policy.rb CHANGED
@@ -6,6 +6,7 @@ require 'ii_policy/errors'
6
6
  require 'ii_policy/base'
7
7
  require 'ii_policy/controller'
8
8
  require 'ii_policy/helper'
9
+ require 'ii_policy/log_subscriber'
9
10
  require 'ii_policy/railtie' if defined?(Rails)
10
11
 
11
12
  module IIPolicy
@@ -1,42 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'context'
4
+ require_relative 'core'
4
5
  require_relative 'callbacks'
6
+ require_relative 'instrumentation'
5
7
  require_relative 'lookup'
6
8
  require_relative 'chain'
7
9
 
8
10
  module IIPolicy
9
11
  class Base
12
+ include Core
10
13
  include Callbacks
14
+ include Instrumentation
11
15
  include Lookup
12
-
13
- attr_reader :context, :user, :item
14
-
15
- def initialize(context = {})
16
- @context = if context.is_a?(IIPolicy::Context)
17
- context
18
- else
19
- IIPolicy::Context.new(context)
20
- end
21
- @item = @context.item
22
- @user = @context.user
23
- end
24
-
25
- def call(action)
26
- run_callbacks(:call) do
27
- return false if respond_to?(action) && !send(action)
28
- end
29
- return true
30
- end
31
-
32
- def allowed(action)
33
- call(action)
34
- end
35
-
36
- def policy(item)
37
- context = @context.dup
38
- context.item = item
39
- self.class.lookup(item).new(context)
40
- end
16
+ include Chain
41
17
  end
42
18
  end
@@ -9,6 +9,12 @@ module IIPolicy
9
9
  define_callbacks :call
10
10
  end
11
11
 
12
+ def call(action)
13
+ run_callbacks(:call) do
14
+ super
15
+ end
16
+ end
17
+
12
18
  class_methods do
13
19
  def before_call(*args, &block)
14
20
  set_callback(:call, :before, *args, &block)
@@ -10,15 +10,28 @@ module IIPolicy
10
10
  end
11
11
 
12
12
  def call(action)
13
- self.class._chains.each do |policy|
13
+ lookup.each do |policy|
14
14
  return false unless policy.new(@context).call(action)
15
15
  end
16
16
  super
17
17
  end
18
18
 
19
+ def lookup
20
+ self.class._chains.map do |policy|
21
+ if policy.is_a?(Symbol) && respond_to?(policy, true)
22
+ send(policy)
23
+ elsif policy.is_a?(Proc)
24
+ instance_exec(&policy)
25
+ else
26
+ policy
27
+ end
28
+ end.flatten.compact
29
+ end
30
+
19
31
  class_methods do
20
- def chain(*policies)
32
+ def chain(*policies, &block)
21
33
  self._chains = _chains + policies
34
+ self._chains << block if block
22
35
  end
23
36
  end
24
37
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IIPolicy
4
+ module Core
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attr_reader :context, :user, :item, :_result
9
+ end
10
+
11
+ def initialize(context = {})
12
+ @context = if context.is_a?(IIPolicy::Context)
13
+ context
14
+ else
15
+ IIPolicy::Context.new(context)
16
+ end
17
+ @item = @context.item
18
+ @user = @context.user
19
+ end
20
+
21
+ def call(action)
22
+ if respond_to?(action) && !send(action)
23
+ @_result = false
24
+ else
25
+ @_result = true
26
+ end
27
+ end
28
+
29
+ def allowed(action)
30
+ call(action)
31
+ end
32
+
33
+ def policy(item)
34
+ context = @context.dup
35
+ context.item = item
36
+ self.class.lookup(item).new(context)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IIPolicy
4
+ module Instrumentation
5
+ extend ActiveSupport::Concern
6
+
7
+ def call(action)
8
+ ActiveSupport::Notifications.instrument 'call.ii_policy', policy: self, action: action do
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IIPolicy
4
+ class LogSubscriber < ActiveSupport::LogSubscriber
5
+ def call(event)
6
+ debug do
7
+ policy = event.payload[:policy]
8
+ action = event.payload[:action]
9
+ item = " for #{policy.item.class}##{policy.item.id}" if policy.item
10
+ "Called #{policy.class}##{action}#{item} and return #{policy._result} (#{additional_log(event)})"
11
+ end
12
+ end
13
+
14
+ def additional_log(event)
15
+ additions = ["Duration: %.1fms" % event.duration]
16
+ additions << "Allocations: %d" % event.allocations if event.respond_to?(:allocations)
17
+ additions.join(', ')
18
+ end
19
+ end
20
+ end
@@ -11,14 +11,14 @@ module IIPolicy
11
11
  end
12
12
 
13
13
  class << self
14
- class_attribute :_cache
15
- self._cache = {}
14
+ class_attribute :cache
15
+ self.cache = {}
16
16
 
17
17
  def call(klass)
18
18
  klass = klass.class unless klass.is_a?(Module)
19
19
  return if terminate?(klass)
20
20
 
21
- cache(klass) do
21
+ with_cache(klass) do
22
22
  if klass.name && (policy = resolve(klass))
23
23
  policy
24
24
  elsif klass.superclass
@@ -29,9 +29,9 @@ module IIPolicy
29
29
 
30
30
  private
31
31
 
32
- def cache(klass)
32
+ def with_cache(klass)
33
33
  if Config.lookup_cache
34
- self._cache[klass] ||= yield
34
+ self.cache[klass] ||= yield
35
35
  else
36
36
  yield
37
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IIPolicy
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ii_policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshikazu Kaneta
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-06 00:00:00.000000000 Z
11
+ date: 2021-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -124,8 +124,11 @@ files:
124
124
  - lib/ii_policy/config.rb
125
125
  - lib/ii_policy/context.rb
126
126
  - lib/ii_policy/controller.rb
127
+ - lib/ii_policy/core.rb
127
128
  - lib/ii_policy/errors.rb
128
129
  - lib/ii_policy/helper.rb
130
+ - lib/ii_policy/instrumentation.rb
131
+ - lib/ii_policy/log_subscriber.rb
129
132
  - lib/ii_policy/lookup.rb
130
133
  - lib/ii_policy/railtie.rb
131
134
  - lib/ii_policy/version.rb