FIX: properly handle invalid from header
This commit is contained in:
parent
5c3d14b421
commit
54262cc9b2
|
@ -31,6 +31,7 @@ module Email
|
||||||
end
|
end
|
||||||
|
|
||||||
def process
|
def process
|
||||||
|
@from_email, @from_display_name = parse_from_field
|
||||||
@incoming_email = find_or_create_incoming_email
|
@incoming_email = find_or_create_incoming_email
|
||||||
process_internal
|
process_internal
|
||||||
rescue => e
|
rescue => e
|
||||||
|
@ -42,14 +43,14 @@ module Email
|
||||||
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |incoming_email|
|
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |incoming_email|
|
||||||
incoming_email.raw = @raw_email
|
incoming_email.raw = @raw_email
|
||||||
incoming_email.subject = subject
|
incoming_email.subject = subject
|
||||||
incoming_email.from_address = @mail.from.first.downcase
|
incoming_email.from_address = @from_email
|
||||||
incoming_email.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
|
incoming_email.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
|
||||||
incoming_email.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
|
incoming_email.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_internal
|
def process_internal
|
||||||
user = find_or_create_user(from)
|
user = find_or_create_user(@from_email, @from_display_name)
|
||||||
@incoming_email.update_columns(user_id: user.id)
|
@incoming_email.update_columns(user_id: user.id)
|
||||||
body = select_body || ""
|
body = select_body || ""
|
||||||
|
|
||||||
|
@ -150,25 +151,29 @@ module Email
|
||||||
reply.split(previous_replies_regex)[0]
|
reply.split(previous_replies_regex)[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
def from
|
def parse_from_field
|
||||||
@from ||= @mail[:from].address_list.addresses.first
|
if @mail[:from].errors.blank?
|
||||||
|
address_field = @mail[:from].address_list.addresses.first
|
||||||
|
address_field.decoded
|
||||||
|
from_address = address_field.address
|
||||||
|
from_display_name = address_field.display_name.try(:to_s)
|
||||||
|
else
|
||||||
|
from_address = @mail.from[/<([^>]+)>/, 1]
|
||||||
|
from_display_name = @mail.from[/^([^<]+)/, 1]
|
||||||
|
end
|
||||||
|
[from_address.downcase, from_display_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def subject
|
def subject
|
||||||
@suject ||= @mail.subject.presence || I18n.t("emails.incoming.default_subject", email: @mail.from.first.downcase)
|
@suject ||= @mail.subject.presence || I18n.t("emails.incoming.default_subject", email: @from_email)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_or_create_user(address_field)
|
def find_or_create_user(email, display_name)
|
||||||
# decode the address field
|
username = UserNameSuggester.sanitize_username(display_name) if display_name.present?
|
||||||
address_field.decoded
|
|
||||||
# extract email and name
|
|
||||||
email = address_field.address.downcase
|
|
||||||
name = address_field.display_name.try(:to_s)
|
|
||||||
username = UserNameSuggester.sanitize_username(name) if name.present?
|
|
||||||
|
|
||||||
User.find_or_create_by(email: email) do |user|
|
User.find_or_create_by(email: email) do |user|
|
||||||
user.username = UserNameSuggester.suggest(username.presence || email)
|
user.username = UserNameSuggester.suggest(username.presence || email)
|
||||||
user.name = name.presence || User.suggest_name(email)
|
user.name = display_name.presence || User.suggest_name(email)
|
||||||
user.staged = true
|
user.staged = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -336,9 +341,11 @@ module Email
|
||||||
if @mail[d] && @mail[d].address_list && @mail[d].address_list.addresses
|
if @mail[d] && @mail[d].address_list && @mail[d].address_list.addresses
|
||||||
@mail[d].address_list.addresses.each do |address_field|
|
@mail[d].address_list.addresses.each do |address_field|
|
||||||
begin
|
begin
|
||||||
|
address_field.decoded
|
||||||
email = address_field.address.downcase
|
email = address_field.address.downcase
|
||||||
|
display_name = address_field.display_name.try(:to_s)
|
||||||
if should_invite?(email)
|
if should_invite?(email)
|
||||||
user = find_or_create_user(address_field)
|
user = find_or_create_user(email, display_name)
|
||||||
if can_invite?(topic, user)
|
if can_invite?(topic, user)
|
||||||
topic.topic_allowed_users.create!(user_id: user.id)
|
topic.topic_allowed_users.create!(user_id: user.id)
|
||||||
topic.add_small_action(sender, "invited_user", user.username)
|
topic.add_small_action(sender, "invited_user", user.username)
|
||||||
|
|
|
@ -131,6 +131,11 @@ describe Email::Receiver do
|
||||||
expect(topic.posts.last.raw).to eq("Do you like liquorice?\n\nI really like them. One could even say that I am *addicted* to liquorice. Anf if\nyou can mix it up with some anise, then I'm in heaven ;)")
|
expect(topic.posts.last.raw).to eq("Do you like liquorice?\n\nI really like them. One could even say that I am *addicted* to liquorice. Anf if\nyou can mix it up with some anise, then I'm in heaven ;)")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "handles invalid from header" do
|
||||||
|
expect { process(:invalid_from) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This email was sent with an invalid from header field.")
|
||||||
|
end
|
||||||
|
|
||||||
describe 'Unsubscribing via email' do
|
describe 'Unsubscribing via email' do
|
||||||
let(:last_email) { ActionMailer::Base.deliveries.last }
|
let(:last_email) { ActionMailer::Base.deliveries.last }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar [THIS IS INVALID] <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <41@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
This email was sent with an invalid from header field.
|
Loading…
Reference in New Issue