* refactor utils/config* to config/

* pull validateLdapFilter into app

* clean up Config/GetConfig/GetSanitizedConfig usage

Eliminate app.GetConfig() in favour of just using app.Config() directly,
but expose app.GetSanitizedConfig() for when the old behaviour was
required.

* web: isolate config setup

* TestInvitePeopleProvider: make config explicit

* regenerateClientConfig: avoid racey map access

* integrate watch flag into app.ConfigFile option

* make app.Option return an error

* release.mk: only cp static files from config/

* release.mk: fix cp static files from config/

* api4: TestPlugin cleanup

* s/c/cfg/ for clarity

* fix merge conflict

* testlib: allow customization of testlib driver name
Этот коммит содержится в:
Jesse Hallam
2019-02-12 08:37:54 -05:00
коммит произвёл GitHub
родитель aca8914e35
Коммит 3a71709103
30 изменённых файлов: 221 добавлений и 185 удалений

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

@@ -79,7 +79,7 @@ func setupTestHelper(enterprise bool, updateConfig func(*model.Config)) *TestHel
panic(err) panic(err)
} }
options := []app.Option{app.ConfigFile(tempConfig.Name()), app.DisableConfigWatch} options := []app.Option{app.ConfigFile(tempConfig.Name(), false)}
options = append(options, app.StoreOverride(testStore)) options = append(options, app.StoreOverride(testStore))
s, err := app.NewServer(options...) s, err := app.NewServer(options...)

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

@@ -20,19 +20,9 @@ func TestPlugin(t *testing.T) {
th := Setup().InitBasic() th := Setup().InitBasic()
defer th.TearDown() defer th.TearDown()
enablePlugins := *th.App.Config().PluginSettings.Enable
enableUploadPlugins := *th.App.Config().PluginSettings.EnableUploads
statesJson, _ := json.Marshal(th.App.Config().PluginSettings.PluginStates) statesJson, _ := json.Marshal(th.App.Config().PluginSettings.PluginStates)
states := map[string]*model.PluginState{} states := map[string]*model.PluginState{}
json.Unmarshal(statesJson, &states) json.Unmarshal(statesJson, &states)
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = enablePlugins
*cfg.PluginSettings.EnableUploads = enableUploadPlugins
cfg.PluginSettings.PluginStates = states
})
th.App.SaveConfig(th.App.Config(), false)
}()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true *cfg.PluginSettings.Enable = true
*cfg.PluginSettings.EnableUploads = true *cfg.PluginSettings.EnableUploads = true

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

@@ -741,7 +741,7 @@ func TestPinPost(t *testing.T) {
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
t.Run("unable-to-pin-post-in-read-only-town-square", func(t *testing.T) { t.Run("unable-to-pin-post-in-read-only-town-square", func(t *testing.T) {
townSquareIsReadOnly := *th.App.GetConfig().TeamSettings.ExperimentalTownSquareIsReadOnly townSquareIsReadOnly := *th.App.Config().TeamSettings.ExperimentalTownSquareIsReadOnly
th.App.SetLicense(model.NewTestLicense()) th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })

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

@@ -103,7 +103,7 @@ func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
cfg := c.App.GetConfig() cfg := c.App.GetSanitizedConfig()
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Write([]byte(cfg.ToJson())) w.Write([]byte(cfg.ToJson()))
@@ -134,12 +134,12 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
} }
// Do not allow plugin uploads to be toggled through the API // Do not allow plugin uploads to be toggled through the API
cfg.PluginSettings.EnableUploads = c.App.GetConfig().PluginSettings.EnableUploads cfg.PluginSettings.EnableUploads = c.App.Config().PluginSettings.EnableUploads
// If the Message Export feature has been toggled in the System Console, rewrite the ExportFromTimestamp field to an // If the Message Export feature has been toggled in the System Console, rewrite the ExportFromTimestamp field to an
// appropriate value. The rewriting occurs here to ensure it doesn't affect values written to the config file // appropriate value. The rewriting occurs here to ensure it doesn't affect values written to the config file
// directly and not through the System Console UI. // directly and not through the System Console UI.
if *cfg.MessageExportSettings.EnableExport != *c.App.GetConfig().MessageExportSettings.EnableExport { if *cfg.MessageExportSettings.EnableExport != *c.App.Config().MessageExportSettings.EnableExport {
if *cfg.MessageExportSettings.EnableExport && *cfg.MessageExportSettings.ExportFromTimestamp == int64(0) { if *cfg.MessageExportSettings.EnableExport && *cfg.MessageExportSettings.ExportFromTimestamp == int64(0) {
// When the feature is toggled on, use the current timestamp as the start time for future exports. // When the feature is toggled on, use the current timestamp as the start time for future exports.
cfg.MessageExportSettings.ExportFromTimestamp = model.NewInt64(model.GetMillis()) cfg.MessageExportSettings.ExportFromTimestamp = model.NewInt64(model.GetMillis())
@@ -158,7 +158,7 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("updateConfig") c.LogAudit("updateConfig")
cfg = c.App.GetConfig() cfg = c.App.GetSanitizedConfig()
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Write([]byte(cfg.ToJson())) w.Write([]byte(cfg.ToJson()))
@@ -477,8 +477,7 @@ func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) {
m := make(map[string]string) m := make(map[string]string)
m["location"] = "" m["location"] = ""
cfg := c.App.GetConfig() if !*c.App.Config().ServiceSettings.EnableLinkPreviews {
if !*cfg.ServiceSettings.EnableLinkPreviews {
w.Write([]byte(model.MapToJson(m))) w.Write([]byte(model.MapToJson(m)))
return return
} }

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

@@ -131,19 +131,19 @@ func TestUpdateConfig(t *testing.T) {
require.Equal(t, SiteName, cfg.TeamSettings.SiteName, "It should update the SiteName") require.Equal(t, SiteName, cfg.TeamSettings.SiteName, "It should update the SiteName")
t.Run("Should not be able to modify PluginSettings.EnableUploads", func(t *testing.T) { t.Run("Should not be able to modify PluginSettings.EnableUploads", func(t *testing.T) {
oldEnableUploads := *th.App.GetConfig().PluginSettings.EnableUploads oldEnableUploads := *th.App.Config().PluginSettings.EnableUploads
*cfg.PluginSettings.EnableUploads = !oldEnableUploads *cfg.PluginSettings.EnableUploads = !oldEnableUploads
cfg, resp = th.SystemAdminClient.UpdateConfig(cfg) cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
CheckNoError(t, resp) CheckNoError(t, resp)
assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads) assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads)
assert.Equal(t, oldEnableUploads, *th.App.GetConfig().PluginSettings.EnableUploads) assert.Equal(t, oldEnableUploads, *th.App.Config().PluginSettings.EnableUploads)
cfg.PluginSettings.EnableUploads = nil cfg.PluginSettings.EnableUploads = nil
cfg, resp = th.SystemAdminClient.UpdateConfig(cfg) cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
CheckNoError(t, resp) CheckNoError(t, resp)
assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads) assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads)
assert.Equal(t, oldEnableUploads, *th.App.GetConfig().PluginSettings.EnableUploads) assert.Equal(t, oldEnableUploads, *th.App.Config().PluginSettings.EnableUploads)
}) })
} }

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

