From 397a1dda9ce51635dc55ffe4bd38f072f01922aa Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Tue, 4 Apr 2023 18:46:11 +0800 Subject: [PATCH] fix: send email queue to cc --- pkg/apis/notify/emailqueue.go | 6 ++++ pkg/mcclient/options/notify/emailqueues.go | 4 +++ pkg/notify/models/emailqueue.go | 36 ++++++++++++++++--- pkg/notify/sender/email.go | 40 ++++++++++++++++++++-- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/pkg/apis/notify/emailqueue.go b/pkg/apis/notify/emailqueue.go index 3318e0a3a9..40c8e8c5d5 100644 --- a/pkg/apis/notify/emailqueue.go +++ b/pkg/apis/notify/emailqueue.go @@ -24,6 +24,8 @@ import ( type SEmailMessage struct { To []string `json:"to"` + Cc []string `json:"cc"` + Bcc []string `json:"bcc"` Subject string `json:"subject"` Body string `json:"body"` @@ -52,6 +54,10 @@ type EmailQueueCreateInput struct { // swagger: ignore Dest string `json:"dest"` // swagger: ignore + DestCc string `json:"dest_cc"` + // swagger: ignore + DestBcc string `json:"dest_bcc"` + // swagger: ignore Content jsonutils.JSONObject `json:"content"` // swagger: ignore diff --git a/pkg/mcclient/options/notify/emailqueues.go b/pkg/mcclient/options/notify/emailqueues.go index 4d8f0cfa47..017361a2a4 100644 --- a/pkg/mcclient/options/notify/emailqueues.go +++ b/pkg/mcclient/options/notify/emailqueues.go @@ -44,6 +44,8 @@ type EmailQueueCreateOptions struct { SUBJECT string `help:"email subject"` BODY string `help:"email body"` TO []string `json:"to" help:"receiver email"` + Cc []string `json:"cc" help:"cc receivers"` + Bcc []string `json:"bcc" help:"bcc receivers"` SessionId string `help:"session id of sending email"` @@ -53,6 +55,8 @@ type EmailQueueCreateOptions struct { func (rc *EmailQueueCreateOptions) Params() (jsonutils.JSONObject, error) { input := api.EmailQueueCreateInput{} input.To = rc.TO + input.Cc = rc.Cc + input.Bcc = rc.Bcc input.Subject = rc.SUBJECT body, err := ioutil.ReadFile(rc.BODY) if err != nil { diff --git a/pkg/notify/models/emailqueue.go b/pkg/notify/models/emailqueue.go index 5f4292e29a..c54c8492d8 100644 --- a/pkg/notify/models/emailqueue.go +++ b/pkg/notify/models/emailqueue.go @@ -34,6 +34,10 @@ import ( "yunion.io/x/onecloud/pkg/util/stringutils2" ) +const ( + maxEmailDestCount = 256 +) + type SEmailQueueManager struct { db.SLogBaseManager } @@ -45,6 +49,8 @@ type SEmailQueue struct { Dest string `width:"256" charset:"ascii" nullable:"false" list:"user" create:"admin_required"` Subject string `width:"256" charset:"utf8" nullable:"false" list:"user" create:"admin_required"` + DestCc string `width:"256" charset:"ascii" nullable:"false" list:"user" create:"admin_optional"` + DestBcc string `width:"256" charset:"ascii" nullable:"false" list:"user" create:"admin_optional"` SessionId string `width:"256" charset:"utf8" nullable:"false" list:"user" create:"admin_optional"` @@ -92,15 +98,33 @@ func (manager *SEmailQueueManager) ValidateCreateData( return input, errors.Wrap(httperrors.ErrInputParameter, "empty receiver") } invalidTos := make([]string, 0) - for _, to := range input.To { - if !regutils.MatchEmail(to) { - invalidTos = append(invalidTos, to) + for _, tos := range [][]string{ + input.To, + input.Cc, + input.Bcc, + } { + for _, to := range tos { + if !regutils.MatchEmail(to) { + invalidTos = append(invalidTos, to) + } } } + if len(invalidTos) > 0 { return input, errors.Wrapf(httperrors.ErrInputParameter, "invalid email %s", strings.Join(invalidTos, ",")) } input.Dest = strings.Join(input.To, ",") + input.DestCc = strings.Join(input.Cc, ",") + input.DestBcc = strings.Join(input.Bcc, ",") + if len(input.Dest) > maxEmailDestCount { + return input, errors.Wrap(httperrors.ErrInputParameter, "too many tos") + } + if len(input.DestCc) > maxEmailDestCount { + return input, errors.Wrap(httperrors.ErrInputParameter, "too many ccs") + } + if len(input.DestBcc) > maxEmailDestCount { + return input, errors.Wrap(httperrors.ErrInputParameter, "too many bccs") + } msg := api.SEmailMessage{ Body: input.Body, Attachments: input.Attachments, @@ -153,7 +177,7 @@ func (eq *SEmailQueue) doSend(ctx context.Context) { } eq.setStatus(ctx, api.EmailSending, nil) driver := GetDriver(api.EMAIL) - driver.Send(api.SendParams{ + err = driver.Send(api.SendParams{ EmailMsg: msg, }) if err != nil { @@ -169,7 +193,11 @@ func (eq *SEmailQueue) getMessage() (*api.SEmailMessage, error) { if err != nil { return nil, errors.Wrap(err, "Unmarshal") } + msg.To = strings.Split(eq.Dest, ",") + msg.Cc = strings.Split(eq.DestCc, ",") + msg.Bcc = strings.Split(eq.DestBcc, ",") + msg.Subject = eq.Subject return &msg, nil } diff --git a/pkg/notify/sender/email.go b/pkg/notify/sender/email.go index 6915242ba5..dd45bf894a 100644 --- a/pkg/notify/sender/email.go +++ b/pkg/notify/sender/email.go @@ -22,6 +22,7 @@ import ( "mime" "net/http" "net/url" + "strings" "time" gomail "gopkg.in/mail.v2" @@ -75,7 +76,23 @@ func (emailSender *SEmailSender) Send(args api.SendParams) error { return errors.Wrap(err, "dialer.Dial") } retErr := errorMap{} - for _, to := range args.EmailMsg.To { + + destMap := make(map[string]int) + + for _, tos := range [][]string{ + args.EmailMsg.To, + args.EmailMsg.Cc, + args.EmailMsg.Bcc, + } { + for _, to := range tos { + to = strings.ToLower(to) + if _, ok := destMap[to]; !ok { + destMap[to] = 1 + } + } + } + + for to := range destMap { gmsg := gomail.NewMessage() gmsg.SetHeader("From", models.ConfigMap[api.EMAIL].Content.SenderAddress) gmsg.SetHeader("To", to) @@ -126,6 +143,7 @@ func (emailSender *SEmailSender) Send(args api.SendParams) error { } if len(retErr) > 0 { log.Errorf("send email error:%v", jsonutils.Marshal(retErr)) + return errors.Wrap(retErr, "send email") } } else { // 构造email发送请求 @@ -220,6 +238,7 @@ func init() { }) } +/* func SendEmail(conf *api.SEmailConfig, msg *api.SEmailMessage) error { dialer := gomail.NewDialer(conf.Hostname, conf.Hostport, conf.Username, conf.Password) @@ -239,10 +258,26 @@ func SendEmail(conf *api.SEmailConfig, msg *api.SEmailMessage) error { retErr := errorMap{} - for _, to := range msg.To { + destMap := make(map[string]int) + for _, tos := range [][]string{ + msg.To, + msg.Cc, + msg.Bcc, + } { + for _, to := range tos { + to = strings.ToLower(to) + if _, ok := destMap[to]; !ok { + destMap[to] = 1 + } + } + } + + for to := range destMap { + log.Debugf("send to %s %s", to, msg.Subject) gmsg := gomail.NewMessage() gmsg.SetHeader("From", conf.SenderAddress) gmsg.SetHeader("To", to) + gmsg.SetHeader("Subject", msg.Subject) gmsg.SetBody("text/html", msg.Body) @@ -289,3 +324,4 @@ func SendEmail(conf *api.SEmailConfig, msg *api.SEmailMessage) error { } return nil } +*/