action_policy 0.4.4 → 0.5.0

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +203 -174
  3. data/README.md +5 -4
  4. data/lib/action_policy.rb +7 -1
  5. data/lib/action_policy/behaviour.rb +22 -16
  6. data/lib/action_policy/behaviours/policy_for.rb +10 -3
  7. data/lib/action_policy/behaviours/scoping.rb +2 -1
  8. data/lib/action_policy/behaviours/thread_memoized.rb +1 -3
  9. data/lib/action_policy/ext/module_namespace.rb +1 -6
  10. data/lib/action_policy/ext/policy_cache_key.rb +10 -30
  11. data/lib/action_policy/i18n.rb +1 -1
  12. data/lib/action_policy/lookup_chain.rb +29 -15
  13. data/lib/action_policy/policy/aliases.rb +7 -12
  14. data/lib/action_policy/policy/authorization.rb +8 -7
  15. data/lib/action_policy/policy/cache.rb +11 -17
  16. data/lib/action_policy/policy/core.rb +25 -12
  17. data/lib/action_policy/policy/defaults.rb +3 -9
  18. data/lib/action_policy/policy/execution_result.rb +3 -9
  19. data/lib/action_policy/policy/pre_check.rb +19 -58
  20. data/lib/action_policy/policy/reasons.rb +29 -19
  21. data/lib/action_policy/policy/scoping.rb +5 -6
  22. data/lib/action_policy/rails/controller.rb +6 -1
  23. data/lib/action_policy/rails/policy/instrumentation.rb +1 -1
  24. data/lib/action_policy/rspec/be_authorized_to.rb +5 -9
  25. data/lib/action_policy/rspec/dsl.rb +1 -1
  26. data/lib/action_policy/rspec/have_authorized_scope.rb +5 -7
  27. data/lib/action_policy/utils/pretty_print.rb +21 -24
  28. data/lib/action_policy/utils/suggest_message.rb +1 -3
  29. data/lib/action_policy/version.rb +1 -1
  30. data/lib/generators/action_policy/install/templates/{application_policy.rb → application_policy.rb.tt} +0 -0
  31. data/lib/generators/action_policy/policy/policy_generator.rb +4 -1
  32. data/lib/generators/action_policy/policy/templates/{policy.rb → policy.rb.tt} +0 -0
  33. data/lib/generators/rspec/templates/{policy_spec.rb → policy_spec.rb.tt} +0 -0
  34. data/lib/generators/test_unit/templates/{policy_test.rb → policy_test.rb.tt} +0 -0
  35. metadata +29 -119
  36. data/.gitattributes +0 -2
  37. data/.github/ISSUE_TEMPLATE.md +0 -21
  38. data/.github/PULL_REQUEST_TEMPLATE.md +0 -29
  39. data/.github/bug_report_template.rb +0 -175
  40. data/.gitignore +0 -15
  41. data/.rubocop.yml +0 -54
  42. data/.tidelift.yml +0 -6
  43. data/.travis.yml +0 -31
  44. data/Gemfile +0 -22
  45. data/Rakefile +0 -27
  46. data/action_policy.gemspec +0 -44
  47. data/benchmarks/namespaced_lookup_cache.rb +0 -74
  48. data/benchmarks/pre_checks.rb +0 -73
  49. data/bin/console +0 -14
  50. data/bin/setup +0 -8
  51. data/docs/.nojekyll +0 -0
  52. data/docs/CNAME +0 -1
  53. data/docs/README.md +0 -79
  54. data/docs/_sidebar.md +0 -27
  55. data/docs/aliases.md +0 -122
  56. data/docs/assets/docsify-search.js +0 -364
  57. data/docs/assets/docsify.min.js +0 -3
  58. data/docs/assets/fonts/FiraCode-Medium.woff +0 -0
  59. data/docs/assets/fonts/FiraCode-Regular.woff +0 -0
  60. data/docs/assets/images/banner.png +0 -0
  61. data/docs/assets/images/cache.png +0 -0
  62. data/docs/assets/images/cache.svg +0 -70
  63. data/docs/assets/images/layer.png +0 -0
  64. data/docs/assets/images/layer.svg +0 -35
  65. data/docs/assets/prism-ruby.min.js +0 -1
  66. data/docs/assets/styles.css +0 -347
  67. data/docs/assets/vue.min.css +0 -1
  68. data/docs/authorization_context.md +0 -92
  69. data/docs/behaviour.md +0 -113
  70. data/docs/caching.md +0 -291
  71. data/docs/controller_action_aliases.md +0 -109
  72. data/docs/custom_lookup_chain.md +0 -48
  73. data/docs/custom_policy.md +0 -53
  74. data/docs/debugging.md +0 -55
  75. data/docs/decorators.md +0 -27
  76. data/docs/favicon.ico +0 -0
  77. data/docs/graphql.md +0 -302
  78. data/docs/i18n.md +0 -44
  79. data/docs/index.html +0 -43
  80. data/docs/instrumentation.md +0 -84
  81. data/docs/lookup_chain.md +0 -22
  82. data/docs/namespaces.md +0 -77
  83. data/docs/non_rails.md +0 -28
  84. data/docs/pre_checks.md +0 -57
  85. data/docs/pundit_migration.md +0 -80
  86. data/docs/quick_start.md +0 -118
  87. data/docs/rails.md +0 -120
  88. data/docs/reasons.md +0 -120
  89. data/docs/scoping.md +0 -255
  90. data/docs/testing.md +0 -390
  91. data/docs/writing_policies.md +0 -107
  92. data/gemfiles/jruby.gemfile +0 -8
  93. data/gemfiles/rails42.gemfile +0 -9
  94. data/gemfiles/rails6.gemfile +0 -8
  95. data/gemfiles/railsmaster.gemfile +0 -6
  96. data/lib/action_policy/ext/string_match.rb +0 -14
  97. data/lib/action_policy/ext/yield_self_then.rb +0 -25
