Improve email address parsing

If you enter the following RFC 2822 compliant address:
`John Doe <john@doe.com>`

Gitlab will attempt to send three emails:
1) John
2) Doe
3) john@doe.com

With this change given the following:
`John Doe <johndoe@example.com>`
`Jane Doe <janedoe@example.com>`

Gitlab will send emails to `johndoe@example.com` and `janedoe@example.com`
This commit is contained in:
George Thomas 2018-07-12 14:30:36 +05:30
parent 7f0431dd85
commit 32401535b9
No known key found for this signature in database
GPG Key ID: A2F9815E085D444D
4 changed files with 62 additions and 14 deletions

View File

@ -51,7 +51,7 @@ class EmailsOnPushWorker
end end
end end
recipients.split.each do |recipient| valid_recipients(recipients).each do |recipient|
begin begin
send_email( send_email(
recipient, recipient,
@ -89,4 +89,10 @@ class EmailsOnPushWorker
email.header[:skip_premailer] = true if skip_premailer email.header[:skip_premailer] = true if skip_premailer
email.deliver_now email.deliver_now
end end
def valid_recipients(recipients)
recipients.split.select do |recipient|
recipient.include?('@')
end
end
end end

View File

@ -0,0 +1,5 @@
---
title: Emails on push recipients now accepts formats like John Doe <johndoe@example.com>
merge_request:
author: George Thomas
type: added

View File

@ -6,7 +6,7 @@ every change that is pushed to your project.
Navigate to the [Integrations page](project_services.md#accessing-the-project-services) Navigate to the [Integrations page](project_services.md#accessing-the-project-services)
and select the **Emails on push** service to configure it. and select the **Emails on push** service to configure it.
In the _Recipients_ area, provide a list of emails separated by commas. In the _Recipients_ area, provide a list of emails separated by spaces or newlines.
You can configure any of the following settings depending on your preference. You can configure any of the following settings depending on your preference.

View File

@ -100,10 +100,6 @@ describe EmailsOnPushWorker, :mailer do
end end
context "when there are multiple recipients" do context "when there are multiple recipients" do
let(:recipients) do
1.upto(5).map { |i| user.email.sub('@', "+#{i}@") }.join("\n")
end
before do before do
# This is a hack because we modify the mail object before sending, for efficency, # This is a hack because we modify the mail object before sending, for efficency,
# but the TestMailer adapter just appends the objects to an array. To clone a mail # but the TestMailer adapter just appends the objects to an array. To clone a mail
@ -114,16 +110,57 @@ describe EmailsOnPushWorker, :mailer do
end end
end end
it "sends the mail to each of the recipients" do context "when the recipient addresses are a list of email addresses" do
perform let(:recipients) do
expect(ActionMailer::Base.deliveries.count).to eq(5) 1.upto(5).map { |i| user.email.sub('@', "+#{i}@") }.join("\n")
expect(ActionMailer::Base.deliveries.map(&:to).flatten).to contain_exactly(*recipients.split) end
it "sends the mail to each of the recipients" do
perform
expect(ActionMailer::Base.deliveries.count).to eq(5)
expect(email_recipients).to contain_exactly(*recipients.split)
end
it "only generates the mail once" do
expect(Notify).to receive(:repository_push_email).once.and_call_original
expect(Premailer::Rails::CustomizedPremailer).to receive(:new).once.and_call_original
perform
end
end end
it "only generates the mail once" do context "when the recipient addresses contains angle brackets and are separated by spaces" do
expect(Notify).to receive(:repository_push_email).once.and_call_original let(:recipients) { "John Doe <johndoe@example.com> Jane Doe <janedoe@example.com>" }
expect(Premailer::Rails::CustomizedPremailer).to receive(:new).once.and_call_original
perform it "accepts emails separated by whitespace" do
perform
expect(ActionMailer::Base.deliveries.count).to eq(2)
expect(email_recipients).to contain_exactly("johndoe@example.com", "janedoe@example.com")
end
end
context "when the recipient addresses contain a mix of emails with and without angle brackets" do
let(:recipients) { "johndoe@example.com Jane Doe <janedoe@example.com>" }
it "accepts both kind of emails" do
perform
expect(ActionMailer::Base.deliveries.count).to eq(2)
expect(email_recipients).to contain_exactly("johndoe@example.com", "janedoe@example.com")
end
end
context "when the recipient addresses contains angle brackets and are separated by newlines" do
let(:recipients) { "John Doe <johndoe@example.com>\nJane Doe <janedoe@example.com>" }
it "accepts emails separated by newlines" do
perform
expect(ActionMailer::Base.deliveries.count).to eq(2)
expect(email_recipients).to contain_exactly("johndoe@example.com", "janedoe@example.com")
end
end end
end end
end end