運用している公開サイトで絵文字が壊れるのを目にしました。ACLはプライベートに設定されており、access control post dictates security | source: post creator という理由でセキュアとしてマークされています。
uploads:secure_upload_analyse_and_update タスクを実行すると問題は解決しますが、数日後に再び発生します。サイトのロゴでも一度同様のことが発生しましたが、その後は発生していません。
運用している公開サイトで絵文字が壊れるのを目にしました。ACLはプライベートに設定されており、access control post dictates security | source: post creator という理由でセキュアとしてマークされています。
uploads:secure_upload_analyse_and_update タスクを実行すると問題は解決しますが、数日後に再び発生します。サイトのロゴでも一度同様のことが発生しましたが、その後は発生していません。
@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")
最初のクエリでは Post が target_type として表示され、2番目のクエリでは CustomEmoji が target_type として表示されるはずです。
また発生し始めました。毎回同じ絵文字のようです。
上記の投稿で@martinが共有したクエリを実行できますか?
結果を見ると、実際には正反対の結果になっています(最初は CustomEmoji が返され、2番目は Post が返されます)。
興味深いですね。それでは正しいものが返ってきます。リンクされたアップロードについて、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
そして、どのようなレコードが返されるか確認してください。
アクセス制御 post はセキュリティを規定します | source: post creator というメッセージが Wed, 22 Mar 2023 09:13:10.341411000 UTC +00:00 の日付とともに表示されました。
これは、3年以上前に作成され、一度も編集されていないプライベートカテゴリの投稿に対するコントロールポストIDを返しました。
興味深いですね。その投稿でカスタム絵文字は使用されていましたか? 上記のアップロード参照コードをそのアップロードIDで実行すると、何が返されますか? アップロードレコードでこれを実行し、結果を投稿していただけると参考になります。
UploadSecurity.new(upload).should_be_secure_with_reason
その投稿で使用されていました
クエリは以下を返しました。
#<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
>
target_id は、絵文字がまったく含まれていない投稿を指しています。
Upload security は [true, "access control post dictates security"] を返します。
これは本当に予期せぬことです。これを実行すると、UploadReference を介して投稿にリンクされているすべてのアップロードを取得できるはずです。
UploadReference.where(
target_type: "Post",
target_id: 37246,
)
投稿に参照があるにもかかわらず、UIにアップロードが表示されない場合は、移行の問題があったのかもしれません。
IDを間違って入力していたことが判明しました ![]()
はい、絵文字が含まれていますが、親トピックは削除されました。
ええ、問題ありません。では、正しいアップロードでこれを再度実行すると、どうなりますか?
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
もし本当に必要なら、CustomEmojiのUploadReferenceレコードのcreated_atの日時を、そのアップロードの他のUploadReferenceレコードのいずれかよりも前のものに設定することもできますが、それは本来必要ないはずです。
明確にすべきでした。アップロードIDは正しかったのですが、投稿IDが間違っていました(そのため、絵文字が含まれていない投稿になってしまいました。ここに貼り付けたものは正しかったのですが、見つけようとしているときに間違って入力してしまいました)。
他のすべてのコマンドは同じものを返します。
もしそうであれば、日付に関して奇妙な点がある可能性があり、それは自動移行によって引き起こされた可能性があります。これを実行してください。
CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC, id ASC")
target_type: "CustomEmoji" を示す UploadReference レコードを見つけてから、以下を実行してください。
UploadReference.find(ID).update!(created_at: UploadReference.find(752).created_at - 1.day))
その後、問題のあるアップロードに対してこれを実行してください。
upload.update_secure_status
これで解決するはずです…これは主に、この移行以降の古いアップロードの問題だと思います。もう1つの方法として、カスタム絵文字を削除し、再アップロードしてから以下を実行することもできます。
Jobs.enqueue(:rebake_custom_emoji_posts, name: EMOJI_NAME)
日付の更新の方が簡単でしょう。この件でご迷惑をおかけしました!
今のところ、絵文字はもう安全ではありません ![]()
数日後に実際に機能したかどうか分かるでしょう。
この件は解決しましたでしょうか?
まだ何も壊れていません