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