为什么即使动作是索引,cancan 也会启用块?

发布于 2025-01-02 02:32:48 字数 616 浏览 1 评论 0原文

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

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

根据cancan文档< /a>:

仅当存在实际实例对象时才会评估该块。 在检查类的权限时(例如在 索引操作)。

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

我通过注释掉上面的代码确认了这一点,然后用户没有被授权。

据我了解 cancan,该块应该运行(实际上它没有),如果它不运行,则该块被认为返回了 false,因此不是授予许可。

我是否理解错了,或者这是一个错误?

我使用的是 1.67 版本的康康舞。

This is the relevant part of my ability.rb class:

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

According to cancan documentation:

The block is only evaluated when an actual instance object is present.
It is not evaluated when checking permissions on the class (such as in
the index action).

However, for the UsersController index action, even though the block isn't run, it still grants :manage permissions, listing the users.

I have confirmed this by commenting out the above code, and then the user is not authorized.

As far as I understood cancan, the block is supposed to to run (which indeed it doesn't), and if it doesn't run, then the block is considered to have returned false, thus not granting the permission.

Am I getting this wrong, or is this a bug?

I'm using cancan version 1.67.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴者 2025-01-09 02:32:48

我认为您在这里误读了文档:

如果没有评估实例,而是类 cancan 将不会执行该块,因为没有要执行的实例检查。
这省去了让块 nil 具有弹性的麻烦。
由于该块永远不会被执行,因此不会假设它返回什么,并且 cancan 只会查看它的类规则。

如果它会调用该块,您就必须考虑到这一点(在稍微复杂的模型中):

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

我猜默认值被隐藏了 此处,但这似乎是一个合理的默认值。
如果您要允许用户管理自己的帖子,无论如何您都应该阻止他在索引中看到其他人的帖子。因此,对您的唯一威胁是他访问他明确无权访问的资源。
(Cancan 永远不会连接普通的 ActiveRecord 查询并按能力过滤它们。因此 User.all 将始终返回所有用户 - 无论能力如何)

但是:如果您正在尝试实现类似配置文件之类的东西,我建议您只需稍微改变一下 UsersController 逻辑,只需将配置文件设置为单一资源,如 Rails 中所述指南

I think you are misreading the documentation here:

If no instance is evaluated but rather a Class cancan will NOT execute the block as there is no instance check to be performed.
This saves you the hassle of making the block nil resilient.
Since the block is never executed there is no assumption made what it returns and cancan will only look at it's Class rules.

If it would call the block you'd have to account for this (in a slightly more complex model):

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

I guess the default is buried here, but this seems like a sensible default.
If you are going to allow a user to manage his own posts anyway you should prevent him from seeing other's posts in the index anyway. So the only threat to you is him accessing a resource he explicitly has no access to.
(Cancan will never hook up on normal ActiveRecord queries and filter them down by abilities. So User.all will always return all users - regardless of ability)

However: If you are trying to implement something like a profile, I'd suggest you just change around your UsersController logic a bit and simply make the profile a singular resource as described in the Rails Guides

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文