Reduce the coupling of the mailservice with the rest of the application (#16898)

* Reduce the coupling of the mailservice with the rest of the application

* Fixing tests in CI

* Simplifiying mailservice config

* Addressing PR review comments

* Fixing tests

* Removing unnecesary type definition

* Fixing ServerName usage
Этот коммит содержится в:
Jesús Espino
2021-02-16 12:42:03 +01:00
коммит произвёл GitHub
родитель 69ff686667
Коммит d06a62ce64
8 изменённых файлов: 160 добавлений и 242 удалений

Просмотреть файл

@@ -226,7 +226,8 @@ func (a *App) TestEmail(userID string, cfg *model.Config) *model.AppError {
T := utils.GetUserTranslations(user.Locale)
license := a.Srv().License()
if err := mailservice.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), cfg, license != nil && *license.Features.Compliance, ""); err != nil {
mailConfig := a.Srv().MailServiceConfig()
if err := mailservice.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), mailConfig, license != nil && *license.Features.Compliance, ""); err != nil {
return model.NewAppError("testEmail", "app.admin.test_email.failure", map[string]interface{}{"Error": err.Error()}, "", http.StatusInternalServerError)
}

Просмотреть файл

@@ -497,7 +497,8 @@ func (a *App) NotifyAndSetWarnMetricAck(warnMetricId string, sender *model.User,
subject := T("api.templates.warn_metric_ack.subject")
bodyPage.Props["Title"] = warnMetricDisplayTexts.EmailBody
if err := mailservice.SendMailUsingConfig(model.MM_SUPPORT_ADVISOR_ADDRESS, subject, bodyPage.Render(), a.Config(), false, sender.Email); err != nil {
mailConfig := a.Srv().MailServiceConfig()
if err := mailservice.SendMailUsingConfig(model.MM_SUPPORT_ADVISOR_ADDRESS, subject, bodyPage.Render(), mailConfig, false, sender.Email); err != nil {
return model.NewAppError("NotifyAndSetWarnMetricAck", "api.email.send_warn_metric_ack.failure.app_error", map[string]interface{}{"Error": err.Error()}, "", http.StatusInternalServerError)
}
}

Просмотреть файл

@@ -22,6 +22,7 @@ import (
"github.com/mattermost/mattermost-server/v5/config"
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/mailservice"
"github.com/mattermost/mattermost-server/v5/utils"
)
@@ -450,3 +451,25 @@ func (a *App) HandleMessageExportConfig(cfg *model.Config, appCfg *model.Config)
}
}
}
func (s *Server) MailServiceConfig() *mailservice.SMTPConfig {
emailSettings := s.Config().EmailSettings
hostname := utils.GetHostnameFromSiteURL(*s.Config().ServiceSettings.SiteURL)
cfg := mailservice.SMTPConfig{
Hostname: hostname,
ConnectionSecurity: *emailSettings.ConnectionSecurity,
SkipServerCertificateVerification: *emailSettings.SkipServerCertificateVerification,
ServerName: *emailSettings.SMTPServer,
Server: *emailSettings.SMTPServer,
Port: *emailSettings.SMTPPort,
ServerTimeout: *emailSettings.SMTPServerTimeout,
Username: *emailSettings.SMTPUsername,
Password: *emailSettings.SMTPPassword,
EnableSMTPAuth: *emailSettings.EnableSMTPAuth,
SendEmailNotifications: *emailSettings.SendEmailNotifications,
FeedbackName: *emailSettings.FeedbackName,
FeedbackEmail: *emailSettings.FeedbackEmail,
ReplyToAddress: *emailSettings.ReplyToAddress,
}
return &cfg
}

Просмотреть файл

