pundit 2.4.0 → 2.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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +92 -57
- data/.rubocop.yml +18 -8
- data/.rubocop_ignore_git.yml +7 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +61 -42
- data/Gemfile +22 -2
- data/README.md +30 -0
- data/Rakefile +1 -0
- data/lib/generators/pundit/install/install_generator.rb +3 -1
- data/lib/generators/pundit/policy/policy_generator.rb +3 -1
- data/lib/generators/rspec/policy_generator.rb +4 -1
- data/lib/generators/test_unit/policy_generator.rb +4 -1
- data/lib/pundit/authorization.rb +152 -77
- data/lib/pundit/cache_store/legacy_store.rb +7 -0
- data/lib/pundit/cache_store/null_store.rb +9 -0
- data/lib/pundit/cache_store.rb +22 -0
- data/lib/pundit/context.rb +76 -26
- data/lib/pundit/policy_finder.rb +22 -1
- data/lib/pundit/railtie.rb +19 -0
- data/lib/pundit/rspec.rb +67 -6
- data/lib/pundit/version.rb +2 -1
- data/lib/pundit.rb +39 -14
- data/pundit.gemspec +8 -12
- data/spec/authorization_spec.rb +60 -3
- data/spec/policy_finder_spec.rb +5 -1
- data/spec/pundit/helper_spec.rb +18 -0
- data/spec/pundit_spec.rb +37 -11
- data/spec/rspec_dsl_spec.rb +81 -0
- data/spec/simple_cov_check_action_formatter.rb +79 -0
- data/spec/spec_helper.rb +22 -339
- data/spec/support/lib/controller.rb +38 -0
- data/spec/support/lib/custom_cache.rb +19 -0
- data/spec/support/lib/instance_tracking.rb +20 -0
- data/spec/support/models/article.rb +4 -0
- data/spec/support/models/article_tag.rb +7 -0
- data/spec/support/models/artificial_blog.rb +7 -0
- data/spec/support/models/blog.rb +4 -0
- data/spec/support/models/comment.rb +5 -0
- data/spec/support/models/comment_four_five_six.rb +5 -0
- data/spec/support/models/comment_scope.rb +13 -0
- data/spec/support/models/comments_relation.rb +15 -0
- data/spec/support/models/customer/post.rb +11 -0
- data/spec/support/models/default_scope_contains_error.rb +5 -0
- data/spec/support/models/dummy_current_user.rb +7 -0
- data/spec/support/models/foo.rb +4 -0
- data/spec/support/models/post.rb +25 -0
- data/spec/support/models/post_four_five_six.rb +9 -0
- data/spec/support/models/project_one_two_three/avatar_four_five_six.rb +7 -0
- data/spec/support/models/project_one_two_three/tag_four_five_six.rb +11 -0
- data/spec/support/models/wiki.rb +4 -0
- data/spec/support/policies/article_tag_other_name_policy.rb +13 -0
- data/spec/support/policies/base_policy.rb +23 -0
- data/spec/support/policies/blog_policy.rb +5 -0
- data/spec/support/policies/comment_policy.rb +11 -0
- data/spec/support/policies/criteria_policy.rb +5 -0
- data/spec/support/policies/default_scope_contains_error_policy.rb +10 -0
- data/spec/support/policies/denier_policy.rb +7 -0
- data/spec/support/policies/dummy_current_user_policy.rb +9 -0
- data/spec/support/policies/nil_class_policy.rb +17 -0
- data/spec/support/policies/post_policy.rb +36 -0
- data/spec/support/policies/project/admin/comment_policy.rb +15 -0
- data/spec/support/policies/project/comment_policy.rb +17 -0
- data/spec/support/policies/project/criteria_policy.rb +7 -0
- data/spec/support/policies/project/post_policy.rb +13 -0
- data/spec/support/policies/project_one_two_three/avatar_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/comment_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/criteria_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/post_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/tag_four_five_six_policy.rb +6 -0
- data/spec/support/policies/publication_policy.rb +13 -0
- data/spec/support/policies/wiki_policy.rb +8 -0
- metadata +62 -158
- data/spec/dsl_spec.rb +0 -30
- /data/lib/generators/pundit/install/templates/{application_policy.rb → application_policy.rb.tt} +0 -0
- /data/lib/generators/pundit/policy/templates/{policy.rb → policy.rb.tt} +0 -0
- /data/lib/generators/rspec/templates/{policy_spec.rb → policy_spec.rb.tt} +0 -0
- /data/lib/generators/test_unit/templates/{policy_test.rb → policy_test.rb.tt} +0 -0
data/spec/spec_helper.rb
CHANGED
@@ -2,351 +2,34 @@
|
|
2
2
|
|
3
3
|
if ENV["COVERAGE"]
|
4
4
|
require "simplecov"
|
5
|
+
require "simplecov_json_formatter"
|
6
|
+
require_relative "simple_cov_check_action_formatter"
|
7
|
+
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
|
8
|
+
SimpleCov::Formatter::HTMLFormatter,
|
9
|
+
SimpleCov::Formatter::JSONFormatter,
|
10
|
+
SimpleCovCheckActionFormatter.with_options(
|
11
|
+
output_filename: "simplecov-check-action.json"
|
12
|
+
)
|
13
|
+
])
|
5
14
|
SimpleCov.start do
|
6
15
|
add_filter "/spec/"
|
16
|
+
enable_coverage :branch
|
17
|
+
primary_coverage :branch
|
7
18
|
end
|
8
19
|
end
|
9
20
|
|
21
|
+
# @see https://github.com/rails/rails/issues/54260
|
22
|
+
require "logger" if RUBY_ENGINE == "jruby" && RUBY_ENGINE_VERSION.start_with?("9.3")
|
23
|
+
|
10
24
|
require "pundit"
|
11
25
|
require "pundit/rspec"
|
12
|
-
|
13
|
-
require "rack"
|
14
|
-
require "rack/test"
|
15
|
-
require "pry"
|
16
|
-
require "active_support"
|
17
|
-
require "active_support/core_ext"
|
18
26
|
require "active_model/naming"
|
19
|
-
require "action_controller/metal/strong_parameters"
|
20
|
-
|
21
|
-
module InstanceTracking
|
22
|
-
module ClassMethods
|
23
|
-
def instances
|
24
|
-
@instances || 0
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_writer :instances
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.prepended(other)
|
31
|
-
other.extend(ClassMethods)
|
32
|
-
end
|
33
|
-
|
34
|
-
def initialize(*args, **kwargs, &block)
|
35
|
-
self.class.instances += 1
|
36
|
-
super(*args, **kwargs, &block)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class BasePolicy
|
41
|
-
prepend InstanceTracking
|
42
|
-
|
43
|
-
class BaseScope
|
44
|
-
prepend InstanceTracking
|
45
|
-
|
46
|
-
def initialize(user, scope)
|
47
|
-
@user = user
|
48
|
-
@scope = scope
|
49
|
-
end
|
50
|
-
|
51
|
-
attr_reader :user, :scope
|
52
|
-
end
|
53
|
-
|
54
|
-
def initialize(user, record)
|
55
|
-
@user = user
|
56
|
-
@record = record
|
57
|
-
end
|
58
|
-
|
59
|
-
attr_reader :user, :record
|
60
|
-
end
|
61
|
-
|
62
|
-
class PostPolicy < BasePolicy
|
63
|
-
class Scope < BaseScope
|
64
|
-
def resolve
|
65
|
-
scope.published
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
alias post record
|
70
|
-
|
71
|
-
def update?
|
72
|
-
post.user == user
|
73
|
-
end
|
74
|
-
|
75
|
-
def destroy?
|
76
|
-
false
|
77
|
-
end
|
78
|
-
|
79
|
-
def show?
|
80
|
-
true
|
81
|
-
end
|
82
|
-
|
83
|
-
def permitted_attributes
|
84
|
-
if post.user == user
|
85
|
-
%i[title votes]
|
86
|
-
else
|
87
|
-
[:votes]
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def permitted_attributes_for_revise
|
92
|
-
[:body]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
class Post
|
97
|
-
def initialize(user = nil)
|
98
|
-
@user = user
|
99
|
-
end
|
100
|
-
|
101
|
-
attr_reader :user
|
102
|
-
|
103
|
-
def self.published
|
104
|
-
:published
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.read
|
108
|
-
:read
|
109
|
-
end
|
110
|
-
|
111
|
-
def to_s
|
112
|
-
"Post"
|
113
|
-
end
|
114
|
-
|
115
|
-
def inspect
|
116
|
-
"#<Post>"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
module Customer
|
121
|
-
class Post < ::Post
|
122
|
-
def model_name
|
123
|
-
OpenStruct.new(param_key: "customer_post")
|
124
|
-
end
|
125
|
-
|
126
|
-
def self.policy_class
|
127
|
-
PostPolicy
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
class CommentScope
|
133
|
-
attr_reader :original_object
|
134
|
-
|
135
|
-
def initialize(original_object)
|
136
|
-
@original_object = original_object
|
137
|
-
end
|
138
|
-
|
139
|
-
def ==(other)
|
140
|
-
original_object == other.original_object
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
class CommentPolicy < BasePolicy
|
145
|
-
class Scope < BaseScope
|
146
|
-
def resolve
|
147
|
-
CommentScope.new(scope)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
alias comment record
|
152
|
-
end
|
153
|
-
|
154
|
-
class PublicationPolicy < BasePolicy
|
155
|
-
class Scope < BaseScope
|
156
|
-
def resolve
|
157
|
-
scope.published
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def create?
|
162
|
-
true
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
class Comment
|
167
|
-
extend ActiveModel::Naming
|
168
|
-
end
|
169
|
-
|
170
|
-
class CommentsRelation
|
171
|
-
def initialize(empty: false)
|
172
|
-
@empty = empty
|
173
|
-
end
|
174
|
-
|
175
|
-
def blank?
|
176
|
-
@empty
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.model_name
|
180
|
-
Comment.model_name
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
class Article; end
|
185
|
-
|
186
|
-
class BlogPolicy < BasePolicy
|
187
|
-
alias blog record
|
188
|
-
end
|
189
|
-
|
190
|
-
class Blog; end
|
191
|
-
|
192
|
-
class ArtificialBlog < Blog
|
193
|
-
def self.policy_class
|
194
|
-
BlogPolicy
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
class ArticleTagOtherNamePolicy < BasePolicy
|
199
|
-
def show?
|
200
|
-
true
|
201
|
-
end
|
202
|
-
|
203
|
-
def destroy?
|
204
|
-
false
|
205
|
-
end
|
206
|
-
|
207
|
-
alias tag record
|
208
|
-
end
|
209
|
-
|
210
|
-
class ArticleTag
|
211
|
-
def self.policy_class
|
212
|
-
ArticleTagOtherNamePolicy
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
class CriteriaPolicy < BasePolicy
|
217
|
-
alias criteria record
|
218
|
-
end
|
219
|
-
|
220
|
-
module Project
|
221
|
-
class CommentPolicy < BasePolicy
|
222
|
-
class Scope < BaseScope
|
223
|
-
def resolve
|
224
|
-
scope
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def update?
|
229
|
-
true
|
230
|
-
end
|
231
|
-
|
232
|
-
alias comment record
|
233
|
-
end
|
234
|
-
|
235
|
-
class CriteriaPolicy < BasePolicy
|
236
|
-
alias criteria record
|
237
|
-
end
|
238
|
-
|
239
|
-
class PostPolicy < BasePolicy
|
240
|
-
class Scope < BaseScope
|
241
|
-
def resolve
|
242
|
-
scope.read
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
alias post record
|
247
|
-
end
|
248
|
-
|
249
|
-
module Admin
|
250
|
-
class CommentPolicy < BasePolicy
|
251
|
-
def update?
|
252
|
-
true
|
253
|
-
end
|
254
|
-
|
255
|
-
def destroy?
|
256
|
-
false
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
class DenierPolicy < BasePolicy
|
263
|
-
def update?
|
264
|
-
false
|
265
|
-
end
|
266
|
-
end
|
267
27
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
def initialize(current_user, action_name, params)
|
278
|
-
@current_user = current_user
|
279
|
-
@action_name = action_name
|
280
|
-
@params = params
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
class NilClassPolicy < BasePolicy
|
285
|
-
class Scope
|
286
|
-
def initialize(*)
|
287
|
-
raise Pundit::NotDefinedError, "Cannot scope NilClass"
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
def show?
|
292
|
-
false
|
293
|
-
end
|
294
|
-
|
295
|
-
def destroy?
|
296
|
-
false
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
class Wiki; end
|
301
|
-
|
302
|
-
class WikiPolicy
|
303
|
-
class Scope
|
304
|
-
# deliberate typo method
|
305
|
-
def initalize; end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
class Thread
|
310
|
-
def self.all; end
|
311
|
-
end
|
312
|
-
|
313
|
-
class ThreadPolicy < BasePolicy
|
314
|
-
class Scope < BaseScope
|
315
|
-
def resolve
|
316
|
-
# deliberate wrong usage of the method
|
317
|
-
scope.all(:unvalid, :parameters)
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
class PostFourFiveSix
|
323
|
-
def initialize(user)
|
324
|
-
@user = user
|
325
|
-
end
|
326
|
-
|
327
|
-
attr_reader(:user)
|
328
|
-
end
|
329
|
-
|
330
|
-
class CommentFourFiveSix; extend ActiveModel::Naming; end
|
331
|
-
|
332
|
-
module ProjectOneTwoThree
|
333
|
-
class CommentFourFiveSixPolicy < BasePolicy; end
|
334
|
-
|
335
|
-
class CriteriaFourFiveSixPolicy < BasePolicy; end
|
336
|
-
|
337
|
-
class PostFourFiveSixPolicy < BasePolicy; end
|
338
|
-
|
339
|
-
class TagFourFiveSix
|
340
|
-
def initialize(user)
|
341
|
-
@user = user
|
342
|
-
end
|
343
|
-
|
344
|
-
attr_reader(:user)
|
345
|
-
end
|
346
|
-
|
347
|
-
class TagFourFiveSixPolicy < BasePolicy; end
|
348
|
-
|
349
|
-
class AvatarFourFiveSix; extend ActiveModel::Naming; end
|
350
|
-
|
351
|
-
class AvatarFourFiveSixPolicy < BasePolicy; end
|
352
|
-
end
|
28
|
+
# Load all supporting files: models, policies, etc.
|
29
|
+
require "zeitwerk"
|
30
|
+
loader = Zeitwerk::Loader.new
|
31
|
+
loader.push_dir(File.expand_path("support/models", __dir__))
|
32
|
+
loader.push_dir(File.expand_path("support/policies", __dir__))
|
33
|
+
loader.push_dir(File.expand_path("support/lib", __dir__))
|
34
|
+
loader.setup
|
35
|
+
loader.eager_load
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Controller
|
4
|
+
attr_accessor :current_user
|
5
|
+
attr_reader :action_name, :params
|
6
|
+
|
7
|
+
class View
|
8
|
+
def initialize(controller)
|
9
|
+
@controller = controller
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :controller
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def helper(mod)
|
17
|
+
View.include(mod)
|
18
|
+
end
|
19
|
+
|
20
|
+
def helper_method(method)
|
21
|
+
View.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
22
|
+
def #{method}(*args, **kwargs, &block)
|
23
|
+
controller.send(:#{method}, *args, **kwargs, &block)
|
24
|
+
end
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
include Pundit::Authorization
|
30
|
+
# Mark protected methods public so they may be called in test
|
31
|
+
public(*Pundit::Authorization.protected_instance_methods)
|
32
|
+
|
33
|
+
def initialize(current_user, action_name, params)
|
34
|
+
@current_user = current_user
|
35
|
+
@action_name = action_name
|
36
|
+
@params = params
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InstanceTracking
|
4
|
+
module ClassMethods
|
5
|
+
def instances
|
6
|
+
@instances || 0
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_writer :instances
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.prepended(other)
|
13
|
+
other.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(*args, **kwargs, &block)
|
17
|
+
self.class.instances += 1
|
18
|
+
super(*args, **kwargs, &block)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Post
|
4
|
+
def initialize(user = nil)
|
5
|
+
@user = user
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :user
|
9
|
+
|
10
|
+
def self.published
|
11
|
+
:published
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.read
|
15
|
+
:read
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"Post"
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<Post>"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BasePolicy
|
4
|
+
prepend InstanceTracking
|
5
|
+
|
6
|
+
class BaseScope
|
7
|
+
prepend InstanceTracking
|
8
|
+
|
9
|
+
def initialize(user, scope)
|
10
|
+
@user = user
|
11
|
+
@scope = scope
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :user, :scope
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(user, record)
|
18
|
+
@user = user
|
19
|
+
@record = record
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :user, :record
|
23
|
+
end
|