pundit 1.1.0 → 2.3.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.
data/README.md CHANGED
@@ -1,37 +1,38 @@
1
1
  # Pundit
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/elabs/pundit.svg?branch=master)](https://travis-ci.org/elabs/pundit)
4
- [![Code Climate](https://codeclimate.com/github/elabs/pundit.svg)](https://codeclimate.com/github/elabs/pundit)
5
- [![Inline docs](http://inch-ci.org/github/elabs/pundit.svg?branch=master)](http://inch-ci.org/github/elabs/pundit)
3
+ [![Build Status](https://secure.travis-ci.org/varvet/pundit.svg?branch=master)](https://travis-ci.org/varvet/pundit)
4
+ [![Code Climate](https://codeclimate.com/github/varvet/pundit.svg)](https://codeclimate.com/github/varvet/pundit)
5
+ [![Inline docs](http://inch-ci.org/github/varvet/pundit.svg?branch=master)](http://inch-ci.org/github/varvet/pundit)
6
6
  [![Gem Version](https://badge.fury.io/rb/pundit.svg)](http://badge.fury.io/rb/pundit)
7
7
 
8
8
  Pundit provides a set of helpers which guide you in leveraging regular Ruby
9
9
  classes and object oriented design patterns to build a simple, robust and
10
- scaleable authorization system.
10
+ scalable authorization system.
11
11
 
12
12
  Links:
13
13
 
14
- - [API documentation](http://www.rubydoc.info/gems/pundit)
15
- - [Source Code](https://github.com/elabs/pundit)
16
- - [Contributing](https://github.com/elabs/pundit/blob/master/CONTRIBUTING.md)
17
- - [Code of Conduct](https://github.com/elabs/pundit/blob/master/CODE_OF_CONDUCT.md)
14
+ - [API documentation for the most recent version](http://www.rubydoc.info/gems/pundit)
15
+ - [Source Code](https://github.com/varvet/pundit)
16
+ - [Contributing](https://github.com/varvet/pundit/blob/master/CONTRIBUTING.md)
17
+ - [Code of Conduct](https://github.com/varvet/pundit/blob/master/CODE_OF_CONDUCT.md)
18
18
 
19
19
  Sponsored by:
20
20
 
21
- [<img src="http://d3cv91luii1z1d.cloudfront.net/logo-gh.png" alt="Elabs" height="50px"/>](http://elabs.se)
21
+ [<img src="https://www.varvet.com/images/wordmark-red.svg" alt="Varvet" height="50px"/>](https://www.varvet.com)
22
22
 
23
23
  ## Installation
24
24
 
25
- ``` ruby
26
- gem "pundit"
25
+ > **Please note** that the README on GitHub is accurate with the _latest code on GitHub_. You are most likely using a released version of Pundit, so please refer to the [documentation for the latest released version of Pundit](https://www.rubydoc.info/gems/pundit).
26
+
27
+ ``` sh
28
+ bundle add pundit
27
29
  ```
28
30
 
29
- Include Pundit in your application controller:
31
+ Include `Pundit::Authorization` in your application controller:
30
32
 
31
33
  ``` ruby
32
34
  class ApplicationController < ActionController::Base
33
- include Pundit
34
- protect_from_forgery
35
+ include Pundit::Authorization
35
36
  end
36
37
  ```
37
38
 
@@ -61,7 +62,7 @@ class PostPolicy
61
62
  end
62
63
 
63
64
  def update?
64
- user.admin? or not post.published?
65
+ user.admin? || !post.published?
65
66
  end
66
67
  end
67
68
  ```
@@ -116,7 +117,9 @@ and the given record. It then infers from the action name, that it should call
116
117
  `authorize` would have done something like this:
117
118
 
118
119
  ``` ruby
119
- raise "not authorized" unless PostPolicy.new(current_user, @post).update?
120
+ unless PostPolicy.new(current_user, @post).update?
121
+ raise Pundit::NotAuthorizedError, "not allowed to update? this #{@post.inspect}"
122
+ end
120
123
  ```
121
124
 
122
125
  You can pass a second argument to `authorize` if the name of the permission you
@@ -131,6 +134,18 @@ def publish
131
134
  end
132
135
  ```
133
136
 
137
+ You can pass an argument to override the policy class if necessary. For example:
138
+
139
+ ```ruby
140
+ def create
141
+ @publication = find_publication # assume this method returns any model that behaves like a publication
142
+ # @publication.class => Post
143
+ authorize @publication, policy_class: PublicationPolicy
144
+ @publication.publish!
145
+ redirect_to @publication
146
+ end
147
+ ```
148
+
134
149
  If you don't have an instance for the first argument to `authorize`, then you can pass
135
150
  the class. For example:
136
151
 
@@ -151,6 +166,20 @@ def admin_list
151
166
  end
152
167
  ```
153
168
 
169
+ `authorize` returns the instance passed to it, so you can chain it like this:
170
+
171
+ Controller:
172
+ ```ruby
173
+ def show
174
+ @user = authorize User.find(params[:id])
175
+ end
176
+
177
+ # return the record even for namespaced policies
178
+ def show
179
+ @user = authorize [:admin, User.find(params[:id])]
180
+ end
181
+ ```
182
+
154
183
  You can easily get a hold of an instance of the policy through the `policy`
155
184
  method in both the view and controller. This is especially useful for
156
185
  conditionally showing links or buttons in the view:
@@ -167,14 +196,30 @@ you can retrieve it by passing a symbol.
167
196
 
168
197
  ```ruby
169
198
  # app/policies/dashboard_policy.rb
170
- class DashboardPolicy < Struct.new(:user, :dashboard)
171
- # ...
199
+ class DashboardPolicy
200
+ attr_reader :user
201
+
202
+ # _record in this example will just be :dashboard
203
+ def initialize(user, _record)
204
+ @user = user
205
+ end
206
+
207
+ def show?
208
+ user.admin?
209
+ end
172
210
  end
173
211
  ```
174
212
 
213
+ Note that the headless policy still needs to accept two arguments. The
214
+ second argument will just be the symbol `:dashboard` in this case which
215
+ is what is passed as the record to `authorize` below.
216
+
175
217
  ```ruby
176
218
  # In controllers
177
- authorize :dashboard, :show?
219
+ def show
220
+ authorize :dashboard, :show?
221
+ ...
222
+ end
178
223
  ```
179
224
 
180
225
  ```erb
@@ -184,54 +229,6 @@ authorize :dashboard, :show?
184
229
  <% end %>
185
230
  ```
186
231
 
187
- ## Ensuring policies are used
188
-
189
- Pundit adds a method called `verify_authorized` to your controllers. This
190
- method will raise an exception if `authorize` has not yet been called. You
191
- should run this method in an `after_action` to ensure that you haven't
192
- forgotten to authorize the action. For example:
193
-
194
- ``` ruby
195
- class ApplicationController < ActionController::Base
196
- after_action :verify_authorized
197
- end
198
- ```
199
-
200
- Likewise, Pundit also adds `verify_policy_scoped` to your controller. This
201
- will raise an exception in the vein of `verify_authorized`. However, it tracks
202
- if `policy_scope` is used instead of `authorize`. This is mostly useful for
203
- controller actions like `index` which find collections with a scope and don't
204
- authorize individual instances.
205
-
206
- ``` ruby
207
- class ApplicationController < ActionController::Base
208
- after_action :verify_authorized, except: :index
209
- after_action :verify_policy_scoped, only: :index
210
- end
211
- ```
212
-
213
- If you're using `verify_authorized` in your controllers but need to
214
- conditionally bypass verification, you can use `skip_authorization`. For
215
- bypassing `verify_policy_scoped`, use `skip_policy_scope`. These are useful
216
- in circumstances where you don't want to disable verification for the
217
- entire action, but have some cases where you intend to not authorize.
218
-
219
- ```ruby
220
- def show
221
- record = Record.find_by(attribute: "value")
222
- if record.present?
223
- authorize record
224
- else
225
- skip_authorization
226
- end
227
- end
228
- ```
229
-
230
- If you need to perform some more sophisticated logic or you want to raise a custom
231
- exception you can use the two lower level methods `pundit_policy_authorized?`
232
- and `pundit_policy_scoped?` which return `true` or `false` depending on whether
233
- `authorize` or `policy_scope` have been called, respectively.
234
-
235
232
  ## Scopes
236
233
 
237
234
  Often, you will want to have some kind of view listing records which a
@@ -241,8 +238,6 @@ define a class called a policy scope. It can look something like this:
241
238
  ``` ruby
242
239
  class PostPolicy < ApplicationPolicy
243
240
  class Scope
244
- attr_reader :user, :scope
245
-
246
241
  def initialize(user, scope)
247
242
  @user = user
248
243
  @scope = scope
@@ -255,10 +250,14 @@ class PostPolicy < ApplicationPolicy
255
250
  scope.where(published: true)
256
251
  end
257
252
  end
253
+
254
+ private
255
+
256
+ attr_reader :user, :scope
258
257
  end
259
258
 
260
259
  def update?
261
- user.admin? or not post.published?
260
+ user.admin? or not record.published?
262
261
  end
263
262
  end
264
263
  ```
@@ -291,7 +290,7 @@ class PostPolicy < ApplicationPolicy
291
290
  end
292
291
 
293
292
  def update?
294
- user.admin? or not post.published?
293
+ user.admin? or not record.published?
295
294
  end
296
295
  end
297
296
  ```
@@ -302,15 +301,26 @@ You can now use this class from your controller via the `policy_scope` method:
302
301
  def index
303
302
  @posts = policy_scope(Post)
304
303
  end
304
+
305
+ def show
306
+ @post = policy_scope(Post).find(params[:id])
307
+ end
308
+ ```
309
+
310
+ Like with the authorize method, you can also override the policy scope class:
311
+
312
+ ``` ruby
313
+ def index
314
+ # publication_class => Post
315
+ @publications = policy_scope(publication_class, policy_scope_class: PublicationPolicy::Scope)
316
+ end
305
317
  ```
306
318
 
307
- Just as with your policy, this will automatically infer that you want to use
308
- the `PostPolicy::Scope` class, it will instantiate this class and call
309
- `resolve` on the instance. In this case it is a shortcut for doing:
319
+ In this case it is a shortcut for doing:
310
320
 
311
321
  ``` ruby
312
322
  def index
313
- @posts = PostPolicy::Scope.new(current_user, Post).resolve
323
+ @publications = PublicationPolicy::Scope.new(current_user, Post).resolve
314
324
  end
315
325
  ```
316
326
 
@@ -322,6 +332,70 @@ You can, and are encouraged to, use this method in views:
322
332
  <% end %>
323
333
  ```
324
334
 
335
+ ## Ensuring policies and scopes are used
336
+
337
+ When you are developing an application with Pundit it can be easy to forget to
338
+ authorize some action. People are forgetful after all. Since Pundit encourages
339
+ you to add the `authorize` call manually to each controller action, it's really
340
+ easy to miss one.
341
+
342
+ Thankfully, Pundit has a handy feature which reminds you in case you forget.
343
+ Pundit tracks whether you have called `authorize` anywhere in your controller
344
+ action. Pundit also adds a method to your controllers called
345
+ `verify_authorized`. This method will raise an exception if `authorize` has not
346
+ yet been called. You should run this method in an `after_action` hook to ensure
347
+ that you haven't forgotten to authorize the action. For example:
348
+
349
+ ``` ruby
350
+ class ApplicationController < ActionController::Base
351
+ include Pundit::Authorization
352
+ after_action :verify_authorized
353
+ end
354
+ ```
355
+
356
+ Likewise, Pundit also adds `verify_policy_scoped` to your controller. This
357
+ will raise an exception similar to `verify_authorized`. However, it tracks
358
+ if `policy_scope` is used instead of `authorize`. This is mostly useful for
359
+ controller actions like `index` which find collections with a scope and don't
360
+ authorize individual instances.
361
+
362
+ ``` ruby
363
+ class ApplicationController < ActionController::Base
364
+ include Pundit::Authorization
365
+ after_action :verify_authorized, except: :index
366
+ after_action :verify_policy_scoped, only: :index
367
+ end
368
+ ```
369
+
370
+ **This verification mechanism only exists to aid you while developing your
371
+ application, so you don't forget to call `authorize`. It is not some kind of
372
+ failsafe mechanism or authorization mechanism. You should be able to remove
373
+ these filters without affecting how your app works in any way.**
374
+
375
+ Some people have found this feature confusing, while many others
376
+ find it extremely helpful. If you fall into the category of people who find it
377
+ confusing then you do not need to use it. Pundit will work just fine without
378
+ using `verify_authorized` and `verify_policy_scoped`.
379
+
380
+ ### Conditional verification
381
+
382
+ If you're using `verify_authorized` in your controllers but need to
383
+ conditionally bypass verification, you can use `skip_authorization`. For
384
+ bypassing `verify_policy_scoped`, use `skip_policy_scope`. These are useful
385
+ in circumstances where you don't want to disable verification for the
386
+ entire action, but have some cases where you intend to not authorize.
387
+
388
+ ```ruby
389
+ def show
390
+ record = Record.find_by(attribute: "value")
391
+ if record.present?
392
+ authorize record
393
+ else
394
+ skip_authorization
395
+ end
396
+ end
397
+ ```
398
+
325
399
  ## Manually specifying policy classes
326
400
 
327
401
  Sometimes you might want to explicitly declare which policy to use for a given
@@ -335,6 +409,16 @@ class Post
335
409
  end
336
410
  ```
337
411
 
412
+ Alternatively, you can declare an instance method:
413
+
414
+ ``` ruby
415
+ class Post
416
+ def policy_class
417
+ PostablePolicy
418
+ end
419
+ end
420
+ ```
421
+
338
422
  ## Just plain old Ruby
339
423
 
340
424
  As you can see, Pundit doesn't do anything you couldn't have easily done
@@ -362,7 +446,8 @@ rails g pundit:policy post
362
446
 
363
447
  In many applications, only logged in users are really able to do anything. If
364
448
  you're building such a system, it can be kind of cumbersome to check that the
365
- user in a policy isn't `nil` for every single permission.
449
+ user in a policy isn't `nil` for every single permission. Aside from policies,
450
+ you can add this check to the base class for scopes.
366
451
 
367
452
  We suggest that you define a filter that redirects unauthenticated users to the
368
453
  login page. As a secondary defence, if you've defined an ApplicationPolicy, it
@@ -376,6 +461,37 @@ class ApplicationPolicy
376
461
  @user = user
377
462
  @record = record
378
463
  end
464
+
465
+ class Scope
466
+ attr_reader :user, :scope
467
+
468
+ def initialize(user, scope)
469
+ raise Pundit::NotAuthorizedError, "must be logged in" unless user
470
+ @user = user
471
+ @scope = scope
472
+ end
473
+ end
474
+ end
475
+ ```
476
+
477
+ ## NilClassPolicy
478
+
479
+ To support a [null object pattern](https://en.wikipedia.org/wiki/Null_Object_pattern)
480
+ you may find that you want to implement a `NilClassPolicy`. This might be useful
481
+ where you want to extend your ApplicationPolicy to allow some tolerance of, for
482
+ example, associations which might be `nil`.
483
+
484
+ ```ruby
485
+ class NilClassPolicy < ApplicationPolicy
486
+ class Scope < Scope
487
+ def resolve
488
+ raise Pundit::NotDefinedError, "Cannot scope NilClass"
489
+ end
490
+ end
491
+
492
+ def show?
493
+ false # Nobody can see nothing
494
+ end
379
495
  end
380
496
  ```
381
497
 
@@ -388,8 +504,7 @@ method in every controller.
388
504
 
389
505
  ```ruby
390
506
  class ApplicationController < ActionController::Base
391
- protect_from_forgery
392
- include Pundit
507
+ include Pundit::Authorization
393
508
 
394
509
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
395
510
 
@@ -397,11 +512,15 @@ class ApplicationController < ActionController::Base
397
512
 
398
513
  def user_not_authorized
399
514
  flash[:alert] = "You are not authorized to perform this action."
400
- redirect_to(request.referrer || root_path)
515
+ redirect_back(fallback_location: root_path)
401
516
  end
402
517
  end
403
518
  ```
404
519
 
520
+ Alternatively, you can globally handle Pundit::NotAuthorizedError's by having rails handle them as a 403 error and serving a 403 error page. Add the following to application.rb:
521
+
522
+ ```config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbidden```
523
+
405
524
  ## Creating custom error messages
406
525
 
407
526
  `NotAuthorizedError`s provide information on what query (e.g. `:create?`), what
@@ -422,7 +541,7 @@ class ApplicationController < ActionController::Base
422
541
  policy_name = exception.policy.class.to_s.underscore
423
542
 
424
543
  flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
425
- redirect_to(request.referrer || root_path)
544
+ redirect_back(fallback_url: root_path)
426
545
  end
427
546
  end
428
547
  ```
@@ -469,6 +588,47 @@ def pundit_user
469
588
  end
470
589
  ```
471
590
 
591
+ ## Policy Namespacing
592
+ In some cases it might be helpful to have multiple policies that serve different contexts for a
593
+ resource. A prime example of this is the case where User policies differ from Admin policies. To
594
+ authorize with a namespaced policy, pass the namespace into the `authorize` helper in an array:
595
+
596
+ ```ruby
597
+ authorize(post) # => will look for a PostPolicy
598
+ authorize([:admin, post]) # => will look for an Admin::PostPolicy
599
+ authorize([:foo, :bar, post]) # => will look for a Foo::Bar::PostPolicy
600
+
601
+ policy_scope(Post) # => will look for a PostPolicy::Scope
602
+ policy_scope([:admin, Post]) # => will look for an Admin::PostPolicy::Scope
603
+ policy_scope([:foo, :bar, Post]) # => will look for a Foo::Bar::PostPolicy::Scope
604
+ ```
605
+
606
+ If you are using namespaced policies for something like Admin views, it can be useful to
607
+ override the `policy_scope` and `authorize` helpers in your `AdminController` to automatically
608
+ apply the namespacing:
609
+
610
+ ```ruby
611
+ class AdminController < ApplicationController
612
+ def policy_scope(scope)
613
+ super([:admin, scope])
614
+ end
615
+
616
+ def authorize(record, query = nil)
617
+ super([:admin, record], query)
618
+ end
619
+ end
620
+
621
+ class Admin::PostController < AdminController
622
+ def index
623
+ policy_scope(Post)
624
+ end
625
+
626
+ def show
627
+ post = authorize Post.find(params[:id])
628
+ end
629
+ end
630
+ ```
631
+
472
632
  ## Additional context
473
633
 
474
634
  Pundit strongly encourages you to model your application in such a way that the
@@ -497,7 +657,7 @@ class UserContext
497
657
  end
498
658
 
499
659
  class ApplicationController
500
- include Pundit
660
+ include Pundit::Authorization
501
661
 
502
662
  def pundit_user
503
663
  UserContext.new(current_user, request.ip)
@@ -507,9 +667,8 @@ end
507
667
 
508
668
  ## Strong parameters
509
669
 
510
- In Rails 4 (or Rails 3.2 with the
511
- [strong_parameters](https://github.com/rails/strong_parameters) gem),
512
- mass-assignment protection is handled in the controller. With Pundit you can
670
+ In Rails,
671
+ mass-assignment protection is handled in the controller. With Pundit you can
513
672
  control which attributes a user has access to update via your policies. You can
514
673
  set up a `permitted_attributes` method in your policy like this:
515
674
 
@@ -533,7 +692,7 @@ You can now retrieve these attributes from the policy:
533
692
  class PostsController < ApplicationController
534
693
  def update
535
694
  @post = Post.find(params[:id])
536
- if @post.update_attributes(post_params)
695
+ if @post.update(post_params)
537
696
  redirect_to @post
538
697
  else
539
698
  render :edit
@@ -555,7 +714,7 @@ However, this is a bit cumbersome, so Pundit provides a convenient helper method
555
714
  class PostsController < ApplicationController
556
715
  def update
557
716
  @post = Post.find(params[:id])
558
- if @post.update_attributes(permitted_attributes(@post))
717
+ if @post.update(permitted_attributes(@post))
559
718
  redirect_to @post
560
719
  else
561
720
  render :edit
@@ -564,6 +723,45 @@ class PostsController < ApplicationController
564
723
  end
565
724
  ```
566
725
 
726
+ If you want to permit different attributes based on the current action, you can define a `permitted_attributes_for_#{action}` method on your policy:
727
+
728
+ ```ruby
729
+ # app/policies/post_policy.rb
730
+ class PostPolicy < ApplicationPolicy
731
+ def permitted_attributes_for_create
732
+ [:title, :body]
733
+ end
734
+
735
+ def permitted_attributes_for_edit
736
+ [:body]
737
+ end
738
+ end
739
+ ```
740
+
741
+ If you have defined an action-specific method on your policy for the current action, the `permitted_attributes` helper will call it instead of calling `permitted_attributes` on your controller.
742
+
743
+ If you need to fetch parameters based on namespaces different from the suggested one, override the below method, in your controller, and return an instance of `ActionController::Parameters`.
744
+
745
+ ```ruby
746
+ def pundit_params_for(record)
747
+ params.require(PolicyFinder.new(record).param_key)
748
+ end
749
+ ```
750
+
751
+ For example:
752
+
753
+ ```ruby
754
+ # If you don't want to use require
755
+ def pundit_params_for(record)
756
+ params.fetch(PolicyFinder.new(record).param_key, {})
757
+ end
758
+
759
+ # If you are using something like the JSON API spec
760
+ def pundit_params_for(_record)
761
+ params.fetch(:data, {}).fetch(:attributes, {})
762
+ end
763
+ ```
764
+
567
765
  ## RSpec
568
766
 
569
767
  ### Policy Specs
@@ -600,14 +798,33 @@ end
600
798
  An alternative approach to Pundit policy specs is scoping them to a user context as outlined in this
601
799
  [excellent post](http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/) and implemented in the third party [pundit-matchers](https://github.com/chrisalley/pundit-matchers) gem.
602
800
 
801
+ ### Scope Specs
802
+
803
+ Pundit does not provide a DSL for testing scopes. Just test it like a regular Ruby class!
804
+
805
+ ### Linting with RuboCop RSpec
806
+
807
+ When you lint your RSpec spec files with `rubocop-rspec`, it will fail to properly detect RSpec constructs that Pundit defines, `permissions`.
808
+ Make sure to use `rubocop-rspec` 2.0 or newer and add the following to your `.rubocop.yml`:
809
+
810
+ ```yaml
811
+ inherit_gem:
812
+ pundit: config/rubocop-rspec.yml
813
+ ```
814
+
603
815
  # External Resources
604
816
 
605
817
  - [RailsApps Example Application: Pundit and Devise](https://github.com/RailsApps/rails-devise-pundit)
606
818
  - [Migrating to Pundit from CanCan](http://blog.carbonfive.com/2013/10/21/migrating-to-pundit-from-cancan/)
607
819
  - [Testing Pundit Policies with RSpec](http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)
608
- - [Using Pundit outside of a Rails controller](https://github.com/elabs/pundit/pull/136)
820
+ - [Testing Pundit with Minitest](https://github.com/varvet/pundit/issues/204#issuecomment-60166450)
821
+ - [Using Pundit outside of a Rails controller](https://github.com/varvet/pundit/pull/136)
609
822
  - [Straightforward Rails Authorization with Pundit](http://www.sitepoint.com/straightforward-rails-authorization-with-pundit/)
610
823
 
824
+ ## Other implementations
825
+
826
+ - [Flask-Pundit](https://github.com/anurag90x/flask-pundit) (Python) is a [Flask](http://flask.pocoo.org/) extension "heavily inspired by" Pundit
827
+
611
828
  # License
612
829
 
613
830
  Licensed under the MIT license, see the separate LICENSE.txt file.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rubygems"
2
4
  require "bundler/gem_tasks"
3
5
  require "rspec/core/rake_task"
@@ -16,4 +18,3 @@ YARD::Rake::YardocTask.new do |t|
16
18
  end
17
19
 
18
20
  task default: :spec
19
- task default: :rubocop unless RUBY_ENGINE == "rbx"
@@ -0,0 +1,5 @@
1
+ RSpec:
2
+ Language:
3
+ ExampleGroups:
4
+ Regular:
5
+ - permissions
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pundit
2
4
  module Generators
3
5
  class InstallGenerator < ::Rails::Generators::Base
4
- source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def copy_application_policy
7
- template 'application_policy.rb', 'app/policies/application_policy.rb'
9
+ template "application_policy.rb", "app/policies/application_policy.rb"
8
10
  end
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ApplicationPolicy
2
4
  attr_reader :user, :record
3
5
 
@@ -11,7 +13,7 @@ class ApplicationPolicy
11
13
  end
12
14
 
13
15
  def show?
14
- scope.where(:id => record.id).exists?
16
+ false
15
17
  end
16
18
 
17
19
  def create?
@@ -34,20 +36,18 @@ class ApplicationPolicy
34
36
  false
35
37
  end
36
38
 
37
- def scope
38
- Pundit.policy_scope!(user, record.class)
39
- end
40
-
41
39
  class Scope
42
- attr_reader :user, :scope
43
-
44
40
  def initialize(user, scope)
45
41
  @user = user
46
42
  @scope = scope
47
43
  end
48
44
 
49
45
  def resolve
50
- scope
46
+ raise NotImplementedError, "You must define #resolve in #{self.class}"
51
47
  end
48
+
49
+ private
50
+
51
+ attr_reader :user, :scope
52
52
  end
53
53
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pundit
2
4
  module Generators
3
5
  class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def create_policy
7
- template 'policy.rb', File.join('app/policies', class_path, "#{file_name}_policy.rb")
9
+ template "policy.rb", File.join("app/policies", class_path, "#{file_name}_policy.rb")
8
10
  end
9
11
 
10
12
  hook_for :test_framework