@@ -16,10 +16,7 @@ ensure
16
16
  end
17
17
 
18
18
  module ActionPolicy
19
- unless "".respond_to?(:then)
20
- require "action_policy/ext/yield_self_then"
21
- using ActionPolicy::Ext::YieldSelfThen
22
- end
19
+ using RubyNext
23
20
 
24
21
  # Takes the object and a method name,
25
22
  # and returns the "annotated" source code for the method:
@@ -41,7 +38,7 @@ module ActionPolicy
41
38
  # #=> AND
42
39
  # #=> access_feed? #=> true
43
40
  module PrettyPrint
44
- TRUE = "\e[32mtrue\e[0m"
41
+ TRUE = "\e[32mtrue\e[0m"
45
42
  FALSE = "\e[31mfalse\e[0m"
46
43
 
47
44
  class Visitor
@@ -71,7 +68,7 @@ module ActionPolicy
71
68
 
72
69
  def expression_with_result(sexp)
73
70
  expression = Unparser.unparse(sexp)
74
- "#{expression} #=> #{colorize(eval_exp(expression))}"
71
+ "#{expression} #=> #{PrettyPrint.colorize(eval_exp(expression))}"
75
72
  end
76
73
 
77
74
  def eval_exp(exp)
@@ -124,39 +121,39 @@ module ActionPolicy
124
121
 
125
122
  # Some lines should not be evaled
126
123
  def ignore_exp?(exp)
127
- exp.match?(/^\s*binding\.(pry|irb)\s*$/)
128
- end
129
-
130
- def colorize(val)
131
- return val unless $stdout.isatty
132
- return TRUE if val.eql?(true)
133
- return FALSE if val.eql?(false)
134
- val
124
+ PrettyPrint.ignore_expressions.any? { exp.match?(_1) }
135
125
  end
136
126
  end
137
127
 
138
128
  class << self
129
+ attr_accessor :ignore_expressions
130
+
139
131
  if defined?(::Unparser) && defined?(::MethodSource)
140
- def available?
141
- true
142
- end
132
+ def available?() = true
143
133
 
144
134
  def print_method(object, method_name)
145
- ast = object.method(method_name).source.then(&Unparser.method(:parse))
135
+ ast = object.method(method_name).source.then(&Unparser.:parse)
146
136
  # outer node is a method definition itself
147
137
  body = ast.children[2]
148
138
 
149
139
  Visitor.new(object).collect(body)
150
140
  end
151
141
  else
152
- def available?
153
- false
154
- end
142
+ def available?() = false
155
143
 
