[MM-41981] Always install the latest compatible version via the Marketplace (#19613)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
72f937f96b
Коммит
275adc8c30
@@ -151,6 +151,10 @@ func installMarketplacePlugin(c *Context, w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
auditRec.AddMeta("plugin_id", pluginRequest.Id)
|
||||
|
||||
// Always install the latest compatible version
|
||||
// https://mattermost.atlassian.net/browse/MM-41981
|
||||
pluginRequest.Version = ""
|
||||
|
||||
manifest, appErr := c.App.Channels().InstallMarketplacePlugin(pluginRequest)
|
||||
if appErr != nil {
|
||||
c.Err = appErr
|
||||
|
||||
@@ -1308,7 +1308,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
request := &model.InstallMarketplacePluginRequest{Id: "", Version: ""}
|
||||
request := &model.InstallMarketplacePluginRequest{Id: ""}
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
@@ -1374,7 +1374,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
*cfg.PluginSettings.EnableMarketplace = true
|
||||
*cfg.PluginSettings.MarketplaceURL = testServer.URL
|
||||
})
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "some_plugin_id", Version: "0.0.1"}
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "some_plugin_id"}
|
||||
plugin, resp, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.Error(t, err)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
@@ -1395,7 +1395,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
*cfg.PluginSettings.MarketplaceURL = testServer.URL
|
||||
*cfg.PluginSettings.AllowInsecureDownloadURL = true
|
||||
})
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin2", Version: "1.2.2"}
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin2"}
|
||||
plugin, resp, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.Error(t, err)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
@@ -1425,7 +1425,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
appErr := th.App.AddPublicKey("pub_key", key)
|
||||
require.Nil(t, appErr)
|
||||
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin2", Version: "1.2.3"}
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin2"}
|
||||
manifest, _, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, manifest)
|
||||
@@ -1447,6 +1447,51 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
require.Nil(t, appErr)
|
||||
}, "verify, install and remove plugin")
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
|
||||
serverVersion := req.URL.Query().Get("server_version")
|
||||
require.NotEmpty(t, serverVersion)
|
||||
require.Equal(t, model.CurrentVersion, serverVersion)
|
||||
res.WriteHeader(http.StatusOK)
|
||||
json, err := json.Marshal([]*model.MarketplacePlugin{samplePlugins[1]})
|
||||
require.NoError(t, err)
|
||||
res.Write(json)
|
||||
}))
|
||||
defer testServer.Close()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.PluginSettings.EnableMarketplace = true
|
||||
*cfg.PluginSettings.EnableRemoteMarketplace = true
|
||||
*cfg.PluginSettings.MarketplaceURL = testServer.URL
|
||||
})
|
||||
|
||||
key, err := os.Open(filepath.Join(path, "development-private-key.asc"))
|
||||
require.NoError(t, err)
|
||||
appErr := th.App.AddPublicKey("pub_key", key)
|
||||
require.Nil(t, appErr)
|
||||
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin2", Version: "9.9.9"}
|
||||
manifest, _, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, manifest)
|
||||
require.Equal(t, "testplugin2", manifest.Id)
|
||||
require.Equal(t, "1.2.3", manifest.Version)
|
||||
|
||||
filePath := filepath.Join("plugins", "testplugin2.tar.gz.sig")
|
||||
savedSigFile, appErr := th.App.ReadFile(filePath)
|
||||
require.Nil(t, appErr)
|
||||
require.EqualValues(t, sigFile, savedSigFile)
|
||||
|
||||
_, err = client.RemovePlugin(manifest.Id)
|
||||
require.NoError(t, err)
|
||||
exists, appErr := th.App.FileExists(filePath)
|
||||
require.Nil(t, appErr)
|
||||
require.False(t, exists)
|
||||
|
||||
appErr = th.App.DeletePublicKey("pub_key")
|
||||
require.Nil(t, appErr)
|
||||
}, "ignore version in Marketplace request")
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
requestHandled := false
|
||||
|
||||
@@ -1612,7 +1657,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
require.Len(t, pluginsResp.Inactive, 0)
|
||||
|
||||
// Should fail to install unknown prepackaged plugin
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin", Version: "0.0.2"}
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testpluginXX"}
|
||||
manifest, resp, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.Error(t, err)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
@@ -1628,7 +1673,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
require.Len(t, pluginsResp.Active, 0)
|
||||
require.Len(t, pluginsResp.Inactive, 0)
|
||||
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin", Version: "0.0.1"}
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin"}
|
||||
manifest1, _, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, manifest1)
|
||||
@@ -1643,7 +1688,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
}})
|
||||
|
||||
// Try to install remote marketplace plugin
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin2", Version: "1.2.3"}
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin2"}
|
||||
manifest, resp, err = client.InstallMarketplacePlugin(pRequest)
|
||||
require.Error(t, err)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
@@ -1657,7 +1702,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
*cfg.PluginSettings.AllowInsecureDownloadURL = true
|
||||
})
|
||||
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin2", Version: "1.2.3"}
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin2"}
|
||||
manifest2, _, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, manifest2)
|
||||
@@ -1746,7 +1791,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
require.Len(t, pluginsResp.Active, 0)
|
||||
require.Len(t, pluginsResp.Inactive, 0)
|
||||
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin", Version: "0.0.1"}
|
||||
pRequest := &model.InstallMarketplacePluginRequest{Id: "testplugin"}
|
||||
manifest, resp, err := client.InstallMarketplacePlugin(pRequest)
|
||||
require.Error(t, err)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
@@ -1757,7 +1802,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
|
||||
require.Len(t, pluginsResp.Active, 0)
|
||||
require.Len(t, pluginsResp.Inactive, 0)
|
||||
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin2", Version: "1.2.3"}
|
||||
pRequest = &model.InstallMarketplacePluginRequest{Id: "testplugin2"}
|
||||
manifest, resp, err = client.InstallMarketplacePlugin(pRequest)
|
||||
require.Error(t, err)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
|
||||
@@ -196,23 +196,39 @@ func (ch *Channels) InstallMarketplacePlugin(request *model.InstallMarketplacePl
|
||||
signatureFile = bytes.NewReader(prepackagedPlugin.Signature)
|
||||
}
|
||||
|
||||
if *ch.cfgSvc.Config().PluginSettings.EnableRemoteMarketplace && pluginFile == nil {
|
||||
if *ch.cfgSvc.Config().PluginSettings.EnableRemoteMarketplace {
|
||||
var plugin *model.BaseMarketplacePlugin
|
||||
plugin, appErr = ch.getRemoteMarketplacePlugin(request.Id, request.Version)
|
||||
if appErr != nil {
|
||||
return nil, appErr
|
||||
}
|
||||
|
||||
downloadedPluginBytes, err := ch.srv.downloadFromURL(plugin.DownloadURL)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("InstallMarketplacePlugin", "app.plugin.install_marketplace_plugin.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
var prepackagedVersion semver.Version
|
||||
if prepackagedPlugin != nil {
|
||||
var err error
|
||||
prepackagedVersion, err = semver.Parse(prepackagedPlugin.Manifest.Version)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("InstallMarketplacePlugin", "app.plugin.invalid_version.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
signature, err := plugin.DecodeSignature()
|
||||
|
||||
marketplaceVersion, err := semver.Parse(plugin.Manifest.Version)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("InstallMarketplacePlugin", "app.plugin.signature_decode.app_error", nil, err.Error(), http.StatusNotImplemented)
|
||||
return nil, model.NewAppError("InstallMarketplacePlugin", "app.prepackged-plugin.invalid_version.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if prepackagedVersion.LT(marketplaceVersion) { // Always true if no prepackaged plugin was found
|
||||
downloadedPluginBytes, err := ch.srv.downloadFromURL(plugin.DownloadURL)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("InstallMarketplacePlugin", "app.plugin.install_marketplace_plugin.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
signature, err := plugin.DecodeSignature()
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("InstallMarketplacePlugin", "app.plugin.signature_decode.app_error", nil, err.Error(), http.StatusNotImplemented)
|
||||
}
|
||||
pluginFile = bytes.NewReader(downloadedPluginBytes)
|
||||
signatureFile = signature
|
||||
}
|
||||
pluginFile = bytes.NewReader(downloadedPluginBytes)
|
||||
signatureFile = signature
|
||||
}
|
||||
|
||||
if pluginFile == nil {
|
||||
|
||||
@@ -5999,6 +5999,10 @@
|
||||
"id": "app.preference.save.updating.app_error",
|
||||
"translation": "We encountered an error while updating preferences."
|
||||
},
|
||||
{
|
||||
"id": "app.prepackged-plugin.invalid_version.app_error",
|
||||
"translation": "Prepackged plugin version could not be parsed."
|
||||
},
|
||||
{
|
||||
"id": "app.reaction.bulk_get_for_post_ids.app_error",
|
||||
"translation": "Unable to get reactions for post."
|
||||
|
||||
Ссылка в новой задаче
Block a user