From ce2b2be5de578bd9eb44b26e04db75ca61d67ca5 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 31 Oct 2017 09:39:31 -0500 Subject: Refactoring cfg refs and load / save functions (#7749) * refactoring cfg refs and load / save functions * improve error output --- api/admin_test.go | 5 +- api/api_test.go | 7 +- api/apitestlib.go | 14 ++-- api/file_test.go | 6 +- api/user.go | 4 +- api/user_test.go | 2 +- api4/api_test.go | 7 +- api4/apitestlib.go | 14 ++-- api4/saml.go | 10 +-- api4/user.go | 8 +- app/admin.go | 15 ++-- app/analytics.go | 4 +- app/app.go | 19 +++++ app/app_test.go | 7 +- app/apptestlib.go | 12 +-- app/plugins.go | 14 ++-- app/post_test.go | 9 +-- app/saml.go | 12 +-- app/user.go | 70 +++++++++--------- app/user_test.go | 5 +- cmd/platform/test.go | 23 +++--- cmd/platform/user.go | 2 +- store/sqlstore/store_test.go | 2 - utils/config.go | 171 ++++++++++++++++++++++++------------------- utils/config_test.go | 33 ++++++--- utils/file_test.go | 2 +- utils/mail_test.go | 4 +- web/web_test.go | 12 +-- 28 files changed, 248 insertions(+), 245 deletions(-) diff --git a/api/admin_test.go b/api/admin_test.go index a9d59000d..d916e8c4b 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -10,7 +10,6 @@ import ( "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/store" - "github.com/mattermost/mattermost-server/utils" ) func TestGetLogs(t *testing.T) { @@ -139,13 +138,13 @@ func TestSaveConfig(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - if _, err := th.BasicClient.SaveConfig(utils.Cfg); err == nil { + if _, err := th.BasicClient.SaveConfig(th.App.Config()); err == nil { t.Fatal("Shouldn't have permissions") } th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = false }) - if _, err := th.SystemAdminClient.SaveConfig(utils.Cfg); err != nil { + if _, err := th.SystemAdminClient.SaveConfig(th.App.Config()); err != nil { t.Fatal(err) } diff --git a/api/api_test.go b/api/api_test.go index 3d4f5f156..d447fc9bd 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -16,20 +16,15 @@ import ( func TestMain(m *testing.M) { flag.Parse() + utils.TranslationsPreInit() // In the case where a dev just wants to run a single test, it's faster to just use the default // store. if filter := flag.Lookup("test.run").Value.String(); filter != "" && filter != "." { - utils.TranslationsPreInit() - utils.LoadConfig("config.json") l4g.Info("-test.run used, not creating temporary containers") os.Exit(m.Run()) } - utils.TranslationsPreInit() - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - status := 0 container, settings, err := storetest.NewMySQLContainer() diff --git a/api/apitestlib.go b/api/apitestlib.go index 266ca95fc..0548f7843 100644 --- a/api/apitestlib.go +++ b/api/apitestlib.go @@ -64,12 +64,6 @@ func StopTestStore() { } func setupTestHelper(enterprise bool) *TestHelper { - if utils.T == nil { - utils.TranslationsPreInit() - } - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - var options []app.Option if testStore != nil { options = append(options, app.StoreOverride(testStore)) @@ -80,9 +74,11 @@ func setupTestHelper(enterprise bool) *TestHelper { } th.originalConfig = th.App.Config().Clone() - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false }) - th.App.UpdateConfig(func(cfg *model.Config) { cfg.EmailSettings.SendEmailNotifications = true }) + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.TeamSettings.MaxUsersPerTeam = 50 + *cfg.RateLimitSettings.Enable = false + cfg.EmailSettings.SendEmailNotifications = true + }) utils.DisableDebugLogForTest() prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress if testStore != nil { diff --git a/api/file_test.go b/api/file_test.go index cdf06c04d..8b04c732c 100644 --- a/api/file_test.go +++ b/api/file_test.go @@ -517,7 +517,7 @@ func TestGetPublicFileOld(t *testing.T) { // reconstruct old style of link siteURL := fmt.Sprintf("http://localhost:%v", th.App.Srv.ListenAddr.Port) - link := generatePublicLinkOld(siteURL, th.BasicTeam.Id, channel.Id, th.BasicUser.Id, fileId+"/test.png") + link := generatePublicLinkOld(siteURL, th.BasicTeam.Id, channel.Id, th.BasicUser.Id, fileId+"/test.png", *th.App.Config().FileSettings.PublicLinkSalt) // Wait a bit for files to ready time.Sleep(2 * time.Second) @@ -553,8 +553,8 @@ func TestGetPublicFileOld(t *testing.T) { } } -func generatePublicLinkOld(siteURL, teamId, channelId, userId, filename string) string { - hash := app.GeneratePublicLinkHash(filename, *utils.Cfg.FileSettings.PublicLinkSalt) +func generatePublicLinkOld(siteURL, teamId, channelId, userId, filename, salt string) string { + hash := app.GeneratePublicLinkHash(filename, salt) return fmt.Sprintf("%s%s/public/files/get/%s/%s/%s/%s?h=%s", siteURL, model.API_URL_SUFFIX_V3, teamId, channelId, userId, filename, hash) } diff --git a/api/user.go b/api/user.go index 1060d1bda..e1fa63bfa 100644 --- a/api/user.go +++ b/api/user.go @@ -326,7 +326,7 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) { if c.HandleEtag(etag, "Get User", w, r) { return } else { - app.SanitizeProfile(user, c.IsSystemAdmin()) + c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Write([]byte(user.ToJson())) return @@ -560,7 +560,7 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { } var img []byte - img, readFailed, err = app.GetProfileImage(user) + img, readFailed, err = c.App.GetProfileImage(user) if err != nil { c.Err = err return diff --git a/api/user_test.go b/api/user_test.go index a0ffe9fd9..05b6a844f 100644 --- a/api/user_test.go +++ b/api/user_test.go @@ -643,7 +643,7 @@ func TestUserCreateImage(t *testing.T) { Client := th.BasicClient - b, err := app.CreateProfileImage("Corey Hulen", "eo1zkdr96pdj98pjmq8zy35wba") + b, err := app.CreateProfileImage("Corey Hulen", "eo1zkdr96pdj98pjmq8zy35wba", th.App.Config().FileSettings.InitialFont) if err != nil { t.Fatal(err) } diff --git a/api4/api_test.go b/api4/api_test.go index 8a8753a4f..fd804b70d 100644 --- a/api4/api_test.go +++ b/api4/api_test.go @@ -16,20 +16,15 @@ import ( func TestMain(m *testing.M) { flag.Parse() + utils.TranslationsPreInit() // In the case where a dev just wants to run a single test, it's faster to just use the default // store. if filter := flag.Lookup("test.run").Value.String(); filter != "" && filter != "." { - utils.TranslationsPreInit() - utils.LoadConfig("config.json") l4g.Info("-test.run used, not creating temporary containers") os.Exit(m.Run()) } - utils.TranslationsPreInit() - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - status := 0 container, settings, err := storetest.NewMySQLContainer() diff --git a/api4/apitestlib.go b/api4/apitestlib.go index 25d0ecc60..b7d07e89e 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -73,12 +73,6 @@ func StopTestStore() { } func setupTestHelper(enterprise bool) *TestHelper { - if utils.T == nil { - utils.TranslationsPreInit() - } - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - var options []app.Option if testStore != nil { options = append(options, app.StoreOverride(testStore)) @@ -89,9 +83,11 @@ func setupTestHelper(enterprise bool) *TestHelper { } th.originalConfig = th.App.Config().Clone() - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false }) - th.App.UpdateConfig(func(cfg *model.Config) { cfg.EmailSettings.SendEmailNotifications = true }) + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.TeamSettings.MaxUsersPerTeam = 50 + *cfg.RateLimitSettings.Enable = false + cfg.EmailSettings.SendEmailNotifications = true + }) utils.DisableDebugLogForTest() prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress if testStore != nil { diff --git a/api4/saml.go b/api4/saml.go index b2f2b3eef..469576943 100644 --- a/api4/saml.go +++ b/api4/saml.go @@ -40,8 +40,8 @@ func getSamlMetadata(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(metadata)) } -func parseSamlCertificateRequest(r *http.Request) (*multipart.FileHeader, *model.AppError) { - err := r.ParseMultipartForm(*utils.Cfg.FileSettings.MaxFileSize) +func parseSamlCertificateRequest(r *http.Request, maxFileSize int64) (*multipart.FileHeader, *model.AppError) { + err := r.ParseMultipartForm(maxFileSize) if err != nil { return nil, model.NewAppError("addSamlCertificate", "api.admin.add_certificate.no_file.app_error", nil, err.Error(), http.StatusBadRequest) } @@ -66,7 +66,7 @@ func addSamlPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request return } - fileData, err := parseSamlCertificateRequest(r) + fileData, err := parseSamlCertificateRequest(r, *c.App.Config().FileSettings.MaxFileSize) if err != nil { c.Err = err return @@ -85,7 +85,7 @@ func addSamlPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Reques return } - fileData, err := parseSamlCertificateRequest(r) + fileData, err := parseSamlCertificateRequest(r, *c.App.Config().FileSettings.MaxFileSize) if err != nil { c.Err = err return @@ -104,7 +104,7 @@ func addSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) { return } - fileData, err := parseSamlCertificateRequest(r) + fileData, err := parseSamlCertificateRequest(r, *c.App.Config().FileSettings.MaxFileSize) if err != nil { c.Err = err return diff --git a/api4/user.go b/api4/user.go index 8d5c792d6..2f8e72ad9 100644 --- a/api4/user.go +++ b/api4/user.go @@ -122,7 +122,7 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) { if c.Session.UserId == user.Id { user.Sanitize(map[string]bool{}) } else { - app.SanitizeProfile(user, c.IsSystemAdmin()) + c.App.SanitizeProfile(user, c.IsSystemAdmin()) } c.App.UpdateLastActivityAtIfNeeded(c.Session) w.Header().Set(model.HEADER_ETAG_SERVER, etag) @@ -152,7 +152,7 @@ func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) { if c.HandleEtag(etag, "Get User", w, r) { return } else { - app.SanitizeProfile(user, c.IsSystemAdmin()) + c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Write([]byte(user.ToJson())) return @@ -180,7 +180,7 @@ func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { if c.HandleEtag(etag, "Get User", w, r) { return } else { - app.SanitizeProfile(user, c.IsSystemAdmin()) + c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Write([]byte(user.ToJson())) return @@ -208,7 +208,7 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { } var img []byte - img, readFailed, err := app.GetProfileImage(user) + img, readFailed, err := c.App.GetProfileImage(user) if err != nil { c.Err = err return diff --git a/app/admin.go b/app/admin.go index a181fa251..ef5a1c5d5 100644 --- a/app/admin.go +++ b/app/admin.go @@ -131,14 +131,6 @@ func (a *App) GetConfig() *model.Config { return cfg } -func (a *App) ReloadConfig() { - debug.FreeOSMemory() - utils.LoadConfig(a.ConfigFileName()) - - // start/restart email batching job if necessary - a.InitEmailBatching() -} - func (a *App) SaveConfig(cfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError { oldCfg := a.Config() cfg.SetDefaults() @@ -157,8 +149,11 @@ func (a *App) SaveConfig(cfg *model.Config, sendConfigChangeClusterMessage bool) } utils.DisableConfigWatch() - utils.SaveConfig(a.ConfigFileName(), cfg) - utils.LoadConfig(a.ConfigFileName()) + a.UpdateConfig(func(update *model.Config) { + *update = *cfg + }) + a.PersistConfig() + a.ReloadConfig() utils.EnableConfigWatch() if a.Metrics != nil { diff --git a/app/analytics.go b/app/analytics.go index 5d30ad426..f4e6fec95 100644 --- a/app/analytics.go +++ b/app/analytics.go @@ -251,7 +251,7 @@ func (a *App) GetRecentlyActiveUsersForTeamPage(teamId string, page, perPage int users = result.Data.([]*model.User) } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetNewUsersForTeamPage(teamId string, page, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { @@ -262,5 +262,5 @@ func (a *App) GetNewUsersForTeamPage(teamId string, page, perPage int, asAdmin b users = result.Data.([]*model.User) } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } diff --git a/app/app.go b/app/app.go index 002a6a272..a8d2977b5 100644 --- a/app/app.go +++ b/app/app.go @@ -5,6 +5,7 @@ package app import ( "net/http" + "runtime/debug" "sync/atomic" l4g "github.com/alecthomas/log4go" @@ -62,6 +63,12 @@ func New(options ...Option) *App { panic("Only one App should exist at a time. Did you forget to call Shutdown()?") } + if utils.T == nil { + utils.TranslationsPreInit() + } + utils.LoadGlobalConfig("config.json") + utils.InitTranslations(utils.Cfg.LocalizationSettings) + l4g.Info(utils.T("api.server.new_server.init.info")) app := &App{ @@ -246,6 +253,18 @@ func (a *App) UpdateConfig(f func(*model.Config)) { f(utils.Cfg) } +func (a *App) PersistConfig() { + utils.SaveConfig(a.ConfigFileName(), a.Config()) +} + +func (a *App) ReloadConfig() { + debug.FreeOSMemory() + utils.LoadGlobalConfig(a.ConfigFileName()) + + // start/restart email batching job if necessary + a.InitEmailBatching() +} + func (a *App) ConfigFileName() string { return utils.CfgFileName } diff --git a/app/app_test.go b/app/app_test.go index 6f2a3a23a..ac39b49fe 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -16,20 +16,15 @@ import ( func TestMain(m *testing.M) { flag.Parse() + utils.TranslationsPreInit() // In the case where a dev just wants to run a single test, it's faster to just use the default // store. if filter := flag.Lookup("test.run").Value.String(); filter != "" && filter != "." { - utils.TranslationsPreInit() - utils.LoadConfig("config.json") l4g.Info("-test.run used, not creating temporary containers") os.Exit(m.Run()) } - utils.TranslationsPreInit() - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - status := 0 container, settings, err := storetest.NewMySQLContainer() diff --git a/app/apptestlib.go b/app/apptestlib.go index 3557a8727..b34749be3 100644 --- a/app/apptestlib.go +++ b/app/apptestlib.go @@ -48,12 +48,6 @@ func StopTestStore() { } func setupTestHelper(enterprise bool) *TestHelper { - if utils.T == nil { - utils.TranslationsPreInit() - } - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - var options []Option if testStore != nil { options = append(options, StoreOverride(testStore)) @@ -63,8 +57,8 @@ func setupTestHelper(enterprise bool) *TestHelper { App: New(options...), } - *utils.Cfg.TeamSettings.MaxUsersPerTeam = 50 - *utils.Cfg.RateLimitSettings.Enable = false + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 }) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false }) utils.DisableDebugLogForTest() prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress if testStore != nil { @@ -76,7 +70,7 @@ func setupTestHelper(enterprise bool) *TestHelper { utils.EnableDebugLogForTest() th.App.Srv.Store.MarkSystemRanUnitTests() - *utils.Cfg.TeamSettings.EnableOpenServer = true + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) utils.SetIsLicensed(enterprise) if enterprise { diff --git a/app/plugins.go b/app/plugins.go index c2f3c4785..c2e15b385 100644 --- a/app/plugins.go +++ b/app/plugins.go @@ -471,10 +471,11 @@ func (a *App) EnablePlugin(id string) *model.AppError { return model.NewAppError("EnablePlugin", "app.plugin.not_installed.app_error", nil, "", http.StatusBadRequest) } - cfg := a.Config() - cfg.PluginSettings.PluginStates[id] = &model.PluginState{Enable: true} + a.UpdateConfig(func(cfg *model.Config) { + cfg.PluginSettings.PluginStates[id] = &model.PluginState{Enable: true} + }) - if err := a.SaveConfig(cfg, true); err != nil { + if err := a.SaveConfig(a.Config(), true); err != nil { return model.NewAppError("EnablePlugin", "app.plugin.config.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -504,10 +505,11 @@ func (a *App) DisablePlugin(id string) *model.AppError { return model.NewAppError("DisablePlugin", "app.plugin.not_installed.app_error", nil, "", http.StatusBadRequest) } - cfg := a.Config() - cfg.PluginSettings.PluginStates[id] = &model.PluginState{Enable: false} + a.UpdateConfig(func(cfg *model.Config) { + cfg.PluginSettings.PluginStates[id] = &model.PluginState{Enable: false} + }) - if err := a.SaveConfig(cfg, true); err != nil { + if err := a.SaveConfig(a.Config(), true); err != nil { return model.NewAppError("DisablePlugin", "app.plugin.config.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/app/post_test.go b/app/post_test.go index 24910f964..e2e9a7261 100644 --- a/app/post_test.go +++ b/app/post_test.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/require" "github.com/mattermost/mattermost-server/model" - "github.com/mattermost/mattermost-server/utils" ) func TestUpdatePostEditAt(t *testing.T) { @@ -82,11 +81,9 @@ func TestPostAction(t *testing.T) { th := Setup().InitBasic() defer th.TearDown() - allowedInternalConnections := *utils.Cfg.ServiceSettings.AllowedUntrustedInternalConnections - defer func() { - utils.Cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections - }() - *utils.Cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1" + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1" + }) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var request model.PostActionIntegrationRequest diff --git a/app/saml.go b/app/saml.go index 2fdb30e99..3df00a9e1 100644 --- a/app/saml.go +++ b/app/saml.go @@ -65,7 +65,7 @@ func (a *App) AddSamlPublicCertificate(fileData *multipart.FileHeader) *model.Ap } a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) - utils.SaveConfig(a.ConfigFileName(), cfg) + a.PersistConfig() return nil } @@ -83,7 +83,7 @@ func (a *App) AddSamlPrivateCertificate(fileData *multipart.FileHeader) *model.A } a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) - utils.SaveConfig(a.ConfigFileName(), cfg) + a.PersistConfig() return nil } @@ -101,7 +101,7 @@ func (a *App) AddSamlIdpCertificate(fileData *multipart.FileHeader) *model.AppEr } a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) - utils.SaveConfig(a.ConfigFileName(), cfg) + a.PersistConfig() return nil } @@ -134,7 +134,7 @@ func (a *App) RemoveSamlPublicCertificate() *model.AppError { } a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) - utils.SaveConfig(a.ConfigFileName(), cfg) + a.PersistConfig() return nil } @@ -153,7 +153,7 @@ func (a *App) RemoveSamlPrivateCertificate() *model.AppError { } a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) - utils.SaveConfig(a.ConfigFileName(), cfg) + a.PersistConfig() return nil } @@ -172,7 +172,7 @@ func (a *App) RemoveSamlIdpCertificate() *model.AppError { } a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) - utils.SaveConfig(a.ConfigFileName(), cfg) + a.PersistConfig() return nil } diff --git a/app/user.go b/app/user.go index 3272781e7..e6ae7f174 100644 --- a/app/user.go +++ b/app/user.go @@ -39,7 +39,7 @@ const ( ) func (a *App) CreateUserWithHash(user *model.User, hash string, data string) (*model.User, *model.AppError) { - if err := IsUserSignUpAllowed(); err != nil { + if err := a.IsUserSignUpAllowed(); err != nil { return nil, err } @@ -81,7 +81,7 @@ func (a *App) CreateUserWithHash(user *model.User, hash string, data string) (*m } func (a *App) CreateUserWithInviteId(user *model.User, inviteId string) (*model.User, *model.AppError) { - if err := IsUserSignUpAllowed(); err != nil { + if err := a.IsUserSignUpAllowed(); err != nil { return nil, err } @@ -127,7 +127,7 @@ func (a *App) CreateUserAsAdmin(user *model.User) (*model.User, *model.AppError) } func (a *App) CreateUserFromSignup(user *model.User) (*model.User, *model.AppError) { - if err := IsUserSignUpAllowed(); err != nil { + if err := a.IsUserSignUpAllowed(); err != nil { return nil, err } @@ -150,8 +150,8 @@ func (a *App) CreateUserFromSignup(user *model.User) (*model.User, *model.AppErr return ruser, nil } -func IsUserSignUpAllowed() *model.AppError { - if !utils.Cfg.EmailSettings.EnableSignUpWithEmail || !utils.Cfg.TeamSettings.EnableUserCreation { +func (a *App) IsUserSignUpAllowed() *model.AppError { + if !a.Config().EmailSettings.EnableSignUpWithEmail || !a.Config().TeamSettings.EnableUserCreation { err := model.NewAppError("IsUserSignUpAllowed", "api.user.create_user.signup_email_disabled.app_error", nil, "", http.StatusNotImplemented) return err } @@ -421,7 +421,7 @@ func (a *App) GetUsersMap(offset int, limit int, asAdmin bool) (map[string]*mode userMap := make(map[string]*model.User, len(users)) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) userMap[user.Id] = user } @@ -434,7 +434,7 @@ func (a *App) GetUsersPage(page int, perPage int, asAdmin bool) ([]*model.User, return nil, err } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetUsersEtag() string { @@ -466,7 +466,7 @@ func (a *App) GetUsersInTeamMap(teamId string, offset int, limit int, asAdmin bo userMap := make(map[string]*model.User, len(users)) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) userMap[user.Id] = user } @@ -479,7 +479,7 @@ func (a *App) GetUsersInTeamPage(teamId string, page int, perPage int, asAdmin b return nil, err } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { @@ -488,7 +488,7 @@ func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmi return nil, err } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetUsersInTeamEtag(teamId string) string { @@ -516,7 +516,7 @@ func (a *App) GetUsersInChannelMap(channelId string, offset int, limit int, asAd userMap := make(map[string]*model.User, len(users)) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) userMap[user.Id] = user } @@ -529,7 +529,7 @@ func (a *App) GetUsersInChannelPage(channelId string, page int, perPage int, asA return nil, err } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetUsersNotInChannel(teamId string, channelId string, offset int, limit int) ([]*model.User, *model.AppError) { @@ -549,7 +549,7 @@ func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, offset in userMap := make(map[string]*model.User, len(users)) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) userMap[user.Id] = user } @@ -562,7 +562,7 @@ func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, page int return nil, err } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { @@ -571,7 +571,7 @@ func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool) ([]*m return nil, err } - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } func (a *App) GetUsersWithoutTeam(offset int, limit int) ([]*model.User, *model.AppError) { @@ -587,7 +587,7 @@ func (a *App) GetUsersByIds(userIds []string, asAdmin bool) ([]*model.User, *mod return nil, result.Err } else { users := result.Data.([]*model.User) - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } } @@ -596,13 +596,13 @@ func (a *App) GetUsersByUsernames(usernames []string, asAdmin bool) ([]*model.Us return nil, result.Err } else { users := result.Data.([]*model.User) - return sanitizeProfiles(users, asAdmin), nil + return a.sanitizeProfiles(users, asAdmin), nil } } -func sanitizeProfiles(users []*model.User, asAdmin bool) []*model.User { +func (a *App) sanitizeProfiles(users []*model.User, asAdmin bool) []*model.User { for _, u := range users { - SanitizeProfile(u, asAdmin) + a.SanitizeProfile(u, asAdmin) } return users @@ -665,7 +665,7 @@ func (a *App) DeactivateMfa(userId string) *model.AppError { return nil } -func CreateProfileImage(username string, userId string) ([]byte, *model.AppError) { +func CreateProfileImage(username string, userId string, initialFont string) ([]byte, *model.AppError) { colors := []color.NRGBA{ {197, 8, 126, 255}, {227, 207, 18, 255}, @@ -702,7 +702,7 @@ func CreateProfileImage(username string, userId string) ([]byte, *model.AppError initial := string(strings.ToUpper(username)[0]) fontDir, _ := utils.FindDir("fonts") - fontBytes, err := ioutil.ReadFile(fontDir + utils.Cfg.FileSettings.InitialFont) + fontBytes, err := ioutil.ReadFile(fontDir + initialFont) if err != nil { return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -739,13 +739,13 @@ func CreateProfileImage(username string, userId string) ([]byte, *model.AppError } } -func GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) { +func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) { var img []byte readFailed := false if len(*utils.Cfg.FileSettings.DriverName) == 0 { var err *model.AppError - if img, err = CreateProfileImage(user.Username, user.Id); err != nil { + if img, err = CreateProfileImage(user.Username, user.Id, a.Config().FileSettings.InitialFont); err != nil { return nil, false, err } } else { @@ -754,7 +754,7 @@ func GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) { if data, err := utils.ReadFile(path); err != nil { readFailed = true - if img, err = CreateProfileImage(user.Username, user.Id); err != nil { + if img, err = CreateProfileImage(user.Username, user.Id, a.Config().FileSettings.InitialFont); err != nil { return nil, false, err } @@ -932,8 +932,8 @@ func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.A } } -func SanitizeProfile(user *model.User, asAdmin bool) { - options := utils.Cfg.GetSanitizeOptions() +func (a *App) SanitizeProfile(user *model.User, asAdmin bool) { + options := a.Config().GetSanitizeOptions() if asAdmin { options["email"] = true options["fullname"] = true @@ -972,7 +972,7 @@ func (a *App) PatchUser(userId string, patch *model.UserPatch, asAdmin bool) (*m } func (a *App) sendUpdatedUserEvent(user model.User, asAdmin bool) { - SanitizeProfile(&user, asAdmin) + a.SanitizeProfile(&user, asAdmin) omitUsers := make(map[string]bool, 1) omitUsers[user.Id] = true @@ -1373,7 +1373,7 @@ func (a *App) SearchUsersInChannel(channelId string, term string, searchOptions users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } return users, nil @@ -1387,7 +1387,7 @@ func (a *App) SearchUsersNotInChannel(teamId string, channelId string, term stri users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } return users, nil @@ -1401,7 +1401,7 @@ func (a *App) SearchUsersInTeam(teamId string, term string, searchOptions map[st users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } return users, nil @@ -1415,7 +1415,7 @@ func (a *App) SearchUsersNotInTeam(notInTeamId string, term string, searchOption users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } return users, nil @@ -1429,7 +1429,7 @@ func (a *App) SearchUsersWithoutTeam(term string, searchOptions map[string]bool, users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } return users, nil @@ -1448,7 +1448,7 @@ func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term s users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } autocomplete.InChannel = users @@ -1460,7 +1460,7 @@ func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term s users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } autocomplete.OutOfChannel = users @@ -1478,7 +1478,7 @@ func (a *App) AutocompleteUsersInTeam(teamId string, term string, searchOptions users := result.Data.([]*model.User) for _, user := range users { - SanitizeProfile(user, asAdmin) + a.SanitizeProfile(user, asAdmin) } autocomplete.InTeam = users diff --git a/app/user_test.go b/app/user_test.go index 282e2896d..51db207ef 100644 --- a/app/user_test.go +++ b/app/user_test.go @@ -16,7 +16,6 @@ import ( "github.com/mattermost/mattermost-server/einterfaces" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model/gitlab" - "github.com/mattermost/mattermost-server/utils" ) func TestIsUsernameTaken(t *testing.T) { @@ -100,9 +99,7 @@ func TestCreateOAuthUser(t *testing.T) { } func TestCreateProfileImage(t *testing.T) { - utils.LoadConfig("config.json") - - b, err := CreateProfileImage("Corey Hulen", "eo1zkdr96pdj98pjmq8zy35wba") + b, err := CreateProfileImage("Corey Hulen", "eo1zkdr96pdj98pjmq8zy35wba", "luximbi.ttf") if err != nil { t.Fatal(err) } diff --git a/cmd/platform/test.go b/cmd/platform/test.go index 08438e034..faf265a0d 100644 --- a/cmd/platform/test.go +++ b/cmd/platform/test.go @@ -14,6 +14,7 @@ import ( "github.com/mattermost/mattermost-server/api" "github.com/mattermost/mattermost-server/api4" + "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/wsapi" "github.com/spf13/cobra" @@ -51,12 +52,12 @@ func webClientTestsCmdF(cmd *cobra.Command, args []string) error { } defer a.Shutdown() - utils.InitTranslations(utils.Cfg.LocalizationSettings) + utils.InitTranslations(a.Config().LocalizationSettings) a.StartServer() api4.Init(a, a.Srv.Router, false) api.Init(a, a.Srv.Router) wsapi.Init(a, a.Srv.WebSocketRouter) - setupClientTests() + a.UpdateConfig(setupClientTests) runWebClientTests() return nil @@ -69,12 +70,12 @@ func serverForWebClientTestsCmdF(cmd *cobra.Command, args []string) error { } defer a.Shutdown() - utils.InitTranslations(utils.Cfg.LocalizationSettings) + utils.InitTranslations(a.Config().LocalizationSettings) a.StartServer() api4.Init(a, a.Srv.Router, false) api.Init(a, a.Srv.Router) wsapi.Init(a, a.Srv.WebSocketRouter) - setupClientTests() + a.UpdateConfig(setupClientTests) c := make(chan os.Signal) signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) @@ -83,13 +84,13 @@ func serverForWebClientTestsCmdF(cmd *cobra.Command, args []string) error { return nil } -func setupClientTests() { - *utils.Cfg.TeamSettings.EnableOpenServer = true - *utils.Cfg.ServiceSettings.EnableCommands = false - *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false - *utils.Cfg.ServiceSettings.EnableCustomEmoji = true - utils.Cfg.ServiceSettings.EnableIncomingWebhooks = false - utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = false +func setupClientTests(cfg *model.Config) { + *cfg.TeamSettings.EnableOpenServer = true + *cfg.ServiceSettings.EnableCommands = false + *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false + *cfg.ServiceSettings.EnableCustomEmoji = true + cfg.ServiceSettings.EnableIncomingWebhooks = false + cfg.ServiceSettings.EnableOutgoingWebhooks = false utils.SetDefaultRolesBasedOnConfig() } diff --git a/cmd/platform/user.go b/cmd/platform/user.go index bc5838795..66b0f2223 100644 --- a/cmd/platform/user.go +++ b/cmd/platform/user.go @@ -289,7 +289,7 @@ func inviteUser(a *app.App, email string, team *model.Team, teamArg string) erro return fmt.Errorf("Can't find team '%v'", teamArg) } - a.SendInviteEmails(team, "Administrator", invites, *utils.Cfg.ServiceSettings.SiteURL) + a.SendInviteEmails(team, "Administrator", invites, *a.Config().ServiceSettings.SiteURL) CommandPrettyPrintln("Invites may or may not have been sent.") return nil diff --git a/store/sqlstore/store_test.go b/store/sqlstore/store_test.go index d1a5714d6..41d6a9b7e 100644 --- a/store/sqlstore/store_test.go +++ b/store/sqlstore/store_test.go @@ -99,8 +99,6 @@ func tearDownStores() { func TestMain(m *testing.M) { utils.TranslationsPreInit() - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) status := 0 diff --git a/utils/config.go b/utils/config.go index 2c3a9d291..4b377cce2 100644 --- a/utils/config.go +++ b/utils/config.go @@ -70,16 +70,14 @@ func RemoveConfigListener(id string) { delete(cfgListeners, id) } -func FindConfigFile(fileName string) string { - if _, err := os.Stat("./config/" + fileName); err == nil { - fileName, _ = filepath.Abs("./config/" + fileName) - } else if _, err := os.Stat("../config/" + fileName); err == nil { - fileName, _ = filepath.Abs("../config/" + fileName) - } else if _, err := os.Stat(fileName); err == nil { - fileName, _ = filepath.Abs(fileName) +func FindConfigFile(fileName string) (path string) { + for _, dir := range []string{"./config", "../config", "../../config", "."} { + path, _ := filepath.Abs(filepath.Join(dir, fileName)) + if _, err := os.Stat(path); err == nil { + return path + } } - - return fileName + return "" } func FindDir(dir string) (string, bool) { @@ -197,12 +195,6 @@ func SaveConfig(fileName string, config *model.Config) *model.AppError { return nil } -func EnableConfigFromEnviromentVars() { - viper.SetEnvPrefix("mm") - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - viper.AutomaticEnv() -} - func InitializeConfigWatch() { cfgMutex.Lock() defer cfgMutex.Unlock() @@ -230,7 +222,7 @@ func InitializeConfigWatch() { l4g.Info(fmt.Sprintf("Config file watcher detected a change reloading %v", CfgFileName)) if configReadErr := viper.ReadInConfig(); configReadErr == nil { - LoadConfig(CfgFileName) + LoadGlobalConfig(CfgFileName) } else { l4g.Error(fmt.Sprintf("Failed to read while watching config file at %v with err=%v", CfgFileName, configReadErr.Error())) } @@ -274,83 +266,108 @@ func InitAndLoadConfig(filename string) error { return err } - EnableConfigFromEnviromentVars() - LoadConfig(filename) + LoadGlobalConfig(filename) InitializeConfigWatch() EnableConfigWatch() return nil } -// LoadConfig will try to search around for the corresponding config file. -// It will search /tmp/fileName then attempt ./config/fileName, -// then ../config/fileName and last it will look at fileName -func LoadConfig(fileName string) *model.Config { - cfgMutex.Lock() - defer cfgMutex.Unlock() - - // Cfg should never be null - oldConfig := *Cfg +// ReadConfig reads and parses the given configuration. +func ReadConfig(r io.Reader, allowEnvironmentOverrides bool) (*model.Config, error) { + v := viper.New() - fileNameWithExtension := filepath.Base(fileName) - fileExtension := filepath.Ext(fileNameWithExtension) - fileDir := filepath.Dir(fileName) + if allowEnvironmentOverrides { + v.SetEnvPrefix("mm") + v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + v.AutomaticEnv() + } - if len(fileNameWithExtension) > 0 { - fileNameOnly := fileNameWithExtension[:len(fileNameWithExtension)-len(fileExtension)] - viper.SetConfigName(fileNameOnly) - } else { - viper.SetConfigName("config") + v.SetConfigType("json") + if err := v.ReadConfig(r); err != nil { + return nil, err } - if len(fileDir) > 0 { - viper.AddConfigPath(fileDir) + var config model.Config + unmarshalErr := v.Unmarshal(&config) + if unmarshalErr == nil { + // https://github.com/spf13/viper/issues/324 + // https://github.com/spf13/viper/issues/348 + config.PluginSettings = model.PluginSettings{} + unmarshalErr = v.UnmarshalKey("pluginsettings", &config.PluginSettings) } + return &config, unmarshalErr +} - viper.SetConfigType("json") - viper.AddConfigPath("./config") - viper.AddConfigPath("../config") - viper.AddConfigPath("../../config") - viper.AddConfigPath(".") +// ReadConfigFile reads and parses the configuration at the given file path. +func ReadConfigFile(path string, allowEnvironmentOverrides bool) (*model.Config, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return ReadConfig(f, allowEnvironmentOverrides) +} - configReadErr := viper.ReadInConfig() - if configReadErr != nil { - if _, ok := configReadErr.(viper.ConfigFileNotFoundError); ok { - // In case of a file-not-found error, try to copy default.json if it's present. - defaultPath := FindConfigFile("default.json") - if src, err := os.Open(defaultPath); err == nil { - if dest, err := os.OpenFile(filepath.Join(filepath.Dir(defaultPath), "config.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); err == nil { - if _, err := io.Copy(dest, src); err == nil { - configReadErr = viper.ReadInConfig() - } - dest.Close() - } - src.Close() - } +// EnsureConfigFile will attempt to locate a config file with the given name. If it does not exist, +// it will attempt to locate a default config file, and copy it. In either case, the config file +// path is returned. +func EnsureConfigFile(fileName string) (string, error) { + if configFile := FindConfigFile(fileName); configFile != "" { + return configFile, nil + } + if defaultPath := FindConfigFile("default.json"); defaultPath != "" { + destPath := filepath.Join(filepath.Dir(defaultPath), fileName) + src, err := os.Open(defaultPath) + if err != nil { + return "", err + } + defer src.Close() + dest, err := os.OpenFile(destPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return "", err + } + defer dest.Close() + if _, err := io.Copy(dest, src); err == nil { + return destPath, nil } } + return "", fmt.Errorf("no config file found") +} - if configReadErr != nil { - errMsg := T("utils.config.load_config.opening.panic", map[string]interface{}{"Filename": fileName, "Error": configReadErr.Error()}) - fmt.Fprintln(os.Stderr, errMsg) - os.Exit(1) - } +// LoadGlobalConfig will try to search around for the corresponding config file. It will search +// /tmp/fileName then attempt ./config/fileName, then ../config/fileName and last it will look at +// fileName +// +// XXX: This is deprecated. +func LoadGlobalConfig(fileName string) *model.Config { + cfgMutex.Lock() + defer cfgMutex.Unlock() - var config model.Config - unmarshalErr := viper.Unmarshal(&config) - if unmarshalErr == nil { - // https://github.com/spf13/viper/issues/324 - // https://github.com/spf13/viper/issues/348 - config.PluginSettings = model.PluginSettings{} - unmarshalErr = viper.UnmarshalKey("pluginsettings", &config.PluginSettings) + // Cfg should never be null + oldConfig := *Cfg + + var configPath string + if fileName != filepath.Base(fileName) { + configPath = fileName + } else { + if path, err := EnsureConfigFile(fileName); err != nil { + errMsg := T("utils.config.load_config.opening.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()}) + fmt.Fprintln(os.Stderr, errMsg) + os.Exit(1) + } else { + configPath = path + } } - if unmarshalErr != nil { - errMsg := T("utils.config.load_config.decoding.panic", map[string]interface{}{"Filename": fileName, "Error": unmarshalErr.Error()}) + + config, err := ReadConfigFile(configPath, true) + if err != nil { + errMsg := T("utils.config.load_config.decoding.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()}) fmt.Fprintln(os.Stderr, errMsg) os.Exit(1) } - CfgFileName = viper.ConfigFileUsed() + CfgFileName = configPath needSave := len(config.SqlSettings.AtRestEncryptKey) == 0 || len(*config.FileSettings.PublicLinkSalt) == 0 || len(config.EmailSettings.InviteSalt) == 0 @@ -363,16 +380,16 @@ func LoadConfig(fileName string) *model.Config { if needSave { cfgMutex.Unlock() - if err := SaveConfig(CfgFileName, &config); err != nil { + if err := SaveConfig(CfgFileName, config); err != nil { err.Translate(T) l4g.Warn(err.Error()) } cfgMutex.Lock() } - if err := ValidateLocales(&config); err != nil { + if err := ValidateLocales(config); err != nil { cfgMutex.Unlock() - if err := SaveConfig(CfgFileName, &config); err != nil { + if err := SaveConfig(CfgFileName, config); err != nil { err.Translate(T) l4g.Warn(err.Error()) } @@ -388,7 +405,7 @@ func LoadConfig(fileName string) *model.Config { } } - Cfg = &config + Cfg = config CfgHash = fmt.Sprintf("%x", md5.Sum([]byte(Cfg.ToJson()))) ClientCfg = getClientConfig(Cfg) clientCfgJson, _ := json.Marshal(ClientCfg) @@ -398,10 +415,10 @@ func LoadConfig(fileName string) *model.Config { SetSiteURL(*Cfg.ServiceSettings.SiteURL) for _, listener := range cfgListeners { - listener(&oldConfig, &config) + listener(&oldConfig, config) } - return &config + return config } func RegenerateClientConfig() { diff --git a/utils/config_test.go b/utils/config_test.go index 527718bbb..92d3c6fd4 100644 --- a/utils/config_test.go +++ b/utils/config_test.go @@ -9,25 +9,26 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/mattermost/mattermost-server/model" ) func TestConfig(t *testing.T) { TranslationsPreInit() - LoadConfig("config.json") + LoadGlobalConfig("config.json") InitTranslations(Cfg.LocalizationSettings) } func TestConfigFromEnviroVars(t *testing.T) { - os.Setenv("MM_TEAMSETTINGS_SITENAME", "From Enviroment") os.Setenv("MM_TEAMSETTINGS_CUSTOMBRANDTEXT", "Custom Brand") os.Setenv("MM_SERVICESETTINGS_ENABLECOMMANDS", "false") os.Setenv("MM_SERVICESETTINGS_READTIMEOUT", "400") TranslationsPreInit() - EnableConfigFromEnviromentVars() - LoadConfig("config.json") + LoadGlobalConfig("config.json") if Cfg.TeamSettings.SiteName != "From Enviroment" { t.Fatal("Couldn't read config from enviroment var") @@ -56,7 +57,7 @@ func TestConfigFromEnviroVars(t *testing.T) { *Cfg.ServiceSettings.ReadTimeout = 300 SaveConfig(CfgFileName, Cfg) - LoadConfig("config.json") + LoadGlobalConfig("config.json") if Cfg.TeamSettings.SiteName != "Mattermost" { t.Fatal("should have been reset") @@ -65,7 +66,7 @@ func TestConfigFromEnviroVars(t *testing.T) { func TestRedirectStdLog(t *testing.T) { TranslationsPreInit() - LoadConfig("config.json") + LoadGlobalConfig("config.json") InitTranslations(Cfg.LocalizationSettings) log := NewRedirectStdLog("test", false) @@ -110,8 +111,7 @@ func TestAddRemoveConfigListener(t *testing.T) { func TestConfigListener(t *testing.T) { TranslationsPreInit() - EnableConfigFromEnviromentVars() - LoadConfig("config.json") + LoadGlobalConfig("config.json") SiteName := Cfg.TeamSettings.SiteName defer func() { @@ -148,7 +148,7 @@ func TestConfigListener(t *testing.T) { listener2Id := AddConfigListener(listener2) defer RemoveConfigListener(listener2Id) - LoadConfig("config.json") + LoadGlobalConfig("config.json") if !listenerCalled { t.Fatal("listener should've been called") @@ -159,7 +159,7 @@ func TestConfigListener(t *testing.T) { func TestValidateLocales(t *testing.T) { TranslationsPreInit() - LoadConfig("config.json") + LoadGlobalConfig("config.json") defaultServerLocale := *Cfg.LocalizationSettings.DefaultServerLocale defaultClientLocale := *Cfg.LocalizationSettings.DefaultClientLocale @@ -278,10 +278,21 @@ func TestValidateLocales(t *testing.T) { func TestGetClientConfig(t *testing.T) { TranslationsPreInit() - LoadConfig("config.json") + LoadGlobalConfig("config.json") configMap := getClientConfig(Cfg) if configMap["EmailNotificationContentsType"] != *Cfg.EmailSettings.EmailNotificationContentsType { t.Fatal("EmailSettings.EmailNotificationContentsType not exposed to client config") } } + +func TestReadConfig(t *testing.T) { + config, err := ReadConfig(strings.NewReader(`{ + "ServiceSettings": { + "SiteURL": "http://foo.bar" + } + }`), false) + require.NoError(t, err) + + assert.Equal(t, "http://foo.bar", *config.ServiceSettings.SiteURL) +} diff --git a/utils/file_test.go b/utils/file_test.go index ed2e8683b..5c7162450 100644 --- a/utils/file_test.go +++ b/utils/file_test.go @@ -43,7 +43,7 @@ func TestFileMinioTestSuite(t *testing.T) { func (s *FileTestSuite) SetupTest() { TranslationsPreInit() - LoadConfig("config.json") + LoadGlobalConfig("config.json") InitTranslations(Cfg.LocalizationSettings) // Save state to restore after the test has run. diff --git a/utils/mail_test.go b/utils/mail_test.go index 774ecbf5b..1d4643429 100644 --- a/utils/mail_test.go +++ b/utils/mail_test.go @@ -9,7 +9,7 @@ import ( ) func TestMailConnection(t *testing.T) { - LoadConfig("config.json") + LoadGlobalConfig("config.json") if conn, err := connectToSMTPServer(Cfg); err != nil { t.Log(err) @@ -32,7 +32,7 @@ func TestMailConnection(t *testing.T) { } func TestSendMail(t *testing.T) { - LoadConfig("config.json") + LoadGlobalConfig("config.json") T = GetUserTranslations("en") var emailTo string = "test@example.com" diff --git a/web/web_test.go b/web/web_test.go index fe2115f83..52ba89933 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -38,10 +38,6 @@ func StopTestStore() { } func Setup() *app.App { - utils.TranslationsPreInit() - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) - a := app.New(app.StoreOverride(testStore)) prevListenAddress := *a.Config().ServiceSettings.ListenAddress a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) @@ -55,7 +51,9 @@ func Setup() *app.App { a.Srv.Store.MarkSystemRanUnitTests() - *utils.Cfg.TeamSettings.EnableOpenServer = true + a.UpdateConfig(func(cfg *model.Config) { + *cfg.TeamSettings.EnableOpenServer = true + }) return a } @@ -106,7 +104,7 @@ func TestIncomingWebhook(t *testing.T) { channel1 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id} channel1 = ApiClient.Must(ApiClient.CreateChannel(channel1)).Data.(*model.Channel) - if utils.Cfg.ServiceSettings.EnableIncomingWebhooks { + if a.Config().ServiceSettings.EnableIncomingWebhooks { hook1 := &model.IncomingWebhook{ChannelId: channel1.Id} hook1 = ApiClient.Must(ApiClient.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook) @@ -138,8 +136,6 @@ func TestIncomingWebhook(t *testing.T) { func TestMain(m *testing.M) { utils.TranslationsPreInit() - utils.LoadConfig("config.json") - utils.InitTranslations(utils.Cfg.LocalizationSettings) status := 0 -- cgit v1.2.3-1-g7c22