Входящие письма с подписями/таблицами/встроенными изображениями отклоняются с ошибкой «Access Denied»

Я наблюдаю, что входящие письма отклоняются Discourse с сообщением:

Email can not be processed: Access Denied

Сама доставка входящих писем, судя по всему, работает корректно. Сообщение доходит до почтового приемника, и проверки SPF, DKIM и DMARC успешно проходят. Затем Discourse обрабатывает его через Jobs::ProcessEmail.

Поведение системы, похоже, зависит от содержимого MIME/тела письма:

  • простое/текстовое письмо → принимается
  • письмо, содержащее подпись Outlook, таблицу и/или встроенные изображения → отклоняется с ошибкой Access Denied

В логе отклоненного письма показано, что сбой происходит в Email::Processor#process!.

Версия приложения Discourse:

4143157a17dc3ff63c909c64d0cf578243d38861

Эта установка недавно была перенесена/восстановлена на другой сервер, но сама SMTP-доставка входящих сообщений работает, и поведение, кажется, специфически связано с более сложным содержимым тела письма.

При необходимости могу предоставить очищенное от конфиденциальных данных сырое MIME-сообщение и дополнительные диагностические данные IncomingEmail/Email::Receiver.

Обновление: я смог воспроизвести причину ошибок Access Denied, которые я наблюдал, и открыл PR:

Ключевой момент моего первоначального наблюдения был следующим:

  • простые/обычные входящие письма → принимаются
  • более сложные письма, содержащие встроенные медиафайлы → отклоняются с ошибкой Access Denied

Отклоненные сообщения обрабатывались как сообщения пользователей со статусом «staged» (ожидает подтверждения) или «stranger» (неизвестный) в категории, которая разрешает прием входящих писем от неизвестных пользователей.

Начиная с PR #42079, NewPostManager обнаруживает встроенные медиафайлы непосредственно в содержимом поста, когда метаданные о размере изображения отсутствуют. Это корректно приводит к тому, что такие сообщения попадают в путь модерации :contains_media.

Однако перед постановкой поста в очередь на модерацию NewPostManager.default_handler выполняет стандартную проверку прав создания темы в категории через Guardian.

Для пользователя со статусом «staged», отправляющего входящее письмо, эта проверка может завершиться неудачей, даже если Email::Receiver уже принял путь для писем от неизвестных пользователей в данной категории и передал флаг skip_validations.

Это и приводит к ошибке, которую я наблюдал:

Email::Receiver::InvalidPost: Access Denied

Я добавил сквозной регрессионный тест для приемника писем, проверяющий обработку письма со встроенными медиафайлами от неизвестного пользователя.

На текущей ветке main, до применения исправления, тест воспроизводит ошибку:

Email::Receiver::InvalidPost: Access Denied

Я также протестировал тот же сценарий сразу перед PR #42079, где входящее письмо принималось, что подтверждает: это регрессия, введенная данным изменением.

Предложенный PR сохраняет intended-модерацию медиафайлов, а не обходит её. После исправления входящее письмо ставится в очередь как ReviewableQueuedPost, а причина модерации остается:

contains_media

Соответствующие тесты для Email::Receiver и NewPostManager проходят локально:

261 примера, 0 неудач

Таким образом, это объясняет поведение Access Denied, о котором я сообщал выше, включая то, почему простые письма работали, а более сложные сообщения со встроенными медиафайлами — нет.