action_policy 0.7.5 → 0.7.6

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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/lib/.rbnext/3.0/action_policy/behaviours/policy_for.rb +1 -1
  4. data/lib/.rbnext/3.0/action_policy/policy/cache.rb +1 -1
  5. data/lib/.rbnext/3.0/action_policy/policy/pre_check.rb +3 -3
  6. data/lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb +4 -4
  7. data/lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb +4 -4
  8. data/lib/.rbnext/3.0/action_policy/utils/pretty_print.rb +2 -2
  9. data/lib/.rbnext/3.1/action_policy/behaviours/policy_for.rb +1 -1
  10. data/lib/.rbnext/3.2/action_policy/behaviours/policy_for.rb +1 -1
  11. data/lib/.rbnext/3.2/action_policy/rspec/be_authorized_to.rb +4 -4
  12. data/lib/.rbnext/3.2/action_policy/rspec/have_authorized_scope.rb +4 -4
  13. data/lib/.rbnext/3.4/action_policy/behaviours/policy_for.rb +1 -1
  14. data/lib/.rbnext/3.4/action_policy/i18n.rb +1 -1
  15. data/lib/.rbnext/3.4/action_policy/policy/cache.rb +1 -1
  16. data/lib/.rbnext/3.4/action_policy/policy/pre_check.rb +3 -3
  17. data/lib/.rbnext/3.4/action_policy/rspec/be_authorized_to.rb +4 -4
  18. data/lib/.rbnext/3.4/action_policy/rspec/have_authorized_scope.rb +4 -4
  19. data/lib/.rbnext/3.4/action_policy/utils/pretty_print.rb +2 -2
  20. data/lib/action_policy/behaviour.rb +1 -1
  21. data/lib/action_policy/rails/controller.rb +45 -4
  22. data/lib/action_policy/rails/policy/instrumentation.rb +1 -0
  23. data/lib/action_policy/rspec/be_authorized_to.rb +1 -1
  24. data/lib/action_policy/rspec/have_authorized_scope.rb +1 -1
  25. data/lib/action_policy/test_helper.rb +1 -1
  26. data/lib/action_policy/utils/pretty_print.rb +1 -1
  27. data/lib/action_policy/version.rb +1 -1
  28. data/lib/action_policy.rb +1 -1
  29. metadata +3 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3680162e91000d7fb369fcfa17710f557c9a12435c5bf00c6fb367a5045b970
4
- data.tar.gz: 000760f640032e5a0b44e9ea7918908a32c2568cefeffc747fa4ea45c46949bf
3
+ metadata.gz: 322dfe78ddec91cb0d7c46b290f69484ba2fdf417c85c687d23e6b521db3e097
4
+ data.tar.gz: b263d5a7000f202b480331e4dd486726563ab83a4828bd57dbaa8c2e8a3b86a3
5
5
  SHA512:
6
- metadata.gz: f03892d33e150921d3ec4bdfe1038b017301825474597037585c45e0f780affdfd72ed5171c577cee007af69a8542d4172cb8266526a97895b9c3461b4b2abb3
7
- data.tar.gz: e5d9a4259d5dcd8cac8a0cab28b6d85f3aedc46050c51057aa9d458b4c0b8597428bed1a6c57473f3836500b1696cfb1f4a4c1aeac868c2771bb443dc59f10fa
6
+ metadata.gz: 93628bb047eb417395cc9b7f0b15f2f97882d327c32212105d186ef42187fc24e84abd37bdf40968ae5a5988d318d717f0fb3af454f5fb14059a3dc84fe98c08
7
+ data.tar.gz: 9d0387f6aea496ac9d3affdb6cfe89b9fef008d9ff2f96a97a69ce19c0832f8fe01d2023f4497a150325e00e341d6a170b8218e3ce47e06a96d8de28aea38cb5
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.7.6 (2025-01-13)
6
+
7
+ - Execute proc passed to the `:through` option of `authorize` against `self` ([@Pagehey][])
8
+
9
+ - Add authorization result to the instrumentation payload (as `event[:result]`). ([@palkan][])
10
+
5
11
  ## 0.7.5 (2025-05-09) 🎇
6
12
 
7
13
  - Ensure `result.value` is true or false. ([@palkan][])
