轨道 3 和cancan:用户不应被允许编辑记录,但可以吗?
我正在尝试使用 cancan 实现特定对象(行)授权,我希望它的工作方式是用户只能对 Record
进行更改(更新/编辑)(如果他/她有)该特定记录
的角色。在咨询了 cancan 文档后,我尝试执行以下操作:
class Ability
include CanCan::Ability
def initialize(user)
can :manage, Record do |record|
user.can_edit(record)
end
end
end
class User
has_many :assignments
has_many :roles_as_editor, :through => :assignments, :class_name => "Role", :source => :role, :conditions => {:edit => true}
def rec_as_editor
self.roles_as_editor.collect{ |x| Record.where(:cp_secondary_id => x.record_id) }.flatten.uniq
end
def can_edit(rec)
rec_as_editor.include?(rec)
end
end
can_edit
方法接受一个 Record
对象,并确保用户具有通过返回进行更改所需的角色是真是假。此方法经过测试并且工作正常,因此问题似乎出在 CanCan 代码上,因为当我尝试编辑用户不持有角色的记录时,它仍然允许我对记录进行更改,有人知道为什么这不起作用吗?
如果您需要任何进一步的信息,请通过评论告诉我。
谢谢
I am trying to implement specific object (row) authorisation using cancan, I want it to work in a way that a user can only make a change(update/edit) to a Record
if he/she has the role for that specific Record
. after consulting the cancan docs I tried doing the following:
class Ability
include CanCan::Ability
def initialize(user)
can :manage, Record do |record|
user.can_edit(record)
end
end
end
class User
has_many :assignments
has_many :roles_as_editor, :through => :assignments, :class_name => "Role", :source => :role, :conditions => {:edit => true}
def rec_as_editor
self.roles_as_editor.collect{ |x| Record.where(:cp_secondary_id => x.record_id) }.flatten.uniq
end
def can_edit(rec)
rec_as_editor.include?(rec)
end
end
The can_edit
method takes in a Record
object and ensures that a User has the role necessary to make a change to it by returning true or false. this method is tested and works correctly so the problem seems to be with the CanCan code because when i try editing a Record that the user dosent hold the role for it still allows me to make changes to the Record, anyone know why this wont work?
If you require any further information please let me know through a comment.
Thank You
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否在控制器中授权资源?
您应该在关键过程控制器内的控制器
或
编辑方法中添加
load_and_authorize_resource
。Are you authorizing the resource in the controller?
you should have
load_and_authorize_resource
in your controlleror
in your edit method inside the critical process controller.
我个人更喜欢将此逻辑与模型完全分开,这样我就不必深入研究模型代码来查找授权问题。换句话说,user.can_edit 检查授权,这正是能力文件应该负责的。不过应该没关系......在这种情况下,我认为你可能在 can_edit 方法中遇到问题。我多次使用看起来与您的代码几乎相同且没有问题的代码,如下所示:
我建议包括您的 can_edit 代码或使用调试器来查看从 can_edit 返回的值。
I personally prefer to keep this logic completely separate from models so that I don't have to dig into model code to find authorization issues. In other words, user.can_edit checks for authorization which is what the ability file is supposed to be in charge of. Shouldn't matter though... in this case I think you might have a problem inside the can_edit method. I have used code that looks nearly identical to yours without problems many times like this:
I suggest including your code for can_edit or use the debugger to see what value gets returned from can_edit.
我认为问题来自于您查询应该让用户作为编辑者的记录的方式。
我复制/粘贴了您的代码并从头开始构建了其他关联。
并在控制台中测试它,当我使用它时,它按预期工作:
我唯一改变的是记录的查询:它似乎寻找拥有该角色的记录(您的角色有一个 record_id) 但随后在 cp_secondary_id 下查找相同的密钥。
我认为您的查询中有问题,但这取决于您的架构和关联:
据我理解您的代码,我们正在遍历这样的关联:
I think the problem comes from the way you query for the records that are supposed to have the user as an editor.
I copy/pasted your code and built the other associations from scratch.
And testing it in the console it works as expected when I use it:
The only thing I changed is the query for the records: it seemed to look for a record that owns the role (your Role has a record_id) but then looks for the same key under cp_secondary_id.
I think something is wrong in your query, but what depends on your schema and associations:
as I understood your code we are traversing associations like this: