* TestGetLicenseFileFromDisk: avoid using fileutils.FindConfigFile

* config: abstract config-related file access, extend memory store

* simplify config validate to avoid file knowledge

* fix relative file tests

* cluster: fix ConfigChanged event

The old and new configurations were swapped when notifying the enterprise code of configuration changes, creating needless instability in propagating config updates across a cluster.

* config/database: ignore duplicates

* test cleanup

* remove unnecessary Save() in test
Этот коммит содержится в:
Jesse Hallam
2019-03-06 15:06:45 -05:00
коммит произвёл GitHub
родитель 3716918c57
Коммит 1e462da2d4
28 изменённых файлов: 1454 добавлений и 545 удалений

Просмотреть файл

@@ -17,6 +17,7 @@ import (
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/mailservice"
"github.com/mattermost/mattermost-server/utils"
"github.com/pkg/errors"
)
func (a *App) GetLogs(page, perPage int) ([]string, *model.AppError) {
@@ -162,7 +163,7 @@ func (a *App) GetEnvironmentConfig() map[string]interface{} {
func (a *App) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError {
oldCfg, err := a.Srv.configStore.Set(newCfg)
if err == config.ErrReadOnlyConfiguration {
if errors.Cause(err) == config.ErrReadOnlyConfiguration {
return model.NewAppError("saveConfig", "ent.cluster.save_config.error", nil, err.Error(), http.StatusForbidden)
} else if err != nil {
return model.NewAppError("saveConfig", "app.save_config.app_error", nil, err.Error(), http.StatusInternalServerError)
@@ -177,7 +178,7 @@ func (a *App) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bo
}
if a.Cluster != nil {
err := a.Cluster.ConfigChanged(newCfg, oldCfg, sendConfigChangeClusterMessage)
err := a.Cluster.ConfigChanged(oldCfg, newCfg, sendConfigChangeClusterMessage)
if err != nil {
return err
}

Просмотреть файл

@@ -17,6 +17,8 @@ import (
"strconv"
"time"
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
@@ -346,3 +348,13 @@ func (a *App) LimitedClientConfigWithComputed() map[string]string {
return respCfg
}
// GetConfigFile proxies access to the given configuration file to the underlying config store.
func (a *App) GetConfigFile(name string) ([]byte, error) {
data, err := a.Srv.configStore.GetFile(name)
if err != nil {
return nil, errors.Wrapf(err, "failed to get config file %s", name)
}
return data, nil
}

Просмотреть файл

@@ -4,7 +4,6 @@
package app
import (
"io"
"io/ioutil"
"os"
"path/filepath"
@@ -12,10 +11,10 @@ import (
"testing"
"github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/utils/fileutils"
)
type TestHelper struct {
@@ -29,31 +28,21 @@ type TestHelper struct {
SystemAdminUser *model.User
tempConfigPath string
tempWorkspace string
tempWorkspace string
}
func setupTestHelper(enterprise bool, tb testing.TB) *TestHelper {
store := mainHelper.GetStore()
store.DropAllTables()
permConfig, err := os.Open(fileutils.FindConfigFile("config.json"))
memoryStore, err := config.NewMemoryStore()
if err != nil {
panic(err)
}
defer permConfig.Close()
tempConfig, err := ioutil.TempFile("", "")
if err != nil {
panic(err)
}
_, err = io.Copy(tempConfig, permConfig)
tempConfig.Close()
if err != nil {
panic(err)
panic("failed to initialize memory store: " + err.Error())
}
options := []Option{Config(tempConfig.Name(), false)}
options = append(options, StoreOverride(store))
var options []Option
options = append(options, ConfigStore(memoryStore))
options = append(options, StoreOverride(mainHelper.Store))
options = append(options, SetLogger(mlog.NewTestingLogger(tb)))
s, err := NewServer(options...)
@@ -62,9 +51,8 @@ func setupTestHelper(enterprise bool, tb testing.TB) *TestHelper {
}
th := &TestHelper{
App: s.FakeApp(),
Server: s,
tempConfigPath: tempConfig.Name(),
App: s.FakeApp(),
Server: s,
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 })
@@ -418,7 +406,6 @@ func (me *TestHelper) ShutdownApp() {
func (me *TestHelper) TearDown() {
me.ShutdownApp()
os.Remove(me.tempConfigPath)
if err := recover(); err != nil {
panic(err)
}

Просмотреть файл

@@ -4,15 +4,11 @@
package app
import (
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/utils/fileutils"
)
const (
@@ -34,26 +30,28 @@ func (a *App) GetSamlMetadata() (string, *model.AppError) {
return result, nil
}
func WriteSamlFile(filename string, fileData *multipart.FileHeader) *model.AppError {
func (a *App) writeSamlFile(filename string, fileData *multipart.FileHeader) *model.AppError {
file, err := fileData.Open()
if err != nil {
return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.open.app_error", nil, err.Error(), http.StatusInternalServerError)
}
defer file.Close()
configDir, _ := fileutils.FindDir("config")
out, err := os.Create(filepath.Join(configDir, filename))
data, err := ioutil.ReadAll(file)
if err != nil {
return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError)
}
err = a.Srv.configStore.SetFile(filename, data)
if err != nil {
return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError)
}
defer out.Close()
io.Copy(out, file)
return nil
}
func (a *App) AddSamlPublicCertificate(fileData *multipart.FileHeader) *model.AppError {
if err := WriteSamlFile(SamlPublicCertificateName, fileData); err != nil {
if err := a.writeSamlFile(SamlPublicCertificateName, fileData); err != nil {
return err
}
@@ -70,7 +68,7 @@ func (a *App) AddSamlPublicCertificate(fileData *multipart.FileHeader) *model.Ap
}
func (a *App) AddSamlPrivateCertificate(fileData *multipart.FileHeader) *model.AppError {
if err := WriteSamlFile(SamlPrivateKeyName, fileData); err != nil {
if err := a.writeSamlFile(SamlPrivateKeyName, fileData); err != nil {
return err
}
@@ -87,7 +85,7 @@ func (a *App) AddSamlPrivateCertificate(fileData *multipart.FileHeader) *model.A
}
func (a *App) AddSamlIdpCertificate(fileData *multipart.FileHeader) *model.AppError {
if err := WriteSamlFile(SamlIdpCertificateName, fileData); err != nil {
if err := a.writeSamlFile(SamlIdpCertificateName, fileData); err != nil {
return err
}
@@ -103,16 +101,16 @@ func (a *App) AddSamlIdpCertificate(fileData *multipart.FileHeader) *model.AppEr
return nil
}
func RemoveSamlFile(filename string) *model.AppError {
if err := os.Remove(fileutils.FindConfigFile(filename)); err != nil {
return model.NewAppError("removeCertificate", "api.admin.remove_certificate.delete.app_error", map[string]interface{}{"Filename": filename}, filename+": "+err.Error(), http.StatusInternalServerError)
func (a *App) removeSamlFile(filename string) *model.AppError {
if err := a.Srv.configStore.RemoveFile(filename); err != nil {
return model.NewAppError("RemoveSamlFile", "api.admin.remove_certificate.delete.app_error", map[string]interface{}{"Filename": filename}, err.Error(), http.StatusInternalServerError)
}
return nil
}
func (a *App) RemoveSamlPublicCertificate() *model.AppError {
if err := RemoveSamlFile(*a.Config().SamlSettings.PublicCertificateFile); err != nil {
if err := a.removeSamlFile(*a.Config().SamlSettings.PublicCertificateFile); err != nil {
return err
}
@@ -130,7 +128,7 @@ func (a *App) RemoveSamlPublicCertificate() *model.AppError {
}
func (a *App) RemoveSamlPrivateCertificate() *model.AppError {
if err := RemoveSamlFile(*a.Config().SamlSettings.PrivateKeyFile); err != nil {
if err := a.removeSamlFile(*a.Config().SamlSettings.PrivateKeyFile); err != nil {
return err
}
@@ -148,7 +146,7 @@ func (a *App) RemoveSamlPrivateCertificate() *model.AppError {
}
func (a *App) RemoveSamlIdpCertificate() *model.AppError {
if err := RemoveSamlFile(*a.Config().SamlSettings.IdpCertificateFile); err != nil {
if err := a.removeSamlFile(*a.Config().SamlSettings.IdpCertificateFile); err != nil {
return err
}
@@ -168,9 +166,9 @@ func (a *App) RemoveSamlIdpCertificate() *model.AppError {
func (a *App) GetSamlCertificateStatus() *model.SamlCertificateStatus {
status := &model.SamlCertificateStatus{}
status.IdpCertificateFile = utils.FileExistsInConfigFolder(*a.Config().SamlSettings.IdpCertificateFile)
status.PrivateKeyFile = utils.FileExistsInConfigFolder(*a.Config().SamlSettings.PrivateKeyFile)
status.PublicCertificateFile = utils.FileExistsInConfigFolder(*a.Config().SamlSettings.PublicCertificateFile)
status.IdpCertificateFile, _ = a.Srv.configStore.HasFile(*a.Config().SamlSettings.IdpCertificateFile)
status.PrivateKeyFile, _ = a.Srv.configStore.HasFile(*a.Config().SamlSettings.PrivateKeyFile)
status.PublicCertificateFile, _ = a.Srv.configStore.HasFile(*a.Config().SamlSettings.PublicCertificateFile)
return status
}

Просмотреть файл

@@ -34,10 +34,16 @@ func TestStartServerSuccess(t *testing.T) {
func TestStartServerRateLimiterCriticalError(t *testing.T) {
// Attempt to use Rate Limiter with an invalid config
ms, err := config.NewMemoryStore(true)
ms, err := config.NewMemoryStoreWithOptions(&config.MemoryStoreOptions{
SkipValidation: true,
})
require.NoError(t, err)
config := ms.Get()
*config.RateLimitSettings.Enable = true
*config.RateLimitSettings.MaxBurst = -100
_, err = ms.Set(config)
require.NoError(t, err)
*ms.Config.RateLimitSettings.Enable = true
*ms.Config.RateLimitSettings.MaxBurst = -100
s, err := NewServer(ConfigStore(ms))
require.NoError(t, err)