diff --git a/api4/config.go b/api4/config.go index 5609691bea..2a6c0883d0 100644 --- a/api4/config.go +++ b/api4/config.go @@ -407,6 +407,12 @@ func migrateConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } + isCloud := c.App.Srv().License() != nil && *c.App.Srv().License().Features.Cloud + if isCloud { + c.Err = model.NewAppError("migrateConfig", "api.config.migrate_config_restricted.app_error", nil, "", http.StatusForbidden) + return + } + err := config.Migrate(from, to) if err != nil { c.Err = model.NewAppError("migrateConfig", "api.config.migrate_config.app_error", nil, err.Error(), http.StatusInternalServerError) diff --git a/api4/config_local.go b/api4/config_local.go index dff010978e..a6e4f0f683 100644 --- a/api4/config_local.go +++ b/api4/config_local.go @@ -20,7 +20,7 @@ func (api *API) InitConfigLocal() { api.BaseRoutes.APIRoot.Handle("/config", api.APILocal(localUpdateConfig)).Methods("PUT") api.BaseRoutes.APIRoot.Handle("/config/patch", api.APILocal(localPatchConfig)).Methods("PUT") api.BaseRoutes.APIRoot.Handle("/config/reload", api.APILocal(configReload)).Methods("POST") - api.BaseRoutes.APIRoot.Handle("/config/migrate", api.APILocal(migrateConfig)).Methods("POST") + api.BaseRoutes.APIRoot.Handle("/config/migrate", api.APILocal(localMigrateConfig)).Methods("POST") } func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) { @@ -140,3 +140,34 @@ func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) { mlog.Warn("Error while writing response", mlog.Err(err)) } } + +func localMigrateConfig(c *Context, w http.ResponseWriter, r *http.Request) { + props := model.StringInterfaceFromJSON(r.Body) + from, ok := props["from"].(string) + if !ok { + c.SetInvalidParam("from") + return + } + to, ok := props["to"].(string) + if !ok { + c.SetInvalidParam("to") + return + } + + auditRec := c.MakeAuditRecord("migrateConfig", audit.Fail) + defer c.LogAuditRec(auditRec) + + if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { + c.SetPermissionError(model.PermissionManageSystem) + return + } + + err := config.Migrate(from, to) + if err != nil { + c.Err = model.NewAppError("migrateConfig", "api.config.migrate_config.app_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + auditRec.Success() + ReturnStatusOK(w) +} diff --git a/api4/config_test.go b/api4/config_test.go index 953c6b63e3..9b367b23b4 100644 --- a/api4/config_test.go +++ b/api4/config_test.go @@ -787,4 +787,20 @@ func TestMigrateConfig(t *testing.T) { _, err = client.MigrateConfig("from.json", "to.json") require.NoError(t, err) }) + + t.Run("Cloud instances should not access to this API", func(t *testing.T) { + require.True(t, th.App.Srv().SetLicense(model.NewTestLicense("cloud"))) + + f, err := config.NewStoreFromDSN("from.json", false, nil) + require.NoError(t, err) + defer f.RemoveFile("from.json") + + _, err = config.NewStoreFromDSN("to.json", false, nil) + require.NoError(t, err) + defer f.RemoveFile("to.json") + + response, cErr := th.SystemAdminClient.MigrateConfig("from.json", "to.json") + require.Error(t, cErr) + CheckForbiddenStatus(t, response) + }) } diff --git a/i18n/en.json b/i18n/en.json index 8e3a8acced..88c04e4e59 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1454,6 +1454,10 @@ "id": "api.config.migrate_config.app_error", "translation": "Failed to migrate config store." }, + { + "id": "api.config.migrate_config_restricted.app_error", + "translation": "Config migration is restricted due to instance type." + }, { "id": "api.config.patch_config.diff.app_error", "translation": "Failed to diff configs"