Browse Source

tech(notifications): replace internal email code

bergquist 9 năm trước cách đây
mục cha
commit
5bf5ed68e1

+ 0 - 1
pkg/models/notifications.go

@@ -8,7 +8,6 @@ type SendEmailCommand struct {
 	To           []string
 	Template     string
 	Data         map[string]interface{}
-	Massive      bool
 	Info         string
 	EmbededFiles []string
 }

+ 0 - 8
pkg/services/notifications/email.go

@@ -10,18 +10,10 @@ type Message struct {
 	From         string
 	Subject      string
 	Body         string
-	Massive      bool
 	Info         string
 	EmbededFiles []string
 }
 
-// create mail content
-func (m *Message) Content() string {
-	contentType := "text/html; charset=UTF-8"
-	content := "From: " + m.From + "\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
-	return content
-}
-
 func setDefaultTemplateData(data map[string]interface{}, u *m.User) {
 	data["AppUrl"] = setting.AppUrl
 	data["BuildVersion"] = setting.BuildVersion

+ 21 - 171
pkg/services/notifications/mailer.go

@@ -11,12 +11,8 @@ import (
 	"fmt"
 	"html/template"
 	"net"
-	"net/mail"
-	"net/smtp"
-	"os"
 	"strconv"
 	"strings"
-	"time"
 
 	"github.com/grafana/grafana/pkg/log"
 	m "github.com/grafana/grafana/pkg/models"
@@ -35,7 +31,7 @@ func processMailQueue() {
 	for {
 		select {
 		case msg := <-mailQueue:
-			num, err := buildAndSend(msg)
+			num, err := send(msg)
 			tos := strings.Join(msg.To, "; ")
 			info := ""
 			if err != nil {
@@ -54,130 +50,42 @@ var addToMailQueue = func(msg *Message) {
 	mailQueue <- msg
 }
 
-func sendToSmtpServer(recipients []string, msgContent []byte) error {
-	host, port, err := net.SplitHostPort(setting.Smtp.Host)
+func send(msg *Message) (int, error) {
+	dialer, err := createDialer()
 	if err != nil {
-		return err
-	}
-
-	tlsconfig := &tls.Config{
-		InsecureSkipVerify: setting.Smtp.SkipVerify,
-		ServerName:         host,
-	}
-
-	if setting.Smtp.CertFile != "" {
-		cert, err := tls.LoadX509KeyPair(setting.Smtp.CertFile, setting.Smtp.KeyFile)
-		if err != nil {
-			return err
-		}
-		tlsconfig.Certificates = []tls.Certificate{cert}
-	}
-
-	conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), time.Second*10)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-
-	isSecureConn := false
-	// Start TLS directly if the port ends with 465 (SMTPS protocol)
-	if strings.HasSuffix(port, "465") {
-		conn = tls.Client(conn, tlsconfig)
-		isSecureConn = true
-	}
-
-	client, err := smtp.NewClient(conn, host)
-	if err != nil {
-		return err
-	}
-
-	hostname, err := os.Hostname()
-	if err != nil {
-		return err
-	}
-
-	if err = client.Hello(hostname); err != nil {
-		return err
-	}
-
-	// If not using SMTPS, alway use STARTTLS if available
-	hasStartTLS, _ := client.Extension("STARTTLS")
-	if !isSecureConn && hasStartTLS {
-		if err = client.StartTLS(tlsconfig); err != nil {
-			return err
-		}
+		return 0, err
 	}
 
-	canAuth, options := client.Extension("AUTH")
-
-	if canAuth && len(setting.Smtp.User) > 0 {
-		var auth smtp.Auth
-
-		if strings.Contains(options, "CRAM-MD5") {
-			auth = smtp.CRAMMD5Auth(setting.Smtp.User, setting.Smtp.Password)
-		} else if strings.Contains(options, "PLAIN") {
-			auth = smtp.PlainAuth("", setting.Smtp.User, setting.Smtp.Password, host)
+	for _, address := range msg.To {
+		m := gomail.NewMessage()
+		m.SetHeader("From", msg.From)
+		m.SetHeader("To", address)
+		m.SetHeader("Subject", msg.Subject)
+		for _, file := range msg.EmbededFiles {
+			m.Embed(file)
 		}
 
-		if auth != nil {
-			if err = client.Auth(auth); err != nil {
-				return err
-			}
-		}
-	}
-
-	if fromAddress, err := mail.ParseAddress(setting.Smtp.FromAddress); err != nil {
-		return err
-	} else {
-		if err = client.Mail(fromAddress.Address); err != nil {
-			return err
-		}
-	}
+		m.SetBody("text/html", msg.Body)
 
-	for _, rec := range recipients {
-		if err = client.Rcpt(rec); err != nil {
-			return err
+		if err := dialer.DialAndSend(m); err != nil {
+			return 0, err
 		}
 	}
 
-	w, err := client.Data()
-	if err != nil {
-		return err
-	}
-	if _, err = w.Write([]byte(msgContent)); err != nil {
-		return err
-	}
-
-	if err = w.Close(); err != nil {
-		return err
-	}
-
-	return client.Quit()
+	return len(msg.To), nil
 }
 
-func buildAndSend(msg *Message) (int, error) {
-	m := gomail.NewMessage()
-	m.SetHeader("From", msg.From)
-	m.SetHeader("To", msg.To[0])
-	m.SetHeader("Subject", msg.Subject)
-	for _, file := range msg.EmbededFiles {
-		m.Embed(file)
-	}
-
-	m.SetBody("text/html", msg.Body)
-
+func createDialer() (*gomail.Dialer, error) {
 	host, port, err := net.SplitHostPort(setting.Smtp.Host)
 
 	if err != nil {
-		return 0, err
+		return nil, err
 	}
 	iPort, err := strconv.Atoi(port)
 	if err != nil {
-		return 0, err
+		return nil, err
 	}
 
-	d := gomail.NewPlainDialer(host, iPort, setting.Smtp.User, setting.Smtp.Password)
-
 	tlsconfig := &tls.Config{
 		InsecureSkipVerify: setting.Smtp.SkipVerify,
 		ServerName:         host,
@@ -186,72 +94,14 @@ func buildAndSend(msg *Message) (int, error) {
 	if setting.Smtp.CertFile != "" {
 		cert, err := tls.LoadX509KeyPair(setting.Smtp.CertFile, setting.Smtp.KeyFile)
 		if err != nil {
-			return 0, err
+			return nil, err
 		}
 		tlsconfig.Certificates = []tls.Certificate{cert}
 	}
 
+	d := gomail.NewPlainDialer(host, iPort, setting.Smtp.User, setting.Smtp.Password)
 	d.TLSConfig = tlsconfig
-	if err := d.DialAndSend(m); err != nil {
-		return 0, err
-	}
-
-	return 0, nil
-	/*
-		m := email.NewHTMLMessage(msg.Subject, msg.Body)
-		m.From = mail.Address{Name: "From", Address: "alerting@grafana.org"}
-		m.To = msg.To
-
-		log.Info2("Attaching file", "file", msg.Attachment)
-		if err := m.Attach(msg.Attachment); err != nil {
-			return 0, err
-		}
-
-		// send it
-		host, _, _ := net.SplitHostPort(setting.Smtp.Host)
-
-		auth := smtp.PlainAuth("", setting.Smtp.User, setting.Smtp.Password, host)
-		if err := email.Send(setting.Smtp.Host, auth, m); err != nil {
-			return 0, err
-		}
-
-		return 0, nil
-
-			  log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
-
-				// get message body
-				content := msg.Content()
-
-				if len(msg.To) == 0 {
-					return 0, fmt.Errorf("empty receive emails")
-				} else if len(msg.Body) == 0 {
-					return 0, fmt.Errorf("empty email body")
-				}
-
-				if msg.Massive {
-					// send mail to multiple emails one by one
-					num := 0
-					for _, to := range msg.To {
-						body := []byte("To: " + to + "\r\n" + content)
-						err := sendToSmtpServer([]string{to}, body)
-						if err != nil {
-							return num, err
-						}
-						num++
-					}
-					return num, nil
-				} else {
-					body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
-
-					// send to multiple emails in one message
-					err := sendToSmtpServer(msg.To, body)
-					if err != nil {
-						return 0, err
-					} else {
-						return 1, nil
-					}
-				}
-	*/
+	return d, nil
 }
 
 func buildEmailMessage(cmd *m.SendEmailCommand) (*Message, error) {

+ 1 - 2
pkg/services/notifications/notifications.go

@@ -90,7 +90,6 @@ func sendEmailCommandHandlerSync(ctx context.Context, cmd *m.SendEmailCommandSyn
 	message, err := buildEmailMessage(&m.SendEmailCommand{
 		Data:         cmd.Data,
 		Info:         cmd.Info,
-		Massive:      cmd.Massive,
 		Template:     cmd.Template,
 		To:           cmd.To,
 		EmbededFiles: cmd.EmbededFiles,
@@ -100,7 +99,7 @@ func sendEmailCommandHandlerSync(ctx context.Context, cmd *m.SendEmailCommandSyn
 		return err
 	}
 
-	_, err = buildAndSend(message)
+	_, err = send(message)
 
 	return err
 }