action_policy 0.6.7 → 0.6.9

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/LICENSE.txt +1 -1
  4. data/lib/.rbnext/2.7/action_policy/behaviours/policy_for.rb +1 -1
  5. data/lib/.rbnext/2.7/action_policy/rails/scope_matchers/action_controller_params.rb +5 -3
  6. data/lib/.rbnext/2.7/action_policy/rails/scope_matchers/active_record.rb +13 -11
  7. data/lib/.rbnext/2.7/action_policy/rspec/be_authorized_to.rb +1 -1
  8. data/lib/.rbnext/2.7/action_policy/rspec/have_authorized_scope.rb +9 -3
  9. data/lib/.rbnext/3.0/action_policy/ext/policy_cache_key.rb +10 -10
  10. data/lib/.rbnext/3.0/action_policy/policy/core.rb +1 -1
  11. data/lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb +1 -1
  12. data/lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb +9 -3
  13. data/lib/.rbnext/3.0/action_policy/utils/suggest_message.rb +1 -1
  14. data/lib/.rbnext/3.1/action_policy/behaviours/policy_for.rb +1 -1
  15. data/lib/.rbnext/3.1/action_policy/ext/policy_cache_key.rb +10 -10
  16. data/lib/.rbnext/3.2/action_policy/behaviours/policy_for.rb +68 -0
  17. data/lib/.rbnext/3.2/action_policy/ext/policy_cache_key.rb +72 -0
  18. data/lib/.rbnext/3.2/action_policy/lookup_chain.rb +145 -0
  19. data/lib/.rbnext/3.2/action_policy/policy/core.rb +168 -0
  20. data/lib/.rbnext/3.2/action_policy/rspec/be_authorized_to.rb +96 -0
  21. data/lib/.rbnext/3.2/action_policy/rspec/have_authorized_scope.rb +130 -0
  22. data/lib/.rbnext/3.2/action_policy/utils/suggest_message.rb +19 -0
  23. data/lib/action_policy/rails/scope_matchers/action_controller_params.rb +5 -3
  24. data/lib/action_policy/rails/scope_matchers/active_record.rb +13 -11
  25. data/lib/action_policy/railtie.rb +4 -15
  26. data/lib/action_policy/rspec/have_authorized_scope.rb +8 -2
  27. data/lib/action_policy/test_helper.rb +5 -2
  28. data/lib/action_policy/testing.rb +17 -10
  29. data/lib/action_policy/version.rb +1 -1
  30. metadata +15 -8
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_policy/behaviours/policy_for"
4
+ require "action_policy/policy/execution_result"
5
+ require "action_policy/utils/suggest_message"
6
+ require "action_policy/utils/pretty_print"
7
+
8
+ unless "".respond_to?(:underscore)
9
+ require "action_policy/ext/string_underscore"
10
+ using ActionPolicy::Ext::StringUnderscore
11
+ end
12
+
13
+ module ActionPolicy
14
+ using RubyNext
15
+
16
+ # Raised when `resolve_rule` failed to find an approriate
17
+ # policy rule method for the activity
18
+ class UnknownRule < Error
19
+ include ActionPolicy::SuggestMessage
20
+
21
+ attr_reader :policy, :rule, :message
22
+
23
+ def initialize(policy, rule)
24
+ @policy = policy.class
25
+ @rule = rule
26
+ @message = "Couldn't find rule '#{@rule}' for #{@policy}" \
27
+ "#{suggest(@rule, @policy.instance_methods - Object.instance_methods)}"
28
+ end
29
+ end
30
+
31
+ class NonPredicateRule < UnknownRule
32
+ def initialize(policy, rule)
33
+ @policy = policy.class
34
+ @rule = rule
35
+ @message = "The rule '#{@rule}' of '#{@policy}' must ends with ? (question mark)\nDid you mean? #{@rule}?"
36
+ end
37
+ end
38
+
39
+ module Policy
40
+ # Core policy API
41
+ module Core
42
+ class << self
43
+ def included(base)
44
+ base.extend ClassMethods
45
+
46
+ # Generate a new class for each _policy chain_
47
+ # in order to extend it independently
48
+ base.module_eval do
49
+ @result_class = Class.new(ExecutionResult)
50
+
51
+ # we need to make this class _named_,
52
+ # 'cause anonymous classes couldn't be marshalled
53
+ base.const_set(:APR, @result_class)
54
+ end
55
+ end
56
+ end
57
+
58
+ module ClassMethods # :nodoc:
59
+ attr_writer :identifier
60
+
61
+ def result_class
62
+ return @result_class if instance_variable_defined?(:@result_class)
63
+ @result_class = superclass.result_class
64
+ end
65
+
66
+ def identifier
67
+ return @identifier if instance_variable_defined?(:@identifier)
68
+
69
+ @identifier = name.sub(/Policy$/, "").underscore.to_sym
70
+ end
71
+ end
72
+
73
+ include ActionPolicy::Behaviours::PolicyFor
74
+
75
+ attr_reader :record, :result
76
+
77
+ # NEXT_RELEASE: deprecate `record` arg, migrate to `record: nil`
78
+ def initialize(record = nil, *__rest__)
79
+ @record = record
80
+ end
81
+
82
+ # Returns a result of applying the specified rule (true of false).
83
+ # Unlike simply calling a predicate rule (`policy.manage?`),
84
+ # `apply` also calls pre-checks.
85
+ def apply(rule)
86
+ @result = self.class.result_class.new(self.class, rule)
87
+
88
+ catch :policy_fulfilled do
89
+ result.load __apply__(resolve_rule(rule))
90
+ end
91
+
92
+ result.value
93
+ end
94
+
95
+ def deny!
96
+ result&.load false
97
+ throw :policy_fulfilled
98
+ end
99
+
100
+ def allow!
101
+ result&.load true
102
+ throw :policy_fulfilled
103
+ end
104
+
105
+ # This method performs the rule call.
106
+ # Override or extend it to provide custom functionality
107
+ # (such as caching, pre checks, etc.)
108
+ def __apply__(rule) = public_send(rule)
109
+
110
+ # Wrap code that could modify result
111
+ # to prevent the current result modification
112
+ def with_clean_result # :nodoc:
113
+ was_result = @result
114
+ yield
115
+ @result
116
+ ensure
117
+ @result = was_result
118
+ end
119
+
120
+ # Returns a result of applying the specified rule to the specified record.
121
+ # Under the hood a policy class for record is resolved
122
+ # (unless it's explicitly set through `with` option).
123
+ #
124
+ # If record is `nil` then we uses the current policy.
125
+ def allowed_to?(rule, record = :__undef__, **options)
126
+ if (record == :__undef__ || record == self.record) && options.empty?
127
+ __apply__(resolve_rule(rule))
128
+ else
129
+ policy_for(record: record, **options).then do |policy|
130
+ policy.apply(policy.resolve_rule(rule))
131
+ end
132
+ end
133
+ end
134
+
135
+ # An alias for readability purposes
136
+ def check?(*args, **hargs) = allowed_to?(*args, **hargs)
137
+
138
+ # Returns a rule name (policy method name) for activity.
139
+ #
140
+ # By default, rule name is equal to activity name.
141
+ #
142
+ # Raises ActionPolicy::UnknownRule when rule is not found in policy.
143
+ def resolve_rule(activity)
144
+ raise UnknownRule.new(self, activity) unless
145
+ respond_to?(activity)
146
+ activity
147
+ end
148
+
149
+ # Return annotated source code for the rule
150
+ # NOTE: require "method_source" and "unparser" gems to be installed.
151
+ # Otherwise returns empty string.
152
+ def inspect_rule(rule) = PrettyPrint.print_method(self, rule)
153
+
154
+ # Helper for printing the annotated rule source.
155
+ # Useful for debugging: type `pp :show?` within the context of the policy
156
+ # to preview the rule.
157
+ def pp(rule)
158
+ with_clean_result do
159
+ # We need result to exist for `allowed_to?` to work correctly
160
+ @result = self.class.result_class.new(self.class, rule)
161
+ header = "#{self.class.name}##{rule}"
162
+ source = inspect_rule(rule)
163
+ $stdout.puts "#{header}\n#{source}"
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_policy/testing"
4
+
5
+ module ActionPolicy
6
+ module RSpec
7
+ # Authorization matcher `be_authorized_to`.
8
+ #
9
+ # Verifies that a block of code has been authorized using specific policy.
10
+ #
11
+ # Example:
12
+ #
13
+ # # in controller/request specs
14
+ # subject { patch :update, id: product.id }
15
+ #
16
+ # it "is authorized" do
17
+ # expect { subject }
18
+ # .to be_authorized_to(:manage?, product)
19
+ # .with(ProductPolicy)
20
+ # end
21
+ #
22
+ class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
+ attr_reader :rule, :target, :policy, :actual_calls, :context
24
+
25
+ def initialize(rule, target)
26
+ @rule = rule
27
+ @target = target
28
+ end
29
+
30
+ def with(policy)
31
+ @policy = policy
32
+ self
33
+ end
34
+
35
+ def with_context(context)
36
+ @context = context
37
+ self
38
+ end
39
+
40
+ def match(_expected, actual)
41
+ raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
42
+
43
+ @policy ||= ::ActionPolicy.lookup(target)
44
+ @context ||= nil
45
+
46
+ begin
47
+ ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
48
+ rescue ActionPolicy::Unauthorized
49
+ # we don't want to care about authorization result
50
+ end
51
+
52
+ @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
53
+
54
+ actual_calls.any? { _1.matches?(policy, rule, target, context) }
55
+ end
56
+
57
+ def does_not_match?(*__rest__)
58
+ raise "This matcher doesn't support negation"
59
+ end
60
+
61
+ def supports_block_expectations?() = true
62
+
63
+ def failure_message
64
+ "expected #{formatted_record} " \
65
+ "to be authorized with #{policy}##{rule}, " \
66
+ "#{context ? "and context #{context.inspect}, " : ""}" \
67
+ "but #{actual_calls_message}"
68
+ end
69
+
70
+ def actual_calls_message
71
+ if actual_calls.empty?
72
+ "no authorization calls have been made"
73
+ else
74
+ "the following calls were encountered:\n" \
75
+ "#{formatted_calls}"
76
+ end
77
+ end
78
+
79
+ def formatted_calls
80
+ actual_calls.map do
81
+ " - #{_1.inspect}"
82
+ end.join("\n")
83
+ end
84
+
85
+ def formatted_record(record = target) = ::RSpec::Support::ObjectFormatter.format(record)
86
+ end
87
+ end
88
+ end
89
+
90
+ RSpec.configure do |config|
91
+ config.include(Module.new do
92
+ def be_authorized_to(rule, target)
93
+ ActionPolicy::RSpec::BeAuthorizedTo.new(rule, target)
94
+ end
95
+ end)
96
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_policy/testing"
4
+
5
+ module ActionPolicy
6
+ module RSpec
7
+ # Implements `have_authorized_scope` matcher.
8
+ #
9
+ # Verifies that a block of code applies authorization scoping using specific policy.
10
+ #
11
+ # Example:
12
+ #
13
+ # # in controller/request specs
14
+ # subject { get :index }
15
+ #
16
+ # it "has authorized scope" do
17
+ # expect { subject }
18
+ # .to have_authorized_scope(:active_record_relation)
19
+ # .with(ProductPolicy)
20
+ # end
21
+ #
22
+ class HaveAuthorizedScope < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
+ attr_reader :type, :name, :policy, :scope_options, :actual_scopes,
24
+ :target_expectations, :context
25
+
26
+ def initialize(type)
27
+ @type = type
28
+ @name = :default
29
+ @scope_options = nil
30
+ end
31
+
32
+ def with(policy)
33
+ @policy = policy
34
+ self
35
+ end
36
+
37
+ def as(name)
38
+ @name = name
39
+ self
40
+ end
41
+
42
+ def with_scope_options(scope_options)
43
+ @scope_options = scope_options
44
+ self
45
+ end
46
+
47
+ def with_target(&block)
48
+ @target_expectations = block
49
+ self
50
+ end
51
+
52
+ def with_context(context)
53
+ @context = context
54
+ self
55
+ end
56
+
57
+ def match(_expected, actual)
58
+ raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
59
+
60
+ ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
61
+
62
+ @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
63
+
64
+ matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options, context) }
65
+
66
+ return false if matching_scopes.empty?
67
+
68
+ return true unless target_expectations
69
+
70
+ if matching_scopes.size > 1
71
+ raise "Too many matching scopings (#{matching_scopes.size}), " \
72
+ "you can run `.with_target` only when there is the only one match"
73
+ end
74
+
75
+ target_expectations.call(matching_scopes.first.target)
76
+ true
77
+ end
78
+
79
+ def does_not_match?(*__rest__)
80
+ raise "This matcher doesn't support negation"
81
+ end
82
+
83
+ def supports_block_expectations?() = true
84
+
85
+ def failure_message
86
+ "expected a scoping named :#{name} for type :#{type} " \
87
+ "#{scope_options_message} " \
88
+ "#{context ? "and context #{context.inspect} " : ""}" \
89
+ "from #{policy} to have been applied, " \
90
+ "but #{actual_scopes_message}"
91
+ end
92
+
93
+ def scope_options_message
94
+ if scope_options
95
+ if defined?(::RSpec::Matchers::Composable) &&
96
+ scope_options.is_a?(::RSpec::Matchers::Composable)
97
+ "with scope options #{scope_options.description}"
98
+ else
99
+ "with scope options #{scope_options}"
100
+ end
101
+ else
102
+ "without scope options"
103
+ end
104
+ end
105
+
106
+ def actual_scopes_message
107
+ if actual_scopes.empty?
108
+ "no scopings have been made"
109
+ else
110
+ "the following scopings were encountered:\n" \
111
+ "#{formatted_scopings}"
112
+ end
113
+ end
114
+
115
+ def formatted_scopings
116
+ actual_scopes.map do
117
+ " - #{_1.inspect}"
118
+ end.join("\n")
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ RSpec.configure do |config|
125
+ config.include(Module.new do
126
+ def have_authorized_scope(type)
127
+ ActionPolicy::RSpec::HaveAuthorizedScope.new(type)
128
+ end
129
+ end)
130
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionPolicy
4
+ # Adds `suggest` method which uses did_you_mean
5
+ # to generate a suggestion message
6
+ module SuggestMessage
7
+ if defined?(::DidYouMean::SpellChecker)
8
+ def suggest(needle, heystack)
9
+ suggestion = ::DidYouMean::SpellChecker.new(
10
+ dictionary: heystack
11
+ ).correct(needle).first
12
+
13
+ suggestion ? "\nDid you mean? #{suggestion}" : ""
14
+ end
15
+ else
16
+ def suggest(*__rest__) = ""
17
+ end
18
+ end
19
+ end
@@ -12,8 +12,10 @@ module ActionPolicy
12
12
  end
