2017-05-28 71 views
1

我有一个工作能力定义如下:Cancancan嵌套资源授权

的routes.rb

resources :projects do 
    resources :tasks 
end 

ability.rb

can [:manage], Project, invites: {supplier: {:user_id => user.id}} 
can [:new, :create], Task 
can [:update, :show, :destroy, :edit], Task, user_id: user.id 

任务控制器:

load_and_authorize_resource :project 
load_and_authorize_resource :task, :through => :project 

这适当地让th e用户创建一个任务,如果他们被邀请参加一个项目。

但是,我不希望用户能够:管理项目。我只需要用户能够按如下所示对项目进行索引。

ability.rb

can [:index], Project, invites: {supplier: {:user_id => user.id}} ## breaks when changing :manage to :index here 
can [:new, :create], Task 
can [:update, :show, :destroy, :edit, :index], Task, user_id: user.id 

当我把在能力之上,用户可以不再访问或执行的任务的任何行动。如何通过项目创建任务能力,只给项目的索引能力?

+0

'简化条件可以[:索引]项目,邀请:{供应商:{USER_ID:user.id}}' - 但你真的是在复杂的点Pundit是比CanCanCan更好的选择。 – max

+0

是的。这是我需要进行身份验证的最后一部分。看看我能否避免重建。 – HoosierCoder

回答

0

您应该定义用户可以在邀请时read项目。因此:

如果受邀用户可以阅读项目(我猜的条件invites: { supplier: { user: user} }定义了一个邀请的用户)

can :read, Project, invites: { supplier: { user: user} } 

,那么你不得不说,一个用户可以为项目,他得到了创建任务邀请的话:

can [:new, :create], Task, project: { invites: { supplier: { user: user} } } 
到底

定义用户可以管理自己的项目任务,他在他的邀请:

can :manage, Task, user: user, project: { invites: { supplier: { user: user} } } 

您也可以通过提取

invited_to = { invites: { supplier: { user: user} } } 
can :read, Project, invited_to 
can [:new, :create], Task, project: invited_to 
can :manage, Task, user: user, project: invited_to 
+0

几乎在那里,我需要能够在项目中为这个角色定义自定义动作(单一方法),所以我必须避免在Project中使用':read'和':manage',因为这些赋予了太多的权限。我可以一起取出项目认证,但是,只要我能做到:管理,任务,用户:用户,它允许用户在任何项目下创建一个任务,他们没有受到URL黑客攻击。 – HoosierCoder

+0

在你的情况下,''read''应该没问题,因为它给出':index'和':show'。关于第二点我更新了我的答案。 – coorasse

+0

是的,我最终只给了这个项目的'show'权限,并且按照角色限制了页面。 – HoosierCoder