should not allow to can? when raw sql without block is present

This commit is contained in:
Sokolov Yura 2010-09-24 17:15:09 +08:00 committed by Ryan Bates
parent 1f81b8dd1e
commit 12037d7f43
4 changed files with 38 additions and 1 deletions

View File

@ -54,7 +54,7 @@ module CanCan
# #
# Also see the RSpec Matchers to aid in testing. # Also see the RSpec Matchers to aid in testing.
def can?(action, subject, *extra_args) def can?(action, subject, *extra_args)
match = relevant_can_definitions(action, subject).detect do |can_definition| match = relevant_can_definitions_for_match(action, subject).detect do |can_definition|
can_definition.matches_conditions?(action, subject, extra_args) can_definition.matches_conditions?(action, subject, extra_args)
end end
match ? match.base_behavior : false match ? match.base_behavior : false
@ -224,6 +224,10 @@ module CanCan
def has_block?(action, subject) def has_block?(action, subject)
relevant_can_definitions(action, subject).any?(&:only_block?) relevant_can_definitions(action, subject).any?(&:only_block?)
end end
def has_raw_sql?(action, subject)
relevant_can_definitions(action, subject).any?(&:only_raw_sql?)
end
private private
@ -267,6 +271,14 @@ module CanCan
can_definition.relevant? action, subject can_definition.relevant? action, subject
end end
end end
def relevant_can_definitions_for_match(action, subject)
relevant_can_definitions(action, subject).each do |can_definition|
if can_definition.only_raw_sql?
raise Error, "The can? and cannot? call cannot be used with a raw sql 'can' definition. The checking code cannot be determined for #{action.inspect} #{subject.inspect}"
end
end
end
def relevant_can_definitions_for_query(action, subject) def relevant_can_definitions_for_query(action, subject)
relevant_can_definitions(action, subject).each do |can_definition| relevant_can_definitions(action, subject).each do |can_definition|

View File

@ -55,6 +55,10 @@ module CanCan
def only_block? def only_block?
conditions_empty? && !@block.nil? conditions_empty? && !@block.nil?
end end
def only_raw_sql?
@block.nil? && !conditions_empty? && !@conditions.kind_of?(Hash)
end
def conditions_empty? def conditions_empty?
@conditions == {} || @conditions.nil? @conditions == {} || @conditions.nil?

View File

@ -317,6 +317,13 @@ describe CanCan::Ability do
end end
@ability.should have_block(:read, :foo) @ability.should have_block(:read, :foo)
end end
it "should know when raw sql is used in conditions" do
@ability.can :read, :foo
@ability.should_not have_raw_sql(:read, :foo)
@ability.can :read, :foo, 'false'
@ability.should have_raw_sql(:read, :foo)
end
it "should raise access denied exception with default message if not specified" do it "should raise access denied exception with default message if not specified" do
begin begin

View File

@ -56,4 +56,18 @@ describe CanCan::ActiveRecordAdditions do
stub(@model_class).scoped{|*args| args.inspect} stub(@model_class).scoped{|*args| args.inspect}
@model_class.accessible_by(@ability).should == :found_records @model_class.accessible_by(@ability).should == :found_records
end end
it "should not allow to fetch records when ability with just block present" do
@ability.can :read, @model_class do false end
lambda {
@model_class.accessible_by(@ability)
}.should raise_error(CanCan::Error)
end
it "should not allow to check ability on object when nonhash sql ability definition without block present" do
@ability.can :read, @model_class, ['bar = ?', 1]
lambda {
@ability.can? :read, @model_class.new
}.should raise_error(CanCan::Error)
end
end end