github.com/vnforks/kid@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 }