Feedback on the new Review Queue (2019)

If one wanted to write a plugin specific to the Review Queue (new users)
Is there a few hints you guys can provide on the getting started side of things?

End goal I want to provide a 3rd option to new users from Delete, Delete and Block I want a 3rd Custom option that will do other things.
I have looked through the getting started with plugins topic and that’s’ all well and good just looking on pointers on how to hook into the Review Queue

4 лайка

This is an interesting use case and I’d like to help you get it working.

Actions for reviewable types are returned from the build_actions method.

What I’d recommend is having your plugin open the ReviewableUser class and alias the build_actions method. In your version, get the actions from the method you aliased, then add your new action to the delete bundle.

That should work, although you might end up with some hacky looking code. I’d suggest once you get it working to post it here and we can see if we can tidy it up, and perhaps add internal APIs to help out improve it further.

8 лайков

Робин,

Сейчас я готовлю PR для плагина Discord OAuth, основная цель которого — сохранять больше информации о пользователях Discord в Discourse. Я пытаюсь использовать вашу модель ReviewableUser, чтобы сохранить функциональность автоматического одобрения.

Поскольку текущая реализация асинхронно создает проверку для новых пользователей, мне нужно проверить, была ли создана такая проверка, и удалить её.

К сожалению, я столкнулся с очень странной ошибкой Ruby и хотел бы узнать, сталкивались ли вы с ней.

Код:

  def after_create_account(user, auth)
    super
    
    data = auth[:extra_data]
    if !user.approved && data[:auto_approve]
      user.approved = true
      user.approved_by_id = Discourse.system_user.id
      if reviewable_user = ReviewableUser.find_by(target: user)
          reviewable_user.set_approved_fields!(user, Discourse.system_user)
      end
    end
  end

Как только вызывается ReviewUser.find_by, возникает исключение:

*** NameError Exception: wrong constant name #<Class:0x000056134e417870>::DiscordAuthenticator

Хотя я думал, что неплохо продвигаюсь в изучении Ruby, я не понимаю, почему это происходит.

Может быть, это проблема с путями? Я пробовал множество require, но это только усугубляет ситуацию.

Это очень похоже на аналогичные паттерны в основном коде. Буду очень благодарен за любые мысли!

Репозиторий, если нужно: discourse-plugin-discord-auth/plugin.rb at master · merefield/discourse-plugin-discord-auth · GitHub

Такая постоянная ошибка не очень информативна, верно! Думаю, это связано с движками Rails и пространствами имён. Одно быстрое решение, которое можно попробовать, — это ::ReviewableUser с двумя двоеточиями перед ним. Это указывает использовать корневое пространство имён, а не пространство внутри движка.

Этот код также выглядит несколько устаревшим для API reviewable. Он должен выглядеть примерно так:

if !user.approved && data[:auto_approve] && reviewable = ::ReviewableUser.pending.find_by(target: user)
  reviewable.perform(:approve, Discourse.system_user)
end
5 лайков

Это устранило ошибку. Я предполагаю, что из-за того, что класс не был найден ранее, он воспринимался как константа? В любом случае, проблема решена, отлично, большое спасибо! Я больше не застрял!

Причина, по которой у меня было это:

      user.approved = true
      user.approved_by_id = Discourse.system_user.id

до:

reviewable.perform(:approve, Discourse.system_user)

заключается в том, что добавление в очередь ревью выполняется асинхронно. В задаче ревью создается только если approve равно false (discourse/app/jobs/regular/create_user_reviewable.rb at 888e68a1637ca784a7bf51a6bbb524dcf7413b13 · discourse/discourse · GitHub):

    if user = User.find_by(id: args[:user_id])
      return if user.approved?

      @reviewable = ReviewableUser.needs_review!(
        target: user,
        created_by: Discourse.system_user,
        reviewable_by_moderator: true,
        payload: {
          username: user.username,
          name: user.name,
          email: user.email
        }
      )

Существует риск, что задача может выполниться после того, как вы проверили наличие записи ревью?

В результате запись ревью может казаться несуществующей, хотя задача просто ждет запуска. Затем задача выполняется и создает запись ревью, но вы упустили возможность её устранить, так как ваш код проверки уже выполнился.

Это потенциальное состояние гонки?

Установите approved в true перед проверкой наличия записи ревью, и вы решите проблему (поскольку ревью никогда не будет создано после этого, так как это зависит от этого условия).

Я столкнулся с этой проблемой при тестировании своего кода — на dev-окружении всё работало, а на production упало, так как процессы выполнялись в другом порядке.

