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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/.rbnext/3.0/action_policy/behaviours/policy_for.rb +1 -1
- data/lib/.rbnext/3.0/action_policy/policy/cache.rb +1 -1
- data/lib/.rbnext/3.0/action_policy/policy/pre_check.rb +3 -3
- data/lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb +4 -4
- data/lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb +4 -4
- data/lib/.rbnext/3.0/action_policy/utils/pretty_print.rb +2 -2
- data/lib/.rbnext/3.1/action_policy/behaviours/policy_for.rb +1 -1
- data/lib/.rbnext/3.2/action_policy/behaviours/policy_for.rb +1 -1
- data/lib/.rbnext/3.2/action_policy/rspec/be_authorized_to.rb +4 -4
- data/lib/.rbnext/3.2/action_policy/rspec/have_authorized_scope.rb +4 -4
- data/lib/.rbnext/3.4/action_policy/behaviours/policy_for.rb +1 -1
- data/lib/.rbnext/3.4/action_policy/i18n.rb +1 -1
- data/lib/.rbnext/3.4/action_policy/policy/cache.rb +1 -1
- data/lib/.rbnext/3.4/action_policy/policy/pre_check.rb +3 -3
- data/lib/.rbnext/3.4/action_policy/rspec/be_authorized_to.rb +4 -4
- data/lib/.rbnext/3.4/action_policy/rspec/have_authorized_scope.rb +4 -4
- data/lib/.rbnext/3.4/action_policy/utils/pretty_print.rb +2 -2
- data/lib/action_policy/behaviour.rb +1 -1
- data/lib/action_policy/rails/controller.rb +45 -4
- data/lib/action_policy/rails/policy/instrumentation.rb +1 -0
- data/lib/action_policy/rspec/be_authorized_to.rb +1 -1
- data/lib/action_policy/rspec/have_authorized_scope.rb +1 -1
- data/lib/action_policy/test_helper.rb +1 -1
- data/lib/action_policy/utils/pretty_print.rb +1 -1
- data/lib/action_policy/version.rb +1 -1
- data/lib/action_policy.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 322dfe78ddec91cb0d7c46b290f69484ba2fdf417c85c687d23e6b521db3e097
|
|
4
|
+
data.tar.gz: b263d5a7000f202b480331e4dd486726563ab83a4828bd57dbaa8c2e8a3b86a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"#{
|
|
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
|
-
|
|
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
|
|
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
|
-
"#{
|
|
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
|
-
|
|
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
|
-
"#{
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"#{
|
|
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
|
-
|
|
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
|
|
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
|
-
"#{
|
|
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
|
-
|
|
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
|
|
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
|
|
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}",
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"#{
|
|
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
|
-
|
|
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
|
|
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
|
-
"#{
|
|
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
|
-
|
|
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
|
-
"#{
|
|
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
|
|
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
|
-
|
|
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`
|
|
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
|
|
@@ -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
|
-
"#{
|
|
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
|
-
"#{
|
|
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
|
-
"#{
|
|
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
|
-
"#{
|
|
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
|
data/lib/action_policy.rb
CHANGED
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.
|
|
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:
|
|
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.
|
|
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: []
|