github.com/levb/mattermost-server@v5.3.1+incompatible/utils/mail_test.go (about)

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