adding :if and :unless options to check_authorization - closes #284
This commit is contained in:
		
							parent
							
								
									37102fe6f8
								
							
						
					
					
						commit
						80f1ab20fb
					
				@ -226,16 +226,33 @@ module CanCan
 | 
			
		||||
      #     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)
 | 
			
		||||
      #
 | 
			
		||||
      # 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
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Call this in the class of a controller to skip the check_authorization behavior on the actions.
 | 
			
		||||
      #
 | 
			
		||||
 | 
			
		||||
@ -66,17 +66,33 @@ describe CanCan::ControllerAdditions do
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user