pundit 2.1.0 → 2.1.1
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/.gitignore +1 -0
- data/.rubocop.yml +2 -11
- data/.travis.yml +18 -14
- data/CHANGELOG.md +28 -0
- data/README.md +28 -16
- data/lib/generators/pundit/install/install_generator.rb +4 -2
- data/lib/generators/pundit/install/templates/application_policy.rb +6 -2
- data/lib/generators/pundit/policy/policy_generator.rb +4 -2
- data/lib/generators/rspec/policy_generator.rb +4 -2
- data/lib/generators/test_unit/policy_generator.rb +4 -2
- data/lib/pundit.rb +7 -7
- data/lib/pundit/policy_finder.rb +1 -1
- data/lib/pundit/rspec.rb +5 -15
- data/lib/pundit/version.rb +1 -1
- data/pundit.gemspec +3 -2
- data/spec/policies/post_policy_spec.rb +1 -1
- data/spec/policy_finder_spec.rb +80 -17
- data/spec/pundit_spec.rb +38 -2
- data/spec/spec_helper.rb +20 -23
- metadata +21 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: def6c710d9f9d1705ca43cdad9364bb34ce5d878b8a3a9bf26d336802e40efeb
|
4
|
+
data.tar.gz: 0d6618cb61dfef8ae18f811a73b3f059d9945f8def7f9b2f794ae095b3a0f0cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7105cd0a84469071de9211e19f7e7a31f4ea8b5283d7b1ed007b6533805de18d105c09128a9936144612f3daa8fadfdf0698f7448d8db94e47bb459efaa11c4b
|
7
|
+
data.tar.gz: 3805e2664f21f30c66e9a9a05606f0d0d18b1607137e794948c7907bd33c6d6e64a45b9abb97d2f1a21df0d46497ff708679442807e152fa167abc461c8c0abe
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
AllCops:
|
2
|
-
|
3
|
-
TargetRubyVersion: 2.2
|
2
|
+
TargetRubyVersion: 2.6
|
4
3
|
Exclude:
|
5
|
-
- "
|
6
|
-
- "vendor/**/*"
|
7
|
-
- "lib/generators/**/*"
|
4
|
+
- "lib/generators/**/templates/**/*"
|
8
5
|
|
9
6
|
Metrics/BlockLength:
|
10
7
|
Exclude:
|
@@ -40,15 +37,9 @@ Layout/CaseIndentation:
|
|
40
37
|
- end
|
41
38
|
IndentOneStep: true
|
42
39
|
|
43
|
-
Layout/AccessModifierIndentation:
|
44
|
-
EnforcedStyle: outdent
|
45
|
-
|
46
40
|
Layout/EndAlignment:
|
47
41
|
EnforcedStyleAlignWith: variable
|
48
42
|
|
49
|
-
Style/FrozenStringLiteralComment:
|
50
|
-
Enabled: true
|
51
|
-
|
52
43
|
Style/PercentLiteralDelimiters:
|
53
44
|
PreferredDelimiters:
|
54
45
|
'%w': "[]"
|
data/.travis.yml
CHANGED
@@ -1,21 +1,25 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
|
-
- gem install bundler -v 1.17.3
|
2
|
+
dist: focal
|
4
3
|
|
5
4
|
matrix:
|
6
5
|
include:
|
7
|
-
-
|
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.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
- rvm: jruby-9.2.8.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: jruby-9.2.17.0
|
20
21
|
env:
|
21
22
|
- JRUBY_OPTS="--debug"
|
23
|
+
- rvm: truffleruby-head
|
24
|
+
allow_failures:
|
25
|
+
- rvm: truffleruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Pundit
|
2
2
|
|
3
|
+
## Unreleased
|
4
|
+
|
5
|
+
## 2.1.1 (2021-08-13)
|
6
|
+
|
7
|
+
Friday 13th-release!
|
8
|
+
|
9
|
+
Careful! The bugfix below (#626) could break existing code. If you rely on the
|
10
|
+
return value for `authorize` and namespaced policies you might need to do some
|
11
|
+
changes.
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
- `.authorize` and `#authorize` return the instance, even for namespaced
|
16
|
+
policies (#626)
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- Generate application scope with `protected` attr_readers. (#616)
|
21
|
+
|
22
|
+
### Removed
|
23
|
+
|
24
|
+
- Dropped support for Ruby end-of-life versions: 2.1 and 2.2. (#604)
|
25
|
+
- Dropped support for Ruby end-of-life versions: 2.3 (#633)
|
26
|
+
- Dropped support for Ruby end-of-life versions: 2.4, 2.5 and JRuby 9.1 (#676)
|
27
|
+
- Dropped support for RSpec 2 (#615)
|
28
|
+
|
29
|
+
## 2.1.0 (2019-08-14)
|
30
|
+
|
3
31
|
### Fixed
|
4
32
|
|
5
33
|
- Avoid name clashes with the Error class. (#590)
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
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
|
-
|
10
|
+
scalable authorization system.
|
11
11
|
|
12
12
|
Links:
|
13
13
|
|
@@ -31,7 +31,6 @@ Include Pundit in your application controller:
|
|
31
31
|
``` ruby
|
32
32
|
class ApplicationController < ActionController::Base
|
33
33
|
include Pundit
|
34
|
-
protect_from_forgery
|
35
34
|
end
|
36
35
|
```
|
37
36
|
|
@@ -61,7 +60,7 @@ class PostPolicy
|
|
61
60
|
end
|
62
61
|
|
63
62
|
def update?
|
64
|
-
user.admin?
|
63
|
+
user.admin? || !post.published?
|
65
64
|
end
|
66
65
|
end
|
67
66
|
```
|
@@ -165,13 +164,18 @@ def admin_list
|
|
165
164
|
end
|
166
165
|
```
|
167
166
|
|
168
|
-
`authorize` returns the
|
167
|
+
`authorize` returns the instance passed to it, so you can chain it like this:
|
169
168
|
|
170
169
|
Controller:
|
171
170
|
```ruby
|
172
171
|
def show
|
173
172
|
@user = authorize User.find(params[:id])
|
174
173
|
end
|
174
|
+
|
175
|
+
# return the record even for namespaced policies
|
176
|
+
def show
|
177
|
+
@user = authorize [:admin, User.find(params[:id])]
|
178
|
+
end
|
175
179
|
```
|
176
180
|
|
177
181
|
You can easily get a hold of an instance of the policy through the `policy`
|
@@ -220,8 +224,6 @@ define a class called a policy scope. It can look something like this:
|
|
220
224
|
``` ruby
|
221
225
|
class PostPolicy < ApplicationPolicy
|
222
226
|
class Scope
|
223
|
-
attr_reader :user, :scope
|
224
|
-
|
225
227
|
def initialize(user, scope)
|
226
228
|
@user = user
|
227
229
|
@scope = scope
|
@@ -234,6 +236,10 @@ class PostPolicy < ApplicationPolicy
|
|
234
236
|
scope.where(published: true)
|
235
237
|
end
|
236
238
|
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
attr_reader :user, :scope
|
237
243
|
end
|
238
244
|
|
239
245
|
def update?
|
@@ -296,13 +302,11 @@ def index
|
|
296
302
|
end
|
297
303
|
```
|
298
304
|
|
299
|
-
|
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:
|
305
|
+
In this case it is a shortcut for doing:
|
302
306
|
|
303
307
|
``` ruby
|
304
308
|
def index
|
305
|
-
@
|
309
|
+
@publications = PublicationPolicy::Scope.new(current_user, Post).resolve
|
306
310
|
end
|
307
311
|
```
|
308
312
|
|
@@ -391,6 +395,16 @@ class Post
|
|
391
395
|
end
|
392
396
|
```
|
393
397
|
|
398
|
+
Alternatively, you can declare an instance method:
|
399
|
+
|
400
|
+
``` ruby
|
401
|
+
class Post
|
402
|
+
def policy_class
|
403
|
+
PostablePolicy
|
404
|
+
end
|
405
|
+
end
|
406
|
+
```
|
407
|
+
|
394
408
|
## Just plain old Ruby
|
395
409
|
|
396
410
|
As you can see, Pundit doesn't do anything you couldn't have easily done
|
@@ -476,7 +490,6 @@ method in every controller.
|
|
476
490
|
|
477
491
|
```ruby
|
478
492
|
class ApplicationController < ActionController::Base
|
479
|
-
protect_from_forgery
|
480
493
|
include Pundit
|
481
494
|
|
482
495
|
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
|
@@ -597,8 +610,7 @@ class Admin::PostController < AdminController
|
|
597
610
|
end
|
598
611
|
|
599
612
|
def show
|
600
|
-
post = Post.find(params[:id])
|
601
|
-
authorize(post)
|
613
|
+
post = authorize Post.find(params[:id])
|
602
614
|
end
|
603
615
|
end
|
604
616
|
```
|
@@ -641,9 +653,8 @@ end
|
|
641
653
|
|
642
654
|
## Strong parameters
|
643
655
|
|
644
|
-
In Rails
|
645
|
-
|
646
|
-
mass-assignment protection is handled in the controller. With Pundit you can
|
656
|
+
In Rails,
|
657
|
+
mass-assignment protection is handled in the controller. With Pundit you can
|
647
658
|
control which attributes a user has access to update via your policies. You can
|
648
659
|
set up a `permitted_attributes` method in your policy like this:
|
649
660
|
|
@@ -782,6 +793,7 @@ Pundit does not provide a DSL for testing scopes. Just test it like a regular Ru
|
|
782
793
|
- [RailsApps Example Application: Pundit and Devise](https://github.com/RailsApps/rails-devise-pundit)
|
783
794
|
- [Migrating to Pundit from CanCan](http://blog.carbonfive.com/2013/10/21/migrating-to-pundit-from-cancan/)
|
784
795
|
- [Testing Pundit Policies with RSpec](http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)
|
796
|
+
- [Testing Pundit with Minitest](https://github.com/varvet/pundit/issues/204#issuecomment-60166450)
|
785
797
|
- [Using Pundit outside of a Rails controller](https://github.com/varvet/pundit/pull/136)
|
786
798
|
- [Straightforward Rails Authorization with Pundit](http://www.sitepoint.com/straightforward-rails-authorization-with-pundit/)
|
787
799
|
|
@@ -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(
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
5
7
|
|
6
8
|
def copy_application_policy
|
7
|
-
template
|
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,8 +37,6 @@ 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
|
@@ -45,5 +45,9 @@ class ApplicationPolicy
|
|
45
45
|
def resolve
|
46
46
|
scope.all
|
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(
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
5
7
|
|
6
8
|
def create_policy
|
7
|
-
template
|
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,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(
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
5
7
|
|
6
8
|
def create_policy_spec
|
7
|
-
template
|
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(
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
5
7
|
|
6
8
|
def create_policy_test
|
7
|
-
template
|
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
|
data/lib/pundit.rb
CHANGED
@@ -15,7 +15,7 @@ class Pundit::Error < StandardError; end # rubocop:disable Style/ClassAndModuleC
|
|
15
15
|
|
16
16
|
# @api public
|
17
17
|
module Pundit
|
18
|
-
SUFFIX = "Policy"
|
18
|
+
SUFFIX = "Policy"
|
19
19
|
|
20
20
|
# @api private
|
21
21
|
module Generators; end
|
@@ -71,7 +71,7 @@ module Pundit
|
|
71
71
|
|
72
72
|
raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
|
73
73
|
|
74
|
-
record
|
74
|
+
record.is_a?(Array) ? record.last : record
|
75
75
|
end
|
76
76
|
|
77
77
|
# Retrieves the policy scope for the given record.
|
@@ -124,7 +124,7 @@ module Pundit
|
|
124
124
|
# @return [Object, nil] instance of policy class with query methods
|
125
125
|
def policy(user, record)
|
126
126
|
policy = PolicyFinder.new(record).policy
|
127
|
-
policy
|
127
|
+
policy&.new(user, pundit_model(record))
|
128
128
|
rescue ArgumentError
|
129
129
|
raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
|
130
130
|
end
|
@@ -144,7 +144,7 @@ module Pundit
|
|
144
144
|
raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
|
145
145
|
end
|
146
146
|
|
147
|
-
|
147
|
+
private
|
148
148
|
|
149
149
|
def pundit_model(record)
|
150
150
|
record.is_a?(Array) ? record.last : record
|
@@ -167,7 +167,7 @@ module Pundit
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
protected
|
170
|
+
protected
|
171
171
|
|
172
172
|
# @return [Boolean] whether authorization has been performed, i.e. whether
|
173
173
|
# one {#authorize} or {#skip_authorization} has been called
|
@@ -222,7 +222,7 @@ protected
|
|
222
222
|
|
223
223
|
raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
|
224
224
|
|
225
|
-
record
|
225
|
+
record.is_a?(Array) ? record.last : record
|
226
226
|
end
|
227
227
|
|
228
228
|
# Allow this action not to perform authorization.
|
@@ -317,7 +317,7 @@ protected
|
|
317
317
|
current_user
|
318
318
|
end
|
319
319
|
|
320
|
-
private
|
320
|
+
private
|
321
321
|
|
322
322
|
def pundit_policy_scope(scope)
|
323
323
|
policy_scopes[scope] ||= Pundit.policy_scope!(pundit_user, scope)
|
data/lib/pundit/policy_finder.rb
CHANGED
data/lib/pundit/rspec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/array/conversions"
|
4
|
-
|
5
3
|
module Pundit
|
6
4
|
module RSpec
|
7
5
|
module Matchers
|
@@ -74,17 +72,9 @@ module Pundit
|
|
74
72
|
end
|
75
73
|
|
76
74
|
RSpec.configure do |config|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
)
|
83
|
-
else
|
84
|
-
config.include(
|
85
|
-
Pundit::RSpec::PolicyExampleGroup,
|
86
|
-
type: :policy,
|
87
|
-
example_group: { file_path: %r{spec/policies} }
|
88
|
-
)
|
89
|
-
end
|
75
|
+
config.include(
|
76
|
+
Pundit::RSpec::PolicyExampleGroup,
|
77
|
+
type: :policy,
|
78
|
+
file_path: %r{spec/policies}
|
79
|
+
)
|
90
80
|
end
|
data/lib/pundit/version.rb
CHANGED
data/pundit.gemspec
CHANGED
@@ -25,7 +25,8 @@ Gem::Specification.new do |gem|
|
|
25
25
|
gem.add_development_dependency "bundler"
|
26
26
|
gem.add_development_dependency "pry"
|
27
27
|
gem.add_development_dependency "rake"
|
28
|
-
gem.add_development_dependency "rspec", ">=
|
29
|
-
gem.add_development_dependency "rubocop", "0.
|
28
|
+
gem.add_development_dependency "rspec", ">= 3.0.0"
|
29
|
+
gem.add_development_dependency "rubocop", "0.74.0"
|
30
|
+
gem.add_development_dependency "simplecov", ">= 0.17.0"
|
30
31
|
gem.add_development_dependency "yard"
|
31
32
|
end
|
data/spec/policy_finder_spec.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
describe Pundit::PolicyFinder do
|
5
|
+
RSpec.describe Pundit::PolicyFinder do
|
6
6
|
let(:user) { double }
|
7
7
|
let(:post) { Post.new(user) }
|
8
8
|
let(:comment) { CommentFourFiveSix.new }
|
@@ -24,37 +24,100 @@ describe Pundit::PolicyFinder do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
describe "#policy" do
|
27
|
-
|
27
|
+
context "with an instance" do
|
28
|
+
it "returns the associated policy" do
|
29
|
+
object = described_class.new(post)
|
30
|
+
|
31
|
+
expect(object.policy).to eq PostPolicy
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with an array of symbols" do
|
36
|
+
it "returns the associated namespaced policy" do
|
37
|
+
object = described_class.new(%i[project post])
|
38
|
+
|
39
|
+
expect(object.policy).to eq Project::PostPolicy
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with an array of a symbol and an instance" do
|
44
|
+
it "returns the associated namespaced policy" do
|
45
|
+
object = described_class.new([:project, post])
|
28
46
|
|
29
|
-
|
30
|
-
|
47
|
+
expect(object.policy).to eq Project::PostPolicy
|
48
|
+
end
|
31
49
|
end
|
32
50
|
|
33
|
-
context "with a
|
34
|
-
it "returns
|
35
|
-
|
36
|
-
|
51
|
+
context "with an array of a symbol and a class with a specified policy class" do
|
52
|
+
it "returns the associated namespaced policy" do
|
53
|
+
object = described_class.new([:project, Customer::Post])
|
54
|
+
|
55
|
+
expect(object.policy).to eq Project::PostPolicy
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with an array of a symbol and a class with a specified model name" do
|
60
|
+
it "returns the associated namespaced policy" do
|
61
|
+
object = described_class.new([:project, CommentsRelation])
|
62
|
+
|
63
|
+
expect(object.policy).to eq Project::CommentPolicy
|
37
64
|
end
|
38
65
|
end
|
39
66
|
|
40
67
|
context "with a class" do
|
41
|
-
it "returns
|
42
|
-
|
43
|
-
|
68
|
+
it "returns the associated policy" do
|
69
|
+
object = described_class.new(Post)
|
70
|
+
|
71
|
+
expect(object.policy).to eq PostPolicy
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with a class which has a specified policy class" do
|
76
|
+
it "returns the associated policy" do
|
77
|
+
object = described_class.new(Customer::Post)
|
78
|
+
|
79
|
+
expect(object.policy).to eq PostPolicy
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "with an instance which has a specified policy class" do
|
84
|
+
it "returns the associated policy" do
|
85
|
+
object = described_class.new(Customer::Post.new(user))
|
86
|
+
|
87
|
+
expect(object.policy).to eq PostPolicy
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "with a class which has a specified model name" do
|
92
|
+
it "returns the associated policy" do
|
93
|
+
object = described_class.new(CommentsRelation)
|
94
|
+
|
95
|
+
expect(object.policy).to eq CommentPolicy
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "with an instance which has a specified policy class" do
|
100
|
+
it "returns the associated policy" do
|
101
|
+
object = described_class.new(CommentsRelation.new)
|
102
|
+
|
103
|
+
expect(object.policy).to eq CommentPolicy
|
44
104
|
end
|
45
105
|
end
|
46
106
|
|
47
107
|
context "with nil" do
|
48
|
-
it "returns
|
49
|
-
|
50
|
-
|
108
|
+
it "returns a NilClassPolicy" do
|
109
|
+
object = described_class.new(nil)
|
110
|
+
|
111
|
+
expect(object.policy).to eq NilClassPolicy
|
51
112
|
end
|
52
113
|
end
|
53
114
|
|
54
|
-
context "with a
|
115
|
+
context "with a class that doesn't have an associated policy" do
|
55
116
|
it "returns nil" do
|
56
|
-
|
57
|
-
|
117
|
+
class Foo; end
|
118
|
+
object = described_class.new(Foo)
|
119
|
+
|
120
|
+
expect(object.policy).to eq nil
|
58
121
|
end
|
59
122
|
end
|
60
123
|
end
|
data/spec/pundit_spec.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
describe Pundit do
|
5
|
+
RSpec.describe Pundit do
|
6
6
|
let(:user) { double }
|
7
7
|
let(:post) { Post.new(user) }
|
8
8
|
let(:customer_post) { Customer::Post.new(user) }
|
@@ -25,6 +25,26 @@ describe Pundit do
|
|
25
25
|
expect(Pundit.authorize(user, post, :update?)).to be_truthy
|
26
26
|
end
|
27
27
|
|
28
|
+
it "returns the record on successful authorization" do
|
29
|
+
expect(Pundit.authorize(user, post, :update?)).to eq(post)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns the record when passed record with namespace " do
|
33
|
+
expect(Pundit.authorize(user, [:project, comment], :update?)).to eq(comment)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns the record when passed record with nested namespace " do
|
37
|
+
expect(Pundit.authorize(user, [:project, :admin, comment], :update?)).to eq(comment)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the policy name symbol when passed record with headless policy" do
|
41
|
+
expect(Pundit.authorize(user, :publication, :create?)).to eq(:publication)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the class when passed record not a particular instance" do
|
45
|
+
expect(Pundit.authorize(user, Post, :show?)).to eq(Post)
|
46
|
+
end
|
47
|
+
|
28
48
|
it "can be given a different policy class" do
|
29
49
|
expect(Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy)).to be_truthy
|
30
50
|
end
|
@@ -410,7 +430,23 @@ describe Pundit do
|
|
410
430
|
end
|
411
431
|
|
412
432
|
it "returns the record on successful authorization" do
|
413
|
-
expect(controller.authorize(post)).to
|
433
|
+
expect(controller.authorize(post)).to eq(post)
|
434
|
+
end
|
435
|
+
|
436
|
+
it "returns the record when passed record with namespace " do
|
437
|
+
expect(controller.authorize([:project, comment], :update?)).to eq(comment)
|
438
|
+
end
|
439
|
+
|
440
|
+
it "returns the record when passed record with nested namespace " do
|
441
|
+
expect(controller.authorize([:project, :admin, comment], :update?)).to eq(comment)
|
442
|
+
end
|
443
|
+
|
444
|
+
it "returns the policy name symbol when passed record with headless policy" do
|
445
|
+
expect(controller.authorize(:publication, :create?)).to eq(:publication)
|
446
|
+
end
|
447
|
+
|
448
|
+
it "returns the class when passed record not a particular instance" do
|
449
|
+
expect(controller.authorize(Post, :show?)).to eq(Post)
|
414
450
|
end
|
415
451
|
|
416
452
|
it "can be given a different permission to check" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "simplecov"
|
4
|
+
SimpleCov.start do
|
5
|
+
add_filter "/spec/"
|
6
|
+
end
|
7
|
+
|
3
8
|
require "pundit"
|
4
9
|
require "pundit/rspec"
|
5
10
|
|
@@ -11,22 +16,6 @@ require "active_support/core_ext"
|
|
11
16
|
require "active_model/naming"
|
12
17
|
require "action_controller/metal/strong_parameters"
|
13
18
|
|
14
|
-
I18n.enforce_available_locales = false
|
15
|
-
|
16
|
-
module PunditSpecHelper
|
17
|
-
extend RSpec::Matchers::DSL
|
18
|
-
|
19
|
-
matcher :be_truthy do
|
20
|
-
match do |actual|
|
21
|
-
actual
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
RSpec.configure do |config|
|
27
|
-
config.include PunditSpecHelper
|
28
|
-
end
|
29
|
-
|
30
19
|
class PostPolicy < Struct.new(:user, :post)
|
31
20
|
class Scope < Struct.new(:user, :scope)
|
32
21
|
def resolve
|
@@ -86,10 +75,6 @@ module Customer
|
|
86
75
|
def self.policy_class
|
87
76
|
PostPolicy
|
88
77
|
end
|
89
|
-
|
90
|
-
def policy_class
|
91
|
-
self.class.policy_class
|
92
|
-
end
|
93
78
|
end
|
94
79
|
end
|
95
80
|
|
@@ -137,7 +122,7 @@ class CommentsRelation
|
|
137
122
|
@empty
|
138
123
|
end
|
139
124
|
|
140
|
-
def model_name
|
125
|
+
def self.model_name
|
141
126
|
Comment.model_name
|
142
127
|
end
|
143
128
|
end
|
@@ -174,6 +159,10 @@ class CriteriaPolicy < Struct.new(:user, :criteria); end
|
|
174
159
|
|
175
160
|
module Project
|
176
161
|
class CommentPolicy < Struct.new(:user, :comment)
|
162
|
+
def update?
|
163
|
+
true
|
164
|
+
end
|
165
|
+
|
177
166
|
class Scope < Struct.new(:user, :scope)
|
178
167
|
def resolve
|
179
168
|
scope
|
@@ -190,6 +179,14 @@ module Project
|
|
190
179
|
end
|
191
180
|
end
|
192
181
|
end
|
182
|
+
|
183
|
+
module Admin
|
184
|
+
class CommentPolicy < Struct.new(:user, :comment)
|
185
|
+
def update?
|
186
|
+
true
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
193
190
|
end
|
194
191
|
|
195
192
|
class DenierPolicy < Struct.new(:user, :record)
|
@@ -201,9 +198,9 @@ end
|
|
201
198
|
class Controller
|
202
199
|
include Pundit
|
203
200
|
# Mark protected methods public so they may be called in test
|
204
|
-
# rubocop:disable
|
201
|
+
# rubocop:disable Style/AccessModifierDeclarations
|
205
202
|
public(*Pundit.protected_instance_methods)
|
206
|
-
# rubocop:enable
|
203
|
+
# rubocop:enable Style/AccessModifierDeclarations
|
207
204
|
|
208
205
|
attr_reader :current_user, :action_name, :params
|
209
206
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pundit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-08-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -101,28 +101,42 @@ dependencies:
|
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: 3.0.0
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
111
|
+
version: 3.0.0
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: rubocop
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
116
|
- - '='
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: 0.
|
118
|
+
version: 0.74.0
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - '='
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: 0.
|
125
|
+
version: 0.74.0
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: simplecov
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 0.17.0
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 0.17.0
|
126
140
|
- !ruby/object:Gem::Dependency
|
127
141
|
name: yard
|
128
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -194,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
208
|
- !ruby/object:Gem::Version
|
195
209
|
version: '0'
|
196
210
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
211
|
+
rubygems_version: 3.2.25
|
198
212
|
signing_key:
|
199
213
|
specification_version: 4
|
200
214
|
summary: OO authorization for Rails
|