[MM-49929] Work templates: allow simple users to list marketplace plugins (#22151)

This commit is contained in:
Julien Tant 2023-01-26 09:08:05 -07:00 committed by GitHub
parent 1880297a90
commit 7bfca605e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 18 deletions

View file

@ -288,17 +288,18 @@ func getMarketplacePlugins(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadPlugins) {
c.SetPermissionError(model.PermissionSysconsoleReadPlugins)
return
}
filter, err := parseMarketplacePluginFilter(r.URL)
if err != nil {
c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
// if we are looking for remote only, we don't need to check for permissions
if !filter.RemoteOnly && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadPlugins) {
c.SetPermissionError(model.PermissionSysconsoleReadPlugins)
return
}
plugins, appErr := c.App.GetMarketplacePlugins(filter)
if appErr != nil {
c.Err = appErr
@ -386,12 +387,19 @@ func parseMarketplacePluginFilter(u *url.URL) (*model.MarketplacePluginFilter, e
filter := u.Query().Get("filter")
serverVersion := u.Query().Get("server_version")
localOnly, _ := strconv.ParseBool(u.Query().Get("local_only"))
remoteOnly, _ := strconv.ParseBool(u.Query().Get("remote_only"))
if localOnly && remoteOnly {
return nil, errors.New("local_only and remote_only cannot be both true")
}
return &model.MarketplacePluginFilter{
Page: page,
PerPage: perPage,
Filter: filter,
ServerVersion: serverVersion,
LocalOnly: localOnly,
RemoteOnly: remoteOnly,
}, nil
}

View file

@ -1126,6 +1126,62 @@ func TestGetLocalPluginInMarketplace(t *testing.T) {
})
}
func TestGetRemotePluginInMarketplace(t *testing.T) {
th := Setup(t)
defer th.TearDown()
samplePlugins := []*model.MarketplacePlugin{
{
BaseMarketplacePlugin: &model.BaseMarketplacePlugin{
HomepageURL: "https://example.com/mattermost/mattermost-plugin-nps",
IconData: "https://example.com/icon.svg",
DownloadURL: "www.github.com/example",
Manifest: &model.Manifest{
Id: "testplugin2",
Name: "testplugin2",
Description: "a second plugin",
Version: "1.2.2",
MinServerVersion: "",
},
},
InstalledVersion: "",
},
}
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)
json, err := json.Marshal([]*model.MarketplacePlugin{samplePlugins[0]})
require.NoError(t, err)
res.Write(json)
}))
defer testServer.Close()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.EnableMarketplace = true
*cfg.PluginSettings.EnableRemoteMarketplace = true
*cfg.PluginSettings.EnableUploads = true
*cfg.PluginSettings.MarketplaceURL = testServer.URL
})
// Upload one local plugin
path, _ := fileutils.FindDir("tests")
tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)
manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
require.NoError(t, err)
plugins, _, err := th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{RemoteOnly: true})
require.NoError(t, err)
require.Len(t, plugins, 1)
require.Equal(t, samplePlugins[0], plugins[0])
_, err = th.SystemAdminClient.RemovePlugin(manifest.Id)
require.NoError(t, err)
}
func TestGetPrepackagedPluginInMarketplace(t *testing.T) {
th := Setup(t)
defer th.TearDown()

View file

@ -571,24 +571,26 @@ func (a *App) GetMarketplacePlugins(filter *model.MarketplacePluginFilter) ([]*m
plugins = p
}
// Some plugin don't work on cloud. The remote Marketplace is aware of this fact,
// but prepackaged plugins are not. Hence, on a cloud installation prepackaged plugins
// shouldn't be shown in the Marketplace modal.
// This is a short term fix. The long term solution is to have a separate set of
// prepacked plugins for cloud: https://mattermost.atlassian.net/browse/MM-31331.
license := a.Srv().License()
if license == nil || !license.IsCloud() {
appErr := a.mergePrepackagedPlugins(plugins)
if !filter.RemoteOnly {
// Some plugin don't work on cloud. The remote Marketplace is aware of this fact,
// but prepackaged plugins are not. Hence, on a cloud installation prepackaged plugins
// shouldn't be shown in the Marketplace modal.
// This is a short term fix. The long term solution is to have a separate set of
// prepacked plugins for cloud: https://mattermost.atlassian.net/browse/MM-31331.
license := a.Srv().License()
if license == nil || !license.IsCloud() {
appErr := a.mergePrepackagedPlugins(plugins)
if appErr != nil {
return nil, appErr
}
}
appErr := a.mergeLocalPlugins(plugins)
if appErr != nil {
return nil, appErr
}
}
appErr := a.mergeLocalPlugins(plugins)
if appErr != nil {
return nil, appErr
}
// Filter plugins.
var result []*model.MarketplacePlugin
for _, p := range plugins {

View file

@ -89,6 +89,7 @@ type MarketplacePluginFilter struct {
Platform string
PluginId string
ReturnAllVersions bool
RemoteOnly bool
}
// ApplyToURL modifies the given url to include query string parameters for the request.
@ -104,6 +105,7 @@ func (filter *MarketplacePluginFilter) ApplyToURL(u *url.URL) {
q.Add("enterprise_plugins", strconv.FormatBool(filter.EnterprisePlugins))
q.Add("cloud", strconv.FormatBool(filter.Cloud))
q.Add("local_only", strconv.FormatBool(filter.LocalOnly))
q.Add("remote_only", strconv.FormatBool(filter.RemoteOnly))
q.Add("platform", filter.Platform)
q.Add("plugin_id", filter.PluginId)
q.Add("return_all_versions", strconv.FormatBool(filter.ReturnAllVersions))