pundit 2.0.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b973703e2b1653c804d138fb24c204807e41885a81f5b172656d032d7c2a75a
4
- data.tar.gz: 01211cab222a4c16f274e041c074b2d2a1763a4943ab26b6dba938272297a48d
3
+ metadata.gz: b5c9e118c59bc3a683734817ac6fb9036a2b909df7abce2dbbdc00fc16aebdf7
4
+ data.tar.gz: 843cc1b7652e88d598a37a28f93bf13c41710bf3dddefeb96acf74e659279581
5
5
  SHA512:
6
- metadata.gz: 812528978ec4e8d3322af071c3ebd5b31f4123be449d3fe9bfea1e1fd2845704e0fee308d4cdd6e787636987b1d7a03527f8eae5fe5968483a1f4c5f751b40ef
7
- data.tar.gz: c433160a559102336b9a268ec1311a47e8f54e427ad8618b048634435259612a92d9b9187fefb6d7cc4a1ce5576a37f3e51b7adad1e3773d21c2bb6e9827c26f
6
+ metadata.gz: f2430ece33471f7a321a124aeafab7dbc3be4688fbda581b758d90649f4ae06d0cbaf86df768e881d0a2f1c0ab55581cb5dc0f1d3012ab7611b2fd81b8a0f321
7
+ data.tar.gz: 3432cc545ca5139cfcd7e1fc26a17d0882c11de71a3c6949c1d1da232183eba495de18aa06b64462c1233b820099788b43feeb0e9b439911bc9761dc7bd1e141
@@ -0,0 +1,9 @@
1
+ ## To do
2
+
3
+ - [ ] I have read the [contributing guidelines](https://github.com/varvet/pundit/contribute).
4
+ - [ ] I have added relevant tests.
5
+ - [ ] I have adjusted relevant documentation.
6
+ - [ ] I have made sure the individual commits are meaningful.
7
+ - [ ] I have added relevant lines to the CHANGELOG.
8
+
9
+ PS: Thank you for contributing to Pundit ❤️
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .coverage
5
6
  .yardoc
6
7
  Gemfile.lock
7
8
  InstalledFiles
data/.rubocop.yml CHANGED
@@ -1,10 +1,9 @@
1
1
  AllCops:
2
- DisplayCopNames: true
3
- TargetRubyVersion: 2.1
2
+ TargetRubyVersion: 2.6
4
3
  Exclude:
5
- - "gemfiles/**/*"
6
- - "vendor/**/*"
7
- - "lib/generators/**/*"
4
+ - "lib/generators/**/templates/**/*"
5
+ SuggestExtensions: false
6
+ NewCops: disable
8
7
 
9
8
  Metrics/BlockLength:
10
9
  Exclude:
@@ -18,7 +17,7 @@ Metrics/ModuleLength:
18
17
  Exclude:
19
18
  - "**/*_spec.rb"
20
19
 
21
- Metrics/LineLength:
20
+ Layout/LineLength:
22
21
  Max: 120
23
22
 
24
23
  Metrics/AbcSize:
@@ -30,33 +29,12 @@ Metrics/CyclomaticComplexity:
30
29
  Metrics/PerceivedComplexity:
31
30
  Enabled: false
32
31
 
33
- Style/StructInheritance:
34
- Enabled: false
32
+ Gemspec/RequiredRubyVersion:
33
+ Enabled: false
35
34
 
36
- Layout/AlignParameters:
35
+ Layout/ParameterAlignment:
37
36
  EnforcedStyle: with_fixed_indentation
38
37
 
39
- Style/StringLiterals:
40
- EnforcedStyle: double_quotes
41
-
42
- Style/StringLiteralsInInterpolation:
43
- EnforcedStyle: double_quotes
44
-
45
- Layout/ClosingParenthesisIndentation:
46
- Enabled: false
47
-
48
- Style/OneLineConditional:
49
- Enabled: false
50
-
51
- Style/AndOr:
52
- Enabled: false
53
-
54
- Style/Not:
55
- Enabled: false
56
-
57
- Documentation:
58
- Enabled: false # TODO: Enable again once we have more docs
59
-
60
38
  Layout/CaseIndentation:
61
39
  EnforcedStyle: case
62
40
  SupportedStyles:
@@ -64,40 +42,31 @@ Layout/CaseIndentation:
64
42
  - end
65
43
  IndentOneStep: true
66
44
 
45
+ Layout/EndAlignment:
46
+ EnforcedStyleAlignWith: variable
47
+
67
48
  Style/PercentLiteralDelimiters:
68
49
  PreferredDelimiters:
69
50
  '%w': "[]"
70
51
  '%W': "[]"
71
52
 
72
- Layout/AccessModifierIndentation:
73
- EnforcedStyle: outdent
74
-
75
- Style/SignalException:
76
- Enabled: false
77
-
78
- Layout/IndentationWidth:
79
- Enabled: false
80
-
81
- Style/TrivialAccessors:
82
- ExactNameMatch: true
83
-
84
- Layout/EndAlignment:
85
- EnforcedStyleAlignWith: variable
86
-
87
- Layout/DefEndAlignment:
88
- Enabled: false
53
+ Style/StringLiterals:
54
+ EnforcedStyle: double_quotes
89
55
 
90
- Lint/HandleExceptions:
91
- Enabled: false
56
+ Style/StringLiteralsInInterpolation:
57
+ EnforcedStyle: double_quotes
92
58
 
93
- Style/SpecialGlobalVars:
59
+ Style/StructInheritance:
94
60
  Enabled: false
95
61
 
96
- Style/TrivialAccessors:
62
+ Style/AndOr:
97
63
  Enabled: false
98
64
 
99
- Layout/IndentHash:
65
+ Style/Not:
100
66
  Enabled: false
101
67
 
102
68
  Style/DoubleNegation:
103
69
  Enabled: false
70
+
71
+ Style/Documentation:
72
+ Enabled: false # TODO: Enable again once we have more docs
data/.travis.yml CHANGED
@@ -1,21 +1,27 @@
1
1
  language: ruby
2
- sudo: false
3
- before_install:
4
- - gem update --system
5
- - gem install bundler
2
+ dist: focal
6
3
 
7
4
  matrix:
8
5
  include:
9
- - rvm: 2.5.1
6
+ - name: "RuboCop lint on pre-installed Ruby version"
7
+ rvm: 2.7.1 # Pre-installed Ruby version
8
+ before_install:
9
+ - gem install bundler
10
10
  script: bundle exec rake rubocop # ONLY lint once, first
11
- - rvm: 2.1
12
- - rvm: 2.2.8
13
- - rvm: 2.3.5
14
- - rvm: 2.4.2
15
- - rvm: 2.5.1
16
- - rvm: jruby-9.1.8.0
17
- env:
18
- - JRUBY_OPTS="--debug"
19
- - rvm: jruby-9.2.0.0
11
+ - rvm: 2.6.7
12
+ before_script:
13
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
14
+ - chmod +x ./cc-test-reporter
15
+ - ./cc-test-reporter before-build
16
+ after_script:
17
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
18
+ - rvm: 2.7.3
19
+ - rvm: 3.0.1
20
+ - rvm: 3.1.0
21
+ - rvm: 3.2.0
22
+ - rvm: jruby-9.3.10.0
20
23
  env:
21
24
  - JRUBY_OPTS="--debug"
25
+ - rvm: truffleruby-head
26
+ allow_failures:
27
+ - rvm: truffleruby-head
data/CHANGELOG.md CHANGED
@@ -1,21 +1,103 @@
1
1
  # Pundit
2
2
 
3
+ ## Unreleased
4
+
5
+ Nothing.
6
+
7
+ ## 2.3.1 (2023-07-17)
8
+
9
+ ### Fixed
10
+
11
+ - Use `Kernel.warn` instead of `ActiveSupport::Deprecation.warn` for deprecations (#764)
12
+ - Policy generator now works on Ruby 3.2 (#754)
13
+
14
+ ## 2.3.0 (2022-12-19)
15
+
16
+ ### Added
17
+
18
+ - add support for rubocop-rspec syntax extensions (#745)
19
+
20
+ ## 2.2.0 (2022-02-11)
21
+
22
+ ### Fixed
23
+
24
+ - Using `policy_class` and a namespaced record now passes only the record when instantiating the policy. (#697, #689, #694, #666)
25
+
26
+ ### Changed
27
+
28
+ - Require users to explicitly define Scope#resolve in generated policies (#711, #722)
29
+
30
+ ### Deprecated
31
+
32
+ - Deprecate `include Pundit` in favor of `include Pundit::Authorization` (#621)
33
+
34
+ ## 2.1.1 (2021-08-13)
35
+
36
+ Friday 13th-release!
37
+
38
+ Careful! The bugfix below (#626) could break existing code. If you rely on the
39
+ return value for `authorize` and namespaced policies you might need to do some
40
+ changes.
41
+
42
+ ### Fixed
43
+
44
+ - `.authorize` and `#authorize` return the instance, even for namespaced
45
+ policies (#626)
46
+
47
+ ### Changed
48
+
49
+ - Generate application scope with `protected` attr_readers. (#616)
50
+
51
+ ### Removed
52
+
53
+ - Dropped support for Ruby end-of-life versions: 2.1 and 2.2. (#604)
54
+ - Dropped support for Ruby end-of-life versions: 2.3 (#633)
55
+ - Dropped support for Ruby end-of-life versions: 2.4, 2.5 and JRuby 9.1 (#676)
56
+ - Dropped support for RSpec 2 (#615)
57
+
58
+ ## 2.1.0 (2019-08-14)
59
+
60
+ ### Fixed
61
+
62
+ - Avoid name clashes with the Error class. (#590)
63
+
64
+ ### Changed
65
+
66
+ - Return a safer default NotAuthorizedError message. (#583)
67
+
68
+ ## 2.0.1 (2019-01-18)
69
+
70
+ ### Breaking changes
71
+
72
+ None
73
+
74
+ ### Other changes
75
+
76
+ - Improve exception handling for `#policy_scope` and `#policy_scope!`. (#550)
77
+ - Add `:policy` metadata to RSpec template. (#566)
78
+
3
79
  ## 2.0.0 (2018-07-21)
4
80
 
5
81
  No changes since beta1
6
82
 
7
83
  ## 2.0.0.beta1 (2018-07-04)
8
84
 
85
+ ### Breaking changes
86
+
87
+ - Only pass last element of "namespace array" to policy and scope. (#529)
88
+ - Raise `InvalidConstructorError` if a policy or policy scope with an invalid constructor is called. (#462)
89
+ - Return passed object from `#authorize` method to make chaining possible. (#385)
90
+
91
+ ### Other changes
92
+
9
93
  - Add `policy_class` option to `authorize` to be able to override the policy. (#441)
10
94
  - Add `policy_scope_class` option to `authorize` to be able to override the policy scope. (#441)
11
95
  - Fix `param_key` issue when passed an array. (#529)
12
- - Only pass last element of "namespace array" to policy and scope. (#529)
13
96
  - Allow specification of a `NilClassPolicy`. (#525)
14
97
  - Make sure `policy_class` override is called when passed an array. (#475)
15
- - Raise `InvalidConstructorError` if a policy or policy scope with an invalid constructor is called. (#462)
98
+
16
99
  - Use `action_name` instead of `params[:action]`. (#419)
17
100
  - Add `pundit_params_for` method to make it easy to customize params fetching. (#502)
18
- - Return passed object from `#authorize` method to make chaining possible. (#385)
19
101
 
20
102
  ## 1.1.0 (2016-01-14)
21
103
 
data/CONTRIBUTING.md CHANGED
@@ -1,9 +1,6 @@
1
1
  ## Security issues
2
2
 
3
- If you have found a security related issue, please do not file an issue on
4
- GitHub or send a PR addressing the issue. Contact
5
- [Jonas](mailto:jonas.nicklas@gmail.com) directly. You will be given public
6
- credit for your disclosure.
3
+ If you have found a security related issue, please do not file an issue on GitHub or send a PR addressing the issue. Refer to [SECURITY.md](./SECURITY.md) for instructions.
7
4
 
8
5
  ## Reporting issues
9
6
 
data/Gemfile CHANGED
@@ -1,16 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  ruby RUBY_VERSION
4
6
 
5
7
  gemspec
6
-
7
- group :development, :test do
8
- gem "actionpack"
9
- gem "activemodel"
10
- gem "bundler"
11
- gem "pry"
12
- gem "rake"
13
- gem "rspec"
14
- gem "rubocop"
15
- gem "yard"
16
- end
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Jonas Nicklas, Elabs AB
1
+ Copyright (c) 2019 Jonas Nicklas, Varvet AB
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,17 +1,17 @@
1
1
  # Pundit
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/varvet/pundit.svg?branch=master)](https://travis-ci.org/varvet/pundit)
3
+ [![Build Status](https://app.travis-ci.com/varvet/pundit.svg?branch=main)](https://app.travis-ci.com/varvet/pundit)
4
4
  [![Code Climate](https://codeclimate.com/github/varvet/pundit.svg)](https://codeclimate.com/github/varvet/pundit)
5
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
- classes and object oriented design patterns to build a simple, robust and
10
- scaleable authorization system.
9
+ classes and object oriented design patterns to build a straightforward, robust, and
10
+ scalable authorization system.
11
11
 
12
12
  Links:
13
13
 
14
- - [API documentation](http://www.rubydoc.info/gems/pundit)
14
+ - [API documentation for the most recent version](http://www.rubydoc.info/gems/pundit)
15
15
  - [Source Code](https://github.com/varvet/pundit)
16
16
  - [Contributing](https://github.com/varvet/pundit/blob/master/CONTRIBUTING.md)
17
17
  - [Code of Conduct](https://github.com/varvet/pundit/blob/master/CODE_OF_CONDUCT.md)
@@ -22,16 +22,17 @@ Sponsored by:
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
 
@@ -48,8 +49,8 @@ can pick up any classes in the new `app/policies/` directory.
48
49
  ## Policies
49
50
 
50
51
  Pundit is focused around the notion of policy classes. We suggest that you put
51
- these classes in `app/policies`. This is a simple example that allows updating
52
- a post if the user is an admin, or if the post is unpublished:
52
+ these classes in `app/policies`. This is an example that allows updating a post
53
+ if the user is an admin, or if the post is unpublished:
53
54
 
54
55
  ``` ruby
55
56
  class PostPolicy
@@ -61,12 +62,12 @@ 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
  ```
68
69
 
69
- As you can see, this is just a plain Ruby class. Pundit makes the following
70
+ As you can see, this is a plain Ruby class. Pundit makes the following
70
71
  assumptions about this class:
71
72
 
72
73
  - The class has the same name as some kind of model class, only suffixed
@@ -165,13 +166,18 @@ def admin_list
165
166
  end
166
167
  ```
167
168
 
168
- `authorize` returns the object passed to it, so you can chain it like this:
169
+ `authorize` returns the instance passed to it, so you can chain it like this:
169
170
 
170
171
  Controller:
171
172
  ```ruby
172
173
  def show
173
174
  @user = authorize User.find(params[:id])
174
175
  end
176
+
177
+ # return the record even for namespaced policies
178
+ def show
179
+ @user = authorize [:admin, User.find(params[:id])]
180
+ end
175
181
  ```
176
182
 
177
183
  You can easily get a hold of an instance of the policy through the `policy`
@@ -190,14 +196,30 @@ you can retrieve it by passing a symbol.
190
196
 
191
197
  ```ruby
192
198
  # app/policies/dashboard_policy.rb
193
- class DashboardPolicy < Struct.new(:user, :dashboard)
194
- # ...
199
+ class DashboardPolicy
200
+ attr_reader :user
201
+
202
+ # `_record` in this example will be :dashboard
203
+ def initialize(user, _record)
204
+ @user = user
205
+ end
206
+
207
+ def show?
208
+ user.admin?
209
+ end
195
210
  end
196
211
  ```
197
212
 
213
+ Note that the headless policy still needs to accept two arguments. The
214
+ second argument will be the symbol `:dashboard` in this case, which
215
+ is what is passed as the record to `authorize` below.
216
+
198
217
  ```ruby
199
218
  # In controllers
200
- authorize :dashboard, :show?
219
+ def show
220
+ authorize :dashboard, :show?
221
+ ...
222
+ end
201
223
  ```
202
224
 
203
225
  ```erb
@@ -216,8 +238,6 @@ define a class called a policy scope. It can look something like this:
216
238
  ``` ruby
217
239
  class PostPolicy < ApplicationPolicy
218
240
  class Scope
219
- attr_reader :user, :scope
220
-
221
241
  def initialize(user, scope)
222
242
  @user = user
223
243
  @scope = scope
@@ -230,6 +250,10 @@ class PostPolicy < ApplicationPolicy
230
250
  scope.where(published: true)
231
251
  end
232
252
  end
253
+
254
+ private
255
+
256
+ attr_reader :user, :scope
233
257
  end
234
258
 
235
259
  def update?
@@ -292,13 +316,11 @@ def index
292
316
  end
293
317
  ```
294
318
 
295
- Just as with your policy, this will automatically infer that you want to use
296
- the `PostPolicy::Scope` class, it will instantiate this class and call
297
- `resolve` on the instance. In this case it is a shortcut for doing:
319
+ In this case it is a shortcut for doing:
298
320
 
299
321
  ``` ruby
300
322
  def index
301
- @posts = PostPolicy::Scope.new(current_user, Post).resolve
323
+ @publications = PublicationPolicy::Scope.new(current_user, Post).resolve
302
324
  end
303
325
  ```
304
326
 
@@ -326,7 +348,7 @@ that you haven't forgotten to authorize the action. For example:
326
348
 
327
349
  ``` ruby
328
350
  class ApplicationController < ActionController::Base
329
- include Pundit
351
+ include Pundit::Authorization
330
352
  after_action :verify_authorized
331
353
  end
332
354
  ```
@@ -339,7 +361,7 @@ authorize individual instances.
339
361
 
340
362
  ``` ruby
341
363
  class ApplicationController < ActionController::Base
342
- include Pundit
364
+ include Pundit::Authorization
343
365
  after_action :verify_authorized, except: :index
344
366
  after_action :verify_policy_scoped, only: :index
345
367
  end
@@ -352,7 +374,7 @@ these filters without affecting how your app works in any way.**
352
374
 
353
375
  Some people have found this feature confusing, while many others
354
376
  find it extremely helpful. If you fall into the category of people who find it
355
- confusing then you do not need to use it. Pundit will work just fine without
377
+ confusing then you do not need to use it. Pundit will work fine without
356
378
  using `verify_authorized` and `verify_policy_scoped`.
357
379
 
358
380
  ### Conditional verification
@@ -387,20 +409,23 @@ class Post
387
409
  end
388
410
  ```
389
411
 
390
- ## Just plain old Ruby
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
+
422
+ ## Plain old Ruby
423
+
424
+ Pundit is a very small library on purpose, and it doesn't do anything you can't do yourself. There's no secret sauce here. It does as little as possible, and then gets out of your way.
391
425
 
392
- As you can see, Pundit doesn't do anything you couldn't have easily done
393
- yourself. It's a very small library, it just provides a few neat helpers.
394
- Together these give you the power of building a well structured, fully working
395
- authorization system without using any special DSLs or funky syntax or
396
- anything.
426
+ With the few but powerful helpers available in Pundit, you have the power to build a well structured, fully working authorization system without using any special DSLs or funky syntax.
397
427
 
398
- Remember that all of the policy and scope classes are just plain Ruby classes,
399
- which means you can use the same mechanisms you always use to DRY things up.
400
- Encapsulate a set of permissions into a module and include them in multiple
401
- policies. Use `alias_method` to make some permissions behave the same as
402
- others. Inherit from a base set of permissions. Use metaprogramming if you
403
- really have to.
428
+ Remember that all of the policy and scope classes are plain Ruby classes, which means you can use the same mechanisms you always use to DRY things up. Encapsulate a set of permissions into a module and include them in multiple policies. Use `alias_method` to make some permissions behave the same as others. Inherit from a base set of permissions. Use metaprogramming if you really have to.
404
429
 
405
430
  ## Generator
406
431
 
@@ -472,8 +497,7 @@ method in every controller.
472
497
 
473
498
  ```ruby
474
499
  class ApplicationController < ActionController::Base
475
- protect_from_forgery
476
- include Pundit
500
+ include Pundit::Authorization
477
501
 
478
502
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
479
503
 
@@ -481,7 +505,7 @@ class ApplicationController < ActionController::Base
481
505
 
482
506
  def user_not_authorized
483
507
  flash[:alert] = "You are not authorized to perform this action."
484
- redirect_to(request.referrer || root_path)
508
+ redirect_back(fallback_location: root_path)
485
509
  end
486
510
  end
487
511
  ```
@@ -510,7 +534,7 @@ class ApplicationController < ActionController::Base
510
534
  policy_name = exception.policy.class.to_s.underscore
511
535
 
512
536
  flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
513
- redirect_to(request.referrer || root_path)
537
+ redirect_back(fallback_location: root_path)
514
538
  end
515
539
  end
516
540
  ```
@@ -524,8 +548,7 @@ en:
524
548
  create?: 'You cannot create posts!'
525
549
  ```
526
550
 
527
- Of course, this is just an example. Pundit is agnostic as to how you implement
528
- your error messaging.
551
+ This is an example. Pundit is agnostic as to how you implement your error messaging.
529
552
 
530
553
  ## Manually retrieving policies and scopes
531
554
 
@@ -547,9 +570,7 @@ those without the bang will return nil.
547
570
 
548
571
  ## Customize Pundit user
549
572
 
550
- In some cases your controller might not have access to `current_user`, or your
551
- `current_user` is not the method that should be invoked by Pundit. Simply
552
- define a method in your controller called `pundit_user`.
573
+ On occasion, your controller may be unable to access `current_user`, or the method that should be invoked by Pundit may not be `current_user`. To address this, you can define a method in your controller named `pundit_user`.
553
574
 
554
575
  ```ruby
555
576
  def pundit_user
@@ -593,8 +614,7 @@ class Admin::PostController < AdminController
593
614
  end
594
615
 
595
616
  def show
596
- post = Post.find(params[:id])
597
- authorize(post)
617
+ post = authorize Post.find(params[:id])
598
618
  end
599
619
  end
600
620
  ```
@@ -627,7 +647,7 @@ class UserContext
627
647
  end
628
648
 
629
649
  class ApplicationController
630
- include Pundit
650
+ include Pundit::Authorization
631
651
 
632
652
  def pundit_user
633
653
  UserContext.new(current_user, request.ip)
@@ -637,9 +657,8 @@ end
637
657
 
638
658
  ## Strong parameters
639
659
 
640
- In Rails 4 (or Rails 3.2 with the
641
- [strong_parameters](https://github.com/rails/strong_parameters) gem),
642
- mass-assignment protection is handled in the controller. With Pundit you can
660
+ In Rails,
661
+ mass-assignment protection is handled in the controller. With Pundit you can
643
662
  control which attributes a user has access to update via your policies. You can
644
663
  set up a `permitted_attributes` method in your policy like this:
645
664
 
@@ -663,7 +682,7 @@ You can now retrieve these attributes from the policy:
663
682
  class PostsController < ApplicationController
664
683
  def update
665
684
  @post = Post.find(params[:id])
666
- if @post.update_attributes(post_params)
685
+ if @post.update(post_params)
667
686
  redirect_to @post
668
687
  else
669
688
  render :edit
@@ -685,7 +704,7 @@ However, this is a bit cumbersome, so Pundit provides a convenient helper method
685
704
  class PostsController < ApplicationController
686
705
  def update
687
706
  @post = Post.find(params[:id])
688
- if @post.update_attributes(permitted_attributes(@post))
707
+ if @post.update(permitted_attributes(@post))
689
708
  redirect_to @post
690
709
  else
691
710
  render :edit
@@ -767,20 +786,35 @@ end
767
786
  ```
768
787
 
769
788
  An alternative approach to Pundit policy specs is scoping them to a user context as outlined in this
770
- [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.
789
+ [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/punditcommunity/pundit-matchers) gem.
771
790
 
772
791
  ### Scope Specs
773
792
 
774
- Pundit does not provide a DSL for testing scopes. Just test it like a regular Ruby class!
793
+ Pundit does not provide a DSL for testing scopes. Test them like you would a regular Ruby class!
794
+
795
+ ### Linting with RuboCop RSpec
796
+
797
+ When you lint your RSpec spec files with `rubocop-rspec`, it will fail to properly detect RSpec constructs that Pundit defines, `permissions`.
798
+ Make sure to use `rubocop-rspec` 2.0 or newer and add the following to your `.rubocop.yml`:
799
+
800
+ ```yaml
801
+ inherit_gem:
802
+ pundit: config/rubocop-rspec.yml
803
+ ```
775
804
 
776
805
  # External Resources
777
806
 
778
807
  - [RailsApps Example Application: Pundit and Devise](https://github.com/RailsApps/rails-devise-pundit)
779
808
  - [Migrating to Pundit from CanCan](http://blog.carbonfive.com/2013/10/21/migrating-to-pundit-from-cancan/)
780
809
  - [Testing Pundit Policies with RSpec](http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)
810
+ - [Testing Pundit with Minitest](https://github.com/varvet/pundit/issues/204#issuecomment-60166450)
781
811
  - [Using Pundit outside of a Rails controller](https://github.com/varvet/pundit/pull/136)
782
812
  - [Straightforward Rails Authorization with Pundit](http://www.sitepoint.com/straightforward-rails-authorization-with-pundit/)
783
813
 
814
+ ## Other implementations
815
+
816
+ - [Flask-Pundit](https://github.com/anurag90x/flask-pundit) (Python) is a [Flask](http://flask.pocoo.org/) extension "heavily inspired by" Pundit
817
+
784
818
  # License
785
819
 
786
820
  Licensed under the MIT license, see the separate LICENSE.txt file.