即使动作是索引,为什么cancan可以使用块来启用?

时间:2012-02-02 08:31:27

标签: ruby-on-rails cancan

这是我的能力的相关部分.rb类:

def initialize(user)
  can :manage, User do |u|·
    user == u·
  end
end

根据cancan documentation

  

仅在存在实际实例对象时评估该块。   在检查类的权限时(例如在   指数行动)。

但是,对于UsersController index操作,即使该块未运行,它仍会授予:manage权限,列出用户。

我已通过注释掉上述代码确认了这一点,然后用户未获得授权。

据我所知cancan,该块应该运行(实际上它没有),如果它没有运行,那么该块被认为已经返回false,因此没有授予许可。

我错了,还是这个错误?

我正在使用cancan版本1.67。

1 个答案:

答案 0 :(得分:2)

我认为你误解了这里的文档:

如果没有评估实例,而是一个类cancan将不执行该块,因为没有要执行的实例检查。 这样可以省去使块无弹性的麻烦。 由于块永远不会被执行,因此不会假设它返回什么,cancan只会查看它的类规则。

如果它会调用块,你必须考虑到这个(在稍微复杂的模型中):

can :manage, Post do |p|
  p.category.owner == user   #this will blow up because of nil
end 

我猜默认值是here,但这似乎是一个合理的默认值。 如果你打算允许用户管理自己的帖子,你应该阻止他在索引中看到其他帖子。因此,唯一的威胁是他访问他明确无法访问的资源。 (Cancan永远不会挂接正常的ActiveRecord查询并按功能过滤它们。所以User.all将始终返回所有用户 - 无论能力如何)

但是:如果您正在尝试实现类似于配置文件的内容,我建议您稍微改变一下您的UsersController逻辑,并简单地使配置文件成为单一资源,如Rails Guides

中所述