@@ -553,3 +559,4 @@ This value is now stored in a cache (if any) instead of just the call result (`t
553
559
  [@Spone]: https://github.com/Spone
554
560
  [@stephannv]: https://github.com/stephannv
555
561
  [@sedubois]: https://github.com/sedubois
562
+ [@Pagehey]: https://github.com/Pagehey
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **__kwrest__)
63
63
  record_key = record._policy_cache_key(use_object_id: true)
64
- context_key = context.values.map { it = _1;it._policy_cache_key(use_object_id: true) }.join(".")
64
+ context_key = context.values.map { |it| it._policy_cache_key(use_object_id: true) }.join(".")
65
65
 
66
66
  "#{namespace}/#{with}/#{context_key}/#{record_key}"
67
67
  end
@@ -29,7 +29,7 @@ module ActionPolicy # :nodoc:
29
29
  [
30
30
  cache_namespace,
31
31
  *parts
32
- ].map { it = _1;it._policy_cache_key }.join("/")
32
+ ].map { |it| it._policy_cache_key }.join("/")
33
33
  end
34
34
 
35
35
  def rule_cache_key(rule)
@@ -125,7 +125,7 @@ module ActionPolicy
125
125
  def pre_check(*names, **options)
126
126
  names.each do |name|
127
127
  # do not allow pre-check override
128
- check = pre_checks.find { it = _1;it.name == name }
128
+ check = pre_checks.find { |it| it.name == name }
129
129
  raise "Pre-check already defined: #{name}" unless check.nil?
130
130
 
131
131
  pre_checks << Check.new(self, name, **options)
@@ -134,14 +134,14 @@ module ActionPolicy
134
134
 
135
135
  def skip_pre_check(*names, **options)
136
136
  names.each do |name|
137
- check = pre_checks.find { it = _1;it.name == name }
137
+ check = pre_checks.find { |it| it.name == name }
138
138
  raise "Pre-check not found: #{name}" if check.nil?
139
139
 
140
140
  # when no options provided we remove this check completely
141
141
  next pre_checks.delete(check) if options.empty?
142
142
 
143
143
  # otherwise duplicate and apply skip options
144
- pre_checks[pre_checks.index(check)] = check.dup.tap { it = _1;it.skip!(**options) }
144
+ pre_checks[pre_checks.index(check)] = check.dup.tap { |it| it.skip!(**options) }
145
145
  end
146
146
  end
147
147
 
@@ -51,7 +51,7 @@ module ActionPolicy
51
51
 
52
52
  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
53
53
 
54
- actual_calls.any? { it = _1;it.matches?(policy, rule, target, context) }
54
+ actual_calls.any? { |it| it.matches?(policy, rule, target, context) }
55
55
  end
56
56
 
57
57
  def does_not_match?(*__rest__)
@@ -63,7 +63,7 @@ module ActionPolicy
63
63
  def failure_message
64
64
  "expected #{formatted_record} " \
65
65
  "to be authorized with #{policy}##{rule}, " \
66
- "#{context ? "and context #{context.inspect}, " : ""}" \
66
+ "#{"and context #{context.inspect}, " if context}" \
67
67
  "but #{actual_calls_message}"
68
68
  end
69
69
 
@@ -77,8 +77,8 @@ module ActionPolicy
77
77
  end
78
78
 
79
79
  def formatted_calls
80
- actual_calls.map do
81
- it = _1;" - #{it.inspect}"
80
+ actual_calls.map do |it|
81
+ " - #{it.inspect}"
82
82
  end.join("\n")
83
83
  end
84
84
 
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
63
63
 
64
- matching_scopes = actual_scopes.select { it = _1;it.matches?(policy, type, name, scope_options, context) }
64
+ matching_scopes = actual_scopes.select { |it| it.matches?(policy, type, name, scope_options, context) }
65
65
 
66
66
  return false if matching_scopes.empty?
67
67
 
@@ -85,7 +85,7 @@ module ActionPolicy
85
85
  def failure_message
86
86
  "expected a scoping named :#{name} for type :#{type} " \
87
87
  "#{scope_options_message} " \
88
- "#{context ? "and context #{context.inspect} " : ""}" \
88
+ "#{"and context #{context.inspect} " if context}" \
89
89
  "from #{policy} to have been applied, " \
90
90
  "but #{actual_scopes_message}"
91
91
  end
@@ -113,8 +113,8 @@ module ActionPolicy
113
113
  end
114
114
 
115
115
  def formatted_scopings
116
- actual_scopes.map do
117
- it = _1;" - #{it.inspect}"
116
+ actual_scopes.map do |it|
117
+ " - #{it.inspect}"
118
118
  end.join("\n")
119
119
  end
120
120
  end
@@ -111,7 +111,7 @@ module ActionPolicy
111
111
  end
112
112
 
113
113
  def indented(str)
114
- "#{indent.zero? ? "↳ " : ""}#{" " * indent}#{str}".tap do
114
+ "#{"↳ " if indent.zero?}#{" " * indent}#{str}".tap do
115
115
  # increase indent after the first expression
116
116
  self.indent += 2 if indent.zero?
117
117
  end
@@ -119,7 +119,7 @@ module ActionPolicy
119
119
 
120
120
  # Some lines should not be evaled
121
121
  def ignore_exp?(exp)
122
- PrettyPrint.ignore_expressions.any? { it = _1;exp.match?(it) }
122
+ PrettyPrint.ignore_expressions.any? { |it| exp.match?(it) }
123
123
  end
124
124
  end
125
125
 
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **__kwrest__)
63
63
  record_key = record._policy_cache_key(use_object_id: true)
64
- context_key = context.values.map { it = _1;it._policy_cache_key(use_object_id: true) }.join(".")
64
+ context_key = context.values.map { |it| it._policy_cache_key(use_object_id: true) }.join(".")
65
65
 
66
66
  "#{namespace}/#{with}/#{context_key}/#{record_key}"
67
67
  end
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **__kwrest__)
63
63
  record_key = record._policy_cache_key(use_object_id: true)
64
- context_key = context.values.map { it = _1;it._policy_cache_key(use_object_id: true) }.join(".")
64
+ context_key = context.values.map { |it| it._policy_cache_key(use_object_id: true) }.join(".")
65
65
 
66
66
  "#{namespace}/#{with}/#{context_key}/#{record_key}"
67
67
  end
@@ -51,7 +51,7 @@ module ActionPolicy
51
51
 
52
52
  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
53
53
 
54
- actual_calls.any? { it = _1;it.matches?(policy, rule, target, context) }
54
+ actual_calls.any? { |it| it.matches?(policy, rule, target, context) }
55
55
  end
56
56
 
57
57
  def does_not_match?(*__rest__)
@@ -63,7 +63,7 @@ module ActionPolicy
63
63
  def failure_message
64
64
  "expected #{formatted_record} " \
65
65
  "to be authorized with #{policy}##{rule}, " \
66
- "#{context ? "and context #{context.inspect}, " : ""}" \
66
+ "#{"and context #{context.inspect}, " if context}" \
67
67
  "but #{actual_calls_message}"
68
68
  end
69
69
 
@@ -77,8 +77,8 @@ module ActionPolicy
77
77
  end
78
78
 
79
79
  def formatted_calls
80
- actual_calls.map do
81
- it = _1;" - #{it.inspect}"
80
+ actual_calls.map do |it|
81
+ " - #{it.inspect}"
82
82
  end.join("\n")
83
83
  end
84
84
 
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
63
63
 
64
- matching_scopes = actual_scopes.select { it = _1;it.matches?(policy, type, name, scope_options, context) }
64
+ matching_scopes = actual_scopes.select { |it| it.matches?(policy, type, name, scope_options, context) }
65
65
 
66
66
  return false if matching_scopes.empty?
67
67
 
@@ -85,7 +85,7 @@ module ActionPolicy
85
85
  def failure_message
86
86
  "expected a scoping named :#{name} for type :#{type} " \
87
87
  "#{scope_options_message} " \
88
- "#{context ? "and context #{context.inspect} " : ""}" \
88
+ "#{"and context #{context.inspect} " if context}" \
89
89
  "from #{policy} to have been applied, " \
90
90
  "but #{actual_scopes_message}"
91
91
  end
@@ -113,8 +113,8 @@ module ActionPolicy
113
113
  end
114
114
 
115
115
  def formatted_scopings
116
- actual_scopes.map do
117
- it = _1;" - #{it.inspect}"
116
+ actual_scopes.map do |it|
117
+ " - #{it.inspect}"
118
118
  end.join("\n")
119
119
  end
120
120
  end
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **)
63
63
  record_key = record._policy_cache_key(use_object_id: true)
64
- context_key = context.values.map { it = _1;it._policy_cache_key(use_object_id: true) }.join(".")
64
+ context_key = context.values.map { |it| it._policy_cache_key(use_object_id: true) }.join(".")
65
65
 
66
66
  "#{namespace}/#{with}/#{context_key}/#{record_key}"
67
67
  end
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  private
22
22
 
23
23
  def candidates_for(policy_class, rule)
24
- policy_hierarchy = policy_class.ancestors.select { it = _1;it.respond_to?(:identifier) }
24
+ policy_hierarchy = policy_class.ancestors.select { |it| it.respond_to?(:identifier) }
25
25
  [
26
26
  *policy_hierarchy.map { |klass| :"policy.#{klass.identifier}.#{rule}" },
27
27
  :"policy.#{rule}",
@@ -29,7 +29,7 @@ module ActionPolicy # :nodoc:
29
29
  [
30
30
  cache_namespace,
31
31
  *parts
32
- ].map { it = _1;it._policy_cache_key }.join("/")
32
+ ].map { |it| it._policy_cache_key }.join("/")
33
33
  end
34
34
 
35
35
  def rule_cache_key(rule)
@@ -125,7 +125,7 @@ module ActionPolicy
125
125
  def pre_check(*names, **options)
126
126
  names.each do |name|
127
127
  # do not allow pre-check override
128
- check = pre_checks.find { it = _1;it.name == name }
128
+ check = pre_checks.find { |it| it.name == name }
129
129
  raise "Pre-check already defined: #{name}" unless check.nil?
130
130
 
131
131
  pre_checks << Check.new(self, name, **options)
@@ -134,14 +134,14 @@ module ActionPolicy
134
134
 
135
135
  def skip_pre_check(*names, **options)
136
136
  names.each do |name|
137
- check = pre_checks.find { it = _1;it.name == name }
137
+ check = pre_checks.find { |it| it.name == name }
138
138
  raise "Pre-check not found: #{name}" if check.nil?
139
139
 
140
140
  # when no options provided we remove this check completely
141
141
  next pre_checks.delete(check) if options.empty?
142
142
 
143
143
  # otherwise duplicate and apply skip options
144
- pre_checks[pre_checks.index(check)] = check.dup.tap { it = _1;it.skip!(**options) }
144
+ pre_checks[pre_checks.index(check)] = check.dup.tap { |it| it.skip!(**options) }
145
145
  end
146
146
  end
147
147
 
@@ -51,7 +51,7 @@ module ActionPolicy
51
51
 
52
52
  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
53
53
 
54
- actual_calls.any? { it = _1;it.matches?(policy, rule, target, context) }
54
+ actual_calls.any? { |it| it.matches?(policy, rule, target, context) }
55
55
  end
56
56
 
57
57
  def does_not_match?(*)
@@ -63,7 +63,7 @@ module ActionPolicy
63
63
  def failure_message
64
64
  "expected #{formatted_record} " \
65
65
  "to be authorized with #{policy}##{rule}, " \
66
- "#{context ? "and context #{context.inspect}, " : ""}" \
66
+ "#{"and context #{context.inspect}, " if context}" \
67
67
  "but #{actual_calls_message}"
68
68
  end
69
69
 
@@ -77,8 +77,8 @@ module ActionPolicy
77
77
  end
78
78
 
79
79
  def formatted_calls
80
- actual_calls.map do
81
- it = _1;" - #{it.inspect}"
80
+ actual_calls.map do |it|
81
+ " - #{it.inspect}"
82
82
  end.join("\n")
83
83
  end
84
84
 
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
 
62
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
63
63
 
64
- matching_scopes = actual_scopes.select { it = _1;it.matches?(policy, type, name, scope_options, context) }
64
+ matching_scopes = actual_scopes.select { |it| it.matches?(policy, type, name, scope_options, context) }
65
65
 
66
66
  return false if matching_scopes.empty?
67
67
 
@@ -85,7 +85,7 @@ module ActionPolicy
85
85
  def failure_message
86
86
  "expected a scoping named :#{name} for type :#{type} " \
87
87
  "#{scope_options_message} " \
88
- "#{context ? "and context #{context.inspect} " : ""}" \
88
+ "#{"and context #{context.inspect} " if context}" \
89
89
  "from #{policy} to have been applied, " \
90
90
  "but #{actual_scopes_message}"
91
91
  end
@@ -113,8 +113,8 @@ module ActionPolicy
113
113
  end
114
114
 
115
115
  def formatted_scopings
116
- actual_scopes.map do
117
- it = _1;" - #{it.inspect}"
116
+ actual_scopes.map do |it|
117
+ " - #{it.inspect}"
118
118
  end.join("\n")
119
119
  end
120
120
  end
@@ -111,7 +111,7 @@ module ActionPolicy
111
111
  end
112
112
 
113
113
  def indented(str)
114
- "#{indent.zero? ? "↳ " : ""}#{" " * indent}#{str}".tap do
114
+ "#{"↳ " if indent.zero?}#{" " * indent}#{str}".tap do
115
115
  # increase indent after the first expression
116
116
  self.indent += 2 if indent.zero?
117
117
  end
@@ -119,7 +119,7 @@ module ActionPolicy
119
119
 
120
120
  # Some lines should not be evaled
121
121
  def ignore_exp?(exp)
122
- PrettyPrint.ignore_expressions.any? { it = _1;exp.match?(it) }
122
+ PrettyPrint.ignore_expressions.any? { |it| exp.match?(it) }
123
123
  end
124
124
  end
125
125
 
@@ -65,7 +65,7 @@ module ActionPolicy
65
65
  private def build_authorization_context
66
66
  self.class.authorization_targets
67
67
  .each_with_object({}) do |(key, method_or_proc), obj|
68
- obj[key] = method_or_proc.is_a?(Proc) ? method_or_proc.call : send(method_or_proc)
68
+ obj[key] = method_or_proc.is_a?(Proc) ? instance_exec(&method_or_proc) : send(method_or_proc)
69
69
  end
70
70
  end
71
71
 
@@ -11,9 +11,16 @@ module ActionPolicy
11
11
  end
12
12
  end
13
13
 
14
+ # Raised when `authorized_scope` hasn't been called for action
15
+ class UnscopedAction < Error
16
+ def initialize(controller, action)
17
+ super("Action '#{controller}##{action}' hasn't been scoped")
18
+ end
19
+ end
20
+
14
21
  # Controller concern.
15
22
  # Add `authorize!` and `allowed_to?` methods,
16
- # provide `verify_authorized` hook.
23
+ # provide `verify_authorized` and `verify_authorized_scoped` hooks.
17
24
  module Controller
18
25
  extend ActiveSupport::Concern
19
26
 
@@ -29,10 +36,10 @@ module ActionPolicy
29
36
  helper_method :allowance_to
30
37
  end
31
38
 
32
- attr_writer :authorize_count
33
- attr_reader :verify_authorized_skipped
39
+ attr_writer :authorize_count, :scoped_count
40
+ attr_reader :verify_authorized_skipped, :verify_authorized_scoped_skipped
34
41
 
35
- protected :authorize_count=, :authorize_count
42
+ protected :authorize_count=, :authorize_count, :scoped_count=, :scoped_count
36
43
  end
37
44
 
38
45
  # Authorize action against a policy.
@@ -56,6 +63,16 @@ module ActionPolicy
56
63
  policy_record
57
64
  end
58
65
 
66
+ # Apply scope to the target.
67
+ #
68
+ # @return the scoped target
69
+ def authorized_scope(target, **options)
70
+ scoped = super
71
+
72
+ self.scoped_count += 1
73
+ scoped
74
+ end
75
+
59
76
  # Tries to infer the resource class from controller name
60
77
  # (i.e. `controller_name.classify.safe_constantize`).
61
78
  def implicit_authorization_target
@@ -67,14 +84,27 @@ module ActionPolicy
67
84
  authorize_count.zero? && !verify_authorized_skipped
68
85
  end
69
86
 
87
+ def verify_authorized_scoped
88
+ Kernel.raise UnscopedAction.new(controller_path, action_name) if
89
+ scoped_count.zero? && !verify_authorized_scoped_skipped
90
+ end
91
+
70
92
  def authorize_count
71
93
  @authorize_count ||= 0
72
94
  end
73
95
 
96
+ def scoped_count
97
+ @scoped_count ||= 0
98
+ end
99
+
74
100
  def skip_verify_authorized!
75
101
  @verify_authorized_skipped = true
76
102
  end
77
103
 
104
+ def skip_verify_authorized_scoped!
105
+ @verify_authorized_scoped_skipped = true
106
+ end
107
+
78
108
  class_methods do
79
109
  # Adds after_action callback to check that
80
110
  # authorize! method has been called.
@@ -86,6 +116,17 @@ module ActionPolicy
86
116
  def skip_verify_authorized(**options)
87
117
  skip_after_action :verify_authorized, options
88
118
  end
119
+
120
+ # Adds after_action callback to check that
121
+ # authorized_scope method has been called.
122
+ def verify_authorized_scoped(**options)
123
+ after_action :verify_authorized_scoped, options
124
+ end
125
+
126
+ # Skips verify_authorized_scoped after_action callback.
127
+ def skip_verify_authorized_scoped(**options)
128
+ skip_after_action :verify_authorized_scoped, options
129
+ end
89
130
  end
90
131
  end
91
132
  end
@@ -22,6 +22,7 @@ module ActionPolicy # :nodoc:
22
22
  result = super
23
23
  event[:cached] = result.cached?
24
24
  event[:value] = result.value
25
+ event[:result] = result
25
26
  result
26
27
  end
27
28
  end
@@ -63,7 +63,7 @@ module ActionPolicy
63
63
  def failure_message
64
64
  "expected #{formatted_record} " \
65
65
  "to be authorized with #{policy}##{rule}, " \
66
- "#{context ? "and context #{context.inspect}, " : ""}" \
66
+ "#{"and context #{context.inspect}, " if context}" \
67
67
  "but #{actual_calls_message}"
68
68
  end
69
69
 
@@ -85,7 +85,7 @@ module ActionPolicy
85
85
  def failure_message
86
86
  "expected a scoping named :#{name} for type :#{type} " \
87
87
  "#{scope_options_message} " \
88
- "#{context ? "and context #{context.inspect} " : ""}" \
88
+ "#{"and context #{context.inspect} " if context}" \
89
89
  "from #{policy} to have been applied, " \
90
90
  "but #{actual_scopes_message}"
91
91
  end
@@ -52,7 +52,7 @@ module ActionPolicy
52
52
  assert(
53
53
  actual_calls.any? { |call| call.matches?(policy, rule, target, context) },
54
54
  "Expected #{target.inspect} to be authorized with #{policy}##{rule}, " \
55
- "#{context ? "and context #{context}, " : ""}" \
55
+ "#{"and context #{context}, " if context}" \
56
56
  "but no such authorization has been made.\n" \
57
57
  "Registered authorizations: " \
58
58
  "#{actual_calls.empty? ? "none" : actual_calls.map(&:inspect).join(",")}"
@@ -111,7 +111,7 @@ module ActionPolicy
111
111
  end
112
112
 
113
113
  def indented(str)
114
- "#{indent.zero? ? "↳ " : ""}#{" " * indent}#{str}".tap do
114
+ "#{"↳ " if indent.zero?}#{" " * indent}#{str}".tap do
115
115
  # increase indent after the first expression
116
116
  self.indent += 2 if indent.zero?
117
117
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.7.5"
4
+ VERSION = "0.7.6"
5
5
  end
data/lib/action_policy.rb CHANGED
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  @message =
22
22
  message ||
23
23
  "Couldn't find policy class for #{target.inspect}" \
24
- "#{target.is_a?(Module) ? "" : " (#{target.class})"}"
24
+ "#{" (#{target.class})" unless target.is_a?(Module)}"
25
25
  end
26
26
  end
27
27
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-05-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: ruby-next-core
@@ -235,7 +234,6 @@ metadata:
235
234
  documentation_uri: https://actionpolicy.evilmartians.io/
236
235
  homepage_uri: https://actionpolicy.evilmartians.io/
237
236
  source_code_uri: http://github.com/palkan/action_policy
238
- post_install_message:
239
237
  rdoc_options: []
240
238
  require_paths:
241
239
  - lib
@@ -250,8 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
248
  - !ruby/object:Gem::Version
251
249
  version: '0'
252
250
  requirements: []
253
- rubygems_version: 3.4.19
254
- signing_key:
251
+ rubygems_version: 3.6.9
255
252
  specification_version: 4
256
253
  summary: Authorization framework for Ruby/Rails application
257
254
  test_files: []