13
13
  end
14
14
 
15
- # Register params scope matcher
16
- ActionPolicy::Base.scope_matcher :action_controller_params, ActionController::Parameters
17
-
18
15
  # Add alias to base policy
19
16
  ActionPolicy::Base.extend ActionPolicy::ScopeMatchers::ActionControllerParams
17
+
18
+ ActiveSupport.on_load(:action_controller) do
19
+ # Register params scope matcher
20
+ ActionPolicy::Base.scope_matcher :action_controller_params, ActionController::Parameters
21
+ end
@@ -12,18 +12,20 @@ module ActionPolicy
12
12
  end
13
13
  end
14
14
 
15
- # Register relation scope matcher
16
- ActionPolicy::Base.scope_matcher :active_record_relation, ActiveRecord::Relation
17
-
18
15
  # Add alias to base policy
19
16
  ActionPolicy::Base.extend ActionPolicy::ScopeMatchers::ActiveRecord
20
17
 
21
- ActiveRecord::Relation.include(Module.new do
22
- def policy_name
23
- if model.respond_to?(:policy_name)
24
- model.policy_name.to_s
25
- else
26
- "#{model}Policy"
18
+ ActiveSupport.on_load(:active_record) do
19
+ # Register relation scope matcher
20
+ ActionPolicy::Base.scope_matcher :active_record_relation, ActiveRecord::Relation
21
+
22
+ ActiveRecord::Relation.include(Module.new do
23
+ def policy_name
24
+ if model.respond_to?(:policy_name)
25
+ model.policy_name.to_s
26
+ else
27
+ "#{model}Policy"
28
+ end
27
29
  end
28
- end
29
- end)
30
+ end)
31
+ end
@@ -74,8 +74,6 @@ module ActionPolicy # :nodoc:
74
74
  app.config.action_policy.namespace_cache_enabled
