diff options
Diffstat (limited to 'services/mailer/mail.go')
-rw-r--r-- | services/mailer/mail.go | 96 |
1 files changed, 42 insertions, 54 deletions
diff --git a/services/mailer/mail.go b/services/mailer/mail.go index 27767be688..7d26487a07 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -164,13 +164,7 @@ func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) { SendAsync(msg) } -func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionType models.ActionType, fromMention bool, - content string, comment *models.Comment, tos []string, info string) *Message { - - if err := issue.LoadPullRequest(); err != nil { - log.Error("LoadPullRequest: %v", err) - return nil - } +func composeIssueCommentMessages(ctx *mailCommentContext, tos []string, fromMention bool, info string) []*Message { var ( subject string @@ -182,29 +176,29 @@ func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionTy ) commentType := models.CommentTypeComment - if comment != nil { + if ctx.Comment != nil { prefix = "Re: " - commentType = comment.Type - link = issue.HTMLURL() + "#" + comment.HashTag() + commentType = ctx.Comment.Type + link = ctx.Issue.HTMLURL() + "#" + ctx.Comment.HashTag() } else { - link = issue.HTMLURL() + link = ctx.Issue.HTMLURL() } reviewType := models.ReviewTypeComment - if comment != nil && comment.Review != nil { - reviewType = comment.Review.Type + if ctx.Comment != nil && ctx.Comment.Review != nil { + reviewType = ctx.Comment.Review.Type } - fallback = prefix + fallbackMailSubject(issue) + fallback = prefix + fallbackMailSubject(ctx.Issue) // This is the body of the new issue or comment, not the mail body - body := string(markup.RenderByType(markdown.MarkupName, []byte(content), issue.Repo.HTMLURL(), issue.Repo.ComposeMetas())) + body := string(markup.RenderByType(markdown.MarkupName, []byte(ctx.Content), ctx.Issue.Repo.HTMLURL(), ctx.Issue.Repo.ComposeMetas())) - actType, actName, tplName := actionToTemplate(issue, actionType, commentType, reviewType) + actType, actName, tplName := actionToTemplate(ctx.Issue, ctx.ActionType, commentType, reviewType) - if comment != nil && comment.Review != nil { + if ctx.Comment != nil && ctx.Comment.Review != nil { reviewComments = make([]*models.Comment, 0, 10) - for _, lines := range comment.Review.CodeComments { + for _, lines := range ctx.Comment.Review.CodeComments { for _, comments := range lines { reviewComments = append(reviewComments, comments...) } @@ -215,12 +209,12 @@ func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionTy "FallbackSubject": fallback, "Body": body, "Link": link, - "Issue": issue, - "Comment": comment, - "IsPull": issue.IsPull, - "User": issue.Repo.MustOwner(), - "Repo": issue.Repo.FullName(), - "Doer": doer, + "Issue": ctx.Issue, + "Comment": ctx.Comment, + "IsPull": ctx.Issue.IsPull, + "User": ctx.Issue.Repo.MustOwner(), + "Repo": ctx.Issue.Repo.FullName(), + "Doer": ctx.Doer, "IsMention": fromMention, "SubjectPrefix": prefix, "ActionType": actType, @@ -246,18 +240,23 @@ func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionTy log.Error("ExecuteTemplate [%s]: %v", string(tplName)+"/body", err) } - msg := NewMessageFrom(tos, doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String()) - msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info) - - // Set Message-ID on first message so replies know what to reference - if comment == nil { - msg.SetHeader("Message-ID", "<"+issue.ReplyReference()+">") - } else { - msg.SetHeader("In-Reply-To", "<"+issue.ReplyReference()+">") - msg.SetHeader("References", "<"+issue.ReplyReference()+">") + // Make sure to compose independent messages to avoid leaking user emails + msgs := make([]*Message, 0, len(tos)) + for _, to := range tos { + msg := NewMessageFrom([]string{to}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String()) + msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info) + + // Set Message-ID on first message so replies know what to reference + if ctx.Comment == nil { + msg.SetHeader("Message-ID", "<"+ctx.Issue.ReplyReference()+">") + } else { + msg.SetHeader("In-Reply-To", "<"+ctx.Issue.ReplyReference()+">") + msg.SetHeader("References", "<"+ctx.Issue.ReplyReference()+">") + } + msgs = append(msgs, msg) } - return msg + return msgs } func sanitizeSubject(subject string) string { @@ -269,21 +268,15 @@ func sanitizeSubject(subject string) string { return mime.QEncoding.Encode("utf-8", string(runes)) } -// SendIssueCommentMail composes and sends issue comment emails to target receivers. -func SendIssueCommentMail(issue *models.Issue, doer *models.User, actionType models.ActionType, content string, comment *models.Comment, tos []string) { - if len(tos) == 0 { - return - } - - SendAsync(composeIssueCommentMessage(issue, doer, actionType, false, content, comment, tos, "issue comment")) -} - -// SendIssueMentionMail composes and sends issue mention emails to target receivers. -func SendIssueMentionMail(issue *models.Issue, doer *models.User, actionType models.ActionType, content string, comment *models.Comment, tos []string) { - if len(tos) == 0 { - return - } - SendAsync(composeIssueCommentMessage(issue, doer, actionType, true, content, comment, tos, "issue mention")) +// SendIssueAssignedMail composes and sends issue assigned email +func SendIssueAssignedMail(issue *models.Issue, doer *models.User, content string, comment *models.Comment, tos []string) { + SendAsyncs(composeIssueCommentMessages(&mailCommentContext{ + Issue: issue, + Doer: doer, + ActionType: models.ActionType(0), + Content: content, + Comment: comment, + }, tos, false, "issue assigned")) } // actionToTemplate returns the type and name of the action facing the user @@ -341,8 +334,3 @@ func actionToTemplate(issue *models.Issue, actionType models.ActionType, } return } - -// SendIssueAssignedMail composes and sends issue assigned email -func SendIssueAssignedMail(issue *models.Issue, doer *models.User, content string, comment *models.Comment, tos []string) { - SendAsync(composeIssueCommentMessage(issue, doer, models.ActionType(0), false, content, comment, tos, "issue assigned")) -} |