github.com/rr250/mattermost-server@v5.11.1+incompatible/services/mailservice/mail_test.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package mailservice
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"strings"
    10  	"testing"
    11  
    12  	"net/mail"
    13  	"net/smtp"
    14  
    15  	"github.com/mattermost/mattermost-server/config"
    16  	"github.com/mattermost/mattermost-server/model"
    17  	"github.com/mattermost/mattermost-server/services/filesstore"
    18  	"github.com/mattermost/mattermost-server/utils"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestMailConnectionFromConfig(t *testing.T) {
    24  	fs, err := config.NewFileStore("config.json", false)
    25  	require.Nil(t, err)
    26  
    27  	cfg := fs.Get()
    28  
    29  	if conn, err := ConnectToSMTPServer(cfg); err != nil {
    30  		t.Log(err)
    31  		t.Fatal("Should connect to the STMP Server")
    32  	} else {
    33  		if _, err1 := NewSMTPClient(conn, cfg); err1 != nil {
    34  			t.Log(err)
    35  			t.Fatal("Should get new smtp client")
    36  		}
    37  	}
    38  
    39  	*cfg.EmailSettings.SMTPServer = "wrongServer"
    40  	*cfg.EmailSettings.SMTPPort = "553"
    41  
    42  	if _, err := ConnectToSMTPServer(cfg); err == nil {
    43  		t.Log(err)
    44  		t.Fatal("Should not to the STMP Server")
    45  	}
    46  }
    47  
    48  func TestMailConnectionAdvanced(t *testing.T) {
    49  	fs, err := config.NewFileStore("config.json", false)
    50  	require.Nil(t, err)
    51  
    52  	cfg := fs.Get()
    53  
    54  	if conn, err := ConnectToSMTPServerAdvanced(
    55  		&SmtpConnectionInfo{
    56  			ConnectionSecurity:   *cfg.EmailSettings.ConnectionSecurity,
    57  			SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
    58  			SmtpServerName:       *cfg.EmailSettings.SMTPServer,
    59  			SmtpServerHost:       *cfg.EmailSettings.SMTPServer,
    60  			SmtpPort:             *cfg.EmailSettings.SMTPPort,
    61  		},
    62  	); err != nil {
    63  		t.Log(err)
    64  		t.Fatal("Should connect to the STMP Server")
    65  	} else {
    66  		if _, err1 := NewSMTPClientAdvanced(
    67  			conn,
    68  			utils.GetHostnameFromSiteURL(*cfg.ServiceSettings.SiteURL),
    69  			&SmtpConnectionInfo{
    70  				ConnectionSecurity:   *cfg.EmailSettings.ConnectionSecurity,
    71  				SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
    72  				SmtpServerName:       *cfg.EmailSettings.SMTPServer,
    73  				SmtpServerHost:       *cfg.EmailSettings.SMTPServer,
    74  				SmtpPort:             *cfg.EmailSettings.SMTPPort,
    75  				Auth:                 *cfg.EmailSettings.EnableSMTPAuth,
    76  				SmtpUsername:         *cfg.EmailSettings.SMTPUsername,
    77  				SmtpPassword:         *cfg.EmailSettings.SMTPPassword,
    78  			},
    79  		); err1 != nil {
    80  			t.Log(err)
    81  			t.Fatal("Should get new smtp client")
    82  		}
    83  	}
    84  
    85  	if _, err := ConnectToSMTPServerAdvanced(
    86  		&SmtpConnectionInfo{
    87  			ConnectionSecurity:   *cfg.EmailSettings.ConnectionSecurity,
    88  			SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
    89  			SmtpServerName:       "wrongServer",
    90  			SmtpServerHost:       "wrongServer",
    91  			SmtpPort:             "553",
    92  		},
    93  	); err == nil {
    94  		t.Log(err)
    95  		t.Fatal("Should not to the STMP Server")
    96  	}
    97  
    98  }
    99  
   100  func TestSendMailUsingConfig(t *testing.T) {
   101  	utils.T = utils.GetUserTranslations("en")
   102  
   103  	fs, err := config.NewFileStore("config.json", false)
   104  	require.Nil(t, err)
   105  
   106  	cfg := fs.Get()
   107  
   108  	var emailTo = "test@example.com"
   109  	var emailSubject = "Testing this email"
   110  	var emailBody = "This is a test from autobot"
   111  
   112  	//Delete all the messages before check the sample email
   113  	DeleteMailBox(emailTo)
   114  
   115  	if err := SendMailUsingConfig(emailTo, emailSubject, emailBody, cfg, true); err != nil {
   116  		t.Log(err)
   117  		t.Fatal("Should connect to the STMP Server")
   118  	} else {
   119  		//Check if the email was send to the right email address
   120  		var resultsMailbox JSONMessageHeaderInbucket
   121  		err := RetryInbucket(5, func() error {
   122  			var err error
   123  			resultsMailbox, err = GetMailBox(emailTo)
   124  			return err
   125  		})
   126  		if err != nil {
   127  			t.Log(err)
   128  			t.Log("No email was received, maybe due load on the server. Disabling this verification")
   129  		}
   130  		if err == nil && len(resultsMailbox) > 0 {
   131  			if !strings.ContainsAny(resultsMailbox[0].To[0], emailTo) {
   132  				t.Fatal("Wrong To recipient")
   133  			} else {
   134  				if resultsEmail, err := GetMessageFromMailbox(emailTo, resultsMailbox[0].ID); err == nil {
   135  					if !strings.Contains(resultsEmail.Body.Text, emailBody) {
   136  						t.Log(resultsEmail.Body.Text)
   137  						t.Fatal("Received message")
   138  					}
   139  				}
   140  			}
   141  		}
   142  	}
   143  }
   144  
   145  func TestSendMailUsingConfigAdvanced(t *testing.T) {
   146  	utils.T = utils.GetUserTranslations("en")
   147  
   148  	fs, err := config.NewFileStore("config.json", false)
   149  	require.Nil(t, err)
   150  
   151  	cfg := fs.Get()
   152  
   153  	var mimeTo = "test@example.com"
   154  	var smtpTo = "test2@example.com"
   155  	var from = mail.Address{Name: "Nobody", Address: "nobody@mattermost.com"}
   156  	var replyTo = mail.Address{Name: "ReplyTo", Address: "reply_to@mattermost.com"}
   157  	var emailSubject = "Testing this email"
   158  	var emailBody = "This is a test from autobot"
   159  
   160  	//Delete all the messages before check the sample email
   161  	DeleteMailBox(smtpTo)
   162  
   163  	fileBackend, err := filesstore.NewFileBackend(&cfg.FileSettings, true)
   164  	assert.Nil(t, err)
   165  
   166  	// create two files with the same name that will both be attached to the email
   167  	fileName := "file.txt"
   168  	filePath1 := fmt.Sprintf("test1/%s", fileName)
   169  	filePath2 := fmt.Sprintf("test2/%s", fileName)
   170  	fileContents1 := []byte("hello world")
   171  	fileContents2 := []byte("foo bar")
   172  	_, err = fileBackend.WriteFile(bytes.NewReader(fileContents1), filePath1)
   173  	assert.Nil(t, err)
   174  	_, err = fileBackend.WriteFile(bytes.NewReader(fileContents2), filePath2)
   175  	assert.Nil(t, err)
   176  	defer fileBackend.RemoveFile(filePath1)
   177  	defer fileBackend.RemoveFile(filePath2)
   178  
   179  	attachments := make([]*model.FileInfo, 2)
   180  	attachments[0] = &model.FileInfo{
   181  		Name: fileName,
   182  		Path: filePath1,
   183  	}
   184  	attachments[1] = &model.FileInfo{
   185  		Name: fileName,
   186  		Path: filePath2,
   187  	}
   188  
   189  	headers := make(map[string]string)
   190  	headers["TestHeader"] = "TestValue"
   191  
   192  	if err := SendMailUsingConfigAdvanced(mimeTo, smtpTo, from, replyTo, emailSubject, emailBody, attachments, headers, cfg, true); err != nil {
   193  		t.Log(err)
   194  		t.Fatal("Should connect to the STMP Server")
   195  	} else {
   196  		//Check if the email was send to the right email address
   197  		var resultsMailbox JSONMessageHeaderInbucket
   198  		err := RetryInbucket(5, func() error {
   199  			var err error
   200  			resultsMailbox, err = GetMailBox(smtpTo)
   201  			return err
   202  		})
   203  		if err != nil {
   204  			t.Log(err)
   205  			t.Fatal("No emails found for address " + smtpTo)
   206  		}
   207  		if err == nil && len(resultsMailbox) > 0 {
   208  			if !strings.ContainsAny(resultsMailbox[0].To[0], smtpTo) {
   209  				t.Fatal("Wrong To recipient")
   210  			} else {
   211  				if resultsEmail, err := GetMessageFromMailbox(smtpTo, resultsMailbox[0].ID); err == nil {
   212  					if !strings.Contains(resultsEmail.Body.Text, emailBody) {
   213  						t.Log(resultsEmail.Body.Text)
   214  						t.Fatal("Received message")
   215  					}
   216  
   217  					// verify that the To header of the email message is set to the MIME recipient, even though we got it out of the SMTP recipient's email inbox
   218  					assert.Equal(t, mimeTo, resultsEmail.Header["To"][0])
   219  
   220  					// verify that the MIME from address is correct - unfortunately, we can't verify the SMTP from address
   221  					assert.Equal(t, from.String(), resultsEmail.Header["From"][0])
   222  
   223  					// check that the custom mime headers came through - header case seems to get mutated
   224  					assert.Equal(t, "TestValue", resultsEmail.Header["Testheader"][0])
   225  
   226  					// ensure that the attachments were successfully sent
   227  					assert.Len(t, resultsEmail.Attachments, 2)
   228  					assert.Equal(t, fileName, resultsEmail.Attachments[0].Filename)
   229  					assert.Equal(t, fileName, resultsEmail.Attachments[1].Filename)
   230  					attachment1 := string(resultsEmail.Attachments[0].Bytes)
   231  					attachment2 := string(resultsEmail.Attachments[1].Bytes)
   232  					if attachment1 == string(fileContents1) {
   233  						assert.Equal(t, attachment2, string(fileContents2))
   234  					} else if attachment1 == string(fileContents2) {
   235  						assert.Equal(t, attachment2, string(fileContents1))
   236  					} else {
   237  						assert.Fail(t, "Unrecognized attachment contents")
   238  					}
   239  				}
   240  			}
   241  		}
   242  	}
   243  }
   244  
   245  func TestAuthMethods(t *testing.T) {
   246  	auth := &authChooser{
   247  		connectionInfo: &SmtpConnectionInfo{
   248  			SmtpUsername:   "test",
   249  			SmtpPassword:   "fakepass",
   250  			SmtpServerName: "fakeserver",
   251  			SmtpServerHost: "fakeserver",
   252  			SmtpPort:       "25",
   253  		},
   254  	}
   255  	tests := []struct {
   256  		desc   string
   257  		server *smtp.ServerInfo
   258  		err    string
   259  	}{
   260  		{
   261  			desc:   "auth PLAIN success",
   262  			server: &smtp.ServerInfo{Name: "fakeserver:25", Auth: []string{"PLAIN"}, TLS: true},
   263  		},
   264  		{
   265  			desc:   "auth PLAIN unencrypted connection fail",
   266  			server: &smtp.ServerInfo{Name: "fakeserver:25", Auth: []string{"PLAIN"}, TLS: false},
   267  			err:    "unencrypted connection",
   268  		},
   269  		{
   270  			desc:   "auth PLAIN wrong host name",
   271  			server: &smtp.ServerInfo{Name: "wrongServer:999", Auth: []string{"PLAIN"}, TLS: true},
   272  			err:    "wrong host name",
   273  		},
   274  		{
   275  			desc:   "auth LOGIN success",
   276  			server: &smtp.ServerInfo{Name: "fakeserver:25", Auth: []string{"LOGIN"}, TLS: true},
   277  		},
   278  		{
   279  			desc:   "auth LOGIN unencrypted connection fail",
   280  			server: &smtp.ServerInfo{Name: "wrongServer:999", Auth: []string{"LOGIN"}, TLS: true},
   281  			err:    "wrong host name",
   282  		},
   283  		{
   284  			desc:   "auth LOGIN wrong host name",
   285  			server: &smtp.ServerInfo{Name: "fakeserver:25", Auth: []string{"LOGIN"}, TLS: false},
   286  			err:    "unencrypted connection",
   287  		},
   288  	}
   289  
   290  	for i, test := range tests {
   291  		t.Run(test.desc, func(t *testing.T) {
   292  			_, _, err := auth.Start(test.server)
   293  			got := ""
   294  			if err != nil {
   295  				got = err.Error()
   296  			}
   297  			if got != test.err {
   298  				t.Errorf("%d. got error = %q; want %q", i, got, test.err)
   299  			}
   300  		})
   301  	}
   302  }