2017-05-28 4 views
1

Ich habe eine Arbeitsfähigkeit wie folgt definiert:Cancancan verschachtelte Ressourcenautorisierungs

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 

Aufgaben Controller:

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

Das lässt richtig zu Der Benutzer erstellt eine Aufgabe, wenn er zu einem Projekt eingeladen wird.

Ich möchte jedoch nicht, dass der Benutzer in der Lage ist: das Projekt zu verwalten. Ich brauche nur den Benutzer, um das Projekt wie folgt indizieren zu können.

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 

Als ich oben in den die Fähigkeiten setzen, kann der Benutzer keinen Zugriff mehr oder alle Aktionen auf die Aufgabe auszuführen. Wie erstelle ich eine Aufgabenfähigkeit über das Projekt, indem ich dem Projekt nur eine Indexfähigkeit gebe?

+0

'extrahieren kann [: index], Projekt, lädt: {Lieferant: {user_id: user.id}}' - aber Sie wirklich an dem Punkt der Komplexität wo Pundit ist eine viel bessere Wahl als CanCanCan. – max

+0

Wahr. Dies ist das letzte Stück, das ich für die Authentifizierung brauche. Sehen, ob ich eine Neuerstellung vermeiden kann. – HoosierCoder

Antwort

0

Sie sollten wahrscheinlich definieren, dass ein Benutzer read ein Projekt eingeladen werden kann. Deshalb:

ein Benutzer ein Projekt lesen kann, wenn eingeladen wird (ich glaube die Bedingung invites: { supplier: { user: user} } definiert einen eingeladenen Benutzer)

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

dann muss man sagen, dass ein Benutzer Aufgaben für Projekte schaffen, auf die er bekam eingeladen, dann:

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

am Ende legen Sie fest, dass der Benutzer seine eigenen Aufgaben auf Projekte verwalten kann seine lud er zu:

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

Sie können auch die Bedingungen vereinfachen, indem

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

Fast da, ich muss in der Lage sein, benutzerdefinierte Aktionen (eine einzige Methode) für diese Rolle im Projekt zu definieren, also muss ich '' read' und ': manage' auf' Project' vermeiden, da diese zu viele Rechte zuweisen . Ich könnte die Projektauth alle zusammen herausnehmen, aber sobald ich 'kann: verwalten, Aufgabe, Benutzer: Benutzer' erlaubt es dem Benutzer, eine Aufgabe unter jedem Projekt zu erstellen, zu dem sie nicht mit URL-Hacking eingeladen wurden .. – HoosierCoder

+0

': read' sollte in Ihrem Fall für das Projekt in Ordnung sein, da es': index' und ': show' ergibt. Über den zweiten Punkt habe ich meine Antwort aktualisiert. – coorasse

+0

Ja, ich habe am Ende nur eine 'show'-Berechtigung für das Projekt erteilt und die Seite nach Rolle eingeschränkt. – HoosierCoder

Verwandte Themen