75
75
 
76
76
  ActiveSupport.on_load(:action_controller) do
77
- require "action_policy/rails/scope_matchers/action_controller_params"
78
-
79
77
  next unless app.config.action_policy.auto_inject_into_controller
80
78
 
81
79
  ActionController::Base.include ActionPolicy::Controller
@@ -95,21 +93,12 @@ module ActionPolicy # :nodoc:
95
93
  ActionCable::Channel::Base.authorize :user, through: :current_user
96
94
  end
97
95
 
96
+ # Scope matchers
97
+ require "action_policy/rails/scope_matchers/action_controller_params"
98
+ require "action_policy/rails/scope_matchers/active_record"
99
+
98
100
  ActiveSupport.on_load(:active_record) do
99
101
  require "action_policy/rails/ext/active_record"
100
- require "action_policy/rails/scope_matchers/active_record"
101
- end
102
-
103
- # Trigger load hooks of the components that extend ActionPolicy itself
104
- # (e.g., scope matchers)
105
- begin
106
- ::ActionController::Base
107
- rescue NameError
108
- end
109
-
110
- begin
111
- ::ActiveRecord::Base
112
- rescue NameError
113
102
  end
114
103
  end
115
104
  end
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  #
22
22
  class HaveAuthorizedScope < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
23
  attr_reader :type, :name, :policy, :scope_options, :actual_scopes,
