我有一个表单,用户可以在其中编辑用户模型和照片模型中的属性。用户模型有很多照片。
当用户提交表单时,参数将有,
: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是可选的。 params可能包含也可能不包含photos_attributes。如果params [:user]
中没有photos_attributes,解决方案不应该失败答案 0 :(得分:0)
这是一个老问题,但我遇到了同样的问题
根据cancan
wiki(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
答案 1 :(得分:-1)
简短回答:CanCan无法做到这一点(可行的努力)。
答案很长:从CanCan的角度来看,您只处理恰好具有User
属性的photos_attributes
资源。 CanCan必须挂钩ActiveRecord的accepts_nested_attributes_for
实现,以便在控制器上下文中将引用的关联范围限定为Photo.accessible_by(current_ability)
,而不仅仅是Photo
。难看!
如果您认真对待授权并且可以在没有accepts_nested_attributes_for
的额外舒适度的情况下生活,那么唯一可行的实用解决方案可能是您自己处理额外的模型(即在您的控制器代码中)。
答案 2 :(得分:-2)
我假设您将路线定义如下:
resources :users do
resources :photos
end
如果是,那么,在ability.rb
文件中,您可以执行以下操作:
def initialize(user)
can :manage, Photos, :user_id => user.id
end
并且应该验证照片是否属于正确的用户。