pundit 2.0.1 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: dffd7b483c73feb3955b9f1eb6767d9fedb72eaf
4
- data.tar.gz: 5de4a5628f75bfcd87879c52917634f1ddde7072
2
+ SHA256:
3
+ metadata.gz: 82606dec60dec4ddb9086a4d1a71447bda39f9f17fd5e38025937f0fdb7b9b1a
4
+ data.tar.gz: e154a0dadc701871c49687ff843117e590011362be4cf3dfa7bc63ea4e5e698b
5
5
  SHA512:
6
- metadata.gz: f21abdc81639b1d05209f1dfc71579294ba5226372493936ea9e6cfc2cc356e620223042f9f58679a2bb276dabab3f81e793a22d4b6e4bb69ef7edb467d399c1
7
- data.tar.gz: fe50e431d42e21e415ad361a1a0f536373e4a90b6f0631321dce3ba1b8e804c13b3e1d44f0446b3b1e71c68dbd868b5881b7bbaf6367e69b92bf23acf34a1022
6
+ metadata.gz: 0414e7e35eb8e2aa3bac79a75f2d8ae4e45f5cf4152150be239664f620560732990b3547aeac678b50e4b62036ab25c45170f12ca1897c6bf41938589e5ef0bd
7
+ data.tar.gz: 964d660d1f79b36b8ace58452ca0adfef4f5ea68a7436f6373ae248f33cda7f017db5d5c5fbd0efca26fb5ee88a507cf900edc8bd0d7dad89a676cb308bd7bd1
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.2
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,20 +1,26 @@
1
1
  language: ruby
2
- before_install:
3
- - gem install bundler -v 1.17.3
2
+ dist: focal
4
3
 
5
4
  matrix:
6
5
  include:
7
- - 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
8
10
  script: bundle exec rake rubocop # ONLY lint once, first
9
- - rvm: 2.1
10
- - rvm: 2.2
11
- - rvm: 2.3.5
12
- - rvm: 2.4.2
13
- - rvm: 2.5.1
14
- - rvm: 2.6.0
15
- - rvm: jruby-9.1.8.0
16
- env:
17
- - JRUBY_OPTS="--debug"
18
- - rvm: jruby-9.2.5.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: jruby-9.2.17.0
19
22
  env:
20
23
  - JRUBY_OPTS="--debug"
24
+ - rvm: truffleruby-head
25
+ allow_failures:
26
+ - rvm: truffleruby-head
data/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Pundit
2
2
 
