Inherited Resources and CanCan 3 levels nesting
I have a problem with 3 levels nesting of models in CanCan combined with Inherited Resources. I've read that we should nest everything up to 2 levels, but I had to put everything under account
model and now I've tried doing this 开发者_C百科in CanCan:
load_and_authorize_resource :account
load_and_authorize_resource :project, :through => :account
load_and_authorize_resource :model, :through => :project
That gives me @account variable that has a value of @project, like it is overwriting that. @project is what is supposed to be and @model too. Is that fault of mine, CanCan's, Inherited Resources or just CanCan isn't supporting 3 levels nesting? Also, I do this in IR for the ModelsController.
belongs_to :account, :finder => :find_by_name! do
belongs_to :project, :finder => :find_by_name!
end
Another strange thing is when i remove the part load_and_
from CanCan's definition. It works then, but I've read that it can be dangerous not to use the load
part.
Can I use only the authorize_resource
or should I do something with CanCan?
Your authorizations have been correct as far as I can say.
The developer of the CanCan gem ryan posted how this should behave: https://github.com/ryanb/cancan/issues/127#issuecomment-364475
That means that your
load_and_authorize_resource :account
load_and_authorize_resource :project, :through => :account
load_and_authorize_resource :model, :through => :project
will end up in an block like this (here: create action. For other actions should the last authorize! and the @model change):
@account = Account.find(params[:account_id])
authorize! :read, @account
@project = @account.projects.find(params[:project_id])
authorize! :read, @project
@model = @project.models.build
authorize! :new, @model
I hope that this answer can help developers looking for nested cancan authorization :-) .
source: https://github.com/ryanb/cancan/issues/127#issuecomment-364475
ps: wrong behavior for /accounts/1/projects/2/models/new:
load_and_authorize_resource :project
load_and_authorize_resource :model, :through => :project
This is kind of a security issue, because this will do
@project = Project.find(params[:project_id]) [...]
, and does not check if the current account is allowed to read the linked account '1'. And it does not check, if the project '2' is really a project of account '1'.
精彩评论