action_policy 0.4.3 → 0.4.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6530513fc2b087beae97b3b33e662f421a0f12911a1e21b2cce9778dc7f693c9
4
- data.tar.gz: a915127b22da7b43cb0fc1aa1048c8a4d9c0b5a51f458039594eac17b29e92bc
3
+ metadata.gz: aa234de7b74f58df4707ec00f9f4d67bee0d89fb721f2b0e4df90627970530e6
4
+ data.tar.gz: e6e4ba56d3be720b8ddac3a236f42c84eec2472d04b95213914d89e23d291bf7
5
5
  SHA512:
6
- metadata.gz: 2a34ac6a7ab8289521e2ccb977ed6c6b6e655a185deb053676aad2d78674b7367d04c75abd552dafd59b1ae46465cfa117ae97239b9fd2e3cc6947d020d80775
7
- data.tar.gz: 991f5b553314cf11dedaab9964d5d4b4ee384877474ed6dc814fa0c4d4bdf383b8288df46bf987a437b82a33f859ac5314a1c4bd75b1df28d8a2438886f37c40
6
+ metadata.gz: 450572c0987f8d4174ff6c51fdd188d62bd5dfd288b381a593030ee9ef8575df74852b1600706f6dfb1c115fddb9a45e518f03b2dd0a118e653c0a13c0efc05a
7
+ data.tar.gz: 1fa6dac85f5fe5f014026d23357c08e9dba0101b68a07a96315275a1ce2aa28762ab82abffbf0ae985a9a277d942de23c521223d485b7acfe1fdceeae9c4179d
@@ -1,5 +1,5 @@
1
1
  <!--
2
- This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason,
2
+ This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason,
3
3
  feel free to skip the rest of this template.
4
4
  -->
5
5
 
@@ -11,6 +11,9 @@
11
11
 
12
12
  **Action Policy Version:**
13
13
 
