ryanb/cancan — pull request #968 by emiltin (2013-11-24 14:30:45+00:00)
Title: Setting for strick class access

(This is an update of an earlier PR #622. I still think it's relevant until 2.0 is done.)

If you define a block for determing an ability on a clas, "can?" currently returns true for all methods if you pass a class object:

```ruby
#in your ability class
ability.can :destroy, :all { |object| false }

# in your controllers, etc
ability.can? :destroy, {} => false # block called, and returns false
ability.can? :destroy, Hash # => true # careful - block not called, true returned by default
```

This can cause unexpected access.

This PR allows you to turn on strict class access, which mean that "can?" will return false for method on a class with a block defined, unless you specifically permit the method:

```ruby
#in your ability class
ability.strict_class_access = true # enable strict class access
ability.can :destroy, :all { |object| false }

# in your controllers, etc
ability.can? :destroy, {} => false # block is called, and returns false
ability.can? :destroy, Hash # => false # block not called, false returned since strict class access is on

#in your ability class
ability.can :destroy, Hash # specifically allow destroying Hashes

# in your controllers, etc
ability.can? :destroy, Hash # => true # true returned, since we specifically allowed it
```

If you don't enable this setting, everything works as usual. Passing specs are included.