轨道 3 和cancan:用户不应被允许编辑记录,但可以吗?

发布于 2024-10-31 06:01:40 字数 894 浏览 1 评论 0原文

我正在尝试使用 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 技术交流群。

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

发布评论

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

评论(3

戏舞 2024-11-07 06:01:40

您是否在控制器中授权资源?

您应该在关键过程控制器内的控制器

def edit
    @critical_process = CriticalProcess.find(params[:id])
    #this here is what you use
    authorize! :edit, @critical_process
  end 

编辑方法中添加load_and_authorize_resource

Are you authorizing the resource in the controller?

you should have load_and_authorize_resource in your controller

or

def edit
    @critical_process = CriticalProcess.find(params[:id])
    #this here is what you use
    authorize! :edit, @critical_process
  end 

in your edit method inside the critical process controller.

感情旳空白 2024-11-07 06:01:40

我个人更喜欢将此逻辑与模型完全分开,这样我就不必深入研究模型代码来查找授权问题。换句话说,user.can_edit 检查授权,这正是能力文件应该负责的。不过应该没关系......在这种情况下,我认为你可能在 can_edit 方法中遇到问题。我多次使用看起来与您的代码几乎相同且没有问题的代码,如下所示:

can :manage, Record do |record|
  user.has_role?(:record_manager)
end

我建议包括您的 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:

can :manage, Record do |record|
  user.has_role?(:record_manager)
end

I suggest including your code for can_edit or use the debugger to see what value gets returned from can_edit.

み青杉依旧 2024-11-07 06:01:40

我认为问题来自于您查询应该让用户作为编辑者的记录的方式。

我复制/粘贴了您的代码并从头开始构建了其他关联。
并在控制台中测试它,当我使用它时,它按预期工作:

>> u = User.last
>> a = Ability.new(u)
>> a.can :edit, Role.last
false

我唯一改变的是记录的查询:它似乎寻找拥有该角色的记录(您的角色有一个 record_id) 但随后在 cp_secondary_id 下查找相同的密钥。

我认为您的查询中有问题,但这取决于您的架构和关联:

roles_as_editor.collect{ |x| Record.where(:cp_secondary_id => x.record_id) }.flatten.uniq

据我理解您的代码,我们正在遍历这样的关联:

User=>Assignment<=Role(boolean edit flag)<=Record

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:

>> u = User.last
>> a = Ability.new(u)
>> a.can :edit, Role.last
false

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:

roles_as_editor.collect{ |x| Record.where(:cp_secondary_id => x.record_id) }.flatten.uniq

as I understood your code we are traversing associations like this:

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