Commit a08df883 authored by Jesús Espino's avatar Jesús Espino Committed by Christopher Speller

Move file backend to its own service (#9435)

* Move file backend to its own service

* Moving utils/inbucket to mailservice package
parent f1be975d
......@@ -287,6 +287,10 @@ store-mocks: ## Creates mock files.
go get -u github.com/vektra/mockery/...
$(GOPATH)/bin/mockery -dir store -all -output store/storetest/mocks -note 'Regenerate this file using `make store-mocks`.'
filesstore-mocks: ## Creates mock files.
go get -u github.com/vektra/mockery/...
$(GOPATH)/bin/mockery -dir services/filesstore -all -output services/filesstore/mocks -note 'Regenerate this file using `make filesstore-mocks`.'
ldap-mocks: ## Creates mock files for ldap.
go get -u github.com/vektra/mockery/...
$(GOPATH)/bin/mockery -dir enterprise/ldap -all -output enterprise/ldap/mocks -note 'Regenerate this file using `make ldap-mocks`.'
......
......@@ -12,7 +12,7 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/services/filesstore"
)
func (api *API) InitSystem() {
......@@ -427,7 +427,7 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
err := utils.CheckMandatoryS3Fields(&cfg.FileSettings)
err := filesstore.CheckMandatoryS3Fields(&cfg.FileSettings)
if err != nil {
c.Err = err
return
......@@ -438,7 +438,7 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) {
}
license := c.App.License()
backend, appErr := utils.NewFileBackend(&cfg.FileSettings, license != nil && *license.Features.Compliance)
backend, appErr := filesstore.NewFileBackend(&cfg.FileSettings, license != nil && *license.Features.Compliance)
if appErr == nil {
appErr = backend.TestConnection()
}
......
......@@ -15,6 +15,7 @@ import (
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/mailservice"
"github.com/mattermost/mattermost-server/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
......@@ -1894,8 +1895,8 @@ func TestInviteUsersToTeam(t *testing.T) {
emailList := []string{user1, user2}
//Delete all the messages before check the sample email
utils.DeleteMailBox(user1)
utils.DeleteMailBox(user2)
mailservice.DeleteMailBox(user1)
mailservice.DeleteMailBox(user2)
enableEmailInvitations := *th.App.Config().ServiceSettings.EnableEmailInvitations
restrictCreationToDomains := th.App.Config().TeamSettings.RestrictCreationToDomains
......@@ -1925,10 +1926,10 @@ func TestInviteUsersToTeam(t *testing.T) {
//Check if the email was send to the rigth email address
for _, email := range emailList {
var resultsMailbox utils.JSONMessageHeaderInbucket
err := utils.RetryInbucket(5, func() error {
var resultsMailbox mailservice.JSONMessageHeaderInbucket
err := mailservice.RetryInbucket(5, func() error {
var err error
resultsMailbox, err = utils.GetMailBox(email)
resultsMailbox, err = mailservice.GetMailBox(email)
return err
})
if err != nil {
......@@ -1939,7 +1940,7 @@ func TestInviteUsersToTeam(t *testing.T) {
if !strings.ContainsAny(resultsMailbox[len(resultsMailbox)-1].To[0], email) {
t.Fatal("Wrong To recipient")
} else {
if resultsEmail, err := utils.GetMessageFromMailbox(email, resultsMailbox[len(resultsMailbox)-1].ID); err == nil {
if resultsEmail, err := mailservice.GetMessageFromMailbox(email, resultsMailbox[len(resultsMailbox)-1].ID); err == nil {
if resultsEmail.Subject != expectedSubject {
t.Log(resultsEmail.Subject)
t.Log(expectedSubject)
......
......@@ -1919,7 +1919,7 @@ func TestUpdateUserPassword(t *testing.T) {
Client.Logout()
user := th.BasicUser
// Delete all the messages before check the reset password
utils.DeleteMailBox(user.Email)
mailservice.DeleteMailBox(user.Email)
success, resp := Client.SendPasswordResetEmail(user.Email)
CheckNoError(t, resp)
if !success {
......@@ -1934,10 +1934,10 @@ func TestUpdateUserPassword(t *testing.T) {
t.Fatal("should have succeeded")
}
// Check if the email was send to the right email address and the recovery key match
var resultsMailbox utils.JSONMessageHeaderInbucket
err := utils.RetryInbucket(5, func() error {
var resultsMailbox mailservice.JSONMessageHeaderInbucket
err := mailservice.RetryInbucket(5, func() error {
var err error
resultsMailbox, err = utils.GetMailBox(user.Email)
resultsMailbox, err = mailservice.GetMailBox(user.Email)
return err
})
if err != nil {
......@@ -1949,7 +1949,7 @@ func TestUpdateUserPassword(t *testing.T) {
if !strings.ContainsAny(resultsMailbox[0].To[0], user.Email) {
t.Fatal("Wrong To recipient")
} else {
if resultsEmail, err := utils.GetMessageFromMailbox(user.Email, resultsMailbox[0].ID); err == nil {
if resultsEmail, err := mailservice.GetMessageFromMailbox(user.Email, resultsMailbox[0].ID); err == nil {
loc := strings.Index(resultsEmail.Body.Text, "token=")
if loc == -1 {
t.Log(resultsEmail.Body.Text)
......
......@@ -15,6 +15,7 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/mailservice"
"github.com/mattermost/mattermost-server/utils"
)
......@@ -242,7 +243,7 @@ func (a *App) TestEmail(userId string, cfg *model.Config) *model.AppError {
} else {
T := utils.GetUserTranslations(user.Locale)
license := a.License()
if err := utils.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), cfg, license != nil && *license.Features.Compliance); err != nil {
if err := mailservice.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), cfg, license != nil && *license.Features.Compliance); err != nil {
return model.NewAppError("testEmail", "app.admin.test_email.failure", map[string]interface{}{"Error": err.Error()}, "", http.StatusInternalServerError)
}
}
......
......@@ -16,6 +16,7 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/mailservice"
"github.com/mattermost/mattermost-server/utils"
)
......@@ -402,5 +403,5 @@ func (a *App) SendDeactivateAccountEmail(email string, locale, siteURL string) *
func (a *App) SendMail(to, subject, htmlBody string) *model.AppError {
license := a.License()
return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config(), license != nil && *license.Features.Compliance)
return mailservice.SendMailUsingConfig(to, subject, htmlBody, a.Config(), license != nil && *license.Features.Compliance)
}
......@@ -29,6 +29,7 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
"github.com/mattermost/mattermost-server/services/filesstore"
"github.com/mattermost/mattermost-server/utils"
)
......@@ -58,9 +59,9 @@ const (
IMAGE_PREVIEW_PIXEL_WIDTH = 1920
)
func (a *App) FileBackend() (utils.FileBackend, *model.AppError) {
func (a *App) FileBackend() (filesstore.FileBackend, *model.AppError) {
license := a.License()
return utils.NewFileBackend(&a.Config().FileSettings, license != nil && *license.Features.Compliance)
return filesstore.NewFileBackend(&a.Config().FileSettings, license != nil && *license.Features.Compliance)
}
func (a *App) ReadFile(path string) ([]byte, *model.AppError) {
......
......@@ -17,6 +17,7 @@ import (
"github.com/mattermost/mattermost-server/manualtesting"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/mailservice"
"github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/web"
"github.com/mattermost/mattermost-server/wsapi"
......@@ -67,7 +68,7 @@ func runServer(configFileLocation string, disableConfigWatch bool, usedPlatform
}
defer a.Shutdown()
utils.TestConnection(a.Config())
mailservice.TestConnection(a.Config())
pwd, _ := os.Getwd()
if usedPlatform {
......
......@@ -5,7 +5,7 @@ count=0
for fileType in GoFiles; do
for file in `go list -f $'{{range .GoFiles}}{{$.Dir}}/{{.}}\n{{end}}' "$@"`; do
case $file in
*/utils/lru.go|*/store/storetest/mocks/*|*/app/plugin/jira/plugin_*|*/plugin/plugintest/*|*/app/plugin/zoom/plugin_*)
*/utils/lru.go|*/store/storetest/mocks/*|*/services/*/mocks/*|*/app/plugin/jira/plugin_*|*/plugin/plugintest/*|*/app/plugin/zoom/plugin_*)
# Third-party, doesn't require a header.
;;
*)
......
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package filesstore
import (
"io"
......
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package filesstore
import (
"bytes"
......@@ -15,6 +15,7 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
)
type FileBackendTestSuite struct {
......@@ -81,7 +82,7 @@ func runBackendTest(t *testing.T, encrypt bool) {
}
func (s *FileBackendTestSuite) SetupTest() {
TranslationsPreInit()
utils.TranslationsPreInit()
backend, err := NewFileBackend(&s.settings, true)
require.Nil(s.T(), err)
......
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package filesstore
import (
"bytes"
......@@ -13,6 +13,7 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
)
const (
......@@ -62,7 +63,7 @@ func (b *LocalFileBackend) FileExists(path string) (bool, *model.AppError) {
}
func (b *LocalFileBackend) CopyFile(oldPath, newPath string) *model.AppError {
if err := CopyFile(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil {
if err := utils.CopyFile(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil {
return model.NewAppError("copyFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return nil
......
// Code generated by mockery v1.0.0. DO NOT EDIT.
// Regenerate this file using `make files-store-mocks`.
package mocks
import io "io"
import mock "github.com/stretchr/testify/mock"
import model "github.com/mattermost/mattermost-server/model"
// FileBackend is an autogenerated mock type for the FileBackend type
type FileBackend struct {
mock.Mock
}
// CopyFile provides a mock function with given fields: oldPath, newPath
func (_m *FileBackend) CopyFile(oldPath string, newPath string) *model.AppError {
ret := _m.Called(oldPath, newPath)
var r0 *model.AppError
if rf, ok := ret.Get(0).(func(string, string) *model.AppError); ok {
r0 = rf(oldPath, newPath)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.AppError)
}
}
return r0
}
// FileExists provides a mock function with given fields: path
func (_m *FileBackend) FileExists(path string) (bool, *model.AppError) {
ret := _m.Called(path)
var r0 bool
if rf, ok := ret.Get(0).(func(string) bool); ok {
r0 = rf(path)
} else {
r0 = ret.Get(0).(bool)
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(path)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// ListDirectory provides a mock function with given fields: path
func (_m *FileBackend) ListDirectory(path string) (*[]string, *model.AppError) {
ret := _m.Called(path)
var r0 *[]string
if rf, ok := ret.Get(0).(func(string) *[]string); ok {
r0 = rf(path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]string)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(path)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// MoveFile provides a mock function with given fields: oldPath, newPath
func (_m *FileBackend) MoveFile(oldPath string, newPath string) *model.AppError {
ret := _m.Called(oldPath, newPath)
var r0 *model.AppError
if rf, ok := ret.Get(0).(func(string, string) *model.AppError); ok {
r0 = rf(oldPath, newPath)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.AppError)
}
}
return r0
}
// ReadFile provides a mock function with given fields: path
func (_m *FileBackend) ReadFile(path string) ([]byte, *model.AppError) {
ret := _m.Called(path)
var r0 []byte
if rf, ok := ret.Get(0).(func(string) []byte); ok {
r0 = rf(path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]byte)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(path)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// Reader provides a mock function with given fields: path
func (_m *FileBackend) Reader(path string) (io.ReadCloser, *model.AppError) {
ret := _m.Called(path)
var r0 io.ReadCloser
if rf, ok := ret.Get(0).(func(string) io.ReadCloser); ok {
r0 = rf(path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(io.ReadCloser)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(path)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// RemoveDirectory provides a mock function with given fields: path
func (_m *FileBackend) RemoveDirectory(path string) *model.AppError {
ret := _m.Called(path)
var r0 *model.AppError
if rf, ok := ret.Get(0).(func(string) *model.AppError); ok {
r0 = rf(path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.AppError)
}
}
return r0
}
// RemoveFile provides a mock function with given fields: path
func (_m *FileBackend) RemoveFile(path string) *model.AppError {
ret := _m.Called(path)
var r0 *model.AppError
if rf, ok := ret.Get(0).(func(string) *model.AppError); ok {
r0 = rf(path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.AppError)
}
}
return r0
}
// TestConnection provides a mock function with given fields:
func (_m *FileBackend) TestConnection() *model.AppError {
ret := _m.Called()
var r0 *model.AppError
if rf, ok := ret.Get(0).(func() *model.AppError); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.AppError)
}
}
return r0
}
// WriteFile provides a mock function with given fields: fr, path
func (_m *FileBackend) WriteFile(fr io.Reader, path string) (int64, *model.AppError) {
ret := _m.Called(fr, path)
var r0 int64
if rf, ok := ret.Get(0).(func(io.Reader, string) int64); ok {
r0 = rf(fr, path)
} else {
r0 = ret.Get(0).(int64)
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(io.Reader, string) *model.AppError); ok {
r1 = rf(fr, path)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package filesstore
import (
"bytes"
......
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package filesstore
import (
"testing"
......
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package mailservice
import (
"bytes"
......
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package mailservice
import (
"crypto/tls"
......@@ -21,6 +21,8 @@ import (
"github.com/jaytaylor/html2text"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/filesstore"
"github.com/mattermost/mattermost-server/utils"
)
func encodeRFC2047Word(s string) string {
......@@ -160,7 +162,7 @@ func NewSMTPClientAdvanced(conn net.Conn, hostname string, connectionInfo *SmtpC
func NewSMTPClient(conn net.Conn, config *model.Config) (*smtp.Client, *model.AppError) {
return NewSMTPClientAdvanced(
conn,
GetHostnameFromSiteURL(*config.ServiceSettings.SiteURL),
utils.GetHostnameFromSiteURL(*config.ServiceSettings.SiteURL),
&SmtpConnectionInfo{
ConnectionSecurity: config.EmailSettings.ConnectionSecurity,
SkipCertVerification: *config.EmailSettings.SkipServerCertificateVerification,
......@@ -181,14 +183,14 @@ func TestConnection(config *model.Config) {
conn, err1 := ConnectToSMTPServer(config)
if err1 != nil {
mlog.Error(fmt.Sprintf("SMTP server settings do not appear to be configured properly err=%v details=%v", T(err1.Message), err1.DetailedError))
mlog.Error(fmt.Sprintf("SMTP server settings do not appear to be configured properly err=%v details=%v", utils.T(err1.Message), err1.DetailedError))
return
}
defer conn.Close()
c, err2 := NewSMTPClient(conn, config)
if err2 != nil {
mlog.Error(fmt.Sprintf("SMTP server settings do not appear to be configured properly err=%v details=%v", T(err2.Message), err2.DetailedError))
mlog.Error(fmt.Sprintf("SMTP server settings do not appear to be configured properly err=%v details=%v", utils.T(err2.Message), err2.DetailedError))
return
}
defer c.Quit()
......@@ -220,7 +222,7 @@ func SendMailUsingConfigAdvanced(mimeTo, smtpTo string, from mail.Address, subje
defer c.Quit()
defer c.Close()
fileBackend, err := NewFileBackend(&config.FileSettings, enableComplianceFeatures)
fileBackend, err := filesstore.NewFileBackend(&config.FileSettings, enableComplianceFeatures)
if err != nil {
return err
}
......@@ -228,7 +230,7 @@ func SendMailUsingConfigAdvanced(mimeTo, smtpTo string, from mail.Address, subje
return SendMail(c, mimeTo, smtpTo, from, subject, htmlBody, attachments, mimeHeaders, fileBackend, time.Now())
}
func SendMail(c *smtp.Client, mimeTo, smtpTo string, from mail.Address, subject, htmlBody string, attachments []*model.FileInfo, mimeHeaders map[string]string, fileBackend FileBackend, date time.Time) *model.AppError {
func SendMail(c *smtp.Client, mimeTo, smtpTo string, from mail.Address, subject, htmlBody string, attachments []*model.FileInfo, mimeHeaders map[string]string, fileBackend filesstore.FileBackend, date time.Time) *model.AppError {
mlog.Debug(fmt.Sprintf("sending mail to %v with subject of '%v'", smtpTo, subject))
htmlMessage := "\r\n<html><body>" + htmlBody + "</body></html>"
......
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
package mailservice
import (
"bytes"
......@@ -13,12 +13,14 @@ import (
"net/smtp"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/filesstore"
"github.com/mattermost/mattermost-server/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMailConnectionFromConfig(t *testing.T) {
cfg, _, _, err := LoadConfig("config.json")
cfg, _, _, err := utils.LoadConfig("config.json")
require.Nil(t, err)
if conn, err := ConnectToSMTPServer(cfg); err != nil {
......@@ -41,7 +43,7 @@ func TestMailConnectionFromConfig(t *testing.T) {
}
func TestMailConnectionAdvanced(t *testing.T) {
cfg, _, _, err := LoadConfig("config.json")
cfg, _, _, err := utils.LoadConfig("config.json")
require.Nil(t, err)
if conn, err := ConnectToSMTPServerAdvanced(
......@@ -58,7 +60,7 @@ func TestMailConnectionAdvanced(t *testing.T) {
} else {
if _, err1 := NewSMTPClientAdvanced(
conn,
GetHostnameFromSiteURL(*cfg.ServiceSettings.SiteURL),
utils.GetHostnameFromSiteURL(*cfg.ServiceSettings.SiteURL),
&SmtpConnectionInfo{
ConnectionSecurity: cfg.EmailSettings.ConnectionSecurity,
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
......@@ -91,9 +93,9 @@ func TestMailConnectionAdvanced(t *testing.T) {
}
func TestSendMailUsingConfig(t *testing.T) {
cfg, _, _, err := LoadConfig("config.json")
cfg, _, _, err := utils.LoadConfig("config.json")
require.Nil(t, err)
T = GetUserTranslations("en")
utils.T = utils.GetUserTranslations("en")
var emailTo = "test@example.com"
var emailSubject = "Testing this email"
......@@ -133,9 +135,9 @@ func TestSendMailUsingConfig(t *testing.T) {
}
func TestSendMailUsingConfigAdvanced(t *testing.T) {
cfg, _, _, err := LoadConfig("config.json")
cfg, _, _, err := utils.LoadConfig("config.json")
require.Nil(t, err)
T = GetUserTranslations("en")
utils.T = utils.GetUserTranslations("en")
var mimeTo = "test@example.com"
var smtpTo = "test2@example.com"
......@@ -146,7 +148,7 @@ func TestSendMailUsingConfigAdvanced(t *testing.T) {
//Delete all the messages before check the sample email
DeleteMailBox(smtpTo)
fileBackend, err := NewFileBackend(&cfg.FileSettings, true)
fileBackend, err := filesstore.NewFileBackend(&cfg.FileSettings, true)
assert.Nil(t, err)
// create two files with the same name that will both be attached to the email
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment