Лучший способ enforce прав доступа — контроллер или ограничение?

У меня есть плагин, который добавляет модель server с полем user_id. Я хочу, чтобы только владелец server мог выполнять POST (или, возможно, лучше PUT? — действие будет запускать пересборку экземпляра Discourse через командную строку на их сервере; я не уверен, что будет лучшей практикой.)

В config/routes.rb это выглядит так:

post “/upgrade/:id” => “servers#queue_upgrade”, constraints: PfaffmanagerConstraint.new

Рекомендуется ли проверять path_parameters[:action] в методе matches? файла pfaffmanager_constraint.rb и применять разрешения там, или же это следует делать в servers_controller.rb?

Кроме того, я думаю, что на самом деле мне стоит перенести этот маршрут в пространство имен namespace :user. Возможно, после решения этой задачи проблема решится сама собой, но сейчас код почти работает, и я хотел бы позволить другим людям протестировать его.

Маршрут Rails здесь:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/config/routes.rb#L12

А мой контроллер пытается применять разрешения:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L53-L70

Однако мой тест возвращает статус 200, когда запрос post делает другой пользователь:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L149-L157

Похоже, мне нужно каким-то образом заставить Ember обратить на это внимание?

Разве нельзя передать метод в before_action для проверки вашего условия?

Я думаю, что проверку прав доступа нужно реализовать в контроллере или через ограничения. Модель, как я понимаю, не знает, кто её вызывает.

Большое спасибо за внимание к этому вопросу.

Думаю, вам нужен метод-страж для проверки, разрешено ли пользователю выполнить данное действие. Например, can_upgrade_server?.

Также, после этого вы можете использовать метод guardian.ensure_can_upgrade_server!, который проверяет условие и выбрасывает исключение, что, как мне кажется, именно то, что вам нужно.

Оооо! Метод стража! Да! Я посмотрю на них! Спасибо.

Единственная модель, использующая guardian, — это модель пользователя. Похоже, что основная логика работы с guardian сосредоточена в контроллерах.

Например, контроллер категорий использует ensure_can_create_category, который, как я полагаю, автоматически создается в lib/guardian.rb.

Однако пока я не использую guardian, так как у меня возникают трудности с правильным его инициализированием. В моем контроллере у меня есть следующее:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L54-L75

А вот спецификации, которые его тестируют:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L154-L181