14
+ **Reproduction Script:** Use [this template](https://github.com/palkan/action_policy/blob/master/.github/bug_report_template.rb) to
15
+ create a standalone reproduction script. That would help us to fix the problem quicker. Thanks!
16
+
14
17
  ### What did you do?
15
18
 
16
19
  ### What did you expect to happen?
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/inline"
4
+
5
+ # This reproduction script allows you to test Action Policy with Rails.
6
+ # It contains:
7
+ # - Headless User model
8
+ # - UserPolicy
9
+ # - UsersController
10
+ # - Example tests for the controller.
11
+ #
12
+ # Update the classes to reproduce the failing case.
13
+ #
14
+ # Run the script as follows:
15
+ #
16
+ # $ ruby bug_report_template.rb
17
+ gemfile(true) do
18
+ source "https://rubygems.org"
19
+
20
+ gem "rails", "~> 6.0"
21
+ gem "action_policy", "~> 0.4"
22
+
23
+ gem "pry-byebug", platform: :mri
24
+ end
25
+
26
+ require "rails"
27
+ require "action_controller/railtie"
28
+ require "action_policy"
29
+
30
+ require "minitest/autorun"
31
+
32
+ module Buggy
33
+ class Application < Rails::Application
34
+ config.logger = Logger.new("/dev/null")
35
+ config.eager_load = false
36
+
37
+ initializer "routes" do
38
+ Rails.application.routes.draw do
39
+ get ":controller(/:action)"
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ Rails.application.initialize!
46
+
47
+ class User
48
+ include Comparable
49
+
50
+ attr_reader :name
51
+
52
+ def initialize(name)
53
+ @name = name
54
+ end
55
+
56
+ def admin?
57
+ name == "admin"
58
+ end
59
+
60
+ def <=>(other)
61
+ return super unless other.is_a?(User)
62
+ name <=> other.name
63
+ end
64
+ end
65
+
66
+ class UserPolicy < ActionPolicy::Base
67
+ def index?
68
+ true
69
+ end
70
+
71
+ def create?
72
+ user.admin?
73
+ end
74
+
75
+ def show?
76
+ true
77
+ end
78
+
79
+ def manage?
80
+ user.admin? && !record.admin?
81
+ end
82
+ end
83
+
84
+ class UsersController < ActionController::Base
85
+ authorize :user, through: :current_user
86
+
87
+ before_action :set_user, only: [:update, :show]
88
+
89
+ def index
90
+ authorize!
91
+ render plain: "OK"
92
+ end
93
+
94
+ def create
95
+ authorize!
96
+ render plain: "OK"
97
+ end
98
+
99
+ def update
100
+ render plain: "OK"
101
+ end
102
+
103
+ def show
104
+ if allowed_to?(:update?, @user)
105
+ render plain: "OK"
106
+ else
107
+ render plain: "Read-only"
108
+ end
109
+ end
110
+
111
+ def current_user
112
+ @current_user ||= User.new(params[:user])
113
+ end
114
+
115
+ private
116
+
117
+ def set_user
118
+ @user = User.new(params[:target])
119
+ authorize! @user
120
+ end
121
+ end
122
+
123
+ class TestBugReproduction < ActionController::TestCase
124
+ tests UsersController
125
+
126
+ def before_setup
127
+ @routes = Rails.application.routes
128
+ super
129
+ end
130
+
131
+ def teardown
132
+ ActionPolicy::PerThreadCache.clear_all
133
+ end
134
+
135
+ def test_index
136
+ get :index, params: {user: "guest"}
137
+ assert_equal "OK", response.body
138
+ end
139
+
140
+ def test_create_failed
141
+ e = assert_raises(ActionPolicy::Unauthorized) do
142
+ post :create, params: {user: "guest"}
143
+ end
144
+
145
+ assert_equal UserPolicy, e.policy
146
+ assert_equal :create?, e.rule
147
+ assert e.result.reasons.is_a?(::ActionPolicy::Policy::FailureReasons)
148
+ end
149
+
150
+ def test_create_succeed
151
+ post :create, params: {user: "admin"}
152
+ assert_equal "OK", response.body
153
+ end
154
+
155
+ def test_update_failed
156
+ assert_raises(ActionPolicy::Unauthorized) do
157
+ patch :update, params: {user: "admin", target: "admin"}
158
+ end
159
+ end
160
+
161
+ def test_update_succeed
162
+ patch :update, params: {user: "admin", target: "guest"}
163
+ assert_equal "OK", response.body
164
+ end
165
+
166
+ def test_show
167
+ get :show, params: {user: "admin", target: "guest"}
168
+ assert_equal "OK", response.body
169
+ end
170
+
171
+ def test_show_admin
172
+ get :show, params: {user: "admin", target: "admin"}
173
+ assert_equal "Read-only", response.body
174
+ end
175
+ end
@@ -2,6 +2,23 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.4.4 (2020-07-07)
6
+
7
+ - Fix symbol lookup with namespaces. ([@palkan][])
8
+
9
+ Fixes [#122](https://github.com/palkan/action_policy/issues/122).
10
+
11
+ - Separated `#classify`-based and `#camelize`-based symbol lookups. ([Be-ngt-oH][])
12
+
13
+ Only affects Rails apps. Now lookup for `:users` tries to find `UsersPolicy` first (camelize),
14
+ and only then search for `UserPolicy` (classify).
15
+
16
+ See [PR#118](https://github.com/palkan/action_policy/pull/118).
17
+
18
+ - Fix calling rules with `allowed_to?` directly. ([@palkan][])
19
+
20
+ Fixes [#113](https://github.com/palkan/action_policy/issues/113)
21
+
5
22
  ## 0.4.3 (2019-12-14)
6
23
 
7
24
  - Add `#cache(*parts, **options) { ... }` method. ([@palkan][])
@@ -382,3 +399,4 @@
382
399
  [@korolvs]: https://github.com/korolvs
383
400
  [@nicolas-brousse]: https://github.com/nicolas-brousse
384
401
  [@somenugget]: https://github.com/somenugget
402
+ [@Be-ngt-oH]: https://github.com/Be-ngt-oH
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018-2019 Vladimir Dementyev
3
+ Copyright (c) 2018-2020 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
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [![Build Status](https://travis-ci.org/palkan/action_policy.svg?branch=master)](https://travis-ci.org/palkan/action_policy)
3
3
  [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://actionpolicy.evilmartians.io)
4
4
 
5
- # ActionPolicy
5
+ # Action Policy
6
6
 
7
7
  Authorization framework for Ruby and Rails applications.
8
8
 
@@ -98,7 +98,7 @@ There is also an `allowed_to?` method which returns `true` or `false`, and could
98
98
  <% @posts.each do |post| %>
99
99
  <li><%= post.title %>
100
100
  <% if allowed_to?(:edit?, post) %>
101
- = link_to post, "Edit"
101
+ <%= link_to post, "Edit">
102
102
  <% end %>
103
103
  </li>
104
104
  <% end %>
@@ -121,8 +121,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/palkan
121
121
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
122
122
 
123
123
  [Documentation]: http://actionpolicy.evilmartians.io
124
-
125
- ## Security Contact
126
-
127
- To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
128
-
@@ -39,6 +39,9 @@ if ENV["NO_CACHE"]
39
39
  ActionPolicy::LookupChain.namespace_cache_enabled = false
40
40
  end
41
41
 
42
+ results_path = File.join(__dir__, "../tmp/#{__FILE__.sub(/\.rb$/, ".txt")}")
43
+ FileUtils.mkdir_p File.dirname(results_path)
44
+
42
45
  Benchmark.ips do |x|
43
46
  x.warmup = 0
44
47
 
@@ -58,14 +61,14 @@ Benchmark.ips do |x|
58
61
  ActionPolicy.lookup(b, namespace: X::Y::Z)
59
62
  end
60
63
 
61
- x.hold! "temp_results"
64
+ x.hold! results_path
62
65
 
63
66
  x.compare!
64
67
  end
65
68
 
66
69
  #
67
70
  # Comparison:
68
- # cache B: 178577.4 i/s
69
- # cache A: 173061.4 i/s - same-ish: difference falls within error
70
- # no cache A: 97991.7 i/s - same-ish: difference falls within error
71
- # no cache B: 42505.4 i/s - 4.20x slower
71
+ # cache A: 204788.3 i/s
72
+ # cache B: 202536.9 i/s - same-ish: difference falls within error
73
+ # no cache A: 127772.8 i/s - same-ish: difference falls within error
74
+ # no cache B: 63487.2 i/s - 3.23x slower
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This benchmark measures the difference between catch/throw and jump-less implementation.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
6
+
7
+ require "action_policy"
8
+ require "benchmark/ips"
9
+
10
+ GC.disable
11
+
12
+ class A; end
13
+
14
+ class B; end
15
+
16
+ class APolicy < ActionPolicy::Base
17
+ authorize :user, optional: true
18
+
19
+ pre_check :do_nothing, :deny_all
20
+
21
+ def show?
22
+ true
23
+ end
24
+
25
+ def do_nothing
26
+ end
27
+
28
+ def deny_all
29
+ deny!
30
+ end
31
+ end
32
+
33
+ class BPolicy < APolicy
34
+ def run_pre_checks(rule)
35
+ catch :policy_fulfilled do
36
+ self.class.pre_checks.each do |check|
37
+ next unless check.applicable?(rule)
38
+ check.call(self)
39
+ end
40
+
41
+ return yield if block_given?
42
+ end
43
+
44
+ result.value
45
+ end
46
+
47
+ def deny!
48
+ result.load false
49
+ throw :policy_fulfilled
50
+ end
51
+ end
52
+
53
+ a = A.new
54
+
55
+ (APolicy.new(record: a).apply(:show?) == BPolicy.new(record: a).apply(:show?)) || raise("Implementations are not equal")
56
+
57
+ Benchmark.ips do |x|
58
+ x.warmup = 0
59
+
60
+ x.report("loop pre-check") do
61
+ APolicy.new(record: a).apply(:show?)
62
+ end
63
+
64
+ x.report("catch/throw pre-check") do
65
+ BPolicy.new(record: a).apply(:show?)
66
+ end
67
+
68
+ x.compare!
69
+ end
70
+
71
+ # Comparison:
72
+ # catch/throw pre-check: 286094.2 i/s
73
+ # loop pre-check: 184786.1 i/s - 1.55x slower
@@ -162,7 +162,7 @@ Rails.application.configure do |config|
162
162
  end
163
163
  ```
164
164
 
165
- Cache store must provide at least a `#read(key)` and `write(key, value, **options)` methods.
165
+ Cache store must provide at least a `#read(key)` and `#write(key, value, **options)` methods.
166
166
 
167
167
  **NOTE:** cache store also should take care of serialiation/deserialization since the `value` is `ExecutionResult` instance (which contains also some additional information, e.g. failure reasons). Rails cache store supports serialization/deserialization out-of-the-box.
168
168
 
@@ -2,7 +2,12 @@
2
2
 
3
3
  Action Policy tries to automatically infer policy class from the target using the following _probes_:
4
4
 
5
- 1. If the target is a `Symbol`, then use `"#{target.to_s.classify}Policy"` as a `policy_name` (see below);
5
+ 1. If the target is a `Symbol`:
6
+
7
+ a) Try `"#{target.to_s.camelize}Policy"` as a `policy_name` (see below);
8
+
9
+ b) If `String#classify` is available, e.g. when using Rails' ActiveSupport, try `"#{target.to_s.classify}Policy"`;
10
+
6
11
  2. If the target responds to `policy_class`, then use it;
7
12
  3. If the target's class responds to `policy_class`, then use it;
8
13
  4. If the target or the target's class responds to `policy_name`, then use it (the `policy_name` should end with `Policy` as it's not appended automatically);
@@ -6,7 +6,7 @@ Consider an example:
6
6
 
7
7
  ```ruby
8
8
  module Admin
9
- class UsersController < ApplictionController
9
+ class UsersController < ApplicationController
10
10
  def index
11
11
  # uses Admin::UserPolicy if any, otherwise fallbacks to UserPolicy
12
12
  authorize!
@@ -20,7 +20,7 @@ Module nesting is also supported:
20
20
  ```ruby
21
21
  module Admin
22
22
  module Client
23
- class UsersController < ApplictionController
23
+ class UsersController < ApplicationController
24
24
  def index
25
25
  # lookup for Admin::Client::UserPolicy -> Admin::UserPolicy -> UserPolicy
26
26
  authorize!
@@ -98,7 +98,7 @@ There is also an `allowed_to?` method which returns `true` or `false` and could
98
98
  <% @posts.each do |post| %>
99
99
  <li><%= post.title %>
100
100
  <% if allowed_to?(:edit?, post) %>
101
- = link_to "Edit", post
101
+ <%= link_to "Edit", post %>
102
102
  <% end %>
103
103
  </li>
104
104
  <% end %>
@@ -112,6 +112,8 @@ OR
112
112
 
113
113
  ### Testing scopes
114
114
 
115
+ #### Active Record relation example
116
+
115
117
  There is no single rule on how to test scopes, 'cause it dependes on the _nature_ of the scope.
116
118
 
117
119
  Here's an example of RSpec tests for Active Record scoping rules:
@@ -156,6 +158,35 @@ describe PostPolicy do
156
158
  end
157
159
  ```
158
160
 
161
+ #### Action Controller params example
162
+
163
+ Here's an example of RSpec tests for Action Controller parameters scoping rules:
164
+
165
+ ```ruby
166
+ describe PostPolicy do
167
+ describe "params scope" do
168
+ let(:user) { build_stubbed :user }
169
+ let(:context) { {user: user} }
170
+
171
+ let(:params) { {name: "a", password: "b"} }
172
+ let(:target) { ActionController::Parameters.new(params) }
173
+
174
+ # it's easier to asses the hash representation, not the AC::Params object
175
+ subject { policy.apply_scope(target, type: :action_controller_params).to_h }
176
+
177
+ context "as user" do
178
+ it { is_expected.to eq({name: "a"}) }
179
+ end
180
+
181
+ context "as manager" do
182
+ before { user.update!(role: :manager) }
183
+
184
+ it { is_expected.to eq({name: "a", password: "b"}) }
185
+ end
186
+ end
187
+ end
188
+ ```
189
+
159
190
  ## Testing authorization
160
191
 
161
192
  To test the act of authorization you have to make sure that the `authorize!` method is called with the appropriate arguments.
@@ -331,3 +362,29 @@ expect { subject }.to have_authorized_scope(:scope)
331
362
  expect(target).to eq(User.all)
332
363
  }
333
364
  ```
365
+
366
+
367
+ ## Testing views
368
+
369
+ When you test views that call policies methods as `allowed_to?`, your may have `Missing policy authorization context: user` error.
370
+ You may need to stub `current_user` to resolve the issue.
371
+
372
+ Consider an RSpec example:
373
+
374
+ ```ruby
375
+ describe "users/index.html.slim" do
376
+ let(:user) { build_stubbed :user }
377
+ let(:users) { create_list(:user, 2) }
378
+
379
+ before do
380
+ allow(controller).to receive(:current_user).and_return(user)
381
+
382
+ assign :users, users
383
+ render
384
+ end
385
+
386
+ describe "displays user#index correctly" do
387
+ it { expect(rendered).to have_link(users.first.email, href: edit_user_path(users.first)) }
388
+ end
389
+ end
390
+ ```
@@ -2,15 +2,15 @@
2
2
 
3
3
  module ActionPolicy
4
4
  module Ext
5
- # Add `classify` to Symbol
6
- module SymbolClassify
5
+ # Add `camelize` to Symbol
6
+ module SymbolCamelize
7
7
  refine Symbol do
8
- if "".respond_to?(:classify)
9
- def classify
10
- to_s.classify
8
+ if "".respond_to?(:camelize)
9
+ def camelize
10
+ to_s.camelize
11
11
  end
12
12
  else
13
- def classify
13
+ def camelize
14
14
  word = to_s.capitalize
15
15
  word.gsub!(/(?:_)([a-z\d]*)/) { $1.capitalize }
16
16
  word
@@ -12,8 +12,8 @@ module ActionPolicy
12
12
  using ActionPolicy::Ext::StringConstantize
13
13
  end
14
14
 
15
- require "action_policy/ext/symbol_classify"
16
- using ActionPolicy::Ext::SymbolClassify
15
+ require "action_policy/ext/symbol_camelize"
16
+ using ActionPolicy::Ext::SymbolCamelize
17
17
 
18
18
  require "action_policy/ext/module_namespace"
19
19
  using ActionPolicy::Ext::ModuleNamespace
@@ -54,6 +54,7 @@ module ActionPolicy
54
54
  private
55
55
 
56
56
  def lookup_within_namespace(policy_name, namespace)
57
+ return unless namespace
57
58
  NamespaceCache.fetch(namespace.name, policy_name) do
58
59
  mod = namespace
59
60
 
@@ -114,20 +115,25 @@ module ActionPolicy
114
115
  SYMBOL_LOOKUP = ->(record, namespace: nil, **) {
115
116
  next unless record.is_a?(Symbol)
116
117
 
117
- policy_name = "#{record.classify}Policy"
118
- if namespace.nil?
119
- policy_name.safe_constantize
120
- else
121
- lookup_within_namespace(policy_name, namespace)
122
- end
118
+ policy_name = "#{record.camelize}Policy"
119
+ lookup_within_namespace(policy_name, namespace) || policy_name.safe_constantize
120
+ }
121
+
122
+ # (Optional) Infer using String#classify if available
123
+ CLASSIFY_SYMBOL_LOOKUP = ->(record, namespace: nil, **) {
124
+ next unless record.is_a?(Symbol)
125
+
126
+ policy_name = "#{record.to_s.classify}Policy"
127
+ lookup_within_namespace(policy_name, namespace) || policy_name.safe_constantize
123
128
  }
124
129
 
125
130
  self.chain = [
126
131
  SYMBOL_LOOKUP,
132
+ (CLASSIFY_SYMBOL_LOOKUP if String.method_defined?(:classify)),
127
133
  INSTANCE_POLICY_CLASS,
128
134
  CLASS_POLICY_CLASS,
129
135
  NAMESPACE_LOOKUP,
130
136
  INFER_FROM_CLASS
131
- ]
137
+ ].compact
132
138
  end
133
139
  end
@@ -189,7 +189,7 @@ module ActionPolicy
189
189
  policy.result
190
190
  end
191
191
 
192
- result.reasons.add(policy, rule, res.details) if res.fail?
192
+ result&.reasons&.add(policy, rule, res.details) if res.fail?
193
193
 
194
194
  res.clear_details
195
195
 
@@ -7,4 +7,11 @@ ActiveRecord::Relation.include(Module.new do
7
7
  def policy_cache_key
8
8
  object_id
9
9
  end
10
+
11
+ # Explicitly define the policy_class method to avoid
12
+ # making Relation immutable (by initializing `arel` in `#respond_to_missing?).
13
+ # See https://github.com/palkan/action_policy/issues/101
14
+ def policy_class
15
+ nil
16
+ end
10
17
  end)
@@ -68,7 +68,7 @@ if defined?(::RSpec)
68
68
 
69
69
  ::RSpec.shared_examples_for "action_policy:policy_rule_example" do |success, the_caller|
70
70
  if success
71
- specify do
71
+ specify "is allowed" do
72
72
  next if subject.success?
73
73
  raise(
74
74
  RSpec::Expectations::ExpectationNotMetError,
@@ -77,7 +77,7 @@ if defined?(::RSpec)
77
77
  )
78
78
  end
79
79
  else
80
- specify do
80
+ specify "is denied" do
81
81
  next if subject.fail?
82
82
  raise(
83
83
  RSpec::Expectations::ExpectationNotMetError,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.4.3"
4
+ VERSION = "0.4.4"
5
5
  end
@@ -5,7 +5,7 @@ class ApplicationPolicy < ActionPolicy::Base
5
5
  #
6
6
  # authorize :account, optional: true
7
7
  #
8
- # Read more about authoriztion context: https://actionpolicy.evilmartians.io/#/authorization_context
8
+ # Read more about authorization context: https://actionpolicy.evilmartians.io/#/authorization_context
9
9
 
10
10
  private
11
11
 
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.4.3
4
+ version: 0.4.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: 2019-12-14 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ammeter
@@ -158,9 +158,9 @@ extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
160
  - ".gitattributes"
161
- - ".github/FUNDING.yml"
162
161
  - ".github/ISSUE_TEMPLATE.md"
163
162
  - ".github/PULL_REQUEST_TEMPLATE.md"
163
+ - ".github/bug_report_template.rb"
164
164
  - ".gitignore"
165
165
  - ".rubocop.yml"
166
166
  - ".tidelift.yml"
@@ -172,6 +172,7 @@ files:
172
172
  - Rakefile
173
173
  - action_policy.gemspec
174
174
  - benchmarks/namespaced_lookup_cache.rb
175
+ - benchmarks/pre_checks.rb
175
176
  - bin/console
176
177
  - bin/setup
177
178
  - docs/.nojekyll
@@ -235,7 +236,7 @@ files:
235
236
  - lib/action_policy/ext/string_constantize.rb
236
237
  - lib/action_policy/ext/string_match.rb
237
238
  - lib/action_policy/ext/string_underscore.rb
238
- - lib/action_policy/ext/symbol_classify.rb
239
+ - lib/action_policy/ext/symbol_camelize.rb
239
240
  - lib/action_policy/ext/yield_self_then.rb
240
241
  - lib/action_policy/i18n.rb
241
242
  - lib/action_policy/lookup_chain.rb
@@ -1 +0,0 @@
1
- tidelift: "rubygems/action_policy"