156
- def print_method(_, _)
157
- ""
158
- end
144
+ def print_method(_, _) = ""
145
+ end
146
+
147
+ def colorize(val)
148
+ return val unless $stdout.isatty
149
+ return TRUE if val.eql?(true)
150
+ return FALSE if val.eql?(false)
151
+ val
159
152
  end
160
153
  end
154
+
155
+ self.ignore_expressions = [
156
+ /^\s*binding\.(pry|irb)\s*$/s
157
+ ]
161
158
  end
162
159
  end
@@ -13,9 +13,7 @@ module ActionPolicy
13
13
  suggestion ? "\nDid you mean? #{suggestion}" : ""
14
14
  end
15
15
  else
16
- def suggest(*)
17
- ""
18
- end
16
+ def suggest(*) = ""
19
17
  end
20
18
  end
21
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.4.4"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -8,7 +8,10 @@ module ActionPolicy
8
8
  source_root File.expand_path("templates", __dir__)
9
9
 
10
10
  def run_install_if_needed
11
- return if ::Rails.root.join("app/policies/application_policy.rb").exist?
11
+ in_root do
12
+ return if File.exist?("app/policies/application_policy.rb")
13
+ end
14
+
12
15
  generate "action_policy:install"
13
16
  end
14
17
 
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2020-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby-next-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.3
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: ammeter
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -56,72 +70,30 @@ dependencies:
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '13.0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '13.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '3.3'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '3.3'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 0.67.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 0.67.0
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop-md
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.2'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '0.2'
111
- - !ruby/object:Gem::Dependency
112
- name: standard
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
87
+ - - ">="
116
88
  - !ruby/object:Gem::Version
117
- version: 0.0.39
89
+ version: '3.9'
118
90
  type: :development
119
91
  prerelease: false
120
92
  version_requirements: !ruby/object:Gem::Requirement
121
93
  requirements:
122
- - - "~>"
94
+ - - ">="
123
95
  - !ruby/object:Gem::Version
124
- version: 0.0.39
96
+ version: '3.9'
125
97
  - !ruby/object:Gem::Dependency
126
98
  name: benchmark-ips
127
99
  requirement: !ruby/object:Gem::Requirement
@@ -157,69 +129,9 @@ executables: []
157
129
  extensions: []
158
130
  extra_rdoc_files: []
159
131
  files:
160
- - ".gitattributes"
161
- - ".github/ISSUE_TEMPLATE.md"
162
- - ".github/PULL_REQUEST_TEMPLATE.md"
163
- - ".github/bug_report_template.rb"
164
- - ".gitignore"
165
- - ".rubocop.yml"
166
- - ".tidelift.yml"
167
- - ".travis.yml"
168
132
  - CHANGELOG.md
169
- - Gemfile
170
133
  - LICENSE.txt
171
134
  - README.md
172
- - Rakefile
173
- - action_policy.gemspec
174
- - benchmarks/namespaced_lookup_cache.rb
175
- - benchmarks/pre_checks.rb
176
- - bin/console
177
- - bin/setup
178
- - docs/.nojekyll
179
- - docs/CNAME
180
- - docs/README.md
181
- - docs/_sidebar.md
182
- - docs/aliases.md
183
- - docs/assets/docsify-search.js
184
- - docs/assets/docsify.min.js
185
- - docs/assets/fonts/FiraCode-Medium.woff
186
- - docs/assets/fonts/FiraCode-Regular.woff
187
- - docs/assets/images/banner.png
188
- - docs/assets/images/cache.png
189
- - docs/assets/images/cache.svg
190
- - docs/assets/images/layer.png
191
- - docs/assets/images/layer.svg
192
- - docs/assets/prism-ruby.min.js
193
- - docs/assets/styles.css
194
- - docs/assets/vue.min.css
195
- - docs/authorization_context.md
196
- - docs/behaviour.md
197
- - docs/caching.md
198
- - docs/controller_action_aliases.md
199
- - docs/custom_lookup_chain.md
200
- - docs/custom_policy.md
201
- - docs/debugging.md
202
- - docs/decorators.md
203
- - docs/favicon.ico
204
- - docs/graphql.md
205
- - docs/i18n.md
206
- - docs/index.html
207
- - docs/instrumentation.md
208
- - docs/lookup_chain.md
209
- - docs/namespaces.md
210
- - docs/non_rails.md
211
- - docs/pre_checks.md
212
- - docs/pundit_migration.md
213
- - docs/quick_start.md
214
- - docs/rails.md
215
- - docs/reasons.md
216
- - docs/scoping.md
217
- - docs/testing.md
218
- - docs/writing_policies.md
219
- - gemfiles/jruby.gemfile
220
- - gemfiles/rails42.gemfile
221
- - gemfiles/rails6.gemfile
222
- - gemfiles/railsmaster.gemfile
223
135
  - lib/action_policy.rb