@@ -558,14 +558,16 @@ func (es *EmailService) sendMail(to, subject, htmlBody string) error {
func (es *EmailService) sendMailWithCC(to, subject, htmlBody string, ccMail string) error {
license := es.srv.License()
return mailservice.SendMailUsingConfig(to, subject, htmlBody, es.srv.Config(), license != nil && *license.Features.Compliance, ccMail)
mailConfig := es.srv.MailServiceConfig()
return mailservice.SendMailUsingConfig(to, subject, htmlBody, mailConfig, license != nil && *license.Features.Compliance, ccMail)
}
func (es *EmailService) sendMailWithEmbeddedFiles(to, subject, htmlBody string, embeddedFiles map[string]io.Reader) error {
license := es.srv.License()
config := es.srv.Config()
mailConfig := es.srv.MailServiceConfig()
return mailservice.SendMailWithEmbeddedFilesUsingConfig(to, subject, htmlBody, embeddedFiles, config, license != nil && *license.Features.Compliance, "")
return mailservice.SendMailWithEmbeddedFilesUsingConfig(to, subject, htmlBody, embeddedFiles, mailConfig, license != nil && *license.Features.Compliance, "")
}
func (es *EmailService) CreateVerifyEmailToken(userID string, newEmail string) (*model.Token, *model.AppError) {

Просмотреть файл

@@ -115,7 +115,9 @@ func (s *Server) DoSecurityUpdateCheck() {
for _, user := range users {
mlog.Info("Sending security bulletin", mlog.String("bulletin_id", bulletin.Id), mlog.String("user_email", user.Email))
license := s.License()
mailservice.SendMailUsingConfig(user.Email, utils.T("mattermost.bulletin.subject"), string(body), s.Config(), license != nil && *license.Features.Compliance, "")
mailConfig := s.MailServiceConfig()
mailservice.SendMailUsingConfig(user.Email, utils.T("mattermost.bulletin.subject"), string(body), mailConfig, license != nil && *license.Features.Compliance, "")
}
bulletinSeen := &model.System{Name: "SecurityBulletin_" + bulletin.Id, Value: bulletin.Id}

Просмотреть файл

@@ -487,7 +487,9 @@ func NewServer(options ...Option) (*Server, error) {
}
s.WebSocketRouter.app = fakeApp
if nErr := mailservice.TestConnection(s.Config()); nErr != nil {
mailConfig := s.MailServiceConfig()
if nErr := mailservice.TestConnection(mailConfig); nErr != nil {
mlog.Error("Mail server connection test is failed", mlog.Err(nErr))
}

Просмотреть файл

@@ -18,11 +18,30 @@ import (
gomail "gopkg.in/mail.v2"
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/filesstore"
"github.com/mattermost/mattermost-server/v5/utils"
)
const (
TLS = "TLS"
StartTLS = "STARTTLS"
)
type SMTPConfig struct {
ConnectionSecurity string
SkipServerCertificateVerification bool
Hostname string
ServerName string
Server string
Port string
ServerTimeout int
Username string
Password string
EnableSMTPAuth bool
SendEmailNotifications bool
FeedbackName string
FeedbackEmail string
ReplyToAddress string
}
type mailData struct {
mimeTo string
smtpTo string
@@ -31,7 +50,6 @@ type mailData struct {
replyTo mail.Address
subject string
htmlBody string
attachments []*model.FileInfo
embeddedFiles map[string]io.Reader
mimeHeaders map[string]string
}
@@ -48,29 +66,17 @@ func encodeRFC2047Word(s string) string {
return mime.BEncoding.Encode("utf-8", s)
}
type SmtpConnectionInfo struct {
SmtpUsername string
SmtpPassword string
SmtpServerName string
SmtpServerHost string
SmtpPort string
SmtpServerTimeout int
SkipCertVerification bool
ConnectionSecurity string
Auth bool
}
type authChooser struct {
smtp.Auth
connectionInfo *SmtpConnectionInfo
config *SMTPConfig
}
func (a *authChooser) Start(server *smtp.ServerInfo) (string, []byte, error) {
smtpAddress := a.connectionInfo.SmtpServerName + ":" + a.connectionInfo.SmtpPort
a.Auth = LoginAuth(a.connectionInfo.SmtpUsername, a.connectionInfo.SmtpPassword, smtpAddress)
smtpAddress := a.config.ServerName + ":" + a.config.Port
a.Auth = LoginAuth(a.config.Username, a.config.Password, smtpAddress)
for _, method := range server.Auth {
if method == "PLAIN" {
a.Auth = smtp.PlainAuth("", a.connectionInfo.SmtpUsername, a.connectionInfo.SmtpPassword, a.connectionInfo.SmtpServerName+":"+a.connectionInfo.SmtpPort)
a.Auth = smtp.PlainAuth("", a.config.Username, a.config.Password, a.config.ServerName+":"+a.config.Port)
break
}
}
@@ -111,19 +117,19 @@ func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
return nil, nil
}
func ConnectToSMTPServerAdvanced(connectionInfo *SmtpConnectionInfo) (net.Conn, error) {
func ConnectToSMTPServerAdvanced(config *SMTPConfig) (net.Conn, error) {
var conn net.Conn
var err error
smtpAddress := connectionInfo.SmtpServerHost + ":" + connectionInfo.SmtpPort
smtpAddress := config.Server + ":" + config.Port
dialer := &net.Dialer{
Timeout: time.Duration(connectionInfo.SmtpServerTimeout) * time.Second,
Timeout: time.Duration(config.ServerTimeout) * time.Second,
}
if connectionInfo.ConnectionSecurity == model.CONN_SECURITY_TLS {
if config.ConnectionSecurity == TLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: connectionInfo.SkipCertVerification,
ServerName: connectionInfo.SmtpServerName,
InsecureSkipVerify: config.SkipServerCertificateVerification,
ServerName: config.ServerName,
}
conn, err = tls.DialWithDialer(dialer, "tcp", smtpAddress, tlsconfig)
@@ -140,20 +146,11 @@ func ConnectToSMTPServerAdvanced(connectionInfo *SmtpConnectionInfo) (net.Conn,
return conn, nil
}
func ConnectToSMTPServer(config *model.Config) (net.Conn, error) {
return ConnectToSMTPServerAdvanced(
&SmtpConnectionInfo{
ConnectionSecurity: *config.EmailSettings.ConnectionSecurity,
SkipCertVerification: *config.EmailSettings.SkipServerCertificateVerification,
SmtpServerName: *config.EmailSettings.SMTPServer,
SmtpServerHost: *config.EmailSettings.SMTPServer,
SmtpPort: *config.EmailSettings.SMTPPort,
SmtpServerTimeout: *config.EmailSettings.SMTPServerTimeout,
},
)
func ConnectToSMTPServer(config *SMTPConfig) (net.Conn, error) {
return ConnectToSMTPServerAdvanced(config)
}
func NewSMTPClientAdvanced(ctx context.Context, conn net.Conn, hostname string, connectionInfo *SmtpConnectionInfo) (*smtp.Client, error) {
func NewSMTPClientAdvanced(ctx context.Context, conn net.Conn, config *SMTPConfig) (*smtp.Client, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
@@ -161,7 +158,7 @@ func NewSMTPClientAdvanced(ctx context.Context, conn net.Conn, hostname string,
ec := make(chan error)
go func() {
var err error
c, err = smtp.NewClient(conn, connectionInfo.SmtpServerName+":"+connectionInfo.SmtpPort)
c, err = smtp.NewClient(conn, config.ServerName+":"+config.Port)
if err != nil {
ec <- err
return
@@ -179,50 +176,39 @@ func NewSMTPClientAdvanced(ctx context.Context, conn net.Conn, hostname string,
return nil, errors.Wrap(err, "unable to connect to the SMTP server")
}
if hostname != "" {
err := c.Hello(hostname)
if config.Hostname != "" {
err := c.Hello(config.Hostname)
if err != nil {
return nil, errors.Wrap(err, "unable to send hello message")
}
}
if connectionInfo.ConnectionSecurity == model.CONN_SECURITY_STARTTLS {
if config.ConnectionSecurity == StartTLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: connectionInfo.SkipCertVerification,
ServerName: connectionInfo.SmtpServerName,
InsecureSkipVerify: config.SkipServerCertificateVerification,
ServerName: config.ServerName,
}
c.StartTLS(tlsconfig)
}
if connectionInfo.Auth {
if err := c.Auth(&authChooser{connectionInfo: connectionInfo}); err != nil {
if config.EnableSMTPAuth {
if err := c.Auth(&authChooser{config: config}); err != nil {
return nil, errors.Wrap(err, "authentication failed")
}
}
return c, nil
}
func NewSMTPClient(ctx context.Context, conn net.Conn, config *model.Config) (*smtp.Client, error) {
func NewSMTPClient(ctx context.Context, conn net.Conn, config *SMTPConfig) (*smtp.Client, error) {
return NewSMTPClientAdvanced(
ctx,
conn,
utils.GetHostnameFromSiteURL(*config.ServiceSettings.SiteURL),
&SmtpConnectionInfo{
ConnectionSecurity: *config.EmailSettings.ConnectionSecurity,
SkipCertVerification: *config.EmailSettings.SkipServerCertificateVerification,
SmtpServerName: *config.EmailSettings.SMTPServer,
SmtpServerHost: *config.EmailSettings.SMTPServer,
SmtpPort: *config.EmailSettings.SMTPPort,
SmtpServerTimeout: *config.EmailSettings.SMTPServerTimeout,
Auth: *config.EmailSettings.EnableSMTPAuth,
SmtpUsername: *config.EmailSettings.SMTPUsername,
SmtpPassword: *config.EmailSettings.SMTPPassword,
},
config,
)
}
func TestConnection(config *model.Config) error {
if !*config.EmailSettings.SendEmailNotifications {
func TestConnection(config *SMTPConfig) error {
if !config.SendEmailNotifications {
return errors.New("SendEmailNotifications is not true")
}
@@ -232,7 +218,7 @@ func TestConnection(config *model.Config) error {
}
defer conn.Close()
sec := *config.EmailSettings.SMTPServerTimeout
sec := config.ServerTimeout
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, time.Duration(sec)*time.Second)
@@ -248,9 +234,9 @@ func TestConnection(config *model.Config) error {
return nil
}
func SendMailWithEmbeddedFilesUsingConfig(to, subject, htmlBody string, embeddedFiles map[string]io.Reader, config *model.Config, enableComplianceFeatures bool, ccMail string) error {
fromMail := mail.Address{Name: *config.EmailSettings.FeedbackName, Address: *config.EmailSettings.FeedbackEmail}
replyTo := mail.Address{Name: *config.EmailSettings.FeedbackName, Address: *config.EmailSettings.ReplyToAddress}
func SendMailWithEmbeddedFilesUsingConfig(to, subject, htmlBody string, embeddedFiles map[string]io.Reader, config *SMTPConfig, enableComplianceFeatures bool, ccMail string) error {
fromMail := mail.Address{Name: config.FeedbackName, Address: config.FeedbackEmail}
replyTo := mail.Address{Name: config.FeedbackName, Address: config.ReplyToAddress}
mail := mailData{
mimeTo: to,
@@ -266,13 +252,13 @@ func SendMailWithEmbeddedFilesUsingConfig(to, subject, htmlBody string, embedded
return sendMailUsingConfigAdvanced(mail, config, enableComplianceFeatures)
}
func SendMailUsingConfig(to, subject, htmlBody string, config *model.Config, enableComplianceFeatures bool, ccMail string) error {
func SendMailUsingConfig(to, subject, htmlBody string, config *SMTPConfig, enableComplianceFeatures bool, ccMail string) error {
return SendMailWithEmbeddedFilesUsingConfig(to, subject, htmlBody, nil, config, enableComplianceFeatures, ccMail)
}
// allows for sending an email with attachments and differing MIME/SMTP recipients
func sendMailUsingConfigAdvanced(mail mailData, config *model.Config, enableComplianceFeatures bool) error {
if *config.EmailSettings.SMTPServer == "" {
// allows for sending an email with differing MIME/SMTP recipients
func sendMailUsingConfigAdvanced(mail mailData, config *SMTPConfig, enableComplianceFeatures bool) error {
if config.Server == "" {
return nil
}
@@ -282,7 +268,7 @@ func sendMailUsingConfigAdvanced(mail mailData, config *model.Config, enableComp
}
defer conn.Close()
sec := *config.EmailSettings.SMTPServerTimeout
sec := config.ServerTimeout
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, time.Duration(sec)*time.Second)
@@ -295,15 +281,10 @@ func sendMailUsingConfigAdvanced(mail mailData, config *model.Config, enableComp
defer c.Quit()
defer c.Close()
fileBackend, nErr := filesstore.NewFileBackend(config.FileSettings.ToFileBackendSettings(enableComplianceFeatures))
if nErr != nil {
return errors.Wrap(nErr, "unable to initialize file backend")
}
return SendMail(c, mail, fileBackend, time.Now())
return SendMail(c, mail, time.Now())
}
func SendMail(c smtpClient, mail mailData, fileBackend filesstore.FileBackend, date time.Time) error {
func SendMail(c smtpClient, mail mailData, date time.Time) error {
mlog.Debug("sending mail", mlog.String("to", mail.smtpTo), mlog.String("subject", mail.subject))
htmlMessage := "\r\n<html><body>" + mail.htmlBody + "</body></html>"
@@ -345,20 +326,6 @@ func SendMail(c smtpClient, mail mailData, fileBackend filesstore.FileBackend, d
m.EmbedReader(name, reader)
}
for _, fileInfo := range mail.attachments {
bytes, nErr := fileBackend.ReadFile(fileInfo.Path)
if nErr != nil {
return errors.Wrap(err, "failed to read attachment")
}
m.Attach(fileInfo.Name, gomail.SetCopyFunc(func(writer io.Writer) error {
if _, nErr = writer.Write(bytes); nErr != nil {
return errors.Wrap(err, "failed to write attachment to email")
}
return nil
}))
}
if err = c.Mail(mail.from.Address); err != nil {
return errors.Wrap(err, "failed to set the from address")
}

Просмотреть файл

@@ -6,7 +6,6 @@ package mailservice
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"net"
@@ -19,16 +18,38 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v5/config"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/filesstore"
"github.com/mattermost/mattermost-server/v5/utils"
)
func getConfig() *SMTPConfig {
server := os.Getenv("MM_EMAILSETTINGS_SMTPSERVER")
if server == "" {
server = "localhost"
}
port := os.Getenv("MM_EMAILSETTINGS_SMTPPORT")
if port == "" {
port = "10025"
}
return &SMTPConfig{
ConnectionSecurity: "",
SkipServerCertificateVerification: false,
Hostname: "localhost",
ServerName: server,
Server: server,
Port: port,
ServerTimeout: 10,
Username: "",
Password: "",
EnableSMTPAuth: false,
SendEmailNotifications: true,
FeedbackName: "",
FeedbackEmail: "test@example.com",
ReplyToAddress: "test@example.com",
}
}
func TestMailConnectionFromConfig(t *testing.T) {
store := config.NewTestMemoryStore()
cfg := store.Get()
cfg := getConfig()
conn, err := ConnectToSMTPServer(cfg)
require.NoError(t, err, "Should connect to the SMTP Server %v", err)
@@ -37,8 +58,8 @@ func TestMailConnectionFromConfig(t *testing.T) {
require.NoError(t, err, "Should get new SMTP client")
*cfg.EmailSettings.SMTPServer = "wrongServer"
*cfg.EmailSettings.SMTPPort = "553"
cfg.Server = "wrongServer"
cfg.Port = "553"
_, err = ConnectToSMTPServer(cfg)
@@ -46,56 +67,23 @@ func TestMailConnectionFromConfig(t *testing.T) {
}
func TestMailConnectionAdvanced(t *testing.T) {
store := config.NewTestMemoryStore()
cfg := store.Get()
cfg := getConfig()
conn, err := ConnectToSMTPServerAdvanced(
&SmtpConnectionInfo{
ConnectionSecurity: *cfg.EmailSettings.ConnectionSecurity,
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
SmtpServerName: *cfg.EmailSettings.SMTPServer,
SmtpServerHost: *cfg.EmailSettings.SMTPServer,
SmtpPort: *cfg.EmailSettings.SMTPPort,
},
)
conn, err := ConnectToSMTPServerAdvanced(cfg)
require.NoError(t, err, "Should connect to the SMTP Server")
defer conn.Close()
_, err2 := NewSMTPClientAdvanced(
context.Background(),
conn,
utils.GetHostnameFromSiteURL(*cfg.ServiceSettings.SiteURL),
&SmtpConnectionInfo{
ConnectionSecurity: *cfg.EmailSettings.ConnectionSecurity,
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
SmtpServerName: *cfg.EmailSettings.SMTPServer,
SmtpServerHost: *cfg.EmailSettings.SMTPServer,
SmtpPort: *cfg.EmailSettings.SMTPPort,
Auth: *cfg.EmailSettings.EnableSMTPAuth,
SmtpUsername: *cfg.EmailSettings.SMTPUsername,
SmtpPassword: *cfg.EmailSettings.SMTPPassword,
SmtpServerTimeout: 1,
},
)
_, err2 := NewSMTPClientAdvanced(context.Background(), conn, cfg)
require.NoError(t, err2, "Should get new SMTP client")
l, err3 := net.Listen("tcp", "localhost:") // emulate nc -l <random-port>
require.NoError(t, err3, "Should've open a network socket and listen")
defer l.Close()
cfg.Server = strings.Split(l.Addr().String(), ":")[0]
cfg.Port = strings.Split(l.Addr().String(), ":")[1]
cfg.ServerTimeout = 1
connInfo := &SmtpConnectionInfo{
ConnectionSecurity: *cfg.EmailSettings.ConnectionSecurity,
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
SmtpServerName: *cfg.EmailSettings.SMTPServer,
SmtpServerHost: strings.Split(l.Addr().String(), ":")[0],
SmtpPort: strings.Split(l.Addr().String(), ":")[1],
Auth: *cfg.EmailSettings.EnableSMTPAuth,
SmtpUsername: *cfg.EmailSettings.SMTPUsername,
SmtpPassword: *cfg.EmailSettings.SMTPPassword,
SmtpServerTimeout: 1,
}
conn2, err := ConnectToSMTPServerAdvanced(connInfo)
conn2, err := ConnectToSMTPServerAdvanced(cfg)
require.NoError(t, err, "Should connect to the SMTP Server")
defer conn2.Close()
@@ -106,33 +94,20 @@ func TestMailConnectionAdvanced(t *testing.T) {
_, err4 := NewSMTPClientAdvanced(
ctx,
conn2,
utils.GetHostnameFromSiteURL(*cfg.ServiceSettings.SiteURL),
connInfo,
cfg,
)
require.Error(t, err4, "Should get a timeout get while creating a new SMTP client")
assert.Contains(t, err4.Error(), "unable to connect to the SMTP server")
_, err5 := ConnectToSMTPServerAdvanced(
&SmtpConnectionInfo{
ConnectionSecurity: *cfg.EmailSettings.ConnectionSecurity,
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
SmtpServerName: "wrongServer",
SmtpServerHost: "wrongServer",
SmtpPort: "553",
},
)
cfg.Server = "wrongServer"
cfg.Port = "553"
_, err5 := ConnectToSMTPServerAdvanced(cfg)
require.Error(t, err5, "Should not connect to the SMTP Server")
}
func TestSendMailUsingConfig(t *testing.T) {
utils.T = utils.GetUserTranslations("en")
fsInner, err := config.NewFileStore("config.json", false)
require.NoError(t, err)
fs, err := config.NewStoreFromBacking(fsInner, nil, false)
require.NoError(t, err)
cfg := fs.Get()
cfg := getConfig()
var emailTo = "test@example.com"
var emailSubject = "Testing this email"
@@ -166,14 +141,7 @@ func TestSendMailUsingConfig(t *testing.T) {
}
func TestSendMailWithEmbeddedFilesUsingConfig(t *testing.T) {
utils.T = utils.GetUserTranslations("en")
fsInner, err := config.NewFileStore("config.json", false)
require.NoError(t, err)
fs, err := config.NewStoreFromBacking(fsInner, nil, false)
require.NoError(t, err)
cfg := fs.Get()
cfg := getConfig()
var emailTo = "test@example.com"
var emailSubject = "Testing this email"
@@ -213,42 +181,23 @@ func TestSendMailWithEmbeddedFilesUsingConfig(t *testing.T) {
}
func TestSendMailUsingConfigAdvanced(t *testing.T) {
utils.T = utils.GetUserTranslations("en")
fsInner, err := config.NewFileStore("config.json", false)
require.NoError(t, err)
fs, err := config.NewStoreFromBacking(fsInner, nil, false)
require.NoError(t, err)
cfg := fs.Get()
cfg := getConfig()
//Delete all the messages before check the sample email
DeleteMailBox("test2@example.com")
fileBackend, err := filesstore.NewFileBackend(cfg.FileSettings.ToFileBackendSettings(true))
assert.NoError(t, err)
// create two files with the same name that will both be attached to the email
filePath1 := fmt.Sprintf("test1/%s", "file1.txt")
filePath2 := fmt.Sprintf("test2/%s", "file2.txt")
fileContents1 := []byte("hello world")
fileContents2 := []byte("foo bar")
_, err = fileBackend.WriteFile(bytes.NewReader(fileContents1), filePath1)
assert.NoError(t, err)
_, err = fileBackend.WriteFile(bytes.NewReader(fileContents2), filePath2)
assert.NoError(t, err)
defer fileBackend.RemoveFile(filePath1)
defer fileBackend.RemoveFile(filePath2)
file1, err := ioutil.TempFile("", "*")
require.NoError(t, err)
defer os.Remove(file1.Name())
file1.Write([]byte("hello world"))
file1.Close()
file2, err := ioutil.TempFile("", "*")
attachments := make([]*model.FileInfo, 2)
attachments[0] = &model.FileInfo{
Name: "file1.txt",
Path: filePath1,
}
attachments[1] = &model.FileInfo{
Name: "file2.txt",
Path: filePath2,
}
require.NoError(t, err)
defer os.Remove(file2.Name())
file2.Write([]byte("foo bar"))
file2.Close()
embeddedFiles := map[string]io.Reader{
"test": bytes.NewReader([]byte("test data")),
@@ -264,7 +213,6 @@ func TestSendMailUsingConfigAdvanced(t *testing.T) {
replyTo: mail.Address{Name: "ReplyTo", Address: "reply_to@mattermost.com"},
subject: "Testing this email",
htmlBody: "This is a test from autobot",
attachments: attachments,
embeddedFiles: embeddedFiles,
mimeHeaders: headers,
}
@@ -297,37 +245,16 @@ func TestSendMailUsingConfigAdvanced(t *testing.T) {
// check that the custom mime headers came through - header case seems to get mutated
assert.Equal(t, "TestValue", resultsEmail.Header["Testheader"][0])
// ensure that the attachments were successfully sent
assert.Len(t, resultsEmail.Attachments, 3)
attachmentsFilenames := []string{
resultsEmail.Attachments[0].Filename,
resultsEmail.Attachments[1].Filename,
resultsEmail.Attachments[2].Filename,
}
assert.Contains(t, attachmentsFilenames, "file1.txt")
assert.Contains(t, attachmentsFilenames, "file2.txt")
assert.Contains(t, attachmentsFilenames, "test")
attachment1 := string(resultsEmail.Attachments[0].Bytes)
attachment2 := string(resultsEmail.Attachments[1].Bytes)
attachment3 := string(resultsEmail.Attachments[2].Bytes)
attachmentsData := []string{attachment1, attachment2, attachment3}
assert.Contains(t, attachmentsData, string(fileContents1))
assert.Contains(t, attachmentsData, string(fileContents2))
assert.Contains(t, attachmentsData, "test data")
}
func TestAuthMethods(t *testing.T) {
auth := &authChooser{
connectionInfo: &SmtpConnectionInfo{
SmtpUsername: "test",
SmtpPassword: "fakepass",
SmtpServerName: "fakeserver",
SmtpServerHost: "fakeserver",
SmtpPort: "25",
config: &SMTPConfig{
Username: "test",
Password: "fakepass",
ServerName: "fakeserver",
Server: "fakeserver",
Port: "25",
},
}
tests := []struct {
@@ -394,13 +321,6 @@ func TestSendMail(t *testing.T) {
dir, err := ioutil.TempDir(".", "mail-test-")
require.NoError(t, err)
defer os.RemoveAll(dir)
settings := model.FileSettings{
DriverName: model.NewString(model.IMAGE_DRIVER_LOCAL),
Directory: &dir,
}
settings.SetDefaults(true)
mockBackend, err := filesstore.NewFileBackend(settings.ToFileBackendSettings(true))
require.NoError(t, err)
mocm := &mockMailer{}
testCases := map[string]struct {
@@ -422,8 +342,8 @@ func TestSendMail(t *testing.T) {
for testName, tc := range testCases {
t.Run(testName, func(t *testing.T) {
mail := mailData{"", "", mail.Address{}, "", tc.replyTo, "", "", nil, nil, nil}
err = SendMail(mocm, mail, mockBackend, time.Now())
mail := mailData{"", "", mail.Address{}, "", tc.replyTo, "", "", nil, nil}
err = SendMail(mocm, mail, time.Now())
require.NoError(t, err)
if tc.contains != "" {
require.Contains(t, string(mocm.data), tc.contains)