3
+ ## 2.2.0 (2022-02-11)
4
+
5
+ ### Fixed
6
+
7
+ - Using `policy_class` and a namespaced record now passes only the record when instantiating the policy. (#697, #689, #694, #666)
8
+
9
+ ### Changed
10
+
11
+ - Require users to explicitly define Scope#resolve in generated policies (#711, #722)
12
+
13
+ ### Deprecated
14
+
15
+ - Deprecate `include Pundit` in favor of `include Pundit::Authorization` (#621)
16
+
17
+ ## 2.1.1 (2021-08-13)
18
+
19
+ Friday 13th-release!
20
+
21
+ Careful! The bugfix below (#626) could break existing code. If you rely on the
22
+ return value for `authorize` and namespaced policies you might need to do some
23
+ changes.
24
+
25
+ ### Fixed
26
+
27
+ - `.authorize` and `#authorize` return the instance, even for namespaced
28
+ policies (#626)
29
+
30
+ ### Changed
31
+
32
+ - Generate application scope with `protected` attr_readers. (#616)
33
+
34
+ ### Removed
35
+
36
+ - Dropped support for Ruby end-of-life versions: 2.1 and 2.2. (#604)
37
+ - Dropped support for Ruby end-of-life versions: 2.3 (#633)
38
+ - Dropped support for Ruby end-of-life versions: 2.4, 2.5 and JRuby 9.1 (#676)
39
+ - Dropped support for RSpec 2 (#615)
40
+
41
+ ## 2.1.0 (2019-08-14)
42
+
43
+ ### Fixed
44
+
45
+ - Avoid name clashes with the Error class. (#590)
46
+
47
+ ### Changed
48
+
49
+ - Return a safer default NotAuthorizedError message. (#583)
50
+
3
51
  ## 2.0.1 (2019-01-18)
4
52
 
5
53
  ### Breaking changes
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) 2018 Jonas Nicklas, Varvet AB
1
+ Copyright (c) 2019 Jonas Nicklas, Varvet AB
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -7,11 +7,11 @@
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)
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
+ > **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
+
25
27
  ``` ruby
26
28
  gem "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
  ```
@@ -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,8 +196,17 @@ 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 just 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
 
@@ -201,7 +216,10 @@ is what is passed as the record to `authorize` below.
201
216
 
202
217
  ```ruby
203
218
  # In controllers
204
- authorize :dashboard, :show?
219
+ def show
220
+ authorize :dashboard, :show?
221
+ ...
222
+ end
205
223
  ```
206
224
 
207
225
  ```erb
@@ -220,8 +238,6 @@ define a class called a policy scope. It can look something like this:
220
238
  ``` ruby
221
239
  class PostPolicy < ApplicationPolicy
222
240
  class Scope
223
- attr_reader :user, :scope
224
-
225
241
  def initialize(user, scope)
226
242
  @user = user
227
243
  @scope = scope
@@ -234,6 +250,10 @@ class PostPolicy < ApplicationPolicy
234
250
  scope.where(published: true)
235
251
  end
236
252
  end
253
+
254
+ private
255
+
256
+ attr_reader :user, :scope
237
257
  end
238
258
 
239
259
  def update?
@@ -296,13 +316,11 @@ def index
296
316
  end
297
317
  ```
298
318
 
299
- Just as with your policy, this will automatically infer that you want to use
300
- the `PostPolicy::Scope` class, it will instantiate this class and call
301
- `resolve` on the instance. In this case it is a shortcut for doing:
319
+ In this case it is a shortcut for doing:
302
320
 
303
321
  ``` ruby
304
322
  def index
305
- @posts = PostPolicy::Scope.new(current_user, Post).resolve
323
+ @publications = PublicationPolicy::Scope.new(current_user, Post).resolve
306
324
  end
307
325
  ```
308
326
 
@@ -330,7 +348,7 @@ that you haven't forgotten to authorize the action. For example:
330
348
 
331
349
  ``` ruby
332
350
  class ApplicationController < ActionController::Base
333
- include Pundit
351
+ include Pundit::Authorization
334
352
  after_action :verify_authorized
335
353
  end
336
354
  ```
@@ -343,7 +361,7 @@ authorize individual instances.
343
361
 
344
362
  ``` ruby
345
363
  class ApplicationController < ActionController::Base
346
- include Pundit
364
+ include Pundit::Authorization
347
365
  after_action :verify_authorized, except: :index
348
366
  after_action :verify_policy_scoped, only: :index
349
367
  end
@@ -391,6 +409,16 @@ class Post
391
409
  end
392
410
  ```
393
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
+
394
422
  ## Just plain old Ruby
395
423
 
396
424
  As you can see, Pundit doesn't do anything you couldn't have easily done
@@ -476,8 +504,7 @@ method in every controller.
476
504
 
477
505
  ```ruby
478
506
  class ApplicationController < ActionController::Base
479
- protect_from_forgery
480
- include Pundit
507
+ include Pundit::Authorization
481
508
 
482
509
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
483
510
 
@@ -597,8 +624,7 @@ class Admin::PostController < AdminController
597
624
  end
598
625
 
599
626
  def show
600
- post = Post.find(params[:id])
601
- authorize(post)
627
+ post = authorize Post.find(params[:id])
602
628
  end
603
629
  end
604
630
  ```
@@ -631,7 +657,7 @@ class UserContext
631
657
  end
632
658
 
633
659
  class ApplicationController
634
- include Pundit
660
+ include Pundit::Authorization
635
661
 
636
662
  def pundit_user
637
663
  UserContext.new(current_user, request.ip)
@@ -641,9 +667,8 @@ end
641
667
 
642
668
  ## Strong parameters
643
669
 
644
- In Rails 4 (or Rails 3.2 with the
645
- [strong_parameters](https://github.com/rails/strong_parameters) gem),
646
- 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
647
672
  control which attributes a user has access to update via your policies. You can
648
673
  set up a `permitted_attributes` method in your policy like this:
649
674
 
@@ -782,9 +807,14 @@ Pundit does not provide a DSL for testing scopes. Just test it like a regular Ru
782
807
  - [RailsApps Example Application: Pundit and Devise](https://github.com/RailsApps/rails-devise-pundit)
783
808
  - [Migrating to Pundit from CanCan](http://blog.carbonfive.com/2013/10/21/migrating-to-pundit-from-cancan/)
784
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)
785
811
  - [Using Pundit outside of a Rails controller](https://github.com/varvet/pundit/pull/136)
786
812
  - [Straightforward Rails Authorization with Pundit](http://www.sitepoint.com/straightforward-rails-authorization-with-pundit/)
787
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
+
788
818
  # License
789
819
 
790
820
  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"
@@ -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('templates', __dir__)
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
 
@@ -35,15 +37,17 @@ class ApplicationPolicy
35
37
  end
36
38
 
37
39
  class Scope
38
- attr_reader :user, :scope
39
-
40
40
  def initialize(user, scope)
41
41
  @user = user
42
42
  @scope = scope
43
43
  end
44
44
 
45
45
  def resolve
46
- scope.all
46
+ raise NotImplementedError, "You must define #resolve in #{self.class}"
47
47
  end
48
+
49
+ private
50
+
51
+ attr_reader :user, :scope
48
52
  end
49
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('templates', __dir__)
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
@@ -1,9 +1,10 @@
1
1
  <% module_namespacing do -%>
2
2
  class <%= class_name %>Policy < ApplicationPolicy
3
3
  class Scope < Scope
4
- def resolve
5
- scope.all
6
- end
4
+ # NOTE: Be explicit about which records you allow access to!
5
+ # def resolve
6
+ # scope.all
7
+ # end
7
8
  end
8
9
  end
9
10
  <% end -%>
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rspec
2
4
  module Generators
3
5
  class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def create_policy_spec
7
- template 'policy_spec.rb', File.join('spec/policies', class_path, "#{file_name}_policy_spec.rb")
9
+ template "policy_spec.rb", File.join("spec/policies", class_path, "#{file_name}_policy_spec.rb")
8
10
  end
9
11
  end
10
12
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TestUnit
2
4
  module Generators
3
5
  class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def create_policy_test
7
- template 'policy_test.rb', File.join('test/policies', class_path, "#{file_name}_policy_test.rb")
9
+ template "policy_test.rb", File.join("test/policies", class_path, "#{file_name}_policy_test.rb")
8
10
  end
9
11
  end
10
12
  end