adding check_authorization and skip_authorization controller class methods to ensure authorization is triggered (thanks justinko) - closes #135
This commit is contained in:
parent
7c5243321f
commit
1af6c6f395
|
@ -151,6 +151,20 @@ module CanCan
|
|||
def authorize_resource(*args)
|
||||
ControllerResource.add_before_filter(self, :authorize_resource, *args)
|
||||
end
|
||||
|
||||
def skip_authorization(*args)
|
||||
self.before_filter(*args) do |controller|
|
||||
controller.instance_variable_set(:@_authorized, true)
|
||||
end
|
||||
end
|
||||
|
||||
def check_authorization(*args)
|
||||
self.after_filter(*args) do |controller|
|
||||
unless controller.instance_variable_defined?(:@_authorized)
|
||||
raise AuthorizationNotPerformed, "This action does not authorize the user. Add authorize! or authorize_resource to the controller."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.included(base)
|
||||
|
@ -186,6 +200,7 @@ module CanCan
|
|||
# See the load_and_authorize_resource method to automatically add the authorize! behavior
|
||||
# to the default RESTful actions.
|
||||
def authorize!(*args)
|
||||
@_authorized = true
|
||||
current_ability.authorize!(*args)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ module CanCan
|
|||
# Raised when removed code is called, an alternative solution is provided in message.
|
||||
class ImplementationRemoved < Error; end
|
||||
|
||||
# Raised when using check_authorization without calling authorized!
|
||||
class AuthorizationNotPerformed < Error; end
|
||||
|
||||
# This error is raised when a user isn't allowed to access a given controller action.
|
||||
# This usually happens within a call to ControllerAdditions#authorize! but can be
|
||||
# raised manually.
|
||||
|
|
|
@ -265,6 +265,34 @@ describe CanCan::Ability do
|
|||
@ability.attributes_for(:new, Range).should == {:foo => "foo", :bar => 123, :baz => "baz"}
|
||||
end
|
||||
|
||||
it "should raise access denied exception if ability us unauthorized to perform a certain action" do
|
||||
begin
|
||||
@ability.authorize! :read, :foo, 1, 2, 3, :message => "Access denied!"
|
||||
rescue CanCan::AccessDenied => e
|
||||
e.message.should == "Access denied!"
|
||||
e.action.should == :read
|
||||
e.subject.should == :foo
|
||||
else
|
||||
fail "Expected CanCan::AccessDenied exception to be raised"
|
||||
end
|
||||
end
|
||||
|
||||
it "should not raise access denied exception if ability is authorized to perform an action" do
|
||||
@ability.can :read, :foo
|
||||
lambda { @ability.authorize!(:read, :foo) }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should raise access denied exception with default message if not specified" do
|
||||
begin
|
||||
@ability.authorize! :read, :foo
|
||||
rescue CanCan::AccessDenied => e
|
||||
e.default_message = "Access denied!"
|
||||
e.message.should == "Access denied!"
|
||||
else
|
||||
fail "Expected CanCan::AccessDenied exception to be raised"
|
||||
end
|
||||
end
|
||||
|
||||
describe "unauthorized message" do
|
||||
after(:each) do
|
||||
I18n.backend = nil
|
||||
|
|
|
@ -14,33 +14,10 @@ describe CanCan::ControllerAdditions do
|
|||
lambda { @controller.unauthorized! }.should raise_error(CanCan::ImplementationRemoved)
|
||||
end
|
||||
|
||||
it "should raise access denied exception if ability us unauthorized to perform a certain action" do
|
||||
# TODO this should probably be moved into Ability spec
|
||||
begin
|
||||
@controller.authorize! :read, :foo, 1, 2, 3, :message => "Access denied!"
|
||||
rescue CanCan::AccessDenied => e
|
||||
e.message.should == "Access denied!"
|
||||
e.action.should == :read
|
||||
e.subject.should == :foo
|
||||
else
|
||||
fail "Expected CanCan::AccessDenied exception to be raised"
|
||||
end
|
||||
end
|
||||
|
||||
it "should not raise access denied exception if ability is authorized to perform an action" do
|
||||
@controller.current_ability.can :read, :foo
|
||||
lambda { @controller.authorize!(:read, :foo) }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should raise access denied exception with default message if not specified" do
|
||||
begin
|
||||
@controller.authorize! :read, :foo
|
||||
rescue CanCan::AccessDenied => e
|
||||
e.default_message = "Access denied!"
|
||||
e.message.should == "Access denied!"
|
||||
else
|
||||
fail "Expected CanCan::AccessDenied exception to be raised"
|
||||
end
|
||||
it "authorize! should assign @_authorized instance variable and pass args to current ability" do
|
||||
mock(@controller.current_ability).authorize!(:foo, :bar)
|
||||
@controller.authorize!(:foo, :bar)
|
||||
@controller.instance_variable_get(:@_authorized).should be_true
|
||||
end
|
||||
|
||||
it "should have a current_ability method which generates an ability for the current user" do
|
||||
|
@ -76,4 +53,25 @@ describe CanCan::ControllerAdditions do
|
|||
mock(@controller_class).before_filter(:only => [:show, :index]) { |options, block| block.call(@controller) }
|
||||
@controller_class.load_resource :foo => :bar, :only => [:show, :index]
|
||||
end
|
||||
|
||||
it "skip_authorization should set up a before filter which sets @_authorized to true" do
|
||||
mock(@controller_class).before_filter(:filter_options) { |options, block| block.call(@controller) }
|
||||
@controller_class.skip_authorization(:filter_options)
|
||||
@controller.instance_variable_get(:@_authorized).should be_true
|
||||
end
|
||||
|
||||
it "check_authorization should trigger AuthorizationNotPerformed in after filter" do
|
||||
mock(@controller_class).after_filter(:some_options) { |options, block| block.call(@controller) }
|
||||
lambda {
|
||||
@controller_class.check_authorization(:some_options)
|
||||
}.should 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) }
|
||||
lambda {
|
||||
@controller_class.check_authorization(:some_options)
|
||||
}.should_not raise_error(CanCan::AuthorizationNotPerformed)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user