Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding :if and :unless options to check_authorization - closes #284

  • Loading branch information...
commit 80f1ab20fb880d9d995da5dc25708a8be1e9671c 1 parent 37102fe
@ryanb authored
View
31 lib/cancan/controller_additions.rb
@@ -226,14 +226,31 @@ def skip_authorize_resource(*args)
# check_authorization
# end
#
- # Any arguments are passed to the +after_filter+ it triggers.
- #
# See skip_authorization_check to bypass this check on specific controller actions.
- def check_authorization(*args)
- self.after_filter(*args) do |controller|
- unless controller.instance_variable_defined?(:@_authorized)
- raise AuthorizationNotPerformed, "This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check."
- end
+ #
+ # Options:
+ # [:+only+]
+ # Only applies to given actions.
+ #
+ # [:+except+]
+ # Does not apply to given actions.
+ #
+ # [:+if+]
+ # Supply the name of a controller method to be called. The authorization check only takes place if this returns true.
+ #
+ # check_authorization :if => :admin_controller?
+ #
+ # [:+unless+]
+ # Supply the name of a controller method to be called. The authorization check only takes place if this returns false.
+ #
+ # check_authorization :unless => :devise_controller?
+ #
+ def check_authorization(options = {})
+ self.after_filter(options.slice(:only, :except)) do |controller|
+ return if controller.instance_variable_defined?(:@_authorized)
+ return if options[:if] && !controller.send(options[:if])
+ return if options[:unless] && controller.send(options[:unless])
+ raise AuthorizationNotPerformed, "This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check."
end
end
View
24 spec/cancan/controller_additions_spec.rb
@@ -66,17 +66,33 @@
end
it "check_authorization should trigger AuthorizationNotPerformed in after filter" do
- mock(@controller_class).after_filter(:some_options) { |options, block| block.call(@controller) }
+ mock(@controller_class).after_filter(:only => [:test]) { |options, block| block.call(@controller) }
lambda {
- @controller_class.check_authorization(:some_options)
+ @controller_class.check_authorization(:only => [:test])
}.should raise_error(CanCan::AuthorizationNotPerformed)
end
+ it "check_authorization should not trigger AuthorizationNotPerformed when :if is false" do
+ stub(@controller).check_auth? { false }
+ mock(@controller_class).after_filter({}) { |options, block| block.call(@controller) }
+ lambda {
+ @controller_class.check_authorization(:if => :check_auth?)
+ }.should_not raise_error(CanCan::AuthorizationNotPerformed)
+ end
+
+ it "check_authorization should not trigger AuthorizationNotPerformed when :unless is true" do
+ stub(@controller).engine_controller? { true }
+ mock(@controller_class).after_filter({}) { |options, block| block.call(@controller) }
+ lambda {
+ @controller_class.check_authorization(:unless => :engine_controller?)
+ }.should_not raise_error(CanCan::AuthorizationNotPerformed)
+ end
+
it "check_authorization should not raise error when @_authorized is set" do
@controller.instance_variable_set(:@_authorized, true)
- mock(@controller_class).after_filter(:some_options) { |options, block| block.call(@controller) }
+ mock(@controller_class).after_filter(:only => [:test]) { |options, block| block.call(@controller) }
lambda {
- @controller_class.check_authorization(:some_options)
+ @controller_class.check_authorization(:only => [:test])
}.should_not raise_error(CanCan::AuthorizationNotPerformed)
end

0 comments on commit 80f1ab2

Please sign in to comment.
Something went wrong with that request. Please try again.