pundit 2.1.1 → 2.3.0

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: def6c710d9f9d1705ca43cdad9364bb34ce5d878b8a3a9bf26d336802e40efeb
4
- data.tar.gz: 0d6618cb61dfef8ae18f811a73b3f059d9945f8def7f9b2f794ae095b3a0f0cf
3
+ metadata.gz: 74f2f6efff0c12342afad4bb45dc75f12443e20f6ab5a9ed40274f2f842f2441
4
+ data.tar.gz: ad984e338045f040964301fdf2c79323d2e1a1ebffad16fc332d49315de14da2
5
5
  SHA512:
6
- metadata.gz: 7105cd0a84469071de9211e19f7e7a31f4ea8b5283d7b1ed007b6533805de18d105c09128a9936144612f3daa8fadfdf0698f7448d8db94e47bb459efaa11c4b
7
- data.tar.gz: 3805e2664f21f30c66e9a9a05606f0d0d18b1607137e794948c7907bd33c6d6e64a45b9abb97d2f1a21df0d46497ff708679442807e152fa167abc461c8c0abe
6
+ metadata.gz: 106c8df42fc14b485dc4ea3951fba00232b6fa739b0a5910d9c33a33dde04cb1c015ecbf77f07a38274b9f9ae43ea5cfbbafb283f5eddc42fbf9454820ab87af
7
+ data.tar.gz: 4ab2a989938496acf224a9b20c247010e8d5882de168a995a02dbde021d308d7602f6305d675b26d461dcfb171346b02a1979325471f8713644aab8aac2dab9a
data/.rubocop.yml CHANGED
@@ -2,6 +2,8 @@ AllCops:
2
2
  TargetRubyVersion: 2.6
3
3
  Exclude:
4
4
  - "lib/generators/**/templates/**/*"
5
+ SuggestExtensions: false
6
+ NewCops: disable
5
7
 
6
8
  Metrics/BlockLength:
7
9
  Exclude:
@@ -15,7 +17,7 @@ Metrics/ModuleLength:
15
17
  Exclude:
16
18
  - "**/*_spec.rb"
17
19
 
18
- Metrics/LineLength:
20
+ Layout/LineLength:
19
21
  Max: 120
20
22
 
21
23
  Metrics/AbcSize:
@@ -27,7 +29,10 @@ Metrics/CyclomaticComplexity:
27
29
  Metrics/PerceivedComplexity:
28
30
  Enabled: false
29
31
 
30
- Layout/AlignParameters:
32
+ Gemspec/RequiredRubyVersion:
33
+ Enabled: false
34
+
35
+ Layout/ParameterAlignment:
31
36
  EnforcedStyle: with_fixed_indentation
32
37
 
33
38
  Layout/CaseIndentation:
@@ -63,5 +68,5 @@ Style/Not:
63
68
  Style/DoubleNegation:
64
69
  Enabled: false
65
70
 
66
- Documentation:
71
+ Style/Documentation:
67
72
  Enabled: false # TODO: Enable again once we have more docs
data/.travis.yml CHANGED
@@ -17,6 +17,7 @@ matrix:
17
17
  - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
18
18
  - rvm: 2.7.3
19
19
  - rvm: 3.0.1
20
+ - rvm: 3.1.0
20
21
  - rvm: jruby-9.2.17.0
21
22
  env:
22
23
  - JRUBY_OPTS="--debug"
data/CHANGELOG.md CHANGED
@@ -1,6 +1,24 @@
1
1
  # Pundit
2
2
 
