action_policy 0.4.4 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +203 -174
- data/README.md +5 -4
- data/lib/.rbnext/2.7/action_policy/behaviours/policy_for.rb +62 -0
- data/lib/.rbnext/2.7/action_policy/i18n.rb +56 -0
- data/lib/.rbnext/2.7/action_policy/policy/cache.rb +101 -0
- data/lib/.rbnext/2.7/action_policy/policy/pre_check.rb +162 -0
- data/lib/.rbnext/2.7/action_policy/rspec/be_authorized_to.rb +89 -0
- data/lib/.rbnext/2.7/action_policy/rspec/have_authorized_scope.rb +124 -0
- data/lib/.rbnext/2.7/action_policy/utils/pretty_print.rb +159 -0
- data/lib/.rbnext/3.0/action_policy/behaviour.rb +115 -0
- data/lib/.rbnext/3.0/action_policy/behaviours/policy_for.rb +62 -0
- data/lib/.rbnext/3.0/action_policy/behaviours/scoping.rb +35 -0
- data/lib/.rbnext/3.0/action_policy/behaviours/thread_memoized.rb +59 -0
- data/lib/.rbnext/3.0/action_policy/ext/policy_cache_key.rb +72 -0
- data/lib/.rbnext/3.0/action_policy/policy/aliases.rb +69 -0
- data/lib/.rbnext/3.0/action_policy/policy/authorization.rb +87 -0
- data/lib/.rbnext/3.0/action_policy/policy/cache.rb +101 -0
- data/lib/.rbnext/3.0/action_policy/policy/core.rb +161 -0
- data/lib/.rbnext/3.0/action_policy/policy/defaults.rb +31 -0
- data/lib/.rbnext/3.0/action_policy/policy/execution_result.rb +37 -0
- data/lib/.rbnext/3.0/action_policy/policy/pre_check.rb +162 -0
- data/lib/.rbnext/3.0/action_policy/policy/reasons.rb +212 -0
- data/lib/.rbnext/3.0/action_policy/policy/scoping.rb +160 -0
- data/lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb +89 -0
- data/lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb +124 -0
- data/lib/.rbnext/3.0/action_policy/utils/pretty_print.rb +159 -0
- data/lib/.rbnext/3.0/action_policy/utils/suggest_message.rb +19 -0
- data/lib/action_policy.rb +7 -1
- data/lib/action_policy/behaviour.rb +22 -16
- data/lib/action_policy/behaviours/policy_for.rb +10 -3
- data/lib/action_policy/behaviours/scoping.rb +2 -1
- data/lib/action_policy/behaviours/thread_memoized.rb +1 -3
- data/lib/action_policy/ext/module_namespace.rb +1 -6
- data/lib/action_policy/ext/policy_cache_key.rb +10 -30
- data/lib/action_policy/i18n.rb +1 -1
- data/lib/action_policy/lookup_chain.rb +29 -15
- data/lib/action_policy/policy/aliases.rb +7 -12
- data/lib/action_policy/policy/authorization.rb +8 -7
- data/lib/action_policy/policy/cache.rb +11 -17
- data/lib/action_policy/policy/core.rb +25 -12
- data/lib/action_policy/policy/defaults.rb +3 -9
- data/lib/action_policy/policy/execution_result.rb +3 -9
- data/lib/action_policy/policy/pre_check.rb +19 -58
- data/lib/action_policy/policy/reasons.rb +31 -19
- data/lib/action_policy/policy/scoping.rb +5 -6
- data/lib/action_policy/rails/controller.rb +6 -1
- data/lib/action_policy/rails/policy/instrumentation.rb +1 -1
- data/lib/action_policy/rspec/be_authorized_to.rb +5 -9
- data/lib/action_policy/rspec/dsl.rb +1 -1
- data/lib/action_policy/rspec/have_authorized_scope.rb +5 -7
- data/lib/action_policy/utils/pretty_print.rb +21 -24
- data/lib/action_policy/utils/suggest_message.rb +1 -3
- data/lib/action_policy/version.rb +1 -1
- data/lib/generators/action_policy/install/templates/{application_policy.rb → application_policy.rb.tt} +0 -0
- data/lib/generators/action_policy/policy/policy_generator.rb +4 -1
- data/lib/generators/action_policy/policy/templates/{policy.rb → policy.rb.tt} +0 -0
- data/lib/generators/rspec/templates/{policy_spec.rb → policy_spec.rb.tt} +0 -0
- data/lib/generators/test_unit/templates/{policy_test.rb → policy_test.rb.tt} +0 -0
- metadata +54 -119
- data/.gitattributes +0 -2
- data/.github/ISSUE_TEMPLATE.md +0 -21
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -29
- data/.github/bug_report_template.rb +0 -175
- data/.gitignore +0 -15
- data/.rubocop.yml +0 -54
- data/.tidelift.yml +0 -6
- data/.travis.yml +0 -31
- data/Gemfile +0 -22
- data/Rakefile +0 -27
- data/action_policy.gemspec +0 -44
- data/benchmarks/namespaced_lookup_cache.rb +0 -74
- data/benchmarks/pre_checks.rb +0 -73
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/docs/.nojekyll +0 -0
- data/docs/CNAME +0 -1
- data/docs/README.md +0 -79
- data/docs/_sidebar.md +0 -27
- data/docs/aliases.md +0 -122
- data/docs/assets/docsify-search.js +0 -364
- data/docs/assets/docsify.min.js +0 -3
- data/docs/assets/fonts/FiraCode-Medium.woff +0 -0
- data/docs/assets/fonts/FiraCode-Regular.woff +0 -0
- data/docs/assets/images/banner.png +0 -0
- data/docs/assets/images/cache.png +0 -0
- data/docs/assets/images/cache.svg +0 -70
- data/docs/assets/images/layer.png +0 -0
- data/docs/assets/images/layer.svg +0 -35
- data/docs/assets/prism-ruby.min.js +0 -1
- data/docs/assets/styles.css +0 -347
- data/docs/assets/vue.min.css +0 -1
- data/docs/authorization_context.md +0 -92
- data/docs/behaviour.md +0 -113
- data/docs/caching.md +0 -291
- data/docs/controller_action_aliases.md +0 -109
- data/docs/custom_lookup_chain.md +0 -48
- data/docs/custom_policy.md +0 -53
- data/docs/debugging.md +0 -55
- data/docs/decorators.md +0 -27
- data/docs/favicon.ico +0 -0
- data/docs/graphql.md +0 -302
- data/docs/i18n.md +0 -44
- data/docs/index.html +0 -43
- data/docs/instrumentation.md +0 -84
- data/docs/lookup_chain.md +0 -22
- data/docs/namespaces.md +0 -77
- data/docs/non_rails.md +0 -28
- data/docs/pre_checks.md +0 -57
- data/docs/pundit_migration.md +0 -80
- data/docs/quick_start.md +0 -118
- data/docs/rails.md +0 -120
- data/docs/reasons.md +0 -120
- data/docs/scoping.md +0 -255
- data/docs/testing.md +0 -390
- data/docs/writing_policies.md +0 -107
- data/gemfiles/jruby.gemfile +0 -8
- data/gemfiles/rails42.gemfile +0 -9
- data/gemfiles/rails6.gemfile +0 -8
- data/gemfiles/railsmaster.gemfile +0 -6
- data/lib/action_policy/ext/string_match.rb +0 -14
- data/lib/action_policy/ext/yield_self_then.rb +0 -25
@@ -8,8 +8,11 @@ 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)
|
12
|
-
policy_class = with || ::ActionPolicy.lookup(
|
11
|
+
def policy_for(record:, with: nil, namespace: authorization_namespace, context: authorization_context, allow_nil: false, default: default_authorization_policy_class)
|
12
|
+
policy_class = with || ::ActionPolicy.lookup(
|
13
|
+
record,
|
14
|
+
**{namespace, context, allow_nil, default}
|
15
|
+
)
|
13
16
|
policy_class&.new(record, **context)
|
14
17
|
end
|
15
18
|
|
@@ -21,6 +24,10 @@ module ActionPolicy
|
|
21
24
|
# override to provide specific authorization namespace
|
22
25
|
end
|
23
26
|
|
27
|
+
def default_authorization_policy_class
|
28
|
+
# override to provide a policy class use when no policy found
|
29
|
+
end
|
30
|
+
|
24
31
|
# Override this method to provide implicit authorization target
|
25
32
|
# that would be used in case `record` is not specified in
|
26
33
|
# `authorize!` and `allowed_to?` call.
|
@@ -46,7 +53,7 @@ module ActionPolicy
|
|
46
53
|
|
47
54
|
def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **)
|
48
55
|
record_key = record._policy_cache_key(use_object_id: true)
|
49
|
-
context_key = context.values.map {
|
56
|
+
context_key = context.values.map { _1._policy_cache_key(use_object_id: true) }.join(".")
|
50
57
|
|
51
58
|
"#{namespace}/#{with}/#{context_key}/#{record_key}"
|
52
59
|
end
|
@@ -17,8 +17,9 @@ module ActionPolicy
|
|
17
17
|
policy ||= policy_for(record: implicit_authorization_target!, **options)
|
18
18
|
|
19
19
|
type ||= authorization_scope_type_for(policy, target)
|
20
|
+
name = as
|
20
21
|
|
21
|
-
Authorizer.scopify(target, policy, type
|
22
|
+
Authorizer.scopify(target, policy, **{type, name, scope_options})
|
22
23
|
end
|
23
24
|
|
24
25
|
# For backward compatibility
|
@@ -9,11 +9,6 @@ module ActionPolicy
|
|
9
9
|
using ActionPolicy::Ext::StringConstantize
|
10
10
|
end
|
11
11
|
|
12
|
-
unless "".respond_to?(:match?)
|
13
|
-
require "action_policy/ext/string_match"
|
14
|
-
using ActionPolicy::Ext::StringMatch
|
15
|
-
end
|
16
|
-
|
17
12
|
module Ext
|
18
13
|
def namespace
|
19
14
|
return unless name&.match?(/[^^]::/)
|
@@ -23,7 +18,7 @@ module ActionPolicy
|
|
23
18
|
end
|
24
19
|
|
25
20
|
# See https://github.com/jruby/jruby/issues/5220
|
26
|
-
::Module.include(Ext) if RUBY_PLATFORM
|
21
|
+
::Module.include(Ext) if RUBY_PLATFORM.match?(/java/i)
|
27
22
|
|
28
23
|
refine Module do
|
29
24
|
include Ext
|
@@ -27,65 +27,45 @@ module ActionPolicy
|
|
27
27
|
end
|
28
28
|
|
29
29
|
refine NilClass do
|
30
|
-
def _policy_cache_key(*)
|
31
|
-
""
|
32
|
-
end
|
30
|
+
def _policy_cache_key(*) = ""
|
33
31
|
end
|
34
32
|
|
35
33
|
refine TrueClass do
|
36
|
-
def _policy_cache_key(*)
|
37
|
-
"t"
|
38
|
-
end
|
34
|
+
def _policy_cache_key(*) = "t"
|
39
35
|
end
|
40
36
|
|
41
37
|
refine FalseClass do
|
42
|
-
def _policy_cache_key(*)
|
43
|
-
"f"
|
44
|
-
end
|
38
|
+
def _policy_cache_key(*) = "f"
|
45
39
|
end
|
46
40
|
|
47
41
|
refine String do
|
48
|
-
def _policy_cache_key(*)
|
49
|
-
self
|
50
|
-
end
|
42
|
+
def _policy_cache_key(*) = self
|
51
43
|
end
|
52
44
|
|
53
45
|
refine Symbol do
|
54
|
-
def _policy_cache_key(*)
|
55
|
-
to_s
|
56
|
-
end
|
46
|
+
def _policy_cache_key(*) = to_s
|
57
47
|
end
|
58
48
|
|
59
49
|
if RUBY_PLATFORM.match?(/java/i)
|
60
50
|
refine Integer do
|
61
|
-
def _policy_cache_key(*)
|
62
|
-
to_s
|
63
|
-
end
|
51
|
+
def _policy_cache_key(*) = to_s
|
64
52
|
end
|
65
53
|
|
66
54
|
refine Float do
|
67
|
-
def _policy_cache_key(*)
|
68
|
-
to_s
|
69
|
-
end
|
55
|
+
def _policy_cache_key(*) = to_s
|
70
56
|
end
|
71
57
|
else
|
72
58
|
refine Numeric do
|
73
|
-
def _policy_cache_key(*)
|
74
|
-
to_s
|
75
|
-
end
|
59
|
+
def _policy_cache_key(*) = to_s
|
76
60
|
end
|
77
61
|
end
|
78
62
|
|
79
63
|
refine Time do
|
80
|
-
def _policy_cache_key(*)
|
81
|
-
to_s
|
82
|
-
end
|
64
|
+
def _policy_cache_key(*) = to_s
|
83
65
|
end
|
84
66
|
|
85
67
|
refine Module do
|
86
|
-
def _policy_cache_key(*)
|
87
|
-
name
|
88
|
-
end
|
68
|
+
def _policy_cache_key(*) = name
|
89
69
|
end
|
90
70
|
end
|
91
71
|
end
|
data/lib/action_policy/i18n.rb
CHANGED
@@ -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 {
|
24
|
+
policy_hierarchy = policy_class.ancestors.select { _1.respond_to?(:identifier) }
|
25
25
|
[
|
26
26
|
*policy_hierarchy.map { |klass| :"policy.#{klass.identifier}.#{rule}" },
|
27
27
|
:"policy.#{rule}",
|
@@ -24,14 +24,26 @@ module ActionPolicy
|
|
24
24
|
class << self
|
25
25
|
attr_reader :store
|
26
26
|
|
27
|
-
def
|
27
|
+
def put_if_absent(scope, namespace, policy)
|
28
|
+
local_store = store[scope][namespace]
|
29
|
+
return local_store[policy] if local_store[policy]
|
30
|
+
local_store[policy] ||= yield
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch(namespace, policy, strict:, &block)
|
28
34
|
return yield unless LookupChain.namespace_cache_enabled?
|
29
|
-
|
30
|
-
|
35
|
+
|
36
|
+
if strict
|
37
|
+
put_if_absent(:strict, namespace, policy, &block)
|
38
|
+
else
|
39
|
+
cached_policy = put_if_absent(:strict, namespace, policy, &block)
|
40
|
+
put_if_absent(:flexible, namespace, policy) { cached_policy }
|
41
|
+
end
|
31
42
|
end
|
32
43
|
|
33
44
|
def clear
|
34
|
-
|
45
|
+
hash = Hash.new { |h, k| h[k] = {} }
|
46
|
+
@store = {strict: hash, flexible: hash.clone}
|
35
47
|
end
|
36
48
|
end
|
37
49
|
|
@@ -53,23 +65,23 @@ module ActionPolicy
|
|
53
65
|
|
54
66
|
private
|
55
67
|
|
56
|
-
def lookup_within_namespace(policy_name, namespace)
|
68
|
+
def lookup_within_namespace(policy_name, namespace, strict: false)
|
57
69
|
return unless namespace
|
58
|
-
NamespaceCache.fetch(namespace.name, policy_name) do
|
70
|
+
NamespaceCache.fetch(namespace.name, policy_name, strict: strict) do
|
59
71
|
mod = namespace
|
60
|
-
|
61
72
|
loop do
|
62
73
|
policy = "#{mod.name}::#{policy_name}".safe_constantize
|
63
|
-
|
64
74
|
break policy unless policy.nil?
|
65
|
-
|
66
75
|
mod = mod.namespace
|
67
|
-
|
68
|
-
break if mod.nil?
|
76
|
+
break if mod.nil? || strict
|
69
77
|
end
|
70
78
|
end
|
71
79
|
end
|
72
80
|
|
81
|
+
def objectify_policy(policy_name, strict: false)
|
82
|
+
policy_name.safe_constantize unless strict
|
83
|
+
end
|
84
|
+
|
73
85
|
def policy_class_name_for(record)
|
74
86
|
return record.policy_name.to_s if record.respond_to?(:policy_name)
|
75
87
|
|
@@ -112,19 +124,21 @@ module ActionPolicy
|
|
112
124
|
}
|
113
125
|
|
114
126
|
# Infer from passed symbol
|
115
|
-
SYMBOL_LOOKUP = ->(record, namespace: nil, **) {
|
127
|
+
SYMBOL_LOOKUP = ->(record, namespace: nil, strict_namespace: false, **) {
|
116
128
|
next unless record.is_a?(Symbol)
|
117
129
|
|
118
130
|
policy_name = "#{record.camelize}Policy"
|
119
|
-
lookup_within_namespace(policy_name, namespace) ||
|
131
|
+
lookup_within_namespace(policy_name, namespace, strict: strict_namespace) ||
|
132
|
+
objectify_policy(policy_name, strict: strict_namespace)
|
120
133
|
}
|
121
134
|
|
122
135
|
# (Optional) Infer using String#classify if available
|
123
|
-
CLASSIFY_SYMBOL_LOOKUP = ->(record, namespace: nil, **) {
|
136
|
+
CLASSIFY_SYMBOL_LOOKUP = ->(record, namespace: nil, strict_namespace: false, **) {
|
124
137
|
next unless record.is_a?(Symbol)
|
125
138
|
|
126
139
|
policy_name = "#{record.to_s.classify}Policy"
|
127
|
-
lookup_within_namespace(policy_name, namespace) ||
|
140
|
+
lookup_within_namespace(policy_name, namespace, strict: strict_namespace) ||
|
141
|
+
objectify_policy(policy_name, strict: strict_namespace)
|
128
142
|
}
|
129
143
|
|
130
144
|
self.chain = [
|
@@ -46,23 +46,18 @@ module ActionPolicy
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def lookup_alias(rule)
|
50
|
-
rules_aliases[rule]
|
51
|
-
end
|
49
|
+
def lookup_alias(rule) = rules_aliases[rule]
|
52
50
|
|
53
|
-
def lookup_default_rule
|
54
|
-
rules_aliases[DEFAULT]
|
55
|
-
end
|
51
|
+
def lookup_default_rule() = rules_aliases[DEFAULT]
|
56
52
|
|
57
53
|
def rules_aliases
|
58
54
|
return @rules_aliases if instance_variable_defined?(:@rules_aliases)
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
56
|
+
if superclass.respond_to?(:rules_aliases)
|
57
|
+
superclass.rules_aliases.dup
|
58
|
+
else
|
59
|
+
{}
|
60
|
+
end => @rules_aliases
|
66
61
|
end
|
67
62
|
|
68
63
|
def method_added(name)
|
@@ -63,8 +63,10 @@ module ActionPolicy
|
|
63
63
|
|
64
64
|
module ClassMethods # :nodoc:
|
65
65
|
def authorize(*ids, allow_nil: false, optional: false)
|
66
|
+
allow_nil ||= optional
|
67
|
+
|
66
68
|
ids.each do |id|
|
67
|
-
authorization_targets[id] = {allow_nil
|
69
|
+
authorization_targets[id] = {allow_nil, optional}
|
68
70
|
end
|
69
71
|
|
70
72
|
attr_reader(*ids)
|
@@ -73,12 +75,11 @@ module ActionPolicy
|
|
73
75
|
def authorization_targets
|
74
76
|
return @authorization_targets if instance_variable_defined?(:@authorization_targets)
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
78
|
+
if superclass.respond_to?(:authorization_targets)
|
79
|
+
superclass.authorization_targets.dup
|
80
|
+
else
|
81
|
+
{}
|
82
|
+
end => @authorization_targets
|
82
83
|
end
|
83
84
|
end
|
84
85
|
end
|
@@ -3,16 +3,13 @@
|
|
3
3
|
require "action_policy/version"
|
4
4
|
|
5
5
|
module ActionPolicy # :nodoc:
|
6
|
+
using RubyNext
|
7
|
+
|
6
8
|
# By default cache namespace (or prefix) contains major and minor version of the gem
|
7
9
|
CACHE_NAMESPACE = "acp:#{ActionPolicy::VERSION.split(".").take(2).join(".")}"
|
8
10
|
|
9
|
-
require "action_policy/ext/yield_self_then"
|
10
11
|
require "action_policy/ext/policy_cache_key"
|
11
12
|
|
12
|
-
unless "".respond_to?(:then)
|
13
|
-
require "action_policy/ext/yield_self_then"
|
14
|
-
using ActionPolicy::Ext::YieldSelfThen
|
15
|
-
end
|
16
13
|
using ActionPolicy::Ext::PolicyCacheKey
|
17
14
|
|
18
15
|
module Policy
|
@@ -26,15 +23,13 @@ module ActionPolicy # :nodoc:
|
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
29
|
-
def cache_namespace
|
30
|
-
ActionPolicy::CACHE_NAMESPACE
|
31
|
-
end
|
26
|
+
def cache_namespace() = ActionPolicy::CACHE_NAMESPACE
|
32
27
|
|
33
28
|
def cache_key(*parts)
|
34
29
|
[
|
35
30
|
cache_namespace,
|
36
31
|
*parts
|
37
|
-
].map {
|
32
|
+
].map { _1._policy_cache_key }.join("/")
|
38
33
|
end
|
39
34
|
|
40
35
|
def rule_cache_key(rule)
|
@@ -47,7 +42,7 @@ module ActionPolicy # :nodoc:
|
|
47
42
|
end
|
48
43
|
|
49
44
|
def context_cache_key
|
50
|
-
authorization_context.map {
|
45
|
+
authorization_context.map { _2._policy_cache_key.to_s }.join("/")
|
51
46
|
end
|
52
47
|
|
53
48
|
def apply_with_cache(rule)
|
@@ -79,7 +74,7 @@ module ActionPolicy # :nodoc:
|
|
79
74
|
res = store.read(key)
|
80
75
|
next res unless res.nil?
|
81
76
|
res = yield
|
82
|
-
store.write(key, res,
|
77
|
+
store.write(key, res, options)
|
83
78
|
res
|
84
79
|
end
|
85
80
|
end
|
@@ -94,12 +89,11 @@ module ActionPolicy # :nodoc:
|
|
94
89
|
def cached_rules
|
95
90
|
return @cached_rules if instance_variable_defined?(:@cached_rules)
|
96
91
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
92
|
+
if superclass.respond_to?(:cached_rules)
|
93
|
+
superclass.cached_rules.dup
|
94
|
+
else
|
95
|
+
{}
|
96
|
+
end => @cached_rules
|
103
97
|
end
|
104
98
|
end
|
105
99
|
end
|
@@ -11,6 +11,8 @@ unless "".respond_to?(:underscore)
|
|
11
11
|
end
|
12
12
|
|
13
13
|
module ActionPolicy
|
14
|
+
using RubyNext
|
15
|
+
|
14
16
|
# Raised when `resolve_rule` failed to find an approriate
|
15
17
|
# policy rule method for the activity
|
16
18
|
class UnknownRule < Error
|
@@ -75,15 +77,28 @@ module ActionPolicy
|
|
75
77
|
# `apply` also calls pre-checks.
|
76
78
|
def apply(rule)
|
77
79
|
@result = self.class.result_class.new(self.class, rule)
|
78
|
-
|
80
|
+
|
81
|
+
catch :policy_fulfilled do
|
82
|
+
result.load __apply__(rule)
|
83
|
+
end
|
84
|
+
|
85
|
+
result.value
|
86
|
+
end
|
87
|
+
|
88
|
+
def deny!
|
89
|
+
result&.load false
|
90
|
+
throw :policy_fulfilled
|
91
|
+
end
|
92
|
+
|
93
|
+
def allow!
|
94
|
+
result&.load true
|
95
|
+
throw :policy_fulfilled
|
79
96
|
end
|
80
97
|
|
81
98
|
# This method performs the rule call.
|
82
99
|
# Override or extend it to provide custom functionality
|
83
100
|
# (such as caching, pre checks, etc.)
|
84
|
-
def __apply__(rule)
|
85
|
-
public_send(rule)
|
86
|
-
end
|
101
|
+
def __apply__(rule) = public_send(rule)
|
87
102
|
|
88
103
|
# Wrap code that could modify result
|
89
104
|
# to prevent the current result modification
|
@@ -102,16 +117,16 @@ module ActionPolicy
|
|
102
117
|
# If record is `nil` then we uses the current policy.
|
103
118
|
def allowed_to?(rule, record = :__undef__, **options)
|
104
119
|
if (record == :__undef__ || record == self.record) && options.empty?
|
105
|
-
__apply__(rule)
|
120
|
+
__apply__(resolve_rule(rule))
|
106
121
|
else
|
107
|
-
policy_for(record: record, **options).
|
122
|
+
policy_for(record: record, **options).then do |policy|
|
123
|
+
policy.apply(policy.resolve_rule(rule))
|
124
|
+
end
|
108
125
|
end
|
109
126
|
end
|
110
127
|
|
111
128
|
# An alias for readability purposes
|
112
|
-
def check?(*args)
|
113
|
-
allowed_to?(*args)
|
114
|
-
end
|
129
|
+
def check?(*args) = allowed_to?(*args)
|
115
130
|
|
116
131
|
# Returns a rule name (policy method name) for activity.
|
117
132
|
#
|
@@ -127,9 +142,7 @@ module ActionPolicy
|
|
127
142
|
# Return annotated source code for the rule
|
128
143
|
# NOTE: require "method_source" and "unparser" gems to be installed.
|
129
144
|
# Otherwise returns empty string.
|
130
|
-
def inspect_rule(rule)
|
131
|
-
PrettyPrint.print_method(self, rule)
|
132
|
-
end
|
145
|
+
def inspect_rule(rule) = PrettyPrint.print_method(self, rule)
|
133
146
|
|
134
147
|
# Helper for printing the annotated rule source.
|
135
148
|
# Useful for debugging: type `pp :show?` within the context of the policy
|