Явно разрешить область действия Doorkeeper в контроллере

В моем текущем заявлении у меня есть две приставки, user а также admin, В документации привратника для настройки областей в API это показывает

class Api::V1::ProductsController < Api::V1::ApiController
  before_action -> { doorkeeper_authorize! :public }, only: :index
  before_action only: [:create, :update, :destroy] do
    doorkeeper_authorize! :admin, :write
  end

  ...
end

Я не хочу вызывать портье на каждом контроллере, поэтому в моем ApplicationController у меня есть

module API
  module V1
    class ApplicationController < ActionController::API
      before_action { doorkeeper_authorize! :user, :project }
      ...

    end
  end
end

но я не хочу давать :project доступ к каждому контроллеру. Есть ли способ для меня, чтобы позволить user в нашем контроллере приложений before_action { doorkeeper_authorize! :user } и на основе каждого контроллера позволяют project? то есть:

module API
  module V1
    class SomeController < ApplicationController
      before_action only: [:index, :show] { doorkeeper_authorize! :project }

      ...
    end
  end
end

2 ответа

Решение

Я смог решить эту проблему, выполнив следующие действия в моем API::V1::ApplicationController

module API
  module V1
    class ApplicationController < ActionController::API
      WHITELISTED_PROJECT_CONTROLLERS = %w( projects pre_task_plans
                                            job_hazard_analyses ).freeze

      before_action :authorize!

      def authorize!
        if project_scope?
          if !WHITELISTED_PROJECT_CONTROLLERS.include?(controller_name)
            return user_not_authorized
          end
        end
        doorkeeper_authorize! :user, :project
      end

      def project_scope?
        doorkeeper_token&.scopes&.any? { |s| s == 'project' }
      end

     ...

    end
  end
end

Возможно , создание собственного фильтра может быть вариантом

before_action :doorkeeper_user_authorize!,  only: [:create, :update, :destroy]
protected 

def doorkeeper_user_authorize!
  doorkeeper_authorize!( :user )
end 

def doorkeeper_project_authorize!
  doorkeeper_authorize!( :user, :project )
end 

затем в контроллере, где должен быть разрешен проект

skip_before_action :doorkeeper_user_authorize!
before_action :doorkeeper_project_authorize!

Используйте условное с controller_name - кузнец, как это:

before_action { doorkeeper_authorize! :project }, if: -> { controller_name == 'some' }

Проверьте, может быть, вы должны передать параметр лямбда, как:

if: ->(instance) { instance.controller_name == 'some' }

Другие вопросы по тегам