action_policy 0.5.7 → 0.6.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: 021e6da5ccd46f76732cb52c0c04ae1a45ce3a74a2b64643e179ee16c40417e3
4
- data.tar.gz: 96a978308fde0160f5b739d47abdd833005ba7109e97837ac0dd5721f1ec52a8
3
+ metadata.gz: 0fe2b2b40f6a3bd85c312495209382b1ee72950072257e676be008e2ef8d77c5
4
+ data.tar.gz: f0c9b0cb38bc130cdb8c7f3f4cfba3adcc326f25c6435fe75723e8c0d3ba3fe9
5
5
  SHA512:
6
- metadata.gz: 69953fedcbaa8d007c3c922e17dd26618eda2ed840d59bac476111f62bb7aae7c20f2920606925eb4b3acab7e90f994a6e1a9a55b7de0a0740f3747bb4e85aa3
7
- data.tar.gz: 23de3c82949db85f3a41f079187493087add27f88e0cd9315ccb492e925f4490390d5ae17fb493eb3ae290f5469f216ab258e21e7c155be9853de5728c8b3311
6
+ metadata.gz: f49f02d335942aa0a100e681f7570c1b6d042e68d1ed9d02012ec84b9f354b5c0a1d7a42ba15fbd3c84c84536e444af95057a09ef00cdc6ae3c2f5d0b24dd3a6
7
+ data.tar.gz: 2eced066c406feb11e8cdf99113fa8d27f8fe73ff015bcc1d2958c0a657540d195b25a8328dee02206b8539e55d16278f531dcde6b9567fef95ec1bead92cda0
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.6.0 (2021-09-02)
6
+
7
+ - Drop Ruby 2.5 support.
8
+ - [Closes [#186](https://github.com/palkan/action_policy/issues/186)] Add `inline_reasons: true` option to `allowed_to?` to avoid wrapping reasons. ([@palkan][])
9
+ - [Fixes [#173](https://github.com/palkan/action_policy/issues/173)] Explicit context were not merged with implicit one within policy classes. ([@palkan][])
10
+ - Add `strict_namespace:` option to policy_for behaviour ([@kevynlebouille][])
11
+ - Prevent possible side effects in policy lookup ([@tomdalling][])
12
+
5
13
  ## 0.5.7 (2021-03-03)
6
14
 
7
15
  The previous release had incorrect dependencies (due to the missing transpiled files).
@@ -449,3 +457,4 @@ This value is now stored in a cache (if any) instead of just the call result (`t
449
457
  [@Be-ngt-oH]: https://github.com/Be-ngt-oH
450
458
  [@pirj]: https://github.com/pirj
451
459
  [@skojin]: https://github.com/skojin
460
+ [@tomdalling]: https://github.com/tomdalling
@@ -8,16 +8,18 @@ module ActionPolicy
8
8
  using ActionPolicy::Ext::PolicyCacheKey
9
9
 
10
10
  # Returns policy instance for the record.
11
- def policy_for(record:, with: nil, namespace: authorization_namespace, context: authorization_context, allow_nil: false, default: default_authorization_policy_class)
11
+ def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
12
+ context = context ? authorization_context.merge(context) : authorization_context
13
+
12
14
  policy_class = with || ::ActionPolicy.lookup(
13
15
  record,
14
- namespace: namespace, context: context, allow_nil: allow_nil, default: default
16
+ namespace: namespace, context: context, allow_nil: allow_nil, default: default, strict_namespace: strict_namespace
15
17
  )
16
18
  policy_class&.new(record, **context)
17
19
  end
18
20
 
19
21
  def authorization_context
20
- raise NotImplementedError, "Please, define `authorization_context` method!"
22
+ Kernel.raise NotImplementedError, "Please, define `authorization_context` method!"
21
23
  end
22
24
 
23
25
  def authorization_namespace
@@ -28,6 +30,10 @@ module ActionPolicy
28
30
  # override to provide a policy class use when no policy found
29
31
  end
30
32
 
33
+ def authorization_strict_namespace
34
+ # override to provide strict namespace lookup option
35
+ end
36
+
31
37
  # Override this method to provide implicit authorization target
32
38
  # that would be used in case `record` is not specified in
33
39
  # `authorize!` and `allowed_to?` call.
@@ -39,7 +45,7 @@ module ActionPolicy
39
45
 
40
46
  # Return implicit authorization target or raises an exception if it's nil
41
47
  def implicit_authorization_target!
42
- implicit_authorization_target || raise(
48
+ implicit_authorization_target || Kernel.raise(
43
49
  NotFound,
44
50
  [
45
51
  self,
@@ -8,16 +8,18 @@ module ActionPolicy
8
8
  using ActionPolicy::Ext::PolicyCacheKey
9
9
 
10
10
  # Returns policy instance for the record.
11
- def policy_for(record:, with: nil, namespace: authorization_namespace, context: authorization_context, allow_nil: false, default: default_authorization_policy_class)
11
+ def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
12
+ context = context ? authorization_context.merge(context) : authorization_context
13
+
12
14
  policy_class = with || ::ActionPolicy.lookup(
13
15
  record,
14
- namespace: namespace, context: context, allow_nil: allow_nil, default: default
16
+ namespace: namespace, context: context, allow_nil: allow_nil, default: default, strict_namespace: strict_namespace
15
17
  )
16
18
  policy_class&.new(record, **context)
17
19
  end
18
20
 
19
21
  def authorization_context
20
- raise NotImplementedError, "Please, define `authorization_context` method!"
22
+ Kernel.raise NotImplementedError, "Please, define `authorization_context` method!"
21
23
  end
22
24
 
23
25
  def authorization_namespace
@@ -28,6 +30,10 @@ module ActionPolicy
28
30
  # override to provide a policy class use when no policy found
29
31
  end
30
32
 
33
+ def authorization_strict_namespace
34
+ # override to provide strict namespace lookup option
35
+ end
36
+
31
37
  # Override this method to provide implicit authorization target
32
38
  # that would be used in case `record` is not specified in
33
39
  # `authorize!` and `allowed_to?` call.
@@ -39,7 +45,7 @@ module ActionPolicy
39
45
 
40
46
  # Return implicit authorization target or raises an exception if it's nil
41
47
  def implicit_authorization_target!
42
- implicit_authorization_target || raise(
48
+ implicit_authorization_target || Kernel.raise(
43
49
  NotFound,
44
50
  [
45
51
  self,
@@ -133,7 +133,7 @@ module ActionPolicy
133
133
  end
134
134
 
135
135
  # An alias for readability purposes
136
- def check?(*args) ; allowed_to?(*args); end
136
+ def check?(*args, **hargs) ; allowed_to?(*args, **hargs); end
137
137
 
138
138
  # Returns a rule name (policy method name) for activity.
139
139
  #
@@ -31,6 +31,20 @@ module ActionPolicy
31
31
 
32
32
  def present?() ; !empty?; end
33
33
 
34
+ def merge(other)
35
+ other.reasons.each do |policy_class, rules|
36
+ reasons[policy_class] ||= []
37
+
38
+ rules.each do |rule|
39
+ if rule.is_a?(::Hash)
40
+ add_detailed_reason(reasons[policy_class], rule)
41
+ else
42
+ add_non_detailed_reason(reasons[policy_class], rule)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
34
48
  private
35
49
 
36
50
  def add_non_detailed_reason(store, rule)
@@ -182,7 +196,7 @@ module ActionPolicy
182
196
  result.details ||= {}
183
197
  end
184
198
 
185
- def allowed_to?(rule, record = :__undef__, **options)
199
+ def allowed_to?(rule, record = :__undef__, inline_reasons: false, **options)
186
200
  res =
187
201
  if (record == :__undef__ || record == self.record) && options.empty?
188
202
  rule = resolve_rule(rule)
@@ -196,7 +210,9 @@ module ActionPolicy
196
210
  policy.result
197
211
  end
198
212
 
199
- result&.reasons&.add(policy, rule, res.details) if res.fail?
213
+ if res.fail? && result&.reasons
214
+ inline_reasons ? result.reasons.merge(res.reasons) : result.reasons.add(policy, rule, res.details)
215
+ end
200
216
 
201
217
  res.clear_details
202
218
 
@@ -74,10 +74,8 @@ module ActionPolicy
74
74
  end
75
75
 
76
76
  def lookup_authorization_policy(record, **options) # :nodoc:
77
- record = implicit_authorization_target! if record == :__undef__
78
- raise ArgumentError, "Record must be specified" if record.nil?
79
-
80
- options[:context] && (options[:context] = authorization_context.merge(options[:context]))
77
+ record = implicit_authorization_target! if :__undef__ == record # rubocop:disable Style/YodaCondition See https://github.com/palkan/action_policy/pull/180
78
+ Kernel.raise ArgumentError, "Record must be specified" if record.nil?
81
79
 
82
80
  policy_for(record: record, **options)
83
81
  end
@@ -8,16 +8,18 @@ module ActionPolicy
8
8
  using ActionPolicy::Ext::PolicyCacheKey
9
9
 
10
10
  # Returns policy instance for the record.
11
- def policy_for(record:, with: nil, namespace: authorization_namespace, context: authorization_context, allow_nil: false, default: default_authorization_policy_class)
11
+ def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
12
+ context = context ? authorization_context.merge(context) : authorization_context
13
+
12
14
  policy_class = with || ::ActionPolicy.lookup(
13
15
  record,
14
- namespace:, context:, allow_nil:, default:
16
+ namespace:, context:, allow_nil:, default:, strict_namespace:
15
17
  )
16
18
  policy_class&.new(record, **context)
17
19
  end
18
20
 
19
21
  def authorization_context
20
- raise NotImplementedError, "Please, define `authorization_context` method!"
22
+ Kernel.raise NotImplementedError, "Please, define `authorization_context` method!"
21
23
  end
22
24
 
23
25
  def authorization_namespace
@@ -28,6 +30,10 @@ module ActionPolicy
28
30
  # override to provide a policy class use when no policy found
29
31
  end
30
32
 
33
+ def authorization_strict_namespace
34
+ # override to provide strict namespace lookup option
35
+ end
36
+
31
37
  # Override this method to provide implicit authorization target
32
38
  # that would be used in case `record` is not specified in
33
39
  # `authorize!` and `allowed_to?` call.
@@ -39,7 +45,7 @@ module ActionPolicy
39
45
 
40
46
  # Return implicit authorization target or raises an exception if it's nil
41
47
  def implicit_authorization_target!
42
- implicit_authorization_target || raise(
48
+ implicit_authorization_target || Kernel.raise(
43
49
  NotFound,
44
50
  [
45
51
  self,
@@ -133,7 +133,7 @@ module ActionPolicy
133
133
  end
134
134
 
135
135
  # An alias for readability purposes
136
- def check?(*args) = allowed_to?(*args)
136
+ def check?(*args, **hargs) = allowed_to?(*args, **hargs)
137
137
 
138
138
  # Returns a rule name (policy method name) for activity.
139
139
  #
@@ -31,6 +31,20 @@ module ActionPolicy
31
31
 
32
32
  def present?() = !empty?
33
33
 
34
+ def merge(other)
35
+ other.reasons.each do |policy_class, rules|
36
+ reasons[policy_class] ||= []
37
+
38
+ rules.each do |rule|
39
+ if rule.is_a?(::Hash)
40
+ add_detailed_reason(reasons[policy_class], rule)
41
+ else
42
+ add_non_detailed_reason(reasons[policy_class], rule)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
34
48
  private
35
49
 
36
50
  def add_non_detailed_reason(store, rule)
@@ -182,7 +196,7 @@ module ActionPolicy
182
196
  result.details ||= {}
183
197
  end
184
198
 
185
- def allowed_to?(rule, record = :__undef__, **options)
199
+ def allowed_to?(rule, record = :__undef__, inline_reasons: false, **options)
186
200
  res =
187
201
  if (record == :__undef__ || record == self.record) && options.empty?
188
202
  rule = resolve_rule(rule)
@@ -196,7 +210,9 @@ module ActionPolicy
196
210
  policy.result
197
211
  end
198
212
 
199
- result&.reasons&.add(policy, rule, res.details) if res.fail?
213
+ if res.fail? && result&.reasons
214
+ inline_reasons ? result.reasons.merge(res.reasons) : result.reasons.add(policy, rule, res.details)
215
+ end
200
216
 
201
217
  res.clear_details
202
218
 
@@ -57,7 +57,7 @@ module ActionPolicy
57
57
  end
58
58
 
59
59
  def verify_authorized
60
- raise UnauthorizedAction.new(controller_path, action_name) if
60
+ Kernel.raise UnauthorizedAction.new(controller_path, action_name) if
61
61
  authorize_count.zero? && !verify_authorized_skipped
62
62
  end
63
63
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.5.7"
4
+ VERSION = "0.6.0"
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.5.7
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-04 00:00:00.000000000 Z
11
+ date: 2021-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
@@ -222,7 +222,7 @@ metadata:
222
222
  documentation_uri: https://actionpolicy.evilmartians.io/
223
223
  homepage_uri: https://actionpolicy.evilmartians.io/
224
224
  source_code_uri: http://github.com/palkan/action_policy
225
- post_install_message:
225
+ post_install_message:
226
226
  rdoc_options: []
227
227
  require_paths:
228
228
  - lib
@@ -230,15 +230,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
230
  requirements:
231
231
  - - ">="
232
232
  - !ruby/object:Gem::Version
233
- version: 2.5.0
233
+ version: 2.6.0
234
234
  required_rubygems_version: !ruby/object:Gem::Requirement
235
235
  requirements:
236
236
  - - ">="
237
237
  - !ruby/object:Gem::Version
238
238
  version: '0'
239
239
  requirements: []
240
- rubygems_version: 3.0.6
241
- signing_key:
240
+ rubygems_version: 3.2.15
241
+ signing_key:
242
242
  specification_version: 4
243
243
  summary: Authorization framework for Ruby/Rails application
244
244
  test_files: []