24
- :target_expectations
24
+ :target_expectations, :context
25
25
 
26
26
  def initialize(type)
27
27
  @type = type
@@ -49,6 +49,11 @@ module ActionPolicy
49
49
  self
50
50
  end
51
51
 
52
+ def with_context(context)
53
+ @context = context
54
+ self
55
+ end
56
+
52
57
  def match(_expected, actual)
53
58
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
54
59
 
@@ -56,7 +61,7 @@ module ActionPolicy
56
61
 
57
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
58
63
 
59
- matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options) }
64
+ matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options, context) }
60
65
 
61
66
  return false if matching_scopes.empty?
62
67
 
@@ -80,6 +85,7 @@ module ActionPolicy
80
85
  def failure_message
81
86
  "expected a scoping named :#{name} for type :#{type} " \
82
87
  "#{scope_options_message} " \
88
+ "#{context ? "and context #{context.inspect} " : ""}" \
83
89
  "from #{policy} to have been applied, " \
84
90
  "but #{actual_scopes_message}"
85
91
  end
@@ -82,7 +82,7 @@ module ActionPolicy
82
82
  # end
83
83
  # end
84
84
  #
85
- def assert_have_authorized_scope(type:, with:, as: :default, scope_options: nil)
85
+ def assert_have_authorized_scope(type:, with:, as: :default, scope_options: nil, context: {})
86
86
  raise ArgumentError, "Block is required" unless block_given?
