diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index e8155dc8..7dfca8be 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,5 +1,7 @@ Unreleased +* Drop support for actions without a subject (andrew-aladev) + * Removed support for dynamic finders (coorasse) 2.1.3 (Jan 16th, 2018) diff --git a/lib/cancan/exceptions.rb b/lib/cancan/exceptions.rb index ef30a537..4b99f317 100644 --- a/lib/cancan/exceptions.rb +++ b/lib/cancan/exceptions.rb @@ -11,6 +11,9 @@ class ImplementationRemoved < Error; end # Raised when using check_authorization without calling authorized! class AuthorizationNotPerformed < Error; end + # Raised when a rule is created with both a block and a hash of conditions + class BlockAndConditionsError < 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. diff --git a/lib/cancan/rule.rb b/lib/cancan/rule.rb index 2578d3ba..9b3ccf79 100644 --- a/lib/cancan/rule.rb +++ b/lib/cancan/rule.rb @@ -13,10 +13,9 @@ class Rule # :nodoc: # and subject respectively (such as :read, @project). The third argument is a hash # of conditions and the last one is the block passed to the "can" call. def initialize(base_behavior, action, subject, conditions, block) - both_block_and_hash_error = 'You are not able to supply a block with a hash of conditions in '\ - "#{action} #{subject} ability. Use either one." - raise Error, both_block_and_hash_error if conditions.is_a?(Hash) && block + condition_and_block_check(conditions, block, action, subject) @match_all = action.nil? && subject.nil? + raise Error, "Subject is required for #{action}" if action && subject.nil? @base_behavior = base_behavior @actions = Array(action) @subjects = Array(subject) @@ -80,5 +79,11 @@ def matches_subject_class?(subject) (subject.is_a?(Module) && subject.ancestors.include?(sub))) end end + + def condition_and_block_check(conditions, block, action, subject) + return unless conditions.is_a?(Hash) && block + raise BlockAndConditionsError, 'A hash of conditions is mutually exclusive with a block. '\ + "Check \":#{action} #{subject}\" ability." + end end end diff --git a/spec/cancan/ability_spec.rb b/spec/cancan/ability_spec.rb index 236cc58b..71e3cf70 100644 --- a/spec/cancan/ability_spec.rb +++ b/spec/cancan/ability_spec.rb @@ -483,9 +483,15 @@ class Container < Hash @ability.can :read, Array, published: true do false end - end.to raise_error(CanCan::Error, - 'You are not able to supply a block with a hash of conditions in read Array ability. '\ - 'Use either one.') + end.to raise_error(CanCan::BlockAndConditionsError, + 'A hash of conditions is mutually exclusive with a block. '\ + 'Check ":read Array" ability.') + end + + it 'raises an error when attempting to use action without subject' do + expect do + @ability.can :dashboard + end.to raise_error(CanCan::Error, 'Subject is required for dashboard') end describe 'unauthorized message' do