MM-14143 config cleanup final (#10374)
* 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
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
3716918c57
Коммит
1e462da2d4
@@ -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)
|
||||
}
|
||||
|
||||
42
app/saml.go
42
app/saml.go
@@ -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)
|
||||
|
||||
Ссылка в новой задаче
Block a user