FIX: UploadReference order by tiebreaker for UploadSecurity (#20602)

Follow up to 4d2a95ffe6. Sometimes
due to the original UploadReference migration or other issues,
multiple UploadReference records can have the exact same
created_at date and time. To tiebreak and correct the SQL order
when this happens, we can add a secondary `id ASC` ordering
when we check for the first upload reference.
This commit is contained in:
Martin Brennan 2023-03-09 11:52:26 +10:00 committed by GitHub
parent 931eedeb66
commit 5ea89d1fcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 1 deletions

View File

@ -143,7 +143,7 @@ class UploadSecurity
LEFT JOIN posts ON upload_references.target_type = 'Post' AND upload_references.target_id = posts.id
SQL
.where("posts.deleted_at IS NULL")
.order(created_at: :asc)
.order("upload_references.created_at ASC, upload_references.id ASC")
.first
return false if first_reference.blank?
PUBLIC_UPLOAD_REFERENCE_TYPES.include?(first_reference.target_type)

View File

@ -257,6 +257,18 @@ RSpec.describe UploadSecurity do
create_secure_post_reference
expect(subject.should_be_secure?).to eq(false)
end
context "when the created_at dates for upload references are identical" do
it "orders by id as well and returns false" do
now = Time.zone.now
custom_emoji = CustomEmoji.create(name: "meme", upload: upload)
create_secure_post_reference
UploadReference.find_by(target: custom_emoji).update!(created_at: now)
UploadReference.find_by(target: post_in_secure_context).update!(created_at: now)
expect(subject.should_be_secure?).to eq(false)
end
end
end
describe "when the upload is first used for a badge" do