[MM-41981] Always install the latest compatible version via the Marketplace (#19613)

Этот коммит содержится в:
Ben Schumacher
2022-03-03 22:53:01 +01:00
коммит произвёл GitHub
родитель 72f937f96b
Коммит 275adc8c30
4 изменённых файлов: 87 добавлений и 18 удалений

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

@@ -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."