NB: Я понимаю, что вы не писали это для поддержки такого сценария использования, но считаю важным предоставить возможность плагинам автоматически одобрять новых пользователей в особых случаях (например, как это делает плагин Discord, если пользователь является участником доверенного гильдии).

1 лайк

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

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

  • Результат аутентификации может возвращать поле, например skip_approval: true.
  • В ядре системы, если результат аутентификации содержит это поле, запись для проверки не создается; если же одобрение требуется, поля обновляются корректно.
5 лайков

Спасибо, Робин, да.

На данный момент я использовал свой обходной путь, понимая, что его нужно будет устранить до удаления прямого доступа к API.

Есть ли у команды интерес к приоритетному решению этого вопроса до удаления прямого доступа на запись user.approve?

Я считаю, что это изменение сломает текущую функцию автоматического одобрения доверенных гильдий в плагине Auth Discord Login (даже без моего только что созданного PR для этого плагина). @featheredtoast

Буду рад обновить свой PR с поддержкой этого изменения, если оно будет реализовано.

Я не вижу, чтобы мы убирали это в ближайшее время. Я не хочу полагаться на это вечно, но это должно быть достаточно на какое-то время.

3 лайка

Очередь удобна, и функция «группировка по теме» тоже полезна.

Однако, насколько я могу судить, нет возможности массового выбора и обработки постов. Каждый пост нужно обрабатывать индивидуально.

Массовый выбор и обработка сэкономили бы много времени!

45

4 лайка

Я считаю, что это было бы отличным улучшением. Если быть честным, в очереди флагов никогда не было массовых операций, так что это не регресс.

Кроме того, некоторые действия, такие как «Приостановить», выглядят немного странно при работе с несколькими строками. Чтобы это имело смысл, нужно ограничиться базовыми операциями.

8 лайков

Нашёл небольшую проблему: кто-то опубликовал сообщение в категории, требующей модерации, поэтому оно появилось в очереди на проверку. Сообщение было размещено в неверной категории, и я попытался переместить его прямо в очереди на проверку. Сами действия прошли без проблем, но категория, в которую я хочу переместить пост, требует наличия одного тега. Этот тег разрешён только для новой категории, однако пост в очереди на проверку всё ещё считается находящимся в исходной категории, где этот тег запрещён. В результате я застрял. Конечно, можно сначала одобрить пост, а потом изменить его, но кажется, что эту ситуацию стоит исправить.

5 лайков

Я знаю, что это должно быть исправлено, но URL-адреса всё ещё не добавляются в список отфильтрованных. Скорее всего, это даже не имеет особого значения, так как действие для отфильтрованных URL-адресов — «ничего не делать». Просто странно.

Просто для подтверждения: вы обновились до правильной версии? Они должны быть отфильтрованы, если не поддерживают onebox или являются внутренними.

3 лайка

Да, у меня версия v2.4.0.beta2 +66. В следующий раз, когда это произойдет, я сделаю копию сообщения.

Да, после нажатия на «Удалить пользователя» в очереди модерации email и IP-адрес были добавлены в списки блокировки, но URL-адреса — нет. Сообщение было следующим:

Хотите [услуги академического письма](https://myassignmenthelp.com/uk/academic-writing-service.html) онлайн у ведущего в мире провайдера услуг академического письма Myassignmenthelp.com. Профессиональная услуга академического письма предлагает широкий выбор для студентов по лучшей цене.
1 лайк

Насколько я помню, URL-адреса никогда не добавлялись в список отслеживаемых автоматически? Ну, я думаю, что они добавляются — я проверил свой экземпляр, и там есть куча URL-адресов :wink:

А, да, я вспомнил. На самом деле они ничего не делают, они носят лишь информационный характер.

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

Вот почему было бы неплохо добавить их в список отслеживаемых — даже если по URL не предпринимается никаких автоматических действий, это позволит нам видеть, какой спам публикуется. Имейте в виду, что модераторы могут использовать очередь на проверку, но не могут (насколько я знаю) добавлять отслеживаемые слова.

1 лайк

Небольшой фидбек по UX: было бы здорово, если бы очередь модерации запоминала мои настройки. Так как мы работаем в команде модераторов, меня лично больше всего интересуют новые флаги, и я сортирую их по «Дате создания», но эта настройка не сохраняется.

7 лайков

Это не плохая идея. К счастью, на данный момент есть обходной путь: фильтры поиска сохраняются в строке запроса (URL). Если вы добавите фильтр в закладки, вы всегда сможете вернуться к нему.

4 лайка