diff --git a/cmd/mattermost/commands/config.go b/cmd/mattermost/commands/config.go index 273c52f262..6809c6172e 100644 --- a/cmd/mattermost/commands/config.go +++ b/cmd/mattermost/commands/config.go @@ -250,20 +250,8 @@ func configMigrateCmdF(command *cobra.Command, args []string) error { from := args[0] to := args[1] - // Get source config store - invalid config will throw error here - fromConfigStore, err := config.NewStore(from, false) - if err != nil { - return errors.Wrapf(err, "failed to access config %s", from) - } + err := config.Migrate(from, to) - // Get destination config store - toConfigStore, err := config.NewStore(to, false) - if err != nil { - return errors.Wrapf(err, "failed to access config %s", to) - } - - // Copy config from source to destination - _, err = toConfigStore.Set(fromConfigStore.Get()) if err != nil { return errors.Wrap(err, "failed to migrate config") } diff --git a/config/migrate.go b/config/migrate.go new file mode 100644 index 0000000000..c6e9856e2c --- /dev/null +++ b/config/migrate.go @@ -0,0 +1,52 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package config + +import "github.com/pkg/errors" + +func Migrate(from, to string) error { + source, err := NewStore(from, false) + if err != nil { + return errors.Wrapf(err, "failed to access source config %s", from) + } + + destination, err := NewStore(to, false) + if err != nil { + return errors.Wrapf(err, "failed to access destination config %s", to) + } + + sourceConfig := source.Get() + if _, err = destination.Set(sourceConfig); err != nil { + return errors.Wrapf(err, "failed to set config") + } + + files := []string{*sourceConfig.SamlSettings.IdpCertificateFile, *sourceConfig.SamlSettings.PublicCertificateFile, + *sourceConfig.SamlSettings.PrivateKeyFile} + + for _, file := range files { + err = migrateFile(file, source, destination) + + if err != nil { + return err + } + } + return nil +} + +func migrateFile(name string, source Store, destination Store) error { + fileExists, err := source.HasFile(name) + if err != nil { + return errors.Wrapf(err, "failed to check existence of %s", name) + } + + if fileExists { + file, err := source.GetFile(name) + err = destination.SetFile(name, file) + if err != nil { + return errors.Wrapf(err, "failed to migrate %s", name) + } + } + + return nil +} diff --git a/config/migrate_test.go b/config/migrate_test.go new file mode 100644 index 0000000000..0560a7d01b --- /dev/null +++ b/config/migrate_test.go @@ -0,0 +1,60 @@ +package config + +import ( + "fmt" + "github.com/mattermost/mattermost-server/testlib" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func TestMigrateDatabaseToFile(t *testing.T) { + helper := testlib.NewMainHelper() + sqlSettings := helper.GetSqlSettings() + sqlDSN := fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource) + fileDSN := "config.json" + files := []string{"IdpCertificateFile", "PublicCertificateFile", "PrivateKeyFile"} + data := make([]byte, 5) + ds, err := NewDatabaseStore(sqlDSN) + defer ds.Close() + require.NoError(t, err) + config := ds.Get() + config.SamlSettings.IdpCertificateFile = &files[0] + config.SamlSettings.PublicCertificateFile = &files[1] + config.SamlSettings.PrivateKeyFile = &files[2] + _, err = ds.Set(config) + require.NoError(t, err) + + for _, file := range files { + err = ds.SetFile(file, data) + require.NoError(t, err) + } + err = Migrate(sqlDSN, fileDSN) + require.NoError(t, err) + + fs, err := NewFileStore(fileDSN, false) + require.NoError(t, err) + defer fs.Close() + + for _, file := range files { + hasFile, err := fs.HasFile(file) + require.NoError(t, err) + defer fs.RemoveFile(file) + assert.True(t, hasFile) + } + + assert.Equal(t, ds.Get(), fs.Get()) +} + +func TestMigrateFileToDatabaseWhenFilePathIsNotSpecified(t *testing.T) { + helper := testlib.NewMainHelper() + sqlSettings := helper.GetSqlSettings() + sqlDSN := fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource) + fileDSN := "config.json" + + _, err := NewFileStore(fileDSN, true) + require.NoError(t, err) + + err = Migrate(fileDSN, sqlDSN) + require.NoError(t, err) +}