Преглед на файлове

Send multiple emails for multiple recipients

- One email per recipient doesn't leak user emails and doesn't require
BCC.
- The message creation function now only accepts single string recipient
address ("To" field).
- Issue comment and mention notification functions, which were the only
places where multiple recipients show up, loop through recipient
addresses and create one message per address.
Achilleas Koutsou преди 6 години
родител
ревизия
bdb0eb0590
променени са 2 файла, в които са добавени 24 реда и са изтрити 15 реда
  1. 21 12
      pkg/mailer/mail.go
  2. 3 3
      pkg/mailer/mailer.go

+ 21 - 12
pkg/mailer/mail.go

@@ -52,7 +52,7 @@ func InitMailRender(dir, appendDir string, funcMap []template.FuncMap) {
 }
 
 func SendTestMail(email string) error {
-	return gomail.Send(&Sender{}, NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
+	return gomail.Send(&Sender{}, NewMessage(email, "Gogs Test Email!", "Gogs Test Email!").Message)
 }
 
 /*
@@ -95,7 +95,7 @@ func SendUserMail(c *macaron.Context, u User, tpl, code, subject, info string) {
 		return
 	}
 
-	msg := NewMessage([]string{u.Email()}, subject, body)
+	msg := NewMessage(u.Email(), subject, body)
 	msg.Info = fmt.Sprintf("UID: %d, %s", u.ID(), info)
 
 	Send(msg)
@@ -127,7 +127,7 @@ func SendActivateEmailMail(c *macaron.Context, u User, email string) {
 		return
 	}
 
-	msg := NewMessage([]string{email}, c.Tr("mail.activate_email"), body)
+	msg := NewMessage(email, c.Tr("mail.activate_email"), body)
 	msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID())
 
 	Send(msg)
@@ -144,7 +144,7 @@ func SendRegisterNotifyMail(c *macaron.Context, u User) {
 		return
 	}
 
-	msg := NewMessage([]string{u.Email()}, c.Tr("mail.register_notify"), body)
+	msg := NewMessage(u.Email(), c.Tr("mail.register_notify"), body)
 	msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID())
 
 	Send(msg)
@@ -165,7 +165,7 @@ func SendCollaboratorMail(u, doer User, repo Repository) {
 		return
 	}
 
-	msg := NewMessage([]string{u.Email()}, subject, body)
+	msg := NewMessage(u.Email(), subject, body)
 	msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID())
 
 	Send(msg)
@@ -179,7 +179,7 @@ func composeTplData(subject, body, link string) map[string]interface{} {
 	return data
 }
 
-func composeIssueMessage(issue Issue, repo Repository, doer User, tplName string, tos []string, info string) *Message {
+func composeIssueMessages(issue Issue, repo Repository, doer User, tplName string, tos []string, info string) []*Message {
 	subject := issue.MailSubject()
 	body := string(markup.Markdown([]byte(issue.Content()), repo.HTMLURL(), repo.ComposeMetas()))
 	data := composeTplData(subject, body, issue.HTMLURL())
@@ -189,9 +189,13 @@ func composeIssueMessage(issue Issue, repo Repository, doer User, tplName string
 		log.Error(3, "HTMLString (%s): %v", tplName, err)
 	}
 	from := gomail.NewMessage().FormatAddress(setting.MailService.FromEmail, doer.DisplayName())
-	msg := NewMessageFrom(tos, from, subject, content)
-	msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
-	return msg
+	msgs := make([]*Message, len(tos))
+	for idx, to := range tos {
+		msg := NewMessageFrom(to, from, subject, content)
+		msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
+		msgs[idx] = msg
+	}
+	return msgs
 }
 
 // SendIssueCommentMail composes and sends issue comment emails to target receivers.
@@ -199,8 +203,10 @@ func SendIssueCommentMail(issue Issue, repo Repository, doer User, tos []string)
 	if len(tos) == 0 {
 		return
 	}
-
-	Send(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_COMMENT, tos, "issue comment"))
+	msgs := composeIssueMessages(issue, repo, doer, MAIL_ISSUE_COMMENT, tos, "issue comment")
+	for _, msg := range msgs {
+		Send(msg)
+	}
 }
 
 // SendIssueMentionMail composes and sends issue mention emails to target receivers.
@@ -208,5 +214,8 @@ func SendIssueMentionMail(issue Issue, repo Repository, doer User, tos []string)
 	if len(tos) == 0 {
 		return
 	}
-	Send(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_MENTION, tos, "issue mention"))
+	msgs := composeIssueMessages(issue, repo, doer, MAIL_ISSUE_MENTION, tos, "issue mention")
+	for _, msg := range msgs {
+		Send(msg)
+	}
 }

+ 3 - 3
pkg/mailer/mailer.go

@@ -28,12 +28,12 @@ type Message struct {
 }
 
 // NewMessageFrom creates new mail message object with custom From header.
-func NewMessageFrom(to []string, from, subject, htmlBody string) *Message {
+func NewMessageFrom(to string, from, subject, htmlBody string) *Message {
 	log.Trace("NewMessageFrom (htmlBody):\n%s", htmlBody)
 
 	msg := gomail.NewMessage()
 	msg.SetHeader("From", from)
-	msg.SetHeader("To", to...)
+	msg.SetHeader("To", to)
 	msg.SetHeader("Subject", setting.MailService.SubjectPrefix+subject)
 	msg.SetDateHeader("Date", time.Now())
 
@@ -64,7 +64,7 @@ func NewMessageFrom(to []string, from, subject, htmlBody string) *Message {
 }
 
 // NewMessage creates new mail message object with default From header.
-func NewMessage(to []string, subject, body string) *Message {
+func NewMessage(to string, subject, body string) *Message {
 	return NewMessageFrom(to, setting.MailService.From, subject, body)
 }