action_policy 0.6.7 → 0.6.9

Sign up to get free protection for your applications and to get access to all the features.
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: []