87
87
 
88
88
  policy = with
@@ -97,10 +97,13 @@ module ActionPolicy
97
97
  "without scope options"
98
98
  end
99
99
 
100
+ context_message = context.empty? ? "without context" : "with context: #{context}"
101
+
100
102
  assert(
101
- actual_scopes.any? { |scope| scope.matches?(policy, type, as, scope_options) },
103
+ actual_scopes.any? { |scope| scope.matches?(policy, type, as, scope_options, context) },
102
104
  "Expected a scoping named :#{as} for :#{type} type " \
103
105
  "#{scope_options_message} " \
106
+ "and #{context_message} " \
104
107
  "from #{policy} to have been applied, " \
105
108
  "but no such scoping has been made.\n" \
106
109
  "Registered scopings: " \
@@ -5,7 +5,19 @@ module ActionPolicy
5
5
  module Testing
6
6
  # Collects all Authorizer calls
7
7
  module AuthorizeTracker
8
+ module Context
9
+ private
10
+
11
+ def context_matches?(context, actual)
12
+ return true unless context
13
+
14
+ context === actual || actual >= context
15
+ end
16
+ end
17
+
8
18
  class Call # :nodoc:
19
+ include Context
20
+
9
21
  attr_reader :policy, :rule
10
22
 
11
23
  def initialize(policy, rule)
@@ -23,17 +35,11 @@ module ActionPolicy
23
35
  "#{policy.record.inspect} was authorized with #{policy.class}##{rule} " \
24
36
  "and context #{policy.authorization_context.inspect}"
25
37
  end
26
-
27
- private
28
-
29
- def context_matches?(context, actual)
30
- return true unless context
31
-
32
- context === actual || actual >= context
33
- end
34
38
  end
35
39
 
36
40
  class Scoping # :nodoc:
41
+ include Context
42
+
37
43
  attr_reader :policy, :target, :type, :name, :scope_options
38
44
 
39
45
  def initialize(policy, target, type, name, scope_options)
@@ -44,11 +50,12 @@ module ActionPolicy
44
50
  @scope_options = scope_options
45
51
  end
46
52
 
47
- def matches?(policy_class, actual_type, actual_name, actual_scope_options)
53
+ def matches?(policy_class, actual_type, actual_name, actual_scope_options, actual_context)
48
54
  policy_class == policy.class &&
49
55
  type == actual_type &&
50
56
  name == actual_name &&
51
- actual_scope_options === scope_options
57
+ actual_scope_options === scope_options &&
58
+ context_matches?(actual_context, policy.authorization_context)
52
59
  end
53
60
 
54
61
  def inspect
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.6.7"
4
+ VERSION = "0.6.9"
5
5
  end
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.7
4
+ version: 0.6.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-14 00:00:00.000000000 Z
11
+ date: 2024-04-19 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.14.0
19
+ version: '1.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.14.0
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ammeter
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -162,6 +162,13 @@ files:
162
162
  - lib/.rbnext/3.1/action_policy/ext/module_namespace.rb
163
163
  - lib/.rbnext/3.1/action_policy/ext/policy_cache_key.rb
164
164
  - lib/.rbnext/3.1/action_policy/policy/authorization.rb
165
+ - lib/.rbnext/3.2/action_policy/behaviours/policy_for.rb
166
+ - lib/.rbnext/3.2/action_policy/ext/policy_cache_key.rb
167
+ - lib/.rbnext/3.2/action_policy/lookup_chain.rb
168
+ - lib/.rbnext/3.2/action_policy/policy/core.rb
169
+ - lib/.rbnext/3.2/action_policy/rspec/be_authorized_to.rb
170
+ - lib/.rbnext/3.2/action_policy/rspec/have_authorized_scope.rb
171
+ - lib/.rbnext/3.2/action_policy/utils/suggest_message.rb
165
172
  - lib/action_policy.rb
166
173
  - lib/action_policy/authorizer.rb
167
174
  - lib/action_policy/base.rb
@@ -227,7 +234,7 @@ metadata:
227
234
  documentation_uri: https://actionpolicy.evilmartians.io/
228
235
  homepage_uri: https://actionpolicy.evilmartians.io/
229
236
  source_code_uri: http://github.com/palkan/action_policy
230
- post_install_message:
237
+ post_install_message:
231
238
  rdoc_options: []
232
239
  require_paths:
233
240
  - lib
@@ -242,8 +249,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
242
249
  - !ruby/object:Gem::Version
243
250
  version: '0'
244
251
  requirements: []
245
- rubygems_version: 3.4.8
246
- signing_key:
252
+ rubygems_version: 3.4.19
253
+ signing_key:
247
254
  specification_version: 4
248
255
  summary: Authorization framework for Ruby/Rails application
249
256
  test_files: []