hyper-max-mod 0.0.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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/cancancan-3.6.1/cancancan.gemspec +29 -0
  3. data/cancancan-3.6.1/init.rb +3 -0
  4. data/cancancan-3.6.1/lib/cancan/ability/actions.rb +93 -0
  5. data/cancancan-3.6.1/lib/cancan/ability/rules.rb +96 -0
  6. data/cancancan-3.6.1/lib/cancan/ability/strong_parameter_support.rb +41 -0
  7. data/cancancan-3.6.1/lib/cancan/ability.rb +312 -0
  8. data/cancancan-3.6.1/lib/cancan/class_matcher.rb +30 -0
  9. data/cancancan-3.6.1/lib/cancan/conditions_matcher.rb +147 -0
  10. data/cancancan-3.6.1/lib/cancan/config.rb +101 -0
  11. data/cancancan-3.6.1/lib/cancan/controller_additions.rb +399 -0
  12. data/cancancan-3.6.1/lib/cancan/controller_resource.rb +141 -0
  13. data/cancancan-3.6.1/lib/cancan/controller_resource_builder.rb +26 -0
  14. data/cancancan-3.6.1/lib/cancan/controller_resource_finder.rb +42 -0
  15. data/cancancan-3.6.1/lib/cancan/controller_resource_loader.rb +120 -0
  16. data/cancancan-3.6.1/lib/cancan/controller_resource_name_finder.rb +23 -0
  17. data/cancancan-3.6.1/lib/cancan/controller_resource_sanitizer.rb +32 -0
  18. data/cancancan-3.6.1/lib/cancan/exceptions.rb +70 -0
  19. data/cancancan-3.6.1/lib/cancan/matchers.rb +56 -0
  20. data/cancancan-3.6.1/lib/cancan/model_adapters/abstract_adapter.rb +77 -0
  21. data/cancancan-3.6.1/lib/cancan/model_adapters/active_record_4_adapter.rb +62 -0
  22. data/cancancan-3.6.1/lib/cancan/model_adapters/active_record_5_adapter.rb +61 -0
  23. data/cancancan-3.6.1/lib/cancan/model_adapters/active_record_adapter.rb +229 -0
  24. data/cancancan-3.6.1/lib/cancan/model_adapters/conditions_extractor.rb +75 -0
  25. data/cancancan-3.6.1/lib/cancan/model_adapters/conditions_normalizer.rb +49 -0
  26. data/cancancan-3.6.1/lib/cancan/model_adapters/default_adapter.rb +9 -0
  27. data/cancancan-3.6.1/lib/cancan/model_adapters/sti_normalizer.rb +47 -0
  28. data/cancancan-3.6.1/lib/cancan/model_adapters/strategies/base.rb +40 -0
  29. data/cancancan-3.6.1/lib/cancan/model_adapters/strategies/joined_alias_each_rule_as_exists_subquery.rb +93 -0
  30. data/cancancan-3.6.1/lib/cancan/model_adapters/strategies/joined_alias_exists_subquery.rb +31 -0
  31. data/cancancan-3.6.1/lib/cancan/model_adapters/strategies/left_join.rb +11 -0
  32. data/cancancan-3.6.1/lib/cancan/model_adapters/strategies/subquery.rb +18 -0
  33. data/cancancan-3.6.1/lib/cancan/model_additions.rb +34 -0
  34. data/cancancan-3.6.1/lib/cancan/parameter_validators.rb +9 -0
  35. data/cancancan-3.6.1/lib/cancan/relevant.rb +29 -0
  36. data/cancancan-3.6.1/lib/cancan/rule.rb +140 -0
  37. data/cancancan-3.6.1/lib/cancan/rules_compressor.rb +41 -0
  38. data/cancancan-3.6.1/lib/cancan/sti_detector.rb +12 -0
  39. data/cancancan-3.6.1/lib/cancan/unauthorized_message_resolver.rb +24 -0
  40. data/cancancan-3.6.1/lib/cancan/version.rb +5 -0
  41. data/cancancan-3.6.1/lib/cancan.rb +29 -0
  42. data/cancancan-3.6.1/lib/cancancan.rb +6 -0
  43. data/cancancan-3.6.1/lib/generators/cancan/ability/USAGE +4 -0
  44. data/cancancan-3.6.1/lib/generators/cancan/ability/ability_generator.rb +13 -0
  45. data/cancancan-3.6.1/lib/generators/cancan/ability/templates/ability.rb +32 -0
  46. data/hyper-max-mod.gemspec +12 -0
  47. metadata +86 -0
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CanCan
4
+ module ConditionsMatcher
5
+ # Matches the block or conditions hash
6
+ def matches_conditions?(action, subject, attribute = nil, *extra_args)
7
+ return call_block_with_all(action, subject, extra_args) if @match_all
8
+ return matches_block_conditions(subject, attribute, *extra_args) if @block
9
+ return matches_non_block_conditions(subject) unless conditions_empty?
10
+
11
+ true
12
+ end
13
+
14
+ private
15
+
16
+ def subject_class?(subject)
17
+ klass = (subject.is_a?(Hash) ? subject.values.first : subject).class
18
+ [Class, Module].include? klass
19
+ end
20
+
21
+ def matches_block_conditions(subject, attribute, *extra_args)
22
+ return @base_behavior if subject_class?(subject)
23
+
24
+ if attribute
25
+ @block.call(subject, attribute, *extra_args)
26
+ else
27
+ @block.call(subject, *extra_args)
28
+ end
29
+ end
30
+
31
+ def matches_non_block_conditions(subject)
32
+ return nested_subject_matches_conditions?(subject) if subject.class == Hash
33
+ return matches_conditions_hash?(subject) unless subject_class?(subject)
34
+
35
+ # Don't stop at "cannot" definitions when there are conditions.
36
+ @base_behavior
37
+ end
38
+
39
+ def nested_subject_matches_conditions?(subject_hash)
40
+ parent, child = subject_hash.first
41
+
42
+ adapter = model_adapter(parent)
43
+
44
+ parent_condition_name = adapter.parent_condition_name(parent, child)
45
+
46
+ matches_base_parent_conditions = matches_conditions_hash?(parent,
47
+ @conditions[parent_condition_name] || {})
48
+
49
+ matches_base_parent_conditions &&
50
+ (!adapter.override_nested_subject_conditions_matching?(parent, child, @conditions) ||
51
+ adapter.nested_subject_matches_conditions?(parent, child, @conditions))
52
+ end
53
+
54
+ # Checks if the given subject matches the given conditions hash.
55
+ # This behavior can be overridden by a model adapter by defining two class methods:
56
+ # override_matching_for_conditions?(subject, conditions) and
57
+ # matches_conditions_hash?(subject, conditions)
58
+ def matches_conditions_hash?(subject, conditions = @conditions)
59
+ return true if conditions.is_a?(Hash) && conditions.empty?
60
+
61
+ adapter = model_adapter(subject)
62
+
63
+ if adapter.override_conditions_hash_matching?(subject, conditions)
64
+ return adapter.matches_conditions_hash?(subject, conditions)
65
+ end
66
+
67
+ matches_all_conditions?(adapter, subject, conditions)
68
+ end
69
+
70
+ def matches_all_conditions?(adapter, subject, conditions)
71
+ if conditions.is_a?(Hash)
72
+ matches_hash_conditions?(adapter, subject, conditions)
73
+ elsif conditions.respond_to?(:include?)
74
+ conditions.include?(subject)
75
+ else
76
+ subject == conditions
77
+ end
78
+ end
79
+
80
+ def matches_hash_conditions?(adapter, subject, conditions)
81
+ conditions.all? do |name, value|
82
+ if adapter.override_condition_matching?(subject, name, value)
83
+ adapter.matches_condition?(subject, name, value)
84
+ else
85
+ condition_match?(subject.send(name), value)
86
+ end
87
+ end
88
+ end
89
+
90
+ def condition_match?(attribute, value)
91
+ case value
92
+ when Hash
93
+ hash_condition_match?(attribute, value)
94
+ when Range
95
+ value.cover?(attribute)
96
+ when Enumerable
97
+ value.include?(attribute)
98
+ else
99
+ attribute == value
100
+ end
101
+ end
102
+
103
+ def hash_condition_match?(attribute, value)
104
+ if attribute.is_a?(Array) || (defined?(ActiveRecord) && attribute.is_a?(ActiveRecord::Relation))
105
+ array_like_matches_condition_hash?(attribute, value)
106
+ else
107
+ attribute && matches_conditions_hash?(attribute, value)
108
+ end
109
+ end
110
+
111
+ def array_like_matches_condition_hash?(attribute, value)
112
+ if attribute.any?
113
+ attribute.any? { |element| matches_conditions_hash?(element, value) }
114
+ else
115
+ # you can use `nil`s in your ability definition to tell cancancan to find
116
+ # objects that *don't* have any children in a has_many relationship.
117
+ #
118
+ # for example, given ability:
119
+ # => can :read, Article, comments: { id: nil }
120
+ # cancancan will return articles where `article.comments == []`
121
+ #
122
+ # this is implemented here. `attribute` is `article.comments`, and it's an empty array.
123
+ # the expression below returns true if this was expected.
124
+ !value.values.empty? && value.values.all?(&:nil?)
125
+ end
126
+ end
127
+
128
+ def call_block_with_all(action, subject, *extra_args)
129
+ if subject.class == Class
130
+ @block.call(action, subject, nil, *extra_args)
131
+ else
132
+ @block.call(action, subject.class, subject, *extra_args)
133
+ end
134
+ end
135
+
136
+ def model_adapter(subject)
137
+ CanCan::ModelAdapters::AbstractAdapter.adapter_class(subject_class?(subject) ? subject : subject.class)
138
+ end
139
+
140
+ def conditions_empty?
141
+ # @conditions might be an ActiveRecord::Associations::CollectionProxy
142
+ # which it's `==` implementation will fetch all records for comparison
143
+
144
+ (@conditions.is_a?(Hash) && @conditions == {}) || @conditions.nil?
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CanCan
4
+ def self.valid_accessible_by_strategies
5
+ strategies = [:left_join]
6
+
7
+ unless does_not_support_subquery_strategy?
8
+ strategies.push(:joined_alias_exists_subquery, :joined_alias_each_rule_as_exists_subquery, :subquery)
9
+ end
10
+
11
+ strategies
12
+ end
13
+
14
+ # You can disable the rules compressor if it's causing unexpected issues.
15
+ def self.rules_compressor_enabled
16
+ return @rules_compressor_enabled if defined?(@rules_compressor_enabled)
17
+
18
+ @rules_compressor_enabled = true
19
+ end
20
+
21
+ def self.rules_compressor_enabled=(value)
22
+ @rules_compressor_enabled = value
23
+ end
24
+
25
+ def self.with_rules_compressor_enabled(value)
26
+ return yield if value == rules_compressor_enabled
27
+
28
+ begin
29
+ rules_compressor_enabled_was = rules_compressor_enabled
30
+ @rules_compressor_enabled = value
31
+ yield
32
+ ensure
33
+ @rules_compressor_enabled = rules_compressor_enabled_was
34
+ end
35
+ end
36
+
37
+ # Determines how CanCan should build queries when calling accessible_by,
38
+ # if the query will contain a join. The default strategy is `:subquery`.
39
+ #
40
+ # # config/initializers/cancan.rb
41
+ # CanCan.accessible_by_strategy = :subquery
42
+ #
43
+ # Valid strategies are:
44
+ # - :subquery - Creates a nested query with all joins, wrapped by a
45
+ # WHERE IN query.
46
+ # - :left_join - Calls the joins directly using `left_joins`, and
47
+ # ensures records are unique using `distinct`. Note that
48
+ # `distinct` is not reliable in some cases. See
49
+ # https://github.com/CanCanCommunity/cancancan/pull/605
50
+ def self.accessible_by_strategy
51
+ return @accessible_by_strategy if @accessible_by_strategy
52
+
53
+ @accessible_by_strategy = default_accessible_by_strategy
54
+ end
55
+
56
+ def self.default_accessible_by_strategy
57
+ if does_not_support_subquery_strategy?
58
+ # see https://github.com/CanCanCommunity/cancancan/pull/655 for where this was added
59
+ # the `subquery` strategy (from https://github.com/CanCanCommunity/cancancan/pull/619
60
+ # only works in Rails 5 and higher
61
+ :left_join
62
+ else
63
+ :subquery
64
+ end
65
+ end
66
+
67
+ def self.accessible_by_strategy=(value)
68
+ validate_accessible_by_strategy!(value)
69
+
70
+ if value == :subquery && does_not_support_subquery_strategy?
71
+ raise ArgumentError, 'accessible_by_strategy = :subquery requires ActiveRecord 5 or newer'
72
+ end
73
+
74
+ @accessible_by_strategy = value
75
+ end
76
+
77
+ def self.with_accessible_by_strategy(value)
78
+ return yield if value == accessible_by_strategy
79
+
80
+ validate_accessible_by_strategy!(value)
81
+
82
+ begin
83
+ strategy_was = accessible_by_strategy
84
+ @accessible_by_strategy = value
85
+ yield
86
+ ensure
87
+ @accessible_by_strategy = strategy_was
88
+ end
89
+ end
90
+
91
+ def self.validate_accessible_by_strategy!(value)
92
+ return if valid_accessible_by_strategies.include?(value)
93
+
94
+ raise ArgumentError, "accessible_by_strategy must be one of #{valid_accessible_by_strategies.join(', ')}"
95
+ end
96
+
97
+ def self.does_not_support_subquery_strategy?
98
+ !defined?(CanCan::ModelAdapters::ActiveRecordAdapter) ||
99
+ CanCan::ModelAdapters::ActiveRecordAdapter.version_lower?('5.0.0')
100
+ end
101
+ end
@@ -0,0 +1,399 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CanCan
4
+ # This module is automatically included into all controllers.
5
+ # It also makes the "can?" and "cannot?" methods available to all views.
6
+ module ControllerAdditions
7
+ module ClassMethods
8
+ # Sets up a before filter which loads and authorizes the current resource. This performs both
9
+ # load_resource and authorize_resource and accepts the same arguments. See those methods for details.
10
+ #
11
+ # class BooksController < ApplicationController
12
+ # load_and_authorize_resource
13
+ # end
14
+ #
15
+ def load_and_authorize_resource(*args)
16
+ cancan_resource_class.add_before_action(self, :load_and_authorize_resource, *args)
17
+ end
18
+
19
+ # Sets up a before filter which loads the model resource into an instance variable.
20
+ # For example, given an ArticlesController it will load the current article into the @article
21
+ # instance variable. It does this by either calling Article.find(params[:id]) or
22
+ # Article.new(params[:article]) depending upon the action. The index action will
23
+ # automatically set @articles to Article.accessible_by(current_ability).
24
+ #
25
+ # If a conditions hash is used in the Ability, the +new+ and +create+ actions will set
26
+ # the initial attributes based on these conditions. This way these actions will satisfy
27
+ # the ability restrictions.
28
+ #
29
+ # Call this method directly on the controller class.
30
+ #
31
+ # class BooksController < ApplicationController
32
+ # load_resource
33
+ # end
34
+ #
35
+ # A resource is not loaded if the instance variable is already set. This makes it easy to override
36
+ # the behavior through a before_action on certain actions.
37
+ #
38
+ # class BooksController < ApplicationController
39
+ # before_action :find_book_by_permalink, :only => :show
40
+ # load_resource
41
+ #
42
+ # private
43
+ #
44
+ # def find_book_by_permalink
45
+ # @book = Book.find_by_permalink!(params[:id])
46
+ # end
47
+ # end
48
+ #
49
+ # If a name is provided which does not match the controller it assumes it is a parent resource. Child
50
+ # resources can then be loaded through it.
51
+ #
52
+ # class BooksController < ApplicationController
53
+ # load_resource :author
54
+ # load_resource :book, :through => :author
55
+ # end
56
+ #
57
+ # Here the author resource will be loaded before each action using params[:author_id]. The book resource
58
+ # will then be loaded through the @author instance variable.
59
+ #
60
+ # That first argument is optional and will default to the singular name of the controller.
61
+ # A hash of options (see below) can also be passed to this method to further customize it.
62
+ #
63
+ # See load_and_authorize_resource to automatically authorize the resource too.
64
+ #
65
+ # Options:
66
+ # [:+only+]
67
+ # Only applies before filter to given actions.
68
+ #
69
+ # [:+except+]
70
+ # Does not apply before filter to given actions.
71
+ #
72
+ # [:+through+]
73
+ # Load this resource through another one. This should match the name of the parent instance variable or method.
74
+ #
75
+ # [:+through_association+]
76
+ # The name of the association to fetch the child records through the parent resource.
77
+ # This is normally not needed because it defaults to the pluralized resource name.
78
+ #
79
+ # [:+shallow+]
80
+ # Pass +true+ to allow this resource to be loaded directly when parent is +nil+. Defaults to +false+.
81
+ #
82
+ # [:+singleton+]
83
+ # Pass +true+ if this is a singleton resource through a +has_one+ association.
84
+ #
85
+ # [:+parent+]
86
+ # True or false depending on if the resource is considered a parent resource.
87
+ # This defaults to +true+ if a resource name is given which does not match the controller.
88
+ #
89
+ # [:+class+]
90
+ # The class to use for the model (string or constant).
91
+ #
92
+ # [:+instance_name+]
93
+ # The name of the instance variable to load the resource into.
94
+ #
95
+ # [:+find_by+]
96
+ # Find using a different attribute other than id. For example.
97
+ #
98
+ # load_resource :find_by => :permalink # will use find_by_permalink!(params[:id])
99
+ #
100
+ # [:+id_param+]
101
+ # Find using a param key other than :id. For example:
102
+ #
103
+ # load_resource :id_param => :url # will use find(params[:url])
104
+ #
105
+ # [:+collection+]
106
+ # Specify which actions are resource collection actions in addition to :+index+. This
107
+ # is usually not necessary because it will try to guess depending on if the id param is present.
108
+ #
109
+ # load_resource :collection => [:sort, :list]
110
+ #
111
+ # [:+new+]
112
+ # Specify which actions are new resource actions in addition to :+new+ and :+create+.
113
+ # Pass an action name into here if you would like to build a new resource instead of
114
+ # fetch one.
115
+ #
116
+ # load_resource :new => :build
117
+ #
118
+ # [:+prepend+]
119
+ # Passing +true+ will use prepend_before_action instead of a normal before_action.
120
+ #
121
+ def load_resource(*args)
122
+ cancan_resource_class.add_before_action(self, :load_resource, *args)
123
+ end
124
+
125
+ # Sets up a before filter which authorizes the resource using the instance variable.
126
+ # For example, if you have an ArticlesController it will check the @article instance variable
127
+ # and ensure the user can perform the current action on it. Under the hood it is doing
128
+ # something like the following.
129
+ #
130
+ # authorize!(params[:action].to_sym, @article || Article)
131
+ #
132
+ # Call this method directly on the controller class.
133
+ #
134
+ # class BooksController < ApplicationController
135
+ # authorize_resource
136
+ # end
137
+ #
138
+ # If you pass in the name of a resource which does not match the controller it will assume
139
+ # it is a parent resource.
140
+ #
141
+ # class BooksController < ApplicationController
142
+ # authorize_resource :author
143
+ # authorize_resource :book
144
+ # end
145
+ #
146
+ # Here it will authorize :+show+, @+author+ on every action before authorizing the book.
147
+ #
148
+ # That first argument is optional and will default to the singular name of the controller.
149
+ # A hash of options (see below) can also be passed to this method to further customize it.
150
+ #
151
+ # See load_and_authorize_resource to automatically load the resource too.
152
+ #
153
+ # Options:
154
+ # [:+only+]
155
+ # Only applies before filter to given actions.
156
+ #
157
+ # [:+except+]
158
+ # Does not apply before filter to given actions.
159
+ #
160
+ # [:+singleton+]
161
+ # Pass +true+ if this is a singleton resource through a +has_one+ association.
162
+ #
163
+ # [:+parent+]
164
+ # True or false depending on if the resource is considered a parent resource.
165
+ # This defaults to +true+ if a resource name is given which does not match the controller.
166
+ #
167
+ # [:+class+]
168
+ # The class to use for the model (string or constant). This passed in when the instance variable is not set.
169
+ # Pass +false+ if there is no associated class for this resource and it will use a symbol of the resource name.
170
+ #
171
+ # [:+instance_name+]
172
+ # The name of the instance variable for this resource.
173
+ #
174
+ # [:+id_param+]
175
+ # Find using a param key other than :id. For example:
176
+ #
177
+ # load_resource :id_param => :url # will use find(params[:url])
178
+ #
179
+ # [:+through+]
180
+ # Authorize conditions on this parent resource when instance isn't available.
181
+ #
182
+ # [:+prepend+]
183
+ # Passing +true+ will use prepend_before_action instead of a normal before_action.
184
+ #
185
+ def authorize_resource(*args)
186
+ cancan_resource_class.add_before_action(self, :authorize_resource, *args)
187
+ end
188
+
189
+ # Skip both the loading and authorization behavior of CanCan for this given controller. This is primarily
190
+ # useful to skip the behavior of a superclass. You can pass :only and :except options to specify which actions
191
+ # to skip the effects on. It will apply to all actions by default.
192
+ #
193
+ # class ProjectsController < SomeOtherController
194
+ # skip_load_and_authorize_resource :only => :index
195
+ # end
196
+ #
197
+ # You can also pass the resource name as the first argument to skip that resource.
198
+ def skip_load_and_authorize_resource(*args)
199
+ skip_load_resource(*args)
200
+ skip_authorize_resource(*args)
201
+ end
202
+
203
+ # Skip the loading behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
204
+ # only do authorization on certain actions. You can pass :only and :except options to specify which actions to
205
+ # skip the effects on. It will apply to all actions by default.
206
+ #
207
+ # class ProjectsController < ApplicationController
208
+ # load_and_authorize_resource
209
+ # skip_load_resource :only => :index
210
+ # end
211
+ #
212
+ # You can also pass the resource name as the first argument to skip that resource.
213
+ def skip_load_resource(*args)
214
+ options = args.extract_options!
215
+ name = args.first
216
+ cancan_skipper[:load][name] = options
217
+ end
218
+
219
+ # Skip the authorization behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
220
+ # only do loading on certain actions. You can pass :only and :except options to specify which actions to
221
+ # skip the effects on. It will apply to all actions by default.
222
+ #
223
+ # class ProjectsController < ApplicationController
224
+ # load_and_authorize_resource
225
+ # skip_authorize_resource :only => :index
226
+ # end
227
+ #
228
+ # You can also pass the resource name as the first argument to skip that resource.
229
+ def skip_authorize_resource(*args)
230
+ options = args.extract_options!
231
+ name = args.first
232
+ cancan_skipper[:authorize][name] = options
233
+ end
234
+
235
+ # Add this to a controller to ensure it performs authorization through +authorize+! or +authorize_resource+ call.
236
+ # If neither of these authorization methods are called,
237
+ # a CanCan::AuthorizationNotPerformed exception will be raised.
238
+ # This is normally added to the ApplicationController to ensure all controller actions do authorization.
239
+ #
240
+ # class ApplicationController < ActionController::Base
241
+ # check_authorization
242
+ # end
243
+ #
244
+ # See skip_authorization_check to bypass this check on specific controller actions.
245
+ #
246
+ # Options:
247
+ # [:+only+]
248
+ # Only applies to given actions.
249
+ #
250
+ # [:+except+]
251
+ # Does not apply to given actions.
252
+ #
253
+ # [:+if+]
254
+ # Supply the name of a controller method to be called.
255
+ # The authorization check only takes place if this returns true.
256
+ #
257
+ # check_authorization :if => :admin_controller?
258
+ #
259
+ # [:+unless+]
260
+ # Supply the name of a controller method to be called.
261
+ # The authorization check only takes place if this returns false.
262
+ #
263
+ # check_authorization :unless => :devise_controller?
264
+ #
265
+ def check_authorization(options = {})
266
+ block = proc do |controller|
267
+ next if controller.instance_variable_defined?(:@_authorized)
268
+ next if options[:if] && !controller.send(options[:if])
269
+ next if options[:unless] && controller.send(options[:unless])
270
+
271
+ raise AuthorizationNotPerformed,
272
+ 'This action failed the check_authorization because it does not authorize_resource. ' \
273
+ 'Add skip_authorization_check to bypass this check.'
274
+ end
275
+
276
+ send(:after_action, options.slice(:only, :except), &block)
277
+ end
278
+
279
+ # Call this in the class of a controller to skip the check_authorization behavior on the actions.
280
+ #
281
+ # class HomeController < ApplicationController
282
+ # skip_authorization_check :only => :index
283
+ # end
284
+ #
285
+ # Any arguments are passed to the +before_action+ it triggers.
286
+ def skip_authorization_check(*args)
287
+ block = proc { |controller| controller.instance_variable_set(:@_authorized, true) }
288
+ send(:before_action, *args, &block)
289
+ end
290
+
291
+ def cancan_resource_class
292
+ ControllerResource
293
+ end
294
+
295
+ def cancan_skipper
296
+ self._cancan_skipper ||= { authorize: {}, load: {} }
297
+ end
298
+ end
299
+
300
+ def self.included(base)
301
+ base.extend ClassMethods
302
+ base.helper_method :can?, :cannot?, :current_ability if base.respond_to? :helper_method
303
+ base.class_attribute :_cancan_skipper
304
+ end
305
+
306
+ # Raises a CanCan::AccessDenied exception if the current_ability cannot
307
+ # perform the given action. This is usually called in a controller action or
308
+ # before filter to perform the authorization.
309
+ #
310
+ # def show
311
+ # @article = Article.find(params[:id])
312
+ # authorize! :read, @article
313
+ # end
314
+ #
315
+ # A :message option can be passed to specify a different message.
316
+ #
317
+ # authorize! :read, @article, :message => "Not authorized to read #{@article.name}"
318
+ #
319
+ # You can also use I18n to customize the message. Action aliases defined in Ability work here.
320
+ #
321
+ # en:
322
+ # unauthorized:
323
+ # manage:
324
+ # all: "Not authorized to %{action} %{subject}."
325
+ # user: "Not allowed to manage other user accounts."
326
+ # update:
327
+ # project: "Not allowed to update this project."
328
+ #
329
+ # You can rescue from the exception in the controller to customize how unauthorized
330
+ # access is displayed to the user.
331
+ #
332
+ # class ApplicationController < ActionController::Base
333
+ # rescue_from CanCan::AccessDenied do |exception|
334
+ # redirect_to root_url, :alert => exception.message
335
+ # end
336
+ # end
337
+ #
338
+ # See the CanCan::AccessDenied exception for more details on working with the exception.
339
+ #
340
+ # See the load_and_authorize_resource method to automatically add the authorize! behavior
341
+ # to the default RESTful actions.
342
+ def authorize!(*args)
343
+ @_authorized = true
344
+ current_ability.authorize!(*args)
345
+ end
346
+
347
+ # Creates and returns the current user's ability and caches it. If you
348
+ # want to override how the Ability is defined then this is the place.
349
+ # Just define the method in the controller to change behavior.
350
+ #
351
+ # def current_ability
352
+ # # instead of Ability.new(current_user)
353
+ # @current_ability ||= UserAbility.new(current_account)
354
+ # end
355
+ #
356
+ # Notice it is important to cache the ability object so it is not
357
+ # recreated every time.
358
+ def current_ability
359
+ @current_ability ||= ::Ability.new(current_user)
360
+ end
361
+
362
+ # Use in the controller or view to check the user's permission for a given action
363
+ # and object.
364
+ #
365
+ # can? :destroy, @project
366
+ #
367
+ # You can also pass the class instead of an instance (if you don't have one handy).
368
+ #
369
+ # <% if can? :create, Project %>
370
+ # <%= link_to "New Project", new_project_path %>
371
+ # <% end %>
372
+ #
373
+ # If it's a nested resource, you can pass the parent instance in a hash. This way it will
374
+ # check conditions which reach through that association.
375
+ #
376
+ # <% if can? :create, @category => Project %>
377
+ # <%= link_to "New Project", new_project_path %>
378
+ # <% end %>
379
+ #
380
+ # This simply calls "can?" on the current_ability. See Ability#can?.
381
+ def can?(*args)
382
+ current_ability.can?(*args)
383
+ end
384
+
385
+ # Convenience method which works the same as "can?" but returns the opposite value.
386
+ #
387
+ # cannot? :destroy, @project
388
+ #
389
+ def cannot?(*args)
390
+ current_ability.cannot?(*args)
391
+ end
392
+ end
393
+ end
394
+
395
+ if defined? ActiveSupport
396
+ ActiveSupport.on_load(:action_controller) do
397
+ include CanCan::ControllerAdditions
398
+ end
399
+ end