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