2013-04-13 50 views
1

我有一个表单,在这个表单中用户可以在User模型和Photo模型中编辑它们的属性。用户模型有很多照片。Cancan对嵌套属性的授权操作

当用户提交表单时,PARAMS都会有,

:user => { :name => "blah blah", 
      :photos_attributes => { 
       "1" => { "id" => 10, "description" => "Some description"} 
      } 
     } 

,我在控制器上做current_user.update_attributes(params[:user])

一切工作正常。但是没有对该行为进行授权。从而留下一个安全漏洞。用户可以通过改变表单帖子中传递的id(在photo_attribtues中)来修改他意愿的任何照片。

如何检查当前用户是否拥有使用CanCan更改photo_attributes中指定的照片的权限(即,如果他是所有者)。

注意:photos_attributes是可选的。该参数可能包含或不包含photos_attributes。 [:用户]

回答

-1

我假设你定义你的路由如下:如果在PARAMS没有photos_attributes的解决方案应该不会失败

resources :users do 
    resources :photos 
end 

如果是这样,那么,在你的ability.rb文件,你可以这样做:

def initialize(user) 
    can :manage, Photos, :user_id => user.id 
end 

它应该验证照片是否属于正确的用户。

请参见:https://github.com/ryanb/cancan/wiki/Nested-Resources

+0

问题是关于嵌套属性模型,而不是嵌套的资源。 – hmans

-1

简短的回答:这个不能做(与可行的努力)与惨惨。

很长的答案:从CanCan的角度来看,您只能处理User资源,该资源碰巧有一个名为photos_attributes的属性。 CanCan将不得不挂钩到ActiveRecord的accepts_nested_attributes_for的实现中,以便在控制器上下文中将参考关联范围限定为Photo.accessible_by(current_ability)而不仅仅是Photo。丑陋!

如果您认真对待授权并且可以在没有accepts_nested_attributes_for的附加舒适度的情况下生活,唯一可行的解​​决方案可能是您自己处理额外的模型(即在您的控制器代码中)。

0

这是一个老问题,但我遇到了同样的问题

根据cancan维基(Defining Abilities),可以利用的条件,哈希,喜欢的东西:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    #... 
    #other abilities 
    #... 

    # first we check user can only edit his profile (id: user.id) 
    # then we check he can only edit his photos 
    can :update, User, id: user.id, photos: { id: user.photos_ids } 
    end 
end