FIX: don't process the same incoming email more than once

This commit is contained in:
Régis Hanol 2017-05-18 16:43:07 +02:00
parent 13e489b4ca
commit 4fb335f1f0
2 changed files with 18 additions and 9 deletions

View File

@ -41,8 +41,9 @@ module Email
return if is_blacklisted? return if is_blacklisted?
DistributedMutex.synchronize(@message_id) do DistributedMutex.synchronize(@message_id) do
begin begin
return if IncomingEmail.exists?(message_id: @message_id)
@from_email, @from_display_name = parse_from_field(@mail) @from_email, @from_display_name = parse_from_field(@mail)
@incoming_email = find_or_create_incoming_email @incoming_email = create_incoming_email
process_internal process_internal
rescue => e rescue => e
@incoming_email.update_columns(error: e.to_s) if @incoming_email @incoming_email.update_columns(error: e.to_s) if @incoming_email
@ -56,14 +57,15 @@ module Email
Regexp.new(SiteSetting.ignore_by_title) =~ @mail.subject Regexp.new(SiteSetting.ignore_by_title) =~ @mail.subject
end end
def find_or_create_incoming_email def create_incoming_email
IncomingEmail.find_or_create_by(message_id: @message_id) do |ie| IncomingEmail.create(
ie.raw = @raw_email message_id: @message_id,
ie.subject = subject raw: @raw_email,
ie.from_address = @from_email subject: subject,
ie.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present? from_address: @from_email,
ie.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present? to_addresses: @mail.to&.map(&:downcase)&.join(";"),
end cc_addresses: @mail.cc&.map(&:downcase)&.join(";"),
)
end end
def process_internal def process_internal

View File

@ -160,6 +160,13 @@ describe Email::Receiver do
expect(topic.posts.last.raw).to eq("This is a **HTML** reply ;)") expect(topic.posts.last.raw).to eq("This is a **HTML** reply ;)")
end end
it "doesn't process email with same message-id more than once" do
expect do
process(:text_reply)
process(:text_reply)
end.to change { topic.posts.count }.by(1)
end
it "handles different encodings correctly" do it "handles different encodings correctly" do
expect { process(:hebrew_reply) }.to change { topic.posts.count } expect { process(:hebrew_reply) }.to change { topic.posts.count }
expect(topic.posts.last.raw).to eq("שלום! מה שלומך היום?") expect(topic.posts.last.raw).to eq("שלום! מה שלומך היום?")