Эмодзи помечены как безопасные

Я замечаю, что на публичном сайте, который я администрирую, эмодзи отображаются некорректно. ACL установлен как приватный и помечен как безопасный с причиной «политика контроля доступа определяет безопасность | источник: создатель публикации».

Запуск задачи uploads:secure_upload_analyse_and_update исправляет проблему, но через несколько дней она возникает снова. Это также однажды произошло с логотипом сайта, но больше не повторялось.

3 лайка

Привет, @Wolftallemo, это довольно сложная проблема, когда кастомные эмодзи (или любые публично доступные загрузки, которые могут использоваться в постах) комбинируются с защищёнными загрузками. Некоторое время назад мы начали использовать таблицу UploadReference, чтобы отслеживать связи между сущностями и загрузками. Однако при миграции на эту таблицу мы установили одинаковые значения для всех полей created_at. Это привело к тому, что при проверке того, является ли первое использование загрузки публичным (в целях безопасности), порядок иногда оказывается неверным, и мы используем не ту запись. Дело в том, что если у обеих записей одинаковое значение created_at, PostgreSQL действует по своему усмотрению:

Ваше упоминание этого заставило меня ещё раз пересмотреть ситуацию, и я думаю, что мы можем решить это лучше, сортируя сначала по created_at ASC, а затем по id ASC. Таким образом, даже при наличии таких конфликтов будет использоваться действительно первая запись.

Если после объединения этого изменения (я постараюсь сделать это сегодня) проблемы сохранятся и вы уже загрузили свой сайт, мы сможем обсудить дополнительные варианты. Однако я подозреваю, что именно в этом ваша проблема. Вы можете подтвердить это, выполнив следующие запросы и сравнив результаты на своём сайте:

CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC")

CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC, id ASC")

В первом случае target_type должен быть Post, во втором — CustomEmoji.

4 лайка

Опять началось, и, кажется, каждый раз это один и тот же эмодзи.

2 лайка

Можешь выполнить запросы, которые @martin опубликовал в сообщении выше?

2 лайка

Судя по результатам, я получаю ровно наоборот: первый возвращает CustomEmoji, а второй — Post

2 лайка

Интересно, значит, возвращается правильный результат. Для загруженного файла, который вы прислали по ссылке, пожалуйста, опубликуйте значения security_last_changed_reason и security_last_changed_at, а также проверьте, заполнено ли поле access_control_post_id. Оно не должно помечать эту загрузку как защищённую, если первое упоминание — это пользовательский эмодзи. Попробуйте также следующее:

Upload.find(ID)
  .upload_references
  .joins(<<~SQL)
    LEFT JOIN posts ON upload_references.target_type = 'Post' AND upload_references.target_id = posts.id
  SQL
  .where("posts.deleted_at IS NULL")
  .order("upload_references.created_at ASC, upload_references.id ASC")
  .first

И посмотрите, какую запись он вернёт.

1 лайк

Я получил access control post dictates security | source: post creator с датой Wed, 22 Mar 2023 09:13:10.341411000 UTC +00:00

Мне был предоставлен идентификатор контрольного поста для публикации в закрытой категории, которая была создана более трёх лет назад и никогда не редактировалась.

2 лайка

Интересно, а в том посте использовался пользовательский эмодзи? Что возвращается, если запустить приведённый выше код для загрузки с этим ID загрузки? Также было бы полезно запустить это с записью о загрузке и вывести результат:

UploadSecurity.new(upload).should_be_secure_with_reason
1 лайк

Это было использовано в том посте

Запрос вернул следующее:

=> #<UploadReference:0x0000ffffa6846100
 id: 752,
 upload_id: 236,
 target_type: "Post",
 target_id: 37246,
 created_at: Mon, 25 Nov 2019 22:24:50.002473000 UTC +00:00,
 updated_at: Sun, 29 May 2022 08:13:24.844072000 UTC +00:00>

Идентификатор цели указывает на пост, в котором вообще нет эмодзи.

Проверка безопасности загрузки возвращает [true, "access control post dictates security"]

2 лайка

Это действительно неожиданно. Запуск этого запроса должен вернуть все загрузки, связанные с постом через UploadReference:

UploadReference.where(
    target_type: "Post",
    target_id: 37246,
)

Если у поста есть ссылки, но в интерфейсе не отображаются загрузки, возможно, возникла проблема при миграции?

Оказывается, я неправильно ввёл id :facepalm:

Да, там есть эмодзи, хотя родительская тема была удалена.

1 лайк

Хе-хе, без проблем. Так что если вы запустите это снова с правильным файлом загрузки, что вы получите?

UploadSecurity.new(upload).should_be_secure_with_reason

И

upload
  .upload_references
  .joins(<<~SQL)
    LEFT JOIN posts ON upload_references.target_type = 'Post' AND upload_references.target_id = posts.id
  SQL
  .where("posts.deleted_at IS NULL")
  .order("upload_references.created_at ASC, upload_references.id ASC")
  .first

Если нам действительно это нужно, вы можете просто установить дату и время created_at для записи UploadReference CustomEmoji на время раньше, чем у любых других записей UploadReference для этой загрузки, но вам не должно приходится этого делать.

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

Все остальные команды по-прежнему возвращают то же самое.

1 лайк

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

CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC, id ASC")

Найдите запись UploadReference, у которой target_type: "CustomEmoji", затем выполните:

UploadReference.find(ID).update!(created_at: UploadReference.find(752).created_at - 1.day)

Затем выполните это для проблемной загрузки:

upload.update_secure_status

И проблема должна быть решена… Я действительно думаю, что это будет в основном проблемой для более старых загрузок после этой миграции. Ещё один вариант, который вы можете попробовать, — удалить пользовательский эмодзи, загрузить его заново, а затем выполнить:

Jobs.enqueue(:rebake_custom_emoji_posts, name: EMOJI_NAME)

Хотя обновление даты будет проще. Извините за путаницу с этим!

1 лайк

Пока что эмодзи больше не является безопасным :meow_heart:

Думаю, через несколько дней я узнаю, сработало ли это на самом деле или нет

1 лайк

Привет @Wolftallemo :slight_smile:

У тебя всё получилось?

Пока ничего не сломалось

1 лайк