action_policy 0.6.0 → 0.6.3
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 +14 -0
- data/lib/.rbnext/3.0/action_policy/ext/policy_cache_key.rb +1 -1
- data/lib/.rbnext/3.0/action_policy/policy/core.rb +2 -2
- data/lib/.rbnext/3.0/action_policy/rspec/be_an_alias_of.rb +70 -0
- data/lib/.rbnext/{1995.next → 3.1}/action_policy/behaviours/policy_for.rb +0 -0
- data/lib/.rbnext/{1995.next → 3.1}/action_policy/behaviours/scoping.rb +0 -0
- data/lib/.rbnext/3.1/action_policy/ext/module_namespace.rb +32 -0
- data/lib/.rbnext/3.1/action_policy/ext/policy_cache_key.rb +72 -0
- data/lib/.rbnext/{1995.next → 3.1}/action_policy/policy/authorization.rb +0 -0
- data/lib/action_policy/behaviour.rb +16 -7
- data/lib/action_policy/ext/module_namespace.rb +5 -1
- data/lib/action_policy/ext/policy_cache_key.rb +1 -1
- data/lib/action_policy/lookup_chain.rb +10 -2
- data/lib/action_policy/policy/authorization.rb +1 -1
- data/lib/action_policy/policy/core.rb +2 -2
- data/lib/action_policy/rails/controller.rb +4 -1
- data/lib/action_policy/rspec/be_an_alias_of.rb +70 -0
- data/lib/action_policy/rspec.rb +1 -0
- data/lib/action_policy/version.rb +1 -1
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 611389adf65ee131b0b5b272885fe0ba6a7066330a1e9b97d7f0b9cb8dd47530
|
4
|
+
data.tar.gz: f2f29bf49216ef6406b408935250fc845619d14657d8956d7a20a6344b8a3032
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86baaf070430319da764d5287542f418a32f9b28870518bddeb6c25ad3875ea14482993c2d0d185750e1dea36ad45263182f285f893b9a44a95f29dcd734f653
|
7
|
+
data.tar.gz: 6fbb1736b962bd2b80d24ffe2ada43ced3bf4324f5d4790d6ca39f7f1c5a654bffcde93caca846c6ce49ce5a1d68a299fd050edda595cdc114bd552de83ac1d5
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,20 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.6.3 (2022-08-16)
|
6
|
+
|
7
|
+
- Fix regression for [#179](https://github.com/palkan/action_policy/issues/179). ([@palkan][])
|
8
|
+
|
9
|
+
## 0.6.2 (2022-08-12)
|
10
|
+
|
11
|
+
- Allow omitting authorization record if `with` is provided. ([@palkan][])
|
12
|
+
|
13
|
+
## 0.6.1 (2022-05-23)
|
14
|
+
|
15
|
+
- Fix policy lookup when a namespaced record is passed and the strict mode is used. ([@palkan][])
|
16
|
+
- Expose `#authorized_scope` as helper. ([@palkan][])
|
17
|
+
- [Fixes [#207](https://github.com/palkan/action_policy/issues/207)] refinement#include deprecation warning on Ruby 3.1
|
18
|
+
|
5
19
|
## 0.6.0 (2021-09-02)
|
6
20
|
|
7
21
|
- Drop Ruby 2.5 support.
|
@@ -86,7 +86,7 @@ module ActionPolicy
|
|
86
86
|
@result = self.class.result_class.new(self.class, rule)
|
87
87
|
|
88
88
|
catch :policy_fulfilled do
|
89
|
-
result.load __apply__(rule)
|
89
|
+
result.load __apply__(resolve_rule(rule))
|
90
90
|
end
|
91
91
|
|
92
92
|
result.value
|
@@ -139,7 +139,7 @@ module ActionPolicy
|
|
139
139
|
#
|
140
140
|
# By default, rule name is equal to activity name.
|
141
141
|
#
|
142
|
-
# Raises ActionPolicy::
|
142
|
+
# Raises ActionPolicy::UnknownRule when rule is not found in policy.
|
143
143
|
def resolve_rule(activity)
|
144
144
|
raise UnknownRule.new(self, activity) unless
|
145
145
|
respond_to?(activity)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_policy/testing"
|
4
|
+
|
5
|
+
module ActionPolicy
|
6
|
+
module RSpec
|
7
|
+
# Policy rule alias matcher `be_an_alias_of`.
|
8
|
+
#
|
9
|
+
# Verifies that for given policy a policy rule has an alias.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# # in policy specs
|
14
|
+
# subject(:policy) { described_class.new(record, user: user) }
|
15
|
+
#
|
16
|
+
# let(:user) { build_stubbed(:user) }
|
17
|
+
# let(:record) { build_stubbed(:post) }
|
18
|
+
#
|
19
|
+
# describe "#show?" do
|
20
|
+
# it "is an alias of :index? policy rule" do
|
21
|
+
# expect(:show?).to be_an_alias_of(policy, :index?)
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# # negated version
|
26
|
+
# describe "#show?" do
|
27
|
+
# it "is not an alias of :index? policy rule" do
|
28
|
+
# expect(:show?).to_not be_an_alias_of(policy, :index?)
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
class BeAnAliasOf < ::RSpec::Matchers::BuiltIn::BaseMatcher
|
33
|
+
attr_reader :policy, :rule, :actual
|
34
|
+
|
35
|
+
def initialize(policy, rule)
|
36
|
+
@policy = policy
|
37
|
+
@rule = rule
|
38
|
+
end
|
39
|
+
|
40
|
+
def match(_expected, actual)
|
41
|
+
policy.resolve_rule(actual) == rule
|
42
|
+
end
|
43
|
+
|
44
|
+
def does_not_match?(actual)
|
45
|
+
@actual = actual
|
46
|
+
policy.resolve_rule(actual) != rule
|
47
|
+
end
|
48
|
+
|
49
|
+
def supports_block_expectations?() ; false; end
|
50
|
+
|
51
|
+
def failure_message
|
52
|
+
"expected #{policy}##{actual} " \
|
53
|
+
"to be an alias of #{policy}##{rule}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def failure_message_when_negated
|
57
|
+
"expected #{policy}##{actual} " \
|
58
|
+
"to not be an alias of #{policy}##{rule}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
RSpec.configure do |config|
|
65
|
+
config.include(Module.new do
|
66
|
+
def be_an_alias_of(policy, rule)
|
67
|
+
ActionPolicy::RSpec::BeAnAliasOf.new(policy, rule)
|
68
|
+
end
|
69
|
+
end)
|
70
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionPolicy
|
4
|
+
module Ext
|
5
|
+
# Add Module#namespace method
|
6
|
+
module ModuleNamespace # :nodoc: all
|
7
|
+
unless "".respond_to?(:safe_constantize)
|
8
|
+
require "action_policy/ext/string_constantize"
|
9
|
+
using ActionPolicy::Ext::StringConstantize
|
10
|
+
end
|
11
|
+
|
12
|
+
module Ext
|
13
|
+
def namespace
|
14
|
+
return unless name&.match?(/[^^]::/)
|
15
|
+
|
16
|
+
name.sub(/::[^:]+$/, "").safe_constantize
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# See https://github.com/jruby/jruby/issues/5220
|
21
|
+
::Module.include(Ext) if RUBY_PLATFORM.match?(/java/i)
|
22
|
+
|
23
|
+
refine Module do
|
24
|
+
if RUBY_VERSION <= "2.7.0"
|
25
|
+
include Ext
|
26
|
+
else
|
27
|
+
::RubyNext::Core.import_methods(Ext, binding)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionPolicy
|
4
|
+
module Ext
|
5
|
+
# Adds #_policy_cache_key method to Object,
|
6
|
+
# which just call #policy_cache_key or #cache_key
|
7
|
+
# or #object_id (if `use_object_id` parameter is set to true).
|
8
|
+
#
|
9
|
+
# For other core classes returns string representation.
|
10
|
+
#
|
11
|
+
# Raises ArgumentError otherwise.
|
12
|
+
module PolicyCacheKey # :nodoc: all
|
13
|
+
module ObjectExt
|
14
|
+
def _policy_cache_key(use_object_id: false)
|
15
|
+
return policy_cache_key if respond_to?(:policy_cache_key)
|
16
|
+
return cache_key_with_version if respond_to?(:cache_key_with_version)
|
17
|
+
return cache_key if respond_to?(:cache_key)
|
18
|
+
|
19
|
+
return object_id.to_s if use_object_id == true
|
20
|
+
|
21
|
+
raise ArgumentError, "object is not cacheable"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
refine Object do
|
26
|
+
::RubyNext::Core.import_methods(ObjectExt, binding)
|
27
|
+
end
|
28
|
+
|
29
|
+
refine NilClass do
|
30
|
+
def _policy_cache_key(*) = ""
|
31
|
+
end
|
32
|
+
|
33
|
+
refine TrueClass do
|
34
|
+
def _policy_cache_key(*) = "t"
|
35
|
+
end
|
36
|
+
|
37
|
+
refine FalseClass do
|
38
|
+
def _policy_cache_key(*) = "f"
|
39
|
+
end
|
40
|
+
|
41
|
+
refine String do
|
42
|
+
def _policy_cache_key(*) = self
|
43
|
+
end
|
44
|
+
|
45
|
+
refine Symbol do
|
46
|
+
def _policy_cache_key(*) = to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
if RUBY_PLATFORM.match?(/java/i)
|
50
|
+
refine Integer do
|
51
|
+
def _policy_cache_key(*) = to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
refine Float do
|
55
|
+
def _policy_cache_key(*) = to_s
|
56
|
+
end
|
57
|
+
else
|
58
|
+
refine Numeric do
|
59
|
+
def _policy_cache_key(*) = to_s
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
refine Time do
|
64
|
+
def _policy_cache_key(*) = to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
refine Module do
|
68
|
+
def _policy_cache_key(*) = name
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
File without changes
|
@@ -58,10 +58,11 @@ module ActionPolicy
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def authorization_context
|
61
|
-
|
62
|
-
|
61
|
+
@_authorization_context ||= build_authorization_context
|
62
|
+
end
|
63
63
|
|
64
|
-
|
64
|
+
private def build_authorization_context
|
65
|
+
self.class.authorization_targets
|
65
66
|
.each_with_object({}) do |(key, meth), obj|
|
66
67
|
obj[key] = send(meth)
|
67
68
|
end
|
@@ -73,11 +74,19 @@ module ActionPolicy
|
|
73
74
|
policy.resolve_rule(rule)
|
74
75
|
end
|
75
76
|
|
76
|
-
def lookup_authorization_policy(record, **options) # :nodoc:
|
77
|
-
|
78
|
-
|
77
|
+
def lookup_authorization_policy(record, with: nil, **options) # :nodoc:
|
78
|
+
if :__undef__ == record # rubocop:disable Style/YodaCondition
|
79
|
+
record =
|
80
|
+
if with
|
81
|
+
implicit_authorization_target
|
82
|
+
else
|
83
|
+
implicit_authorization_target!
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
Kernel.raise ArgumentError, "Record or policy must be specified" if record.nil? && with.nil?
|
79
88
|
|
80
|
-
policy_for(record: record, **options)
|
89
|
+
policy_for(record: record, with: with, **options)
|
81
90
|
end
|
82
91
|
|
83
92
|
module ClassMethods # :nodoc:
|
@@ -67,12 +67,20 @@ module ActionPolicy
|
|
67
67
|
def lookup_within_namespace(policy_name, namespace, strict: false)
|
68
68
|
NamespaceCache.fetch(namespace&.name || "Kernel", policy_name, strict: strict) do
|
69
69
|
mod = namespace
|
70
|
+
policy_class = nil
|
71
|
+
|
70
72
|
loop do
|
71
|
-
|
72
|
-
break
|
73
|
+
policy_class = [mod&.name, policy_name].compact.join("::").safe_constantize
|
74
|
+
break policy_class if policy_class || mod.nil?
|
73
75
|
|
74
76
|
mod = mod.namespace
|
75
77
|
end
|
78
|
+
|
79
|
+
next policy_class if !strict || namespace.nil? || policy_class.nil?
|
80
|
+
|
81
|
+
# If we're in the strict mode and the namespace boundary is provided,
|
82
|
+
# we must check that the found policy satisfies it
|
83
|
+
policy_class if policy_class.name.start_with?("#{namespace.name}::")
|
76
84
|
end
|
77
85
|
end
|
78
86
|
|
@@ -86,7 +86,7 @@ module ActionPolicy
|
|
86
86
|
@result = self.class.result_class.new(self.class, rule)
|
87
87
|
|
88
88
|
catch :policy_fulfilled do
|
89
|
-
result.load __apply__(rule)
|
89
|
+
result.load __apply__(resolve_rule(rule))
|
90
90
|
end
|
91
91
|
|
92
92
|
result.value
|
@@ -139,7 +139,7 @@ module ActionPolicy
|
|
139
139
|
#
|
140
140
|
# By default, rule name is equal to activity name.
|
141
141
|
#
|
142
|
-
# Raises ActionPolicy::
|
142
|
+
# Raises ActionPolicy::UnknownRule when rule is not found in policy.
|
143
143
|
def resolve_rule(activity)
|
144
144
|
raise UnknownRule.new(self, activity) unless
|
145
145
|
respond_to?(activity)
|
@@ -23,7 +23,10 @@ module ActionPolicy
|
|
23
23
|
include ActionPolicy::Behaviours::Namespaced
|
24
24
|
|
25
25
|
included do
|
26
|
-
|
26
|
+
if respond_to?(:helper_method)
|
27
|
+
helper_method :allowed_to?
|
28
|
+
helper_method :authorized_scope
|
29
|
+
end
|
27
30
|
|
28
31
|
attr_writer :authorize_count
|
29
32
|
attr_reader :verify_authorized_skipped
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_policy/testing"
|
4
|
+
|
5
|
+
module ActionPolicy
|
6
|
+
module RSpec
|
7
|
+
# Policy rule alias matcher `be_an_alias_of`.
|
8
|
+
#
|
9
|
+
# Verifies that for given policy a policy rule has an alias.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# # in policy specs
|
14
|
+
# subject(:policy) { described_class.new(record, user: user) }
|
15
|
+
#
|
16
|
+
# let(:user) { build_stubbed(:user) }
|
17
|
+
# let(:record) { build_stubbed(:post) }
|
18
|
+
#
|
19
|
+
# describe "#show?" do
|
20
|
+
# it "is an alias of :index? policy rule" do
|
21
|
+
# expect(:show?).to be_an_alias_of(policy, :index?)
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# # negated version
|
26
|
+
# describe "#show?" do
|
27
|
+
# it "is not an alias of :index? policy rule" do
|
28
|
+
# expect(:show?).to_not be_an_alias_of(policy, :index?)
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
class BeAnAliasOf < ::RSpec::Matchers::BuiltIn::BaseMatcher
|
33
|
+
attr_reader :policy, :rule, :actual
|
34
|
+
|
35
|
+
def initialize(policy, rule)
|
36
|
+
@policy = policy
|
37
|
+
@rule = rule
|
38
|
+
end
|
39
|
+
|
40
|
+
def match(_expected, actual)
|
41
|
+
policy.resolve_rule(actual) == rule
|
42
|
+
end
|
43
|
+
|
44
|
+
def does_not_match?(actual)
|
45
|
+
@actual = actual
|
46
|
+
policy.resolve_rule(actual) != rule
|
47
|
+
end
|
48
|
+
|
49
|
+
def supports_block_expectations?() = false
|
50
|
+
|
51
|
+
def failure_message
|
52
|
+
"expected #{policy}##{actual} " \
|
53
|
+
"to be an alias of #{policy}##{rule}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def failure_message_when_negated
|
57
|
+
"expected #{policy}##{actual} " \
|
58
|
+
"to not be an alias of #{policy}##{rule}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
RSpec.configure do |config|
|
65
|
+
config.include(Module.new do
|
66
|
+
def be_an_alias_of(policy, rule)
|
67
|
+
ActionPolicy::RSpec::BeAnAliasOf.new(policy, rule)
|
68
|
+
end
|
69
|
+
end)
|
70
|
+
end
|
data/lib/action_policy/rspec.rb
CHANGED
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.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.14.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.14.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ammeter
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,9 +133,6 @@ files:
|
|
133
133
|
- LICENSE.txt
|
134
134
|
- README.md
|
135
135
|
- config/rubocop-rspec.yml
|
136
|
-
- lib/.rbnext/1995.next/action_policy/behaviours/policy_for.rb
|
137
|
-
- lib/.rbnext/1995.next/action_policy/behaviours/scoping.rb
|
138
|
-
- lib/.rbnext/1995.next/action_policy/policy/authorization.rb
|
139
136
|
- lib/.rbnext/1995.next/action_policy/utils/pretty_print.rb
|
140
137
|
- lib/.rbnext/2.7/action_policy/behaviours/policy_for.rb
|
141
138
|
- lib/.rbnext/2.7/action_policy/i18n.rb
|
@@ -153,10 +150,16 @@ files:
|
|
153
150
|
- lib/.rbnext/3.0/action_policy/policy/execution_result.rb
|
154
151
|
- lib/.rbnext/3.0/action_policy/policy/pre_check.rb
|
155
152
|
- lib/.rbnext/3.0/action_policy/policy/reasons.rb
|
153
|
+
- lib/.rbnext/3.0/action_policy/rspec/be_an_alias_of.rb
|
156
154
|
- lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb
|
157
155
|
- lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb
|
158
156
|
- lib/.rbnext/3.0/action_policy/utils/pretty_print.rb
|
159
157
|
- lib/.rbnext/3.0/action_policy/utils/suggest_message.rb
|
158
|
+
- lib/.rbnext/3.1/action_policy/behaviours/policy_for.rb
|
159
|
+
- lib/.rbnext/3.1/action_policy/behaviours/scoping.rb
|
160
|
+
- lib/.rbnext/3.1/action_policy/ext/module_namespace.rb
|
161
|
+
- lib/.rbnext/3.1/action_policy/ext/policy_cache_key.rb
|
162
|
+
- lib/.rbnext/3.1/action_policy/policy/authorization.rb
|
160
163
|
- lib/action_policy.rb
|
161
164
|
- lib/action_policy/authorizer.rb
|
162
165
|
- lib/action_policy/base.rb
|
@@ -194,6 +197,7 @@ files:
|
|
194
197
|
- lib/action_policy/rails/scope_matchers/active_record.rb
|
195
198
|
- lib/action_policy/railtie.rb
|
196
199
|
- lib/action_policy/rspec.rb
|
200
|
+
- lib/action_policy/rspec/be_an_alias_of.rb
|
197
201
|
- lib/action_policy/rspec/be_authorized_to.rb
|
198
202
|
- lib/action_policy/rspec/dsl.rb
|
199
203
|
- lib/action_policy/rspec/have_authorized_scope.rb
|
@@ -237,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
241
|
- !ruby/object:Gem::Version
|
238
242
|
version: '0'
|
239
243
|
requirements: []
|
240
|
-
rubygems_version: 3.
|
244
|
+
rubygems_version: 3.3.11
|
241
245
|
signing_key:
|
242
246
|
specification_version: 4
|
243
247
|
summary: Authorization framework for Ruby/Rails application
|