Допустим, я использую гем Pundit для авторизации. У меня есть следующий контроллер:
class BlogsController < ApplicationController
before_action :check_authorization
...
private
def check_authorization
authorize :blog
end
end
Pundit смотрит на переданный аргумент :blog
и, таким образом, делает вывод, что существует класс BlogPolicy
. Затем он ищет соответствующее имя действия со знаком вопроса, например: BlogPolicy#index?
.
Если я хочу найти авторизацию на определенном ресурсе, я бы просто сделал это для этого метода check_authorization
:
def check_authorization
authorize @blog
end
Опять же, нет проблем. Pundit смотрит на класс ресурса Blog
, а затем ищет класс BlogPolicy
.
- Пример. Приложение может вызвать метод
BlogPolicy#show?
и передать этот ресурс@blog
.
Вот проблема: что мне делать, когда я хочу авторизоваться на определенном имени контроллера И авторизоваться на определенном ресурсе, но этот ресурс не синхронизируется с именем контроллера?
Пример:
class SomeOtherBlogsController < ApplicationController
before_action :check_authorization
...
private
def check_authorization
authorize :some_other_blog, @blog
end
end
Приведенный выше код не работает, но, надеюсь, он показывает, что я пытаюсь сделать. Давайте представим, что это происходит в действии SomeOtherBlogsController#show
.
- Я пытаюсь, чтобы эксперт нашел метод
SomeOtherBlogPolicy#show?
, - В рамках этого метода политики я также хочу проверить авторизационный доступ к ресурсу
@blog
.
Надеюсь, проблема очевидна. Поскольку класс ресурсов не синхронизируется с именем контроллера, похоже, я не могу сделать это выше. Так что, если у меня есть один и тот же ресурс, используемый в разных контроллерах, мне не повезло. Я бы не смог проверить авторизацию ресурса в этих различных контекстах контроллера. Это невозможно сделать с Пандитом?
Обновление:
В контроллере я также попытался напрямую вызвать метод Policy следующим образом:
SomeOtherBlogPolicy.new(current_user, @blog).show?
Однако колл поднял Pundit::AuthorizationNotPerformedError
. Таким образом, оказывается, что в этом методе authorize
происходит больше, чем просто возврат true
или false
.