如何为Rails引擎创建的路线指定功能?

mar*_*ion 7 ruby-on-rails cancancan ruby-on-rails-5.2 trestle-admin

我正在使用Trestle Admin,这是我的路线:

trestle_path        /admin         Trestle::Engine
Run Code Online (Sandbox Code Playgroud)

当不是管理员的用户访问该/admin路由时,我希望CanCanCan可以处理该路由,就像它处理我的应用程序中的所有其他未授权请求一样。

但是,问题是我无法弄清楚如何在我的能力中指定该能力,ability.rb或者我无法弄清楚在何处添加authorize语句。

当我/admin在应用程序中访问时,日志如下所示:

Started GET "/admin" for ::1 at 2019-03-31 01:10:01 -0500
Processing by Trestle::DashboardController#index as HTML
Redirected to http://localhost:3000/admin/login
Filter chain halted as :require_authenticated_user rendered or redirected
Completed 302 Found in 13ms (ActiveRecord: 0.0ms)
Run Code Online (Sandbox Code Playgroud)

因此,发生的所有事情就是它重定向到/admin/loginTrestle引擎处理它的方式。

但是我想让CanCanCan劫持并像通过我的规则处理整个应用程序中的所有其他未授权请求一样处理它application_controller.rb

rescue_from CanCan::AccessDenied do |exception|
  respond_to do |format|
    format.json { head :forbidden, content_type: 'text/html' }
    format.html { redirect_to main_app.root_url, alert: exception.message }
    format.js   { head :forbidden, content_type: 'text/html' }
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,由于它不是我定义的模型或控制器,所以我不确定在中指定什么ability.rb

我尝试了以下方法,但均无济于事:

  if user.has_role? :admin
    can :manage, :all
  else
    cannot :read, :trestle
  end
Run Code Online (Sandbox Code Playgroud)

要么:

  if user.has_role? :admin
    can :manage, :all
  else
    cannot :read, :admin
  end
Run Code Online (Sandbox Code Playgroud)

我可以做我想做的事吗?

Vas*_*fed 2

您可以使用具有路由约束的 hack:

class CanCanConstraint
  def initialize(action, resource)
    @resource, @action = resource, action
  end

  def matches?(request)
    # this will differ depending on your auth solution, for devise/warden:
    current_user = request.env['warden'].user        
    current_user && Ability.new(current_user).can?(@action, @resource) || false
  end
end

mount Trestle::Engine, at: '/admin', constraints: CanCanConstraint.new(:edit, :trestle)
match "/admin/*glob", to: "some_controller_when#trestle_not_authorized"
Run Code Online (Sandbox Code Playgroud)

如果用户被授权并拥有权限,这种方式/admin只会导致栈桥,否则第一条路线将不匹配,您可以以任何您喜欢的方式处理请求,例如使用包罗万象的第二条路线。

根据您安装支架的方式 - 您可能需要禁用它的自动安装(config.automount = false在相应的初始化程序中)