Как мне указать возможность для маршрута, созданного движком Rails? - PullRequest
7 голосов
/ 31 марта 2019

Я использую Trestle Admin , это мой маршрут:

trestle_path        /admin         Trestle::Engine

Когда пользователь, который не является администратором, посещает маршрут /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)

Так что все, что происходит, это то, что он перенаправляет на/admin/login Вот как обработчик Trestle обрабатывает его.

Но я бы хотел, чтобы 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

Но, учитывая, что это не модель или контроллер, который я определил, я не уверен, что указать в моем ability.rb.

Я попробовал следующее, всебезрезультатно:

  if user.has_role? :admin
    can :manage, :all
  else
    cannot :read, :trestle
  end

или:

  if user.has_role? :admin
    can :manage, :all
  else
    cannot :read, :admin
  end

Возможно ли это длямне делать то, что я пытаюсь сделать?

1 Ответ

1 голос
/ 16 апреля 2019

Вы можете использовать хак с ограничениями маршрута:

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"

Таким образом, /admin приводит к эстакаде только в том случае, если пользователь авторизован и имеет разрешение, в противном случае первый маршрут не будет совпадать, и вы можете обработать запрос любым удобным вам способом, например, со вторым маршрутом перехвата всех сообщений.

В зависимости от того, как вы монтируете эстакаду - вам может потребоваться отключить ее автомонтирование (config.automount = false в соответствующем инициализаторе)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...