Guardian: проверка API до и после

При создании плагинов я несколько раз сталкивался с необходимостью изменять результат проверок can_* в Guardian. В плагине ActivityPub я снова столкнулся с этой задачей:

https://github.com/discourse/discourse-activity-pub/blob/main/extensions/discourse_activity_pub_guardian_extension.rb

Я только что создал черновик PR, который добавляет новый метод API для серверных плагинов, позволяющий регистрировать проверки до и после выполнения методов can_* в Guardian, что даёт возможность изменять результат этих методов. Например:

add_guardian_check(:before, :edit_post) do |guardian, result, post|
  !post.activity_pub_remote?
end

Буду рад получить обратную связь как по подходу, так и по реализации, прежде чем публиковать это для ревью.

Ещё раз поднимаю этот вопрос для всех, кого это касается. cc @pmusaraj

Спасибо, Ангус!

Я не вижу проблем с регистром before_*. С регистром after_* всё немного сложнее. С точки зрения безопасности использование регистра after_* означает, что плагины могут переопределять ядро способами, которые могут быть небезопасными. Очевидно, что плагины могут делать это множеством различных способов, но API плагинов не должен ещё больше этому способствовать.

Кроме того, что произойдёт, если несколько плагинов используют хук after_*? Кто победит?

Да, я понимаю, что вы имеете в виду.

Проверки принимают аргумент приоритета. См. эту спецификацию:

it "respects check priority" do
  plugin.add_guardian_check(:after, :edit_post, 2) { false }
  plugin.add_guardian_check(:after, :edit_post, 0) { true }
  plugin.add_guardian_check(:after, :edit_post, 1) { false }
  expect(Guardian.new(user).can_edit_post?(post)).to be_truthy
end

Как насчёт того, чтобы ограничить этот PR только проверками before? Это решит текущие задачи и немного уменьшит количество переменных в игре.

Да, конечно, давайте начнём только с проверок before. Спасибо!