2017-05-28 108 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