3
- ## Unreleased
3
+ ## 2.3.0 (2022-12-19)
4
+
5
+ ### Added
6
+
7
+ - add support for rubocop-rspec syntax extensions (#745)
8
+
9
+ ## 2.2.0 (2022-02-11)
10
+
11
+ ### Fixed
12
+
13
+ - Using `policy_class` and a namespaced record now passes only the record when instantiating the policy. (#697, #689, #694, #666)
14
+
15
+ ### Changed
16
+
17
+ - Require users to explicitly define Scope#resolve in generated policies (#711, #722)
18
+
19
+ ### Deprecated
20
+
21
+ - Deprecate `include Pundit` in favor of `include Pundit::Authorization` (#621)
4
22
 
5
23
  ## 2.1.1 (2021-08-13)
6
24
 
data/README.md CHANGED
@@ -11,7 +11,7 @@ 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,15 +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
35
+ include Pundit::Authorization
34
36
  end
35
37
  ```
36
38
 
@@ -194,8 +196,17 @@ you can retrieve it by passing a symbol.
194
196
 
195
197
  ```ruby
196
198
  # app/policies/dashboard_policy.rb
197
- class DashboardPolicy < Struct.new(:user, :dashboard)
198
- # ...
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
199
210
  end
200
211
  ```
201
212
 
@@ -205,7 +216,10 @@ is what is passed as the record to `authorize` below.
205
216
 
206
217
  ```ruby
207
218
  # In controllers
208
- authorize :dashboard, :show?
219
+ def show
220
+ authorize :dashboard, :show?
221
+ ...
222
+ end
209
223
  ```
210
224
 
211
225
  ```erb
@@ -334,7 +348,7 @@ that you haven't forgotten to authorize the action. For example:
334
348
 
335
349
  ``` ruby
336
350
  class ApplicationController < ActionController::Base
337
- include Pundit
351
+ include Pundit::Authorization
338
352
  after_action :verify_authorized
339
353
  end
340
354
  ```
@@ -347,7 +361,7 @@ authorize individual instances.
347
361
 
348
362
  ``` ruby
349
363
  class ApplicationController < ActionController::Base
350
- include Pundit
364
+ include Pundit::Authorization
351
365
  after_action :verify_authorized, except: :index
352
366
  after_action :verify_policy_scoped, only: :index
353
367
  end
@@ -490,7 +504,7 @@ method in every controller.
490
504
 
491
505
  ```ruby
492
506
  class ApplicationController < ActionController::Base
493
- include Pundit
507
+ include Pundit::Authorization
494
508
 
495
509
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
496
510
 
@@ -498,7 +512,7 @@ class ApplicationController < ActionController::Base
498
512
 
499
513
  def user_not_authorized
500
514
  flash[:alert] = "You are not authorized to perform this action."
501
- redirect_to(request.referrer || root_path)
515
+ redirect_back(fallback_location: root_path)
502
516
  end
503
517
  end
504
518
  ```
@@ -527,7 +541,7 @@ class ApplicationController < ActionController::Base
527
541
  policy_name = exception.policy.class.to_s.underscore
528
542
 
529
543
  flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
530
- redirect_to(request.referrer || root_path)
544
+ redirect_back(fallback_url: root_path)
531
545
  end
532
546
  end
533
547
  ```
@@ -643,7 +657,7 @@ class UserContext
643
657
  end
644
658
 
645
659
  class ApplicationController
646
- include Pundit
660
+ include Pundit::Authorization
647
661
 
648
662
  def pundit_user
649
663
  UserContext.new(current_user, request.ip)
@@ -678,7 +692,7 @@ You can now retrieve these attributes from the policy:
678
692
  class PostsController < ApplicationController
679
693
  def update
680
694
  @post = Post.find(params[:id])
681
- if @post.update_attributes(post_params)
695
+ if @post.update(post_params)
682
696
  redirect_to @post
683
697
  else
684
698
  render :edit
@@ -700,7 +714,7 @@ However, this is a bit cumbersome, so Pundit provides a convenient helper method
700
714
  class PostsController < ApplicationController
701
715
  def update
702
716
  @post = Post.find(params[:id])
703
- if @post.update_attributes(permitted_attributes(@post))
717
+ if @post.update(permitted_attributes(@post))
704
718
  redirect_to @post
705
719
  else
706
720
  render :edit
@@ -788,6 +802,16 @@ An alternative approach to Pundit policy specs is scoping them to a user context
788
802
 
789
803
  Pundit does not provide a DSL for testing scopes. Just test it like a regular Ruby class!
790
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
+
791
815
  # External Resources
792
816
 
793
817
  - [RailsApps Example Application: Pundit and Devise](https://github.com/RailsApps/rails-devise-pundit)
@@ -0,0 +1,5 @@
1
+ RSpec:
2
+ Language:
3
+ ExampleGroups:
4
+ Regular:
5
+ - permissions
@@ -43,7 +43,7 @@ class ApplicationPolicy
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
48
 
49
49
  private
@@ -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 -%>
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pundit
4
+ module Authorization
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper Helper if respond_to?(:helper)
9
+ if respond_to?(:helper_method)
10
+ helper_method :policy
11
+ helper_method :pundit_policy_scope
12
+ helper_method :pundit_user
13
+ end
14
+ end
15
+
16
+ protected
17
+
18
+ # @return [Boolean] whether authorization has been performed, i.e. whether
19
+ # one {#authorize} or {#skip_authorization} has been called
20
+ def pundit_policy_authorized?
21
+ !!@_pundit_policy_authorized
22
+ end
23
+
24
+ # @return [Boolean] whether policy scoping has been performed, i.e. whether
25
+ # one {#policy_scope} or {#skip_policy_scope} has been called
26
+ def pundit_policy_scoped?
27
+ !!@_pundit_policy_scoped
28
+ end
29
+
30
+ # Raises an error if authorization has not been performed, usually used as an
31
+ # `after_action` filter to prevent programmer error in forgetting to call
32
+ # {#authorize} or {#skip_authorization}.
33
+ #
34
+ # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
35
+ # @raise [AuthorizationNotPerformedError] if authorization has not been performed
36
+ # @return [void]
37
+ def verify_authorized
38
+ raise AuthorizationNotPerformedError, self.class unless pundit_policy_authorized?
39
+ end
40
+
41
+ # Raises an error if policy scoping has not been performed, usually used as an
42
+ # `after_action` filter to prevent programmer error in forgetting to call
43
+ # {#policy_scope} or {#skip_policy_scope} in index actions.
44
+ #
45
+ # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
46
+ # @raise [AuthorizationNotPerformedError] if policy scoping has not been performed
47
+ # @return [void]
48
+ def verify_policy_scoped
49
+ raise PolicyScopingNotPerformedError, self.class unless pundit_policy_scoped?
50
+ end
51
+
52
+ # Retrieves the policy for the given record, initializing it with the record
53
+ # and current user and finally throwing an error if the user is not
54
+ # authorized to perform the given action.
55
+ #
56
+ # @param record [Object, Array] the object we're checking permissions of
57
+ # @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`).
58
+ # If omitted then this defaults to the Rails controller action name.
59
+ # @param policy_class [Class] the policy class we want to force use of
60
+ # @raise [NotAuthorizedError] if the given query method returned false
61
+ # @return [Object] Always returns the passed object record
62
+ def authorize(record, query = nil, policy_class: nil)
63
+ query ||= "#{action_name}?"
64
+
65
+ @_pundit_policy_authorized = true
66
+
67
+ Pundit.authorize(pundit_user, record, query, policy_class: policy_class, cache: policies)
68
+ end
69
+
70
+ # Allow this action not to perform authorization.
71
+ #
72
+ # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
73
+ # @return [void]
74
+ def skip_authorization
75
+ @_pundit_policy_authorized = :skipped
76
+ end
77
+
78
+ # Allow this action not to perform policy scoping.
79
+ #
80
+ # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
81
+ # @return [void]
82
+ def skip_policy_scope
83
+ @_pundit_policy_scoped = :skipped
84
+ end
85
+
86
+ # Retrieves the policy scope for the given record.
87
+ #
88
+ # @see https://github.com/varvet/pundit#scopes
89
+ # @param scope [Object] the object we're retrieving the policy scope for
90
+ # @param policy_scope_class [Class] the policy scope class we want to force use of
91
+ # @return [Scope{#resolve}, nil] instance of scope class which can resolve to a scope
92
+ def policy_scope(scope, policy_scope_class: nil)
93
+ @_pundit_policy_scoped = true
94
+ policy_scope_class ? policy_scope_class.new(pundit_user, scope).resolve : pundit_policy_scope(scope)
95
+ end
96
+
97
+ # Retrieves the policy for the given record.
98
+ #
99
+ # @see https://github.com/varvet/pundit#policies
100
+ # @param record [Object] the object we're retrieving the policy for
101
+ # @return [Object, nil] instance of policy class with query methods
102
+ def policy(record)
103
+ policies[record] ||= Pundit.policy!(pundit_user, record)
104
+ end
105
+
106
+ # Retrieves a set of permitted attributes from the policy by instantiating
107
+ # the policy class for the given record and calling `permitted_attributes` on
108
+ # it, or `permitted_attributes_for_{action}` if `action` is defined. It then infers
109
+ # what key the record should have in the params hash and retrieves the
110
+ # permitted attributes from the params hash under that key.
111
+ #
112
+ # @see https://github.com/varvet/pundit#strong-parameters
113
+ # @param record [Object] the object we're retrieving permitted attributes for
114
+ # @param action [Symbol, String] the name of the action being performed on the record (e.g. `:update`).
115
+ # If omitted then this defaults to the Rails controller action name.
116
+ # @return [Hash{String => Object}] the permitted attributes
117
+ def permitted_attributes(record, action = action_name)
118
+ policy = policy(record)
119
+ method_name = if policy.respond_to?("permitted_attributes_for_#{action}")
120
+ "permitted_attributes_for_#{action}"
121
+ else
122
+ "permitted_attributes"
123
+ end
124
+ pundit_params_for(record).permit(*policy.public_send(method_name))
125
+ end
126
+
127
+ # Retrieves the params for the given record.
128
+ #
129
+ # @param record [Object] the object we're retrieving params for
130
+ # @return [ActionController::Parameters] the params
131
+ def pundit_params_for(record)
132
+ params.require(PolicyFinder.new(record).param_key)
133
+ end
134
+
135
+ # Cache of policies. You should not rely on this method.
136
+ #
137
+ # @api private
138
+ # rubocop:disable Naming/MemoizedInstanceVariableName
139
+ def policies
140
+ @_pundit_policies ||= {}
141
+ end
142
+ # rubocop:enable Naming/MemoizedInstanceVariableName
143
+
144
+ # Cache of policy scope. You should not rely on this method.
145
+ #
146
+ # @api private
147
+ # rubocop:disable Naming/MemoizedInstanceVariableName
148
+ def policy_scopes
149
+ @_pundit_policy_scopes ||= {}
150
+ end
151
+ # rubocop:enable Naming/MemoizedInstanceVariableName
152
+
153
+ # Hook method which allows customizing which user is passed to policies and
154
+ # scopes initialized by {#authorize}, {#policy} and {#policy_scope}.
155
+ #
156
+ # @see https://github.com/varvet/pundit#customize-pundit-user
157
+ # @return [Object] the user object to be used with pundit
158
+ def pundit_user
159
+ current_user
160
+ end
161
+
162
+ private
163
+
164
+ def pundit_policy_scope(scope)
165
+ policy_scopes[scope] ||= Pundit.policy_scope!(pundit_user, scope)
166
+ end
167
+ end
168
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pundit
4
- VERSION = "2.1.1"
4
+ VERSION = "2.3.0"
5
5
  end
data/lib/pundit.rb CHANGED
@@ -7,6 +7,7 @@ require "active_support/core_ext/string/inflections"
7
7
  require "active_support/core_ext/object/blank"
8
8
  require "active_support/core_ext/module/introspection"
9
9
  require "active_support/dependencies/autoload"
10
+ require "pundit/authorization"
10
11
 
11
12
  # @api private
12
13
  # To avoid name clashes with common Error naming when mixing in Pundit,
@@ -53,7 +54,12 @@ module Pundit
53
54
  # Error that will be raised if a policy or policy scope is not defined.
54
55
  class NotDefinedError < Error; end
55
56
 
56
- extend ActiveSupport::Concern
57
+ def self.included(base)
58
+ ActiveSupport::Deprecation.warn <<~WARNING
59
+ 'include Pundit' is deprecated. Please use 'include Pundit::Authorization' instead.
60
+ WARNING
61
+ base.include Authorization
62
+ end
57
63
 
58
64
  class << self
59
65
  # Retrieves the policy for the given record, initializing it with the
@@ -61,17 +67,23 @@ module Pundit
61
67
  # authorized to perform the given action.
62
68
  #
63
69
  # @param user [Object] the user that initiated the action
64
- # @param record [Object] the object we're checking permissions of
70
+ # @param possibly_namespaced_record [Object, Array] the object we're checking permissions of
65
71
  # @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`)
66
72
  # @param policy_class [Class] the policy class we want to force use of
73
+ # @param cache [#[], #[]=] a Hash-like object to cache the found policy instance in
67
74
  # @raise [NotAuthorizedError] if the given query method returned false
68
75
  # @return [Object] Always returns the passed object record
69
- def authorize(user, record, query, policy_class: nil)
70
- policy = policy_class ? policy_class.new(user, record) : policy!(user, record)
76
+ def authorize(user, possibly_namespaced_record, query, policy_class: nil, cache: {})
77
+ record = pundit_model(possibly_namespaced_record)
78
+ policy = if policy_class
79
+ policy_class.new(user, record)
80
+ else
81
+ cache[possibly_namespaced_record] ||= policy!(user, possibly_namespaced_record)
82
+ end
71
83
 
72
84
  raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
73
85
 
74
- record.is_a?(Array) ? record.last : record
86
+ record
75
87
  end
76
88
 
77
89
  # Retrieves the policy scope for the given record.
@@ -157,169 +169,4 @@ module Pundit
157
169
  pundit_policy_scope(scope)
158
170
  end
159
171
  end
160
-
161
- included do
162
- helper Helper if respond_to?(:helper)
163
- if respond_to?(:helper_method)
164
- helper_method :policy
165
- helper_method :pundit_policy_scope
166
- helper_method :pundit_user
167
- end
168
- end
169
-
170
- protected
171
-
172
- # @return [Boolean] whether authorization has been performed, i.e. whether
173
- # one {#authorize} or {#skip_authorization} has been called
174
- def pundit_policy_authorized?
175
- !!@_pundit_policy_authorized
176
- end
177
-
178
- # @return [Boolean] whether policy scoping has been performed, i.e. whether
179
- # one {#policy_scope} or {#skip_policy_scope} has been called
180
- def pundit_policy_scoped?
181
- !!@_pundit_policy_scoped
182
- end
183
-
184
- # Raises an error if authorization has not been performed, usually used as an
185
- # `after_action` filter to prevent programmer error in forgetting to call
186
- # {#authorize} or {#skip_authorization}.
187
- #
188
- # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
189
- # @raise [AuthorizationNotPerformedError] if authorization has not been performed
190
- # @return [void]
191
- def verify_authorized
192
- raise AuthorizationNotPerformedError, self.class unless pundit_policy_authorized?
193
- end
194
-
195
- # Raises an error if policy scoping has not been performed, usually used as an
196
- # `after_action` filter to prevent programmer error in forgetting to call
197
- # {#policy_scope} or {#skip_policy_scope} in index actions.
198
- #
199
- # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
200
- # @raise [AuthorizationNotPerformedError] if policy scoping has not been performed
201
- # @return [void]
202
- def verify_policy_scoped
203
- raise PolicyScopingNotPerformedError, self.class unless pundit_policy_scoped?
204
- end
205
-
206
- # Retrieves the policy for the given record, initializing it with the record
207
- # and current user and finally throwing an error if the user is not
208
- # authorized to perform the given action.
209
- #
210
- # @param record [Object] the object we're checking permissions of
211
- # @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`).
212
- # If omitted then this defaults to the Rails controller action name.
213
- # @param policy_class [Class] the policy class we want to force use of
214
- # @raise [NotAuthorizedError] if the given query method returned false
215
- # @return [Object] Always returns the passed object record
216
- def authorize(record, query = nil, policy_class: nil)
217
- query ||= "#{action_name}?"
218
-
219
- @_pundit_policy_authorized = true
220
-
221
- policy = policy_class ? policy_class.new(pundit_user, record) : policy(record)
222
-
223
- raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
224
-
225
- record.is_a?(Array) ? record.last : record
226
- end
227
-
228
- # Allow this action not to perform authorization.
229
- #
230
- # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
231
- # @return [void]
232
- def skip_authorization
233
- @_pundit_policy_authorized = true
234
- end
235
-
236
- # Allow this action not to perform policy scoping.
237
- #
238
- # @see https://github.com/varvet/pundit#ensuring-policies-and-scopes-are-used
239
- # @return [void]
240
- def skip_policy_scope
241
- @_pundit_policy_scoped = true
242
- end
243
-
244
- # Retrieves the policy scope for the given record.
245
- #
246
- # @see https://github.com/varvet/pundit#scopes
247
- # @param scope [Object] the object we're retrieving the policy scope for
248
- # @param policy_scope_class [Class] the policy scope class we want to force use of
249
- # @return [Scope{#resolve}, nil] instance of scope class which can resolve to a scope
250
- def policy_scope(scope, policy_scope_class: nil)
251
- @_pundit_policy_scoped = true
252
- policy_scope_class ? policy_scope_class.new(pundit_user, scope).resolve : pundit_policy_scope(scope)
253
- end
254
-
255
- # Retrieves the policy for the given record.
256
- #
257
- # @see https://github.com/varvet/pundit#policies
258
- # @param record [Object] the object we're retrieving the policy for
259
- # @return [Object, nil] instance of policy class with query methods
260
- def policy(record)
261
- policies[record] ||= Pundit.policy!(pundit_user, record)
262
- end
263
-
264
- # Retrieves a set of permitted attributes from the policy by instantiating
265
- # the policy class for the given record and calling `permitted_attributes` on
266
- # it, or `permitted_attributes_for_{action}` if `action` is defined. It then infers
267
- # what key the record should have in the params hash and retrieves the
268
- # permitted attributes from the params hash under that key.
269
- #
270
- # @see https://github.com/varvet/pundit#strong-parameters
271
- # @param record [Object] the object we're retrieving permitted attributes for
272
- # @param action [Symbol, String] the name of the action being performed on the record (e.g. `:update`).
273
- # If omitted then this defaults to the Rails controller action name.
274
- # @return [Hash{String => Object}] the permitted attributes
275
- def permitted_attributes(record, action = action_name)
276
- policy = policy(record)
277
- method_name = if policy.respond_to?("permitted_attributes_for_#{action}")
278
- "permitted_attributes_for_#{action}"
279
- else
280
- "permitted_attributes"
281
- end
282
- pundit_params_for(record).permit(*policy.public_send(method_name))
283
- end
284
-
285
- # Retrieves the params for the given record.
286
- #
287
- # @param record [Object] the object we're retrieving params for
288
- # @return [ActionController::Parameters] the params
289
- def pundit_params_for(record)
290
- params.require(PolicyFinder.new(record).param_key)
291
- end
292
-
293
- # Cache of policies. You should not rely on this method.
294
- #
295
- # @api private
296
- # rubocop:disable Naming/MemoizedInstanceVariableName
297
- def policies
298
- @_pundit_policies ||= {}
299
- end
300
- # rubocop:enable Naming/MemoizedInstanceVariableName
301
-
302
- # Cache of policy scope. You should not rely on this method.
303
- #
304
- # @api private
305
- # rubocop:disable Naming/MemoizedInstanceVariableName
306
- def policy_scopes
307
- @_pundit_policy_scopes ||= {}
308
- end
309
- # rubocop:enable Naming/MemoizedInstanceVariableName
310
-
311
- # Hook method which allows customizing which user is passed to policies and
312
- # scopes initialized by {#authorize}, {#policy} and {#policy_scope}.
313
- #
314
- # @see https://github.com/varvet/pundit#customize-pundit-user
315
- # @return [Object] the user object to be used with pundit
316
- def pundit_user
317
- current_user
318
- end
319
-
320
- private
321
-
322
- def pundit_policy_scope(scope)
323
- policy_scopes[scope] ||= Pundit.policy_scope!(pundit_user, scope)
324
- end
325
172
  end
data/pundit.gemspec CHANGED
@@ -24,9 +24,10 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency "activemodel", ">= 3.0.0"
25
25
  gem.add_development_dependency "bundler"
26
26
  gem.add_development_dependency "pry"
27
+ gem.add_development_dependency "railties", ">= 3.0.0"
27
28
  gem.add_development_dependency "rake"
28
29
  gem.add_development_dependency "rspec", ">= 3.0.0"
29
- gem.add_development_dependency "rubocop", "0.74.0"
30
+ gem.add_development_dependency "rubocop", "1.24.0"
30
31
  gem.add_development_dependency "simplecov", ">= 0.17.0"
31
32
  gem.add_development_dependency "yard"
32
33
  end