diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-10-27 15:23:06 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2023-11-02 10:32:36 +0000 |
| commit | c5562b0d28c05b1e9499ff24bebdfd8037b2f82c (patch) | |
| tree | d35170f05837be9c0ff31492f9a4ad67efd40bb9 /dashboard/app/reporting_email.go | |
| parent | 69904c9f85fcfb289eb529599176d42bcb3609eb (diff) | |
dashboard: forward incoming commands emails
Instead of reminding users to mention our mailing lists, forward their
emails there automatically.
Closes #4260.
Diffstat (limited to 'dashboard/app/reporting_email.go')
| -rw-r--r-- | dashboard/app/reporting_email.go | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/dashboard/app/reporting_email.go b/dashboard/app/reporting_email.go index 289f5ad64..42fffb6f3 100644 --- a/dashboard/app/reporting_email.go +++ b/dashboard/app/reporting_email.go @@ -12,6 +12,7 @@ import ( "net/http" "net/mail" "regexp" + "sort" "strconv" "strings" "sync" @@ -501,9 +502,8 @@ func processIncomingEmail(c context.Context, msg *email.Email) error { // A mailing list can send us a duplicate email, to not process/reply // to such duplicate emails, we ignore emails coming from our mailing lists. fromMailingList := msg.MailingList != "" - mailingList := email.CanonicalEmail(emailConfig.Email) - mailingListInCC := checkMailingListInCC(c, msg, mailingList) - log.Infof(c, "from/cc mailing list: %v/%v", fromMailingList, mailingListInCC) + missingLists := missingMailingLists(c, msg, emailConfig) + log.Infof(c, "from/cc mailing list: %v (missing: %v)", fromMailingList, missingLists) if fromMailingList && len(msg.BugIDs) > 0 && len(msg.Commands) > 0 { // Note that if syzbot was not directly mentioned in To or Cc, this is not really // a duplicate message, so it must be processed. We detect it by looking at BugID. @@ -545,8 +545,8 @@ func processIncomingEmail(c context.Context, msg *email.Email) error { replies = append(replies, handleBugCommand(c, bugInfo, msg, nil)) } reply := groupEmailReplies(replies) - if reply == "" && len(msg.Commands) > 0 && !mailingListInCC && !unCc { - reply = warnMailingListInCC(c, msg, mailingList) + if reply == "" && len(msg.Commands) > 0 && len(missingLists) > 0 && !unCc { + return forwardEmail(c, emailConfig, msg, bugInfo, missingLists) } if reply != "" { return replyTo(c, msg, bugInfo.bugReporting.ID, reply) @@ -1205,23 +1205,51 @@ func (p *subjectTitleParser) parseFullTitle(subject string) (string, error) { return parts[len(parts)-1], nil } -func checkMailingListInCC(c context.Context, msg *email.Email, mailingList string) bool { - if msg.MailingList == mailingList { - return true +func missingMailingLists(c context.Context, msg *email.Email, emailConfig *EmailConfig) []string { + // We want to ensure that the incoming message is recorded on both our mailing list + // and the archive mailing list (in case of Linux -- linux-kernel@vger.kernel.org). + mailingLists := []string{ + email.CanonicalEmail(emailConfig.Email), } - for _, cc := range msg.Cc { - if cc == mailingList { - return true + if emailConfig.MailMaintainers { + mailingLists = append(mailingLists, emailConfig.DefaultMaintainers...) + } + // Consider all recipients. + exists := map[string]struct{}{} + if msg.MailingList != "" { + exists[msg.MailingList] = struct{}{} + } + for _, email := range msg.Cc { + exists[email] = struct{}{} + } + var missing []string + for _, list := range mailingLists { + if _, ok := exists[list]; !ok { + missing = append(missing, list) } } - msg.Cc = append(msg.Cc, mailingList) - return false + sort.Strings(missing) + msg.Cc = append(msg.Cc, missing...) + return missing } -func warnMailingListInCC(c context.Context, msg *email.Email, mailingList string) string { - return fmt.Sprintf("Your commands are accepted, but please keep %v mailing list"+ - " in CC next time. It serves as a history of what happened with each bug report."+ - " Thank you.", mailingList) +func forwardEmail(c context.Context, cfg *EmailConfig, msg *email.Email, + info *bugInfoResult, mailingLists []string) error { + log.Infof(c, "forwarding email: id=%q from=%q to=%q", msg.MessageID, msg.Author, mailingLists) + body := fmt.Sprintf(`For archival purposes, forwarding an incoming command email to +%v. + +*** + +Subject: %s +Author: %s + +%s`, strings.Join(mailingLists, ", "), msg.Subject, msg.Author, msg.Body) + from, err := email.AddAddrContext(fromAddr(c), info.bugReporting.ID) + if err != nil { + return err + } + return sendMailText(c, cfg, msg.Subject, from, mailingLists, info.bugReporting.ExtID, body) } func sendMailText(c context.Context, cfg *EmailConfig, subject, from string, to []string, replyTo, body string) error { |