@@ -856,7 +856,7 @@ func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) {
} }
// if EnableUserDeactivation flag is disabled the user cannot deactivate himself. // if EnableUserDeactivation flag is disabled the user cannot deactivate himself.
if isSelfDeactive && !*c.App.GetConfig().TeamSettings.EnableUserDeactivation { if isSelfDeactive && !*c.App.Config().TeamSettings.EnableUserDeactivation {
c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized) c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
return return
} }

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

@@ -6,13 +6,13 @@ package app
import ( import (
"io" "io"
"os" "os"
"strings"
"time" "time"
"runtime/debug" "runtime/debug"
"net/http" "net/http"
"github.com/mattermost/mattermost-server/einterfaces"
"github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/mailservice" "github.com/mattermost/mattermost-server/services/mailservice"
@@ -149,9 +149,8 @@ func (a *App) InvalidateAllCachesSkipSend() {
a.LoadLicense() a.LoadLicense()
} }
func (a *App) GetConfig() *model.Config { func (a *App) GetSanitizedConfig() *model.Config {
json := a.Config().ToJson() cfg := a.Config().Clone()
cfg := model.ConfigFromJson(strings.NewReader(json))
cfg.Sanitize() cfg.Sanitize()
return cfg return cfg
@@ -161,6 +160,14 @@ func (a *App) GetEnvironmentConfig() map[string]interface{} {
return a.EnvironmentConfig() return a.EnvironmentConfig()
} }
func validateLdapFilter(cfg *model.Config, ldap einterfaces.LdapInterface) *model.AppError {
if !*cfg.LdapSettings.Enable || ldap == nil || *cfg.LdapSettings.UserFilter == "" {
return nil
}
return ldap.ValidateFilter(*cfg.LdapSettings.UserFilter)
}
func (a *App) SaveConfig(cfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError { func (a *App) SaveConfig(cfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError {
oldCfg := a.Config() oldCfg := a.Config()
cfg.SetDefaults() cfg.SetDefaults()
@@ -170,7 +177,7 @@ func (a *App) SaveConfig(cfg *model.Config, sendConfigChangeClusterMessage bool)
return err return err
} }
if err := utils.ValidateLdapFilter(cfg, a.Ldap); err != nil { if err := validateLdapFilter(cfg, a.Ldap); err != nil {
return err return err
} }

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

@@ -405,7 +405,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
th.App.DoAdvancedPermissionsMigration() th.App.DoAdvancedPermissionsMigration()
config := th.App.GetConfig() config := th.App.Config()
assert.Equal(t, -1, *config.ServiceSettings.PostEditTimeLimit) assert.Equal(t, -1, *config.ServiceSettings.PostEditTimeLimit)
th.ResetRoleMigration() th.ResetRoleMigration()
@@ -416,7 +416,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
}) })
th.App.DoAdvancedPermissionsMigration() th.App.DoAdvancedPermissionsMigration()
config = th.App.GetConfig() config = th.App.Config()
assert.Equal(t, 300, *config.ServiceSettings.PostEditTimeLimit) assert.Equal(t, 300, *config.ServiceSettings.PostEditTimeLimit)
} }

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

@@ -15,11 +15,10 @@ func TestInvitePeopleProvider(t *testing.T) {
th := Setup().InitBasic() th := Setup().InitBasic()
defer th.TearDown() defer th.TearDown()
enableEmailInvitations := *th.App.Config().ServiceSettings.EnableEmailInvitations th.App.UpdateConfig(func(cfg *model.Config) {
defer func() { *cfg.EmailSettings.SendEmailNotifications = true
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableEmailInvitations = &enableEmailInvitations }) *cfg.ServiceSettings.EnableEmailInvitations = true
}() })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableEmailInvitations = true })
cmd := InvitePeopleProvider{} cmd := InvitePeopleProvider{}

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