224
136
  - lib/action_policy/authorizer.rb
225
137
  - lib/action_policy/base.rb
@@ -234,10 +146,8 @@ files:
234
146
  - lib/action_policy/ext/module_namespace.rb
235
147
  - lib/action_policy/ext/policy_cache_key.rb
236
148
  - lib/action_policy/ext/string_constantize.rb
237
- - lib/action_policy/ext/string_match.rb
238
149
  - lib/action_policy/ext/string_underscore.rb
239
150
  - lib/action_policy/ext/symbol_camelize.rb
240
- - lib/action_policy/ext/yield_self_then.rb
241
151
  - lib/action_policy/i18n.rb
242
152
  - lib/action_policy/lookup_chain.rb
243
153
  - lib/action_policy/policy/aliases.rb
@@ -270,14 +180,14 @@ files:
270
180
  - lib/action_policy/version.rb
271
181
  - lib/generators/action_policy/install/USAGE
272
182
  - lib/generators/action_policy/install/install_generator.rb
273
- - lib/generators/action_policy/install/templates/application_policy.rb
183
+ - lib/generators/action_policy/install/templates/application_policy.rb.tt
274
184
  - lib/generators/action_policy/policy/USAGE
275
185
  - lib/generators/action_policy/policy/policy_generator.rb
276
- - lib/generators/action_policy/policy/templates/policy.rb
186
+ - lib/generators/action_policy/policy/templates/policy.rb.tt
277
187
  - lib/generators/rspec/policy_generator.rb
278
- - lib/generators/rspec/templates/policy_spec.rb
188
+ - lib/generators/rspec/templates/policy_spec.rb.tt
279
189
  - lib/generators/test_unit/policy_generator.rb
280
- - lib/generators/test_unit/templates/policy_test.rb
190
+ - lib/generators/test_unit/templates/policy_test.rb.tt
281
191
  homepage: https://github.com/palkan/action_policy
282
192
  licenses:
283
193
  - MIT
@@ -295,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
295
205
  requirements:
296
206
  - - ">="
297
207
  - !ruby/object:Gem::Version
298
- version: 2.4.0
208
+ version: 2.5.0
299
209
  required_rubygems_version: !ruby/object:Gem::Requirement
300
210
  requirements:
301
211
  - - ">="
@@ -1,2 +0,0 @@
1
- docs/**/* linguist-vendored
2
- .github/**/* linguist-vendored
@@ -1,21 +0,0 @@
1
- <!--
2
- This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason,
3
- feel free to skip the rest of this template.
4
- -->
5
-
6
- ### Tell us about your environment
7
-
8
- **Ruby Version:**
9
-
10
- **Framework Version (Rails, whatever):**
11
-
12
- **Action Policy Version:**
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
-
17
- ### What did you do?
18
-
19
- ### What did you expect to happen?
20
-
21
- ### What actually happened?
@@ -1,29 +0,0 @@
1
- <!--
2
- First of all, thanks for contributing!
3
-
4
- If it's a typo fix or minor documentation update feel free to skip the rest of this template!
5
- -->
6
-
7
- <!--
8
- If it's a bug fix, then link it to the issue, for example:
9
-
10
- Fixes #xxx
11
- -->
12
-
13
-
14
- <!--
15
- Otherwise, describe the changes:
16
-
17
- ### What is the purpose of this pull request?
18
-
19
- ### What changes did you make? (overview)
20
-
21
- ### Is there anything you'd like reviewers to focus on?
22
-
23
- -->
24
-
25
- PR checklist:
26
-
27
- - [ ] Tests included
28
- - [ ] Documentation updated
29
- - [ ] Changelog entry added
@@ -1,175 +0,0 @@
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