action_policy 0.6.2 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/LICENSE.txt +1 -1
- data/lib/.rbnext/2.7/action_policy/rspec/be_authorized_to.rb +9 -2
- data/lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb +9 -2
- data/lib/action_policy/behaviour.rb +2 -2
- data/lib/action_policy/lookup_chain.rb +1 -1
- data/lib/action_policy/railtie.rb +8 -3
- data/lib/action_policy/rspec/be_authorized_to.rb +9 -2
- data/lib/action_policy/test_helper.rb +3 -2
- data/lib/action_policy/testing.rb +12 -3
- data/lib/action_policy/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '095ceaf3dffeb28e23d1b89a20108ad23e6ddfb48e3fc317cf481151cdf82d66'
|
4
|
+
data.tar.gz: a1cac52b3641e0e3e9709a42a409324f348b13a037342cc004a4b51b99bc15ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a4b4c4b40036ca59122dfa6c3623b542525b7e663ddfaacec4fe93fdadb0a85fc2c12d73f6a58c89cba8d0e647bf5ff8dbf094f6bc181db93a44a004fd07284
|
7
|
+
data.tar.gz: 28bbda81d9a149ad339558cc7f6b6d175f8385e3be2f0c8118df5491b8152e271382aed6d60235f3de73d73b92406d6442dcf25b24296e73af74d29054890af4
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.6.4 (2022-01-17)
|
6
|
+
|
7
|
+
- Fix loading of Rails scope matchers. ([@palkan][])
|
8
|
+
|
9
|
+
[Issue #225](https://github.com/palkan/action_policy/issues/225)
|
10
|
+
|
11
|
+
- Add support to assert context in test matchers ([@matsales28][])
|
12
|
+
|
13
|
+
## 0.6.3 (2022-08-16)
|
14
|
+
|
15
|
+
- Fix regression for [#179](https://github.com/palkan/action_policy/issues/179). ([@palkan][])
|
16
|
+
|
5
17
|
## 0.6.2 (2022-08-12)
|
6
18
|
|
7
19
|
- Allow omitting authorization record if `with` is provided. ([@palkan][])
|
@@ -468,3 +480,4 @@ This value is now stored in a cache (if any) instead of just the call result (`t
|
|
468
480
|
[@pirj]: https://github.com/pirj
|
469
481
|
[@skojin]: https://github.com/skojin
|
470
482
|
[@tomdalling]: https://github.com/tomdalling
|
483
|
+
[@matsales28]: https://github.com/matsales28
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2018-
|
3
|
+
Copyright (c) 2018-2023 Vladimir Dementyev
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -20,7 +20,7 @@ module ActionPolicy
|
|
20
20
|
# end
|
21
21
|
#
|
22
22
|
class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
|
23
|
-
attr_reader :rule, :target, :policy, :actual_calls
|
23
|
+
attr_reader :rule, :target, :policy, :actual_calls, :context
|
24
24
|
|
25
25
|
def initialize(rule, target)
|
26
26
|
@rule = rule
|
@@ -32,10 +32,16 @@ module ActionPolicy
|
|
32
32
|
self
|
33
33
|
end
|
34
34
|
|
35
|
+
def with_context(context)
|
36
|
+
@context = context
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
35
40
|
def match(_expected, actual)
|
36
41
|
raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
|
37
42
|
|
38
43
|
@policy ||= ::ActionPolicy.lookup(target)
|
44
|
+
@context ||= nil
|
39
45
|
|
40
46
|
begin
|
41
47
|
ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
|
@@ -45,7 +51,7 @@ module ActionPolicy
|
|
45
51
|
|
46
52
|
@actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
|
47
53
|
|
48
|
-
actual_calls.any? { |_1| _1.matches?(policy, rule, target) }
|
54
|
+
actual_calls.any? { |_1| _1.matches?(policy, rule, target, context) }
|
49
55
|
end
|
50
56
|
|
51
57
|
def does_not_match?(*)
|
@@ -57,6 +63,7 @@ module ActionPolicy
|
|
57
63
|
def failure_message
|
58
64
|
"expected #{formatted_record} " \
|
59
65
|
"to be authorized with #{policy}##{rule}, " \
|
66
|
+
"#{context ? "and context #{context.inspect}, " : ""}" \
|
60
67
|
"but #{actual_calls_message}"
|
61
68
|
end
|
62
69
|
|
@@ -20,7 +20,7 @@ module ActionPolicy
|
|
20
20
|
# end
|
21
21
|
#
|
22
22
|
class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
|
23
|
-
attr_reader :rule, :target, :policy, :actual_calls
|
23
|
+
attr_reader :rule, :target, :policy, :actual_calls, :context
|
24
24
|
|
25
25
|
def initialize(rule, target)
|
26
26
|
@rule = rule
|
@@ -32,10 +32,16 @@ module ActionPolicy
|
|
32
32
|
self
|
33
33
|
end
|
34
34
|
|
35
|
+
def with_context(context)
|
36
|
+
@context = context
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
35
40
|
def match(_expected, actual)
|
36
41
|
raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
|
37
42
|
|
38
43
|
@policy ||= ::ActionPolicy.lookup(target)
|
44
|
+
@context ||= nil
|
39
45
|
|
40
46
|
begin
|
41
47
|
ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
|
@@ -45,7 +51,7 @@ module ActionPolicy
|
|
45
51
|
|
46
52
|
@actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
|
47
53
|
|
48
|
-
actual_calls.any? { _1.matches?(policy, rule, target) }
|
54
|
+
actual_calls.any? { _1.matches?(policy, rule, target, context) }
|
49
55
|
end
|
50
56
|
|
51
57
|
def does_not_match?(*)
|
@@ -57,6 +63,7 @@ module ActionPolicy
|
|
57
63
|
def failure_message
|
58
64
|
"expected #{formatted_record} " \
|
59
65
|
"to be authorized with #{policy}##{rule}, " \
|
66
|
+
"#{context ? "and context #{context.inspect}, " : ""}" \
|
60
67
|
"but #{actual_calls_message}"
|
61
68
|
end
|
62
69
|
|
@@ -61,7 +61,7 @@ module ActionPolicy
|
|
61
61
|
@_authorization_context ||= build_authorization_context
|
62
62
|
end
|
63
63
|
|
64
|
-
def build_authorization_context
|
64
|
+
private def build_authorization_context
|
65
65
|
self.class.authorization_targets
|
66
66
|
.each_with_object({}) do |(key, meth), obj|
|
67
67
|
obj[key] = send(meth)
|
@@ -75,7 +75,7 @@ module ActionPolicy
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def lookup_authorization_policy(record, with: nil, **options) # :nodoc:
|
78
|
-
if
|
78
|
+
if :__undef__ == record # rubocop:disable Style/YodaCondition
|
79
79
|
record =
|
80
80
|
if with
|
81
81
|
implicit_authorization_target
|
@@ -100,7 +100,7 @@ module ActionPolicy
|
|
100
100
|
# Enable namespace cache by default or
|
101
101
|
# if RACK_ENV provided and equal to "production"
|
102
102
|
self.namespace_cache_enabled =
|
103
|
-
!ENV["RACK_ENV"].nil? ? ENV["RACK_ENV"] == "production" : true
|
103
|
+
(!ENV["RACK_ENV"].nil?) ? ENV["RACK_ENV"] == "production" : true
|
104
104
|
|
105
105
|
# By self `policy_class` method
|
106
106
|
INSTANCE_POLICY_CLASS = ->(record, **) {
|
@@ -4,6 +4,14 @@ module ActionPolicy # :nodoc:
|
|
4
4
|
require "action_policy/rails/controller"
|
5
5
|
require "action_policy/rails/channel"
|
6
6
|
|
7
|
+
if defined?(::ActionController)
|
8
|
+
require "action_policy/rails/scope_matchers/action_controller_params"
|
9
|
+
end
|
10
|
+
|
11
|
+
if defined?(::ActiveRecord)
|
12
|
+
require "action_policy/rails/scope_matchers/active_record"
|
13
|
+
end
|
14
|
+
|
7
15
|
class Railtie < ::Rails::Railtie # :nodoc:
|
8
16
|
# Provides Rails-specific configuration,
|
9
17
|
# accessible through `Rails.application.config.action_policy`
|
@@ -81,8 +89,6 @@ module ActionPolicy # :nodoc:
|
|
81
89
|
::Rails.application.config.action_policy.namespace_cache_enabled
|
82
90
|
|
83
91
|
ActiveSupport.on_load(:action_controller) do
|
84
|
-
require "action_policy/rails/scope_matchers/action_controller_params"
|
85
|
-
|
86
92
|
next unless ::Rails.application.config.action_policy.auto_inject_into_controller
|
87
93
|
|
88
94
|
ActionController::Base.include ActionPolicy::Controller
|
@@ -104,7 +110,6 @@ module ActionPolicy # :nodoc:
|
|
104
110
|
|
105
111
|
ActiveSupport.on_load(:active_record) do
|
106
112
|
require "action_policy/rails/ext/active_record"
|
107
|
-
require "action_policy/rails/scope_matchers/active_record"
|
108
113
|
end
|
109
114
|
end
|
110
115
|
end
|
@@ -20,7 +20,7 @@ module ActionPolicy
|
|
20
20
|
# end
|
21
21
|
#
|
22
22
|
class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
|
23
|
-
attr_reader :rule, :target, :policy, :actual_calls
|
23
|
+
attr_reader :rule, :target, :policy, :actual_calls, :context
|
24
24
|
|
25
25
|
def initialize(rule, target)
|
26
26
|
@rule = rule
|
@@ -32,10 +32,16 @@ module ActionPolicy
|
|
32
32
|
self
|
33
33
|
end
|
34
34
|
|
35
|
+
def with_context(context)
|
36
|
+
@context = context
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
35
40
|
def match(_expected, actual)
|
36
41
|
raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
|
37
42
|
|
38
43
|
@policy ||= ::ActionPolicy.lookup(target)
|
44
|
+
@context ||= nil
|
39
45
|
|
40
46
|
begin
|
41
47
|
ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
|
@@ -45,7 +51,7 @@ module ActionPolicy
|
|
45
51
|
|
46
52
|
@actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
|
47
53
|
|
48
|
-
actual_calls.any? { _1.matches?(policy, rule, target) }
|
54
|
+
actual_calls.any? { _1.matches?(policy, rule, target, context) }
|
49
55
|
end
|
50
56
|
|
51
57
|
def does_not_match?(*)
|
@@ -57,6 +63,7 @@ module ActionPolicy
|
|
57
63
|
def failure_message
|
58
64
|
"expected #{formatted_record} " \
|
59
65
|
"to be authorized with #{policy}##{rule}, " \
|
66
|
+
"#{context ? "and context #{context.inspect}, " : ""}" \
|
60
67
|
"but #{actual_calls_message}"
|
61
68
|
end
|
62
69
|
|
@@ -36,7 +36,7 @@ module ActionPolicy
|
|
36
36
|
# get :show, id: user.id
|
37
37
|
# end
|
38
38
|
#
|
39
|
-
def assert_authorized_to(rule, target, with: nil)
|
39
|
+
def assert_authorized_to(rule, target, with: nil, context: {})
|
40
40
|
raise ArgumentError, "Block is required" unless block_given?
|
41
41
|
|
42
42
|
policy = with || ::ActionPolicy.lookup(target)
|
@@ -50,8 +50,9 @@ module ActionPolicy
|
|
50
50
|
actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
|
51
51
|
|
52
52
|
assert(
|
53
|
-
actual_calls.any? { |call| call.matches?(policy, rule, target) },
|
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
56
|
"but no such authorization has been made.\n" \
|
56
57
|
"Registered authorizations: " \
|
57
58
|
"#{actual_calls.empty? ? "none" : actual_calls.map(&:inspect).join(",")}"
|
@@ -13,14 +13,23 @@ module ActionPolicy
|
|
13
13
|
@rule = rule
|
14
14
|
end
|
15
15
|
|
16
|
-
def matches?(policy_class, actual_rule, target)
|
16
|
+
def matches?(policy_class, actual_rule, target, context)
|
17
17
|
policy_class == policy.class &&
|
18
18
|
(target.is_a?(Class) ? target == policy.record : target === policy.record) &&
|
19
|
-
rule == actual_rule
|
19
|
+
rule == actual_rule && context_matches?(context, policy.authorization_context)
|
20
20
|
end
|
21
21
|
|
22
22
|
def inspect
|
23
|
-
"#{policy.record.inspect} was authorized with #{policy.class}##{rule}"
|
23
|
+
"#{policy.record.inspect} was authorized with #{policy.class}##{rule} " \
|
24
|
+
"and context #{policy.authorization_context.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def context_matches?(context, actual)
|
30
|
+
return true unless context
|
31
|
+
|
32
|
+
context === actual || actual >= context
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
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.4
|
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: 2023-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next-core
|