我有一个引擎安装到我的主应用程序,我想保护该引擎内的某些控制器和操作。
发动机安装时:
mount SomeEngine::Engine => '/some_engine'
Devise / CanCan正在使用其他主要应用程序的控制器和操作,但让事情无其他任何事情运行会产生此错误:
This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check.
所以我使用装饰器方法从主应用程序打开引擎控制器并添加:
load_and_authorize_resource
然后我收到此错误:
No route matches {:action=>"new", :controller=>"devise/sessions"}
我可以使用以下方法解决问题,但是当我尝试实现角色时它很笨拙:
authenticate :administrator do
mount SomeEngine::Engine => '/some_engine'
end
笨重的我的意思是我必须在routes.rb文件中为每个有权访问引擎的角色重现上面的代码块...除非有另一种使用身份验证的方法我没有知道???
如果可能的话,我想在控制器中使用正常的Devise / CanCan授权/认证方法。但我认为“没有路由匹配”错误发生,因为引擎不知道如何到达主应用程序的Devise控制器。但是我如何从主应用程序中解决这个问题?
要再添加一个问题...引擎中有一个特定的控制器/操作,我想向所有用户公开。到目前为止,我刚刚在routes.rb文件中的authenticate代码块之前添加了这个。
match '/some_engine' => 'some_engine/some_controller#public_action'
它有效...但是这行与routes.rb中的块似乎我做错了。它不允许我很好地实现角色。
答案 0 :(得分:8)
您可以从主应用程序继承应用程序控制器以使用设备和cancan。
module SomeEngine
class ApplicationController < ::ApplicationController
before_filter :merge_abilities
private
def merge_abilities
current_ability.merge(SomeEngine::Ability.new(current_user))
end
end
end
在此之后,你可以通过创建自己来创建引擎的能力。
module SomeEngine
class Ability
include ::CanCan::Ability
def initialize(user)
return if user.nil?
can :manage, SomeModel
end
end
end
SomeModel
(SomeEngine::SomeModel
)是SomeEngine
引擎的模型。
在资源控制器上,您必须指定资源的类名。
load_and_authorize_resource class: SomeEngine::SomeModel
如果你想在引擎上使用它,请不要忘记在主应用程序布局中将路由助手更改为main_app.MAIN_APP_PATHS
。