@@ -18,6 +18,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/utils"
@@ -63,13 +64,13 @@ func (a *App) UpdateConfig(f func(*model.Config)) {
} }
func (a *App) PersistConfig() { func (a *App) PersistConfig() {
utils.SaveConfig(a.ConfigFileName(), a.Config()) config.SaveConfig(a.ConfigFileName(), a.Config())
} }
func (s *Server) LoadConfig(configFile string) *model.AppError { func (s *Server) LoadConfig(configFile string) *model.AppError {
old := s.Config() old := s.Config()
cfg, configPath, envConfig, err := utils.LoadConfig(configFile) cfg, configPath, envConfig, err := config.LoadConfig(configFile)
if err != nil { if err != nil {
return err return err
} }
@@ -117,7 +118,7 @@ func (a *App) LimitedClientConfig() map[string]string {
func (s *Server) EnableConfigWatch() { func (s *Server) EnableConfigWatch() {
if s.configWatcher == nil && !s.disableConfigWatch { if s.configWatcher == nil && !s.disableConfigWatch {
configWatcher, err := utils.NewConfigWatcher(s.configFile, func() { configWatcher, err := config.NewConfigWatcher(s.configFile, func() {
s.ReloadConfig() s.ReloadConfig()
}) })
if err != nil { if err != nil {
@@ -280,26 +281,28 @@ func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {
} }
func (a *App) regenerateClientConfig() { func (a *App) regenerateClientConfig() {
a.Srv.clientConfig = utils.GenerateClientConfig(a.Config(), a.DiagnosticId(), a.License()) clientConfig := config.GenerateClientConfig(a.Config(), a.DiagnosticId(), a.License())
a.Srv.limitedClientConfig = utils.GenerateLimitedClientConfig(a.Config(), a.DiagnosticId(), a.License()) limitedClientConfig := config.GenerateLimitedClientConfig(a.Config(), a.DiagnosticId(), a.License())
if a.Srv.clientConfig["EnableCustomTermsOfService"] == "true" { if clientConfig["EnableCustomTermsOfService"] == "true" {
termsOfService, err := a.GetLatestTermsOfService() termsOfService, err := a.GetLatestTermsOfService()
if err != nil { if err != nil {
mlog.Err(err) mlog.Err(err)
} else { } else {
a.Srv.clientConfig["CustomTermsOfServiceId"] = termsOfService.Id clientConfig["CustomTermsOfServiceId"] = termsOfService.Id
a.Srv.limitedClientConfig["CustomTermsOfServiceId"] = termsOfService.Id limitedClientConfig["CustomTermsOfServiceId"] = termsOfService.Id
} }
} }
if key := a.AsymmetricSigningKey(); key != nil { if key := a.AsymmetricSigningKey(); key != nil {
der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey) der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
a.Srv.clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der) clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
a.Srv.limitedClientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der) limitedClientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
} }
clientConfigJSON, _ := json.Marshal(a.Srv.clientConfig) clientConfigJSON, _ := json.Marshal(clientConfig)
a.Srv.clientConfig = clientConfig
a.Srv.limitedClientConfig = limitedClientConfig
a.Srv.clientConfigHash = fmt.Sprintf("%x", md5.Sum(clientConfigJSON)) a.Srv.clientConfigHash = fmt.Sprintf("%x", md5.Sum(clientConfigJSON))
} }

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

@@ -42,7 +42,7 @@ func TestLoadConfig(t *testing.T) {
appErr := a.LoadConfig(tempConfig.Name()) appErr := a.LoadConfig(tempConfig.Name())
require.Nil(t, appErr) require.Nil(t, appErr)
assert.Equal(t, "http://localhost:8065", *a.GetConfig().ServiceSettings.SiteURL) assert.Equal(t, "http://localhost:8065", *a.Config().ServiceSettings.SiteURL)
} }
func TestConfigListener(t *testing.T) { func TestConfigListener(t *testing.T) {

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

@@ -120,7 +120,7 @@ func (s *Server) initEnterprise() {
if ldapInterface != nil { if ldapInterface != nil {
s.Ldap = ldapInterface(s.FakeApp()) s.Ldap = ldapInterface(s.FakeApp())
s.AddConfigListener(func(_, cfg *model.Config) { s.AddConfigListener(func(_, cfg *model.Config) {
if err := utils.ValidateLdapFilter(cfg, s.Ldap); err != nil { if err := validateLdapFilter(cfg, s.Ldap); err != nil {
panic(utils.T(err.Id)) panic(utils.T(err.Id))
} }
}) })

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

@@ -51,7 +51,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
panic(err) panic(err)
} }
options := []Option{ConfigFile(tempConfig.Name()), DisableConfigWatch} options := []Option{ConfigFile(tempConfig.Name(), false)}
options = append(options, StoreOverride(mainHelper.Store)) options = append(options, StoreOverride(mainHelper.Store))
s, err := NewServer(options...) s, err := NewServer(options...)

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

@@ -4,56 +4,69 @@
package app package app
import ( import (
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/store" "github.com/mattermost/mattermost-server/store"
) )
type Option func(s *Server) type Option func(s *Server) error
// By default, the app will use the store specified by the configuration. This allows you to // By default, the app will use the store specified by the configuration. This allows you to
// construct an app with a different store. // construct an app with a different store.
// //
// The override parameter must be either a store.Store or func(App) store.Store. // The override parameter must be either a store.Store or func(App) store.Store.
func StoreOverride(override interface{}) Option { func StoreOverride(override interface{}) Option {
return func(s *Server) { return func(s *Server) error {
switch o := override.(type) { switch o := override.(type) {
case store.Store: case store.Store:
s.newStore = func() store.Store { s.newStore = func() store.Store {
return o return o
} }
return nil
case func(*Server) store.Store: case func(*Server) store.Store:
s.newStore = func() store.Store { s.newStore = func() store.Store {
return o(s) return o(s)
} }
return nil
default: default:
panic("invalid StoreOverride") return errors.New("invalid StoreOverride")
} }
} }
} }
func ConfigFile(file string) Option { func ConfigFile(file string, watch bool) Option {
return func(s *Server) { return func(s *Server) error {
s.configFile = file s.configFile = file
s.disableConfigWatch = !watch
return nil
} }
} }
func RunJobs(s *Server) { func RunJobs(s *Server) error {
s.runjobs = true s.runjobs = true
return nil
} }
func JoinCluster(s *Server) { func JoinCluster(s *Server) error {
s.joinCluster = true s.joinCluster = true
return nil
} }
func StartMetrics(s *Server) { func StartMetrics(s *Server) error {
s.startMetrics = true s.startMetrics = true
return nil
} }
func StartElasticsearch(s *Server) { func StartElasticsearch(s *Server) error {
s.startElasticsearch = true s.startElasticsearch = true
}
func DisableConfigWatch(s *Server) { return nil
s.disableConfigWatch = true
} }
type AppOption func(a *App) type AppOption func(a *App)

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

@@ -77,7 +77,7 @@ func (api *PluginAPI) GetSession(sessionId string) (*model.Session, *model.AppEr
} }
func (api *PluginAPI) GetConfig() *model.Config { func (api *PluginAPI) GetConfig() *model.Config {
return api.app.GetConfig() return api.app.GetSanitizedConfig()
} }
func (api *PluginAPI) SaveConfig(config *model.Config) *model.AppError { func (api *PluginAPI) SaveConfig(config *model.Config) *model.AppError {
@@ -85,7 +85,7 @@ func (api *PluginAPI) SaveConfig(config *model.Config) *model.AppError {
} }
func (api *PluginAPI) GetPluginConfig() map[string]interface{} { func (api *PluginAPI) GetPluginConfig() map[string]interface{} {
cfg := api.app.GetConfig() cfg := api.app.GetSanitizedConfig()
if pluginConfig, isOk := cfg.PluginSettings.Plugins[api.manifest.Id]; isOk { if pluginConfig, isOk := cfg.PluginSettings.Plugins[api.manifest.Id]; isOk {
return pluginConfig return pluginConfig
} }
@@ -93,7 +93,7 @@ func (api *PluginAPI) GetPluginConfig() map[string]interface{} {
} }
func (api *PluginAPI) SavePluginConfig(pluginConfig map[string]interface{}) *model.AppError { func (api *PluginAPI) SavePluginConfig(pluginConfig map[string]interface{}) *model.AppError {
cfg := api.app.GetConfig() cfg := api.app.GetSanitizedConfig()
cfg.PluginSettings.Plugins[api.manifest.Id] = pluginConfig cfg.PluginSettings.Plugins[api.manifest.Id] = pluginConfig
return api.app.SaveConfig(cfg, true) return api.app.SaveConfig(cfg, true)
} }

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

@@ -24,6 +24,7 @@ import (
"github.com/throttled/throttled" "github.com/throttled/throttled"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
"github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/einterfaces" "github.com/mattermost/mattermost-server/einterfaces"
"github.com/mattermost/mattermost-server/jobs" "github.com/mattermost/mattermost-server/jobs"
"github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/mlog"
@@ -96,7 +97,7 @@ type Server struct {
logListenerId string logListenerId string
clusterLeaderListenerId string clusterLeaderListenerId string
disableConfigWatch bool disableConfigWatch bool
configWatcher *utils.ConfigWatcher configWatcher *config.ConfigWatcher
asymmetricSigningKey *ecdsa.PrivateKey asymmetricSigningKey *ecdsa.PrivateKey
pluginCommands []*PluginCommand pluginCommands []*PluginCommand
@@ -144,7 +145,9 @@ func NewServer(options ...Option) (*Server, error) {
clientConfig: make(map[string]string), clientConfig: make(map[string]string),
} }
for _, option := range options { for _, option := range options {
option(s) if err := option(s); err != nil {
return nil, errors.Wrap(err, "failed to apply option")
}
} }
if err := s.LoadConfig(s.configFile); err != nil { if err := s.LoadConfig(s.configFile); err != nil {

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

@@ -32,7 +32,10 @@ package:
mkdir -p $(DIST_PATH)/prepackaged_plugins mkdir -p $(DIST_PATH)/prepackaged_plugins
@# Resource directories @# Resource directories
cp -RL config $(DIST_PATH) mkdir -p $(DIST_PATH)/config
cp -L config/README.md $(DIST_PATH)/config
cp -L config/config.json $(DIST_PATH)/config
cp -L config/timezones.json $(DIST_PATH)/config
cp -RL fonts $(DIST_PATH) cp -RL fonts $(DIST_PATH)
cp -RL templates $(DIST_PATH) cp -RL templates $(DIST_PATH)
cp -RL i18n $(DIST_PATH) cp -RL i18n $(DIST_PATH)

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

@@ -14,6 +14,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/utils/fileutils" "github.com/mattermost/mattermost-server/utils/fileutils"
@@ -234,7 +235,7 @@ func configSetCmdF(command *cobra.Command, args []string) error {
return err return err
} }
if err := utils.ValidateLocales(app.Config()); err != nil { if err := config.ValidateLocales(app.Config()); err != nil {
return errors.New("Invalid locale configuration") return errors.New("Invalid locale configuration")
} }

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

@@ -36,7 +36,7 @@ func InitDBCommandContext(configFileLocation string) (*app.App, error) {
} }
model.AppErrorInit(utils.T) model.AppErrorInit(utils.T)
s, err := app.NewServer(app.ConfigFile(configFileLocation)) s, err := app.NewServer(app.ConfigFile(configFileLocation, true))
if err != nil { if err != nil {
return nil, err return nil, err
} }

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

@@ -5,7 +5,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/utils/fileutils" "github.com/mattermost/mattermost-server/utils/fileutils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -15,11 +15,11 @@ func TestPlugin(t *testing.T) {
th := Setup().InitBasic() th := Setup().InitBasic()
defer th.TearDown() defer th.TearDown()
config := th.Config() cfg := th.Config()
*config.PluginSettings.EnableUploads = true *cfg.PluginSettings.EnableUploads = true
*config.PluginSettings.Directory = "./test-plugins" *cfg.PluginSettings.Directory = "./test-plugins"
*config.PluginSettings.ClientDirectory = "./test-client-plugins" *cfg.PluginSettings.ClientDirectory = "./test-client-plugins"
th.SetConfig(config) th.SetConfig(cfg)
os.MkdirAll("./test-plugins", os.ModePerm) os.MkdirAll("./test-plugins", os.ModePerm)
os.MkdirAll("./test-client-plugins", os.ModePerm) os.MkdirAll("./test-client-plugins", os.ModePerm)
@@ -31,12 +31,12 @@ func TestPlugin(t *testing.T) {
th.CheckCommand(t, "plugin", "add", filepath.Join(path, "testplugin.tar.gz")) th.CheckCommand(t, "plugin", "add", filepath.Join(path, "testplugin.tar.gz"))
th.CheckCommand(t, "plugin", "enable", "testplugin") th.CheckCommand(t, "plugin", "enable", "testplugin")
cfg, _, _, err := utils.LoadConfig(th.ConfigPath()) cfg, _, _, err := config.LoadConfig(th.ConfigPath())
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, cfg.PluginSettings.PluginStates["testplugin"].Enable, true) assert.Equal(t, cfg.PluginSettings.PluginStates["testplugin"].Enable, true)
th.CheckCommand(t, "plugin", "disable", "testplugin") th.CheckCommand(t, "plugin", "disable", "testplugin")
cfg, _, _, err = utils.LoadConfig(th.ConfigPath()) cfg, _, _, err = config.LoadConfig(th.ConfigPath())
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, cfg.PluginSettings.PluginStates["testplugin"].Enable, false) assert.Equal(t, cfg.PluginSettings.PluginStates["testplugin"].Enable, false)

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

@@ -45,15 +45,12 @@ func serverCmdF(command *cobra.Command, args []string) error {
func runServer(configFileLocation string, disableConfigWatch bool, usedPlatform bool, interruptChan chan os.Signal) error { func runServer(configFileLocation string, disableConfigWatch bool, usedPlatform bool, interruptChan chan os.Signal) error {
options := []app.Option{ options := []app.Option{
app.ConfigFile(configFileLocation), app.ConfigFile(configFileLocation, !disableConfigWatch),
app.RunJobs, app.RunJobs,
app.JoinCluster, app.JoinCluster,
app.StartElasticsearch, app.StartElasticsearch,
app.StartMetrics, app.StartMetrics,
} }
if disableConfigWatch {
options = append(options, app.DisableConfigWatch)
}
server, err := app.NewServer(options...) server, err := app.NewServer(options...)
if err != nil { if err != nil {
mlog.Critical(err.Error()) mlog.Critical(err.Error())

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

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information. // See License.txt for license information.
package utils package config
import ( import (
"bytes" "bytes"
@@ -21,18 +21,13 @@ import (
"net/http" "net/http"
"github.com/mattermost/mattermost-server/einterfaces"
"github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/utils/fileutils" "github.com/mattermost/mattermost-server/utils/fileutils"
"github.com/mattermost/mattermost-server/utils/jsonutils" "github.com/mattermost/mattermost-server/utils/jsonutils"
) )
const (
LOG_ROTATE_SIZE = 10000
LOG_FILENAME = "mattermost.log"
)
var ( var (
termsOfServiceEnabledAndEmpty = model.NewAppError( termsOfServiceEnabledAndEmpty = model.NewAppError(
"Config.IsValid", "Config.IsValid",
@@ -43,36 +38,6 @@ var (
) )
) )
func MloggerConfigFromLoggerConfig(s *model.LogSettings) *mlog.LoggerConfiguration {
return &mlog.LoggerConfiguration{
EnableConsole: *s.EnableConsole,
ConsoleJson: *s.ConsoleJson,
ConsoleLevel: strings.ToLower(*s.ConsoleLevel),
EnableFile: *s.EnableFile,
FileJson: *s.FileJson,
FileLevel: strings.ToLower(*s.FileLevel),
FileLocation: GetLogFileLocation(*s.FileLocation),
}
}
// DON'T USE THIS Modify the level on the app logger
func DisableDebugLogForTest() {
mlog.GloballyDisableDebugLogForTest()
}
// DON'T USE THIS Modify the level on the app logger
func EnableDebugLogForTest() {
mlog.GloballyEnableDebugLogForTest()
}
func GetLogFileLocation(fileLocation string) string {
if fileLocation == "" {
fileLocation, _ = fileutils.FindDir("logs")
}
return filepath.Join(fileLocation, LOG_FILENAME)
}
func SaveConfig(fileName string, config *model.Config) *model.AppError { func SaveConfig(fileName string, config *model.Config) *model.AppError {
b, err := json.MarshalIndent(config, "", " ") b, err := json.MarshalIndent(config, "", " ")
if err != nil { if err != nil {
@@ -716,18 +681,9 @@ func GenerateLimitedClientConfig(c *model.Config, diagnosticId string, license *
return props return props
} }
func ValidateLdapFilter(cfg *model.Config, ldap einterfaces.LdapInterface) *model.AppError {
if *cfg.LdapSettings.Enable && ldap != nil && *cfg.LdapSettings.UserFilter != "" {
if err := ldap.ValidateFilter(*cfg.LdapSettings.UserFilter); err != nil {
return err
}
}
return nil
}
func ValidateLocales(cfg *model.Config) *model.AppError { func ValidateLocales(cfg *model.Config) *model.AppError {
var err *model.AppError var err *model.AppError
locales := GetSupportedLocales() locales := utils.GetSupportedLocales()
if _, ok := locales[*cfg.LocalizationSettings.DefaultServerLocale]; !ok { if _, ok := locales[*cfg.LocalizationSettings.DefaultServerLocale]; !ok {
*cfg.LocalizationSettings.DefaultServerLocale = model.DEFAULT_LOCALE *cfg.LocalizationSettings.DefaultServerLocale = model.DEFAULT_LOCALE
err = model.NewAppError("ValidateLocales", "utils.config.supported_server_locale.app_error", nil, "", http.StatusBadRequest) err = model.NewAppError("ValidateLocales", "utils.config.supported_server_locale.app_error", nil, "", http.StatusBadRequest)
@@ -760,7 +716,7 @@ func ValidateLocales(cfg *model.Config) *model.AppError {
err = model.NewAppError("ValidateLocales", "utils.config.add_client_locale.app_error", nil, "", http.StatusBadRequest) err = model.NewAppError("ValidateLocales", "utils.config.add_client_locale.app_error", nil, "", http.StatusBadRequest)
} }
*cfg.LocalizationSettings.AvailableLocales = strings.Join(RemoveDuplicatesFromStringArray(strings.Split(availableLocales, ",")), ",") *cfg.LocalizationSettings.AvailableLocales = strings.Join(utils.RemoveDuplicatesFromStringArray(strings.Split(availableLocales, ",")), ",")
} }
return err return err

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

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information. // See License.txt for license information.
package utils package config
import ( import (
"bytes" "bytes"
@@ -14,16 +14,17 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
) )
func TestConfig(t *testing.T) { func TestConfig(t *testing.T) {
TranslationsPreInit() utils.TranslationsPreInit()
_, _, _, err := LoadConfig("config.json") _, _, _, err := LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)
} }
func TestReadConfig(t *testing.T) { func TestReadConfig(t *testing.T) {
TranslationsPreInit() utils.TranslationsPreInit()
_, _, err := ReadConfig(bytes.NewReader([]byte(``)), false) _, _, err := ReadConfig(bytes.NewReader([]byte(``)), false)
require.EqualError(t, err, "parsing error at line 1, character 1: unexpected end of JSON input") require.EqualError(t, err, "parsing error at line 1, character 1: unexpected end of JSON input")
@@ -36,7 +37,7 @@ func TestReadConfig(t *testing.T) {
} }
func TestReadConfig_PluginSettings(t *testing.T) { func TestReadConfig_PluginSettings(t *testing.T) {
TranslationsPreInit() utils.TranslationsPreInit()
config, _, err := ReadConfig(bytes.NewReader([]byte(`{ config, _, err := ReadConfig(bytes.NewReader([]byte(`{
"PluginSettings": { "PluginSettings": {
@@ -109,8 +110,9 @@ func TestReadConfig_PluginSettings(t *testing.T) {
}, *config.PluginSettings.PluginStates["jira"]) }, *config.PluginSettings.PluginStates["jira"])
} }
} }
func TestReadConfig_ImageProxySettings(t *testing.T) { func TestReadConfig_ImageProxySettings(t *testing.T) {
TranslationsPreInit() utils.TranslationsPreInit()
t.Run("deprecated settings should still be read properly", func(t *testing.T) { t.Run("deprecated settings should still be read properly", func(t *testing.T) {
config, _, err := ReadConfig(bytes.NewReader([]byte(`{ config, _, err := ReadConfig(bytes.NewReader([]byte(`{
@@ -130,7 +132,7 @@ func TestReadConfig_ImageProxySettings(t *testing.T) {
} }
func TestConfigFromEnviroVars(t *testing.T) { func TestConfigFromEnviroVars(t *testing.T) {
TranslationsPreInit() utils.TranslationsPreInit()
config := `{ config := `{
"ServiceSettings": { "ServiceSettings": {
@@ -375,7 +377,7 @@ func TestConfigFromEnviroVars(t *testing.T) {
} }
func TestValidateLocales(t *testing.T) { func TestValidateLocales(t *testing.T) {
TranslationsPreInit() utils.TranslationsPreInit()
cfg, _, _, err := LoadConfig("config.json") cfg, _, _, err := LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)

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

@@ -49,7 +49,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
panic(err) panic(err)
} }
options := []app.Option{app.ConfigFile(tempConfig.Name()), app.DisableConfigWatch} options := []app.Option{app.ConfigFile(tempConfig.Name(), false)}
options = append(options, app.StoreOverride(mainHelper.Store)) options = append(options, app.StoreOverride(mainHelper.Store))
s, err := app.NewServer(options...) s, err := app.NewServer(options...)

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

@@ -12,6 +12,7 @@ import (
"net/mail" "net/mail"
"net/smtp" "net/smtp"
"github.com/mattermost/mattermost-server/config"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/filesstore" "github.com/mattermost/mattermost-server/services/filesstore"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/utils"
@@ -20,7 +21,7 @@ import (
) )
func TestMailConnectionFromConfig(t *testing.T) { func TestMailConnectionFromConfig(t *testing.T) {
cfg, _, _, err := utils.LoadConfig("config.json") cfg, _, _, err := config.LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)
if conn, err := ConnectToSMTPServer(cfg); err != nil { if conn, err := ConnectToSMTPServer(cfg); err != nil {
@@ -43,7 +44,7 @@ func TestMailConnectionFromConfig(t *testing.T) {
} }
func TestMailConnectionAdvanced(t *testing.T) { func TestMailConnectionAdvanced(t *testing.T) {
cfg, _, _, err := utils.LoadConfig("config.json") cfg, _, _, err := config.LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)
if conn, err := ConnectToSMTPServerAdvanced( if conn, err := ConnectToSMTPServerAdvanced(
@@ -93,7 +94,7 @@ func TestMailConnectionAdvanced(t *testing.T) {
} }
func TestSendMailUsingConfig(t *testing.T) { func TestSendMailUsingConfig(t *testing.T) {
cfg, _, _, err := utils.LoadConfig("config.json") cfg, _, _, err := config.LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)
utils.T = utils.GetUserTranslations("en") utils.T = utils.GetUserTranslations("en")
@@ -135,7 +136,7 @@ func TestSendMailUsingConfig(t *testing.T) {
} }
func TestSendMailUsingConfigAdvanced(t *testing.T) { func TestSendMailUsingConfigAdvanced(t *testing.T) {
cfg, _, _, err := utils.LoadConfig("config.json") cfg, _, _, err := config.LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)
utils.T = utils.GetUserTranslations("en") utils.T = utils.GetUserTranslations("en")

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

@@ -40,7 +40,12 @@ func NewMainHelper() *MainHelper {
utils.TranslationsPreInit() utils.TranslationsPreInit()
settings := storetest.MakeSqlSettings(model.DATABASE_DRIVER_MYSQL) driverName := os.Getenv("MM_SQLSETTINGS_DRIVERNAME")
if driverName == "" {
driverName = model.DATABASE_DRIVER_MYSQL
}
settings := storetest.MakeSqlSettings(driverName)
clusterInterface := &FakeClusterInterface{} clusterInterface := &FakeClusterInterface{}
sqlSupplier := sqlstore.NewSqlSupplier(*settings, nil) sqlSupplier := sqlstore.NewSqlSupplier(*settings, nil)

48
utils/logger.go Обычный файл
Просмотреть файл

@@ -0,0 +1,48 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
import (
"path/filepath"
"strings"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils/fileutils"
)
const (
LOG_ROTATE_SIZE = 10000
LOG_FILENAME = "mattermost.log"
)
func MloggerConfigFromLoggerConfig(s *model.LogSettings) *mlog.LoggerConfiguration {
return &mlog.LoggerConfiguration{
EnableConsole: *s.EnableConsole,
ConsoleJson: *s.ConsoleJson,
ConsoleLevel: strings.ToLower(*s.ConsoleLevel),
EnableFile: *s.EnableFile,
FileJson: *s.FileJson,
FileLevel: strings.ToLower(*s.FileLevel),
FileLocation: GetLogFileLocation(*s.FileLocation),
}
}
func GetLogFileLocation(fileLocation string) string {
if fileLocation == "" {
fileLocation, _ = fileutils.FindDir("logs")
}
return filepath.Join(fileLocation, LOG_FILENAME)
}
// DON'T USE THIS Modify the level on the app logger
func DisableDebugLogForTest() {
mlog.GloballyDisableDebugLogForTest()
}
// DON'T USE THIS Modify the level on the app logger
func EnableDebugLogForTest() {
mlog.GloballyEnableDebugLogForTest()
}

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

@@ -8,10 +8,8 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func handlerForHTTPErrors(c *Context, w http.ResponseWriter, r *http.Request) { func handlerForHTTPErrors(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -19,14 +17,10 @@ func handlerForHTTPErrors(c *Context, w http.ResponseWriter, r *http.Request) {
} }
func TestHandlerServeHTTPErrors(t *testing.T) { func TestHandlerServeHTTPErrors(t *testing.T) {
s, err := app.NewServer(app.StoreOverride(mainHelper.Store), app.DisableConfigWatch) th := Setup().InitBasic()
require.Nil(t, err) defer th.TearDown()
defer s.Shutdown()
web := New(s, s.AppOptions, s.Router) web := New(th.Server, th.Server.AppOptions, th.Server.Router)
if err != nil {
panic(err)
}
handler := web.NewHandler(handlerForHTTPErrors) handler := web.NewHandler(handlerForHTTPErrors)
var flagtests = []struct { var flagtests = []struct {
@@ -63,21 +57,15 @@ func handlerForHTTPSecureTransport(c *Context, w http.ResponseWriter, r *http.Re
} }
func TestHandlerServeHTTPSecureTransport(t *testing.T) { func TestHandlerServeHTTPSecureTransport(t *testing.T) {
s, err := app.NewServer(app.StoreOverride(mainHelper.Store), app.DisableConfigWatch) th := Setup().InitBasic()
require.Nil(t, err) defer th.TearDown()
defer s.Shutdown()
a := s.FakeApp() th.App.UpdateConfig(func(config *model.Config) {
a.UpdateConfig(func(config *model.Config) {
*config.ServiceSettings.TLSStrictTransport = true *config.ServiceSettings.TLSStrictTransport = true
*config.ServiceSettings.TLSStrictTransportMaxAge = 6000 *config.ServiceSettings.TLSStrictTransportMaxAge = 6000
}) })
web := New(s, s.AppOptions, s.Router) web := New(th.Server, th.Server.AppOptions, th.Server.Router)
if err != nil {
panic(err)
}
handler := web.NewHandler(handlerForHTTPSecureTransport) handler := web.NewHandler(handlerForHTTPSecureTransport)
request := httptest.NewRequest("GET", "/api/v4/test", nil) request := httptest.NewRequest("GET", "/api/v4/test", nil)
@@ -94,7 +82,7 @@ func TestHandlerServeHTTPSecureTransport(t *testing.T) {
t.Errorf("Expected max-age=6000, got %s", header) t.Errorf("Expected max-age=6000, got %s", header)
} }
a.UpdateConfig(func(config *model.Config) { th.App.UpdateConfig(func(config *model.Config) {
*config.ServiceSettings.TLSStrictTransport = false *config.ServiceSettings.TLSStrictTransport = false
}) })
@@ -109,7 +97,6 @@ func TestHandlerServeHTTPSecureTransport(t *testing.T) {
} }
} }
func handlerForCSRFToken(c *Context, w http.ResponseWriter, r *http.Request) { func handlerForCSRFToken(c *Context, w http.ResponseWriter, r *http.Request) {
} }
@@ -117,11 +104,11 @@ func TestHandlerServeCSRFToken(t *testing.T) {
th := Setup().InitBasic() th := Setup().InitBasic()
defer th.TearDown() defer th.TearDown()
session :=&model.Session{ session := &model.Session{
UserId: th.BasicUser.Id, UserId: th.BasicUser.Id,
CreateAt: model.GetMillis(), CreateAt: model.GetMillis(),
Roles: model.SYSTEM_USER_ROLE_ID, Roles: model.SYSTEM_USER_ROLE_ID,
IsOAuth: false, IsOAuth: false,
} }
session.GenerateCSRF() session.GenerateCSRF()
session.SetExpireInDays(1) session.SetExpireInDays(1)
@@ -142,15 +129,15 @@ func TestHandlerServeCSRFToken(t *testing.T) {
} }
cookie := &http.Cookie{ cookie := &http.Cookie{
Name: model.SESSION_COOKIE_USER, Name: model.SESSION_COOKIE_USER,
Value: th.BasicUser.Username, Value: th.BasicUser.Username,
} }
cookie2 := &http.Cookie{ cookie2 := &http.Cookie{
Name: model.SESSION_COOKIE_TOKEN, Name: model.SESSION_COOKIE_TOKEN,
Value: session.Token, Value: session.Token,
} }
cookie3 := &http.Cookie{ cookie3 := &http.Cookie{
Name: model.SESSION_COOKIE_CSRF, Name: model.SESSION_COOKIE_CSRF,
Value: session.GetCSRF(), Value: session.GetCSRF(),
} }
@@ -183,7 +170,7 @@ func TestHandlerServeCSRFToken(t *testing.T) {
// Fallback Behavior Used - Success expected // Fallback Behavior Used - Success expected
// ToDo (DSchalla) 2019/01/04: Remove once legacy CSRF Handling is removed // ToDo (DSchalla) 2019/01/04: Remove once legacy CSRF Handling is removed
th.App.UpdateConfig(func(config *model.Config){ th.App.UpdateConfig(func(config *model.Config) {
*config.ServiceSettings.ExperimentalStrictCSRFEnforcement = false *config.ServiceSettings.ExperimentalStrictCSRFEnforcement = false
}) })
request = httptest.NewRequest("POST", "/api/v4/test", nil) request = httptest.NewRequest("POST", "/api/v4/test", nil)
@@ -200,7 +187,7 @@ func TestHandlerServeCSRFToken(t *testing.T) {
// Fallback Behavior Used with Strict Enforcement - Failure Expected // Fallback Behavior Used with Strict Enforcement - Failure Expected
// ToDo (DSchalla) 2019/01/04: Remove once legacy CSRF Handling is removed // ToDo (DSchalla) 2019/01/04: Remove once legacy CSRF Handling is removed
th.App.UpdateConfig(func(config *model.Config){ th.App.UpdateConfig(func(config *model.Config) {
*config.ServiceSettings.ExperimentalStrictCSRFEnforcement = true *config.ServiceSettings.ExperimentalStrictCSRFEnforcement = true
}) })
response = httptest.NewRecorder() response = httptest.NewRecorder()

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

@@ -5,10 +5,14 @@ package web
import ( import (
"fmt" "fmt"
"io"
"io/ioutil"
"os"
"testing" "testing"
"github.com/mattermost/mattermost-server/app" "github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils/fileutils"
) )
var ApiClient *model.Client4 var ApiClient *model.Client4
@@ -28,7 +32,25 @@ type TestHelper struct {
func Setup() *TestHelper { func Setup() *TestHelper {
mainHelper.Store.DropAllTables() mainHelper.Store.DropAllTables()
s, err := app.NewServer(app.StoreOverride(mainHelper.Store), app.DisableConfigWatch) permConfig, err := os.Open(fileutils.FindConfigFile("config.json"))
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)
}
options := []app.Option{app.ConfigFile(tempConfig.Name(), false)}
options = append(options, app.StoreOverride(mainHelper.Store))
s, err := app.NewServer(options...)
if err != nil { if err != nil {
panic(err) panic(err)
} }

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

@@ -235,13 +235,13 @@ func TestCommandWebhooks(t *testing.T) {
th := Setup().InitBasic() th := Setup().InitBasic()
defer th.TearDown() defer th.TearDown()
cmd, err := th.App.CreateCommand(&model.Command{ cmd, appErr := th.App.CreateCommand(&model.Command{
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
TeamId: th.BasicTeam.Id, TeamId: th.BasicTeam.Id,
URL: "http://nowhere.com", URL: "http://nowhere.com",
Method: model.COMMAND_METHOD_POST, Method: model.COMMAND_METHOD_POST,
Trigger: "delayed"}) Trigger: "delayed"})
require.Nil(t, err) require.Nil(t, appErr)
args := &model.CommandArgs{ args := &model.CommandArgs{
TeamId: th.BasicTeam.Id, TeamId: th.BasicTeam.Id,
@@ -249,22 +249,22 @@ func TestCommandWebhooks(t *testing.T) {
ChannelId: th.BasicChannel.Id, ChannelId: th.BasicChannel.Id,
} }
hook, err := th.App.CreateCommandWebhook(cmd.Id, args) hook, appErr := th.App.CreateCommandWebhook(cmd.Id, args)
if err != nil { if appErr != nil {
t.Fatal(err) t.Fatal(appErr)
} }
if resp, _ := http.Post(ApiClient.Url+"/hooks/commands/123123123123", "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)); resp.StatusCode != http.StatusNotFound { resp, err := http.Post(ApiClient.Url+"/hooks/commands/123123123123", "application/json", bytes.NewBufferString(`{"text":"this is a test"}`))
t.Fatal("expected not-found for non-existent hook") require.NoError(t, err)
} assert.Equal(t, http.StatusNotFound, resp.StatusCode, "expected not-found for non-existent hook")
if resp, err := http.Post(ApiClient.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"invalid`)); err != nil || resp.StatusCode != http.StatusBadRequest { resp, err = http.Post(ApiClient.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"invalid`))
t.Fatal(err) require.NoError(t, err)
} assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
if resp, err := http.Post(ApiClient.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)); err != nil || resp.StatusCode != http.StatusOK { if resp, appErr := http.Post(ApiClient.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)); err != nil || resp.StatusCode != http.StatusOK {
t.Fatal(err) t.Fatal(appErr)
} }
} }