开发者

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'.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