mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-49929] Work templates: allow simple users to list marketplace plugins (#22151)
This commit is contained in:
@@ -288,17 +288,18 @@ func getMarketplacePlugins(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadPlugins) {
|
|
||||||
c.SetPermissionError(model.PermissionSysconsoleReadPlugins)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
filter, err := parseMarketplacePluginFilter(r.URL)
|
filter, err := parseMarketplacePluginFilter(r.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||||
return
|
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)
|
plugins, appErr := c.App.GetMarketplacePlugins(filter)
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
c.Err = appErr
|
c.Err = appErr
|
||||||
@@ -386,12 +387,19 @@ func parseMarketplacePluginFilter(u *url.URL) (*model.MarketplacePluginFilter, e
|
|||||||
filter := u.Query().Get("filter")
|
filter := u.Query().Get("filter")
|
||||||
serverVersion := u.Query().Get("server_version")
|
serverVersion := u.Query().Get("server_version")
|
||||||
localOnly, _ := strconv.ParseBool(u.Query().Get("local_only"))
|
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{
|
return &model.MarketplacePluginFilter{
|
||||||
Page: page,
|
Page: page,
|
||||||
PerPage: perPage,
|
PerPage: perPage,
|
||||||
Filter: filter,
|
Filter: filter,
|
||||||
ServerVersion: serverVersion,
|
ServerVersion: serverVersion,
|
||||||
LocalOnly: localOnly,
|
LocalOnly: localOnly,
|
||||||
|
RemoteOnly: remoteOnly,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
func TestGetPrepackagedPluginInMarketplace(t *testing.T) {
|
||||||
th := Setup(t)
|
th := Setup(t)
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
|
|||||||
@@ -571,6 +571,7 @@ func (a *App) GetMarketplacePlugins(filter *model.MarketplacePluginFilter) ([]*m
|
|||||||
plugins = p
|
plugins = p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !filter.RemoteOnly {
|
||||||
// Some plugin don't work on cloud. The remote Marketplace is aware of this fact,
|
// 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
|
// but prepackaged plugins are not. Hence, on a cloud installation prepackaged plugins
|
||||||
// shouldn't be shown in the Marketplace modal.
|
// shouldn't be shown in the Marketplace modal.
|
||||||
@@ -588,6 +589,7 @@ func (a *App) GetMarketplacePlugins(filter *model.MarketplacePluginFilter) ([]*m
|
|||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return nil, appErr
|
return nil, appErr
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Filter plugins.
|
// Filter plugins.
|
||||||
var result []*model.MarketplacePlugin
|
var result []*model.MarketplacePlugin
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ type MarketplacePluginFilter struct {
|
|||||||
Platform string
|
Platform string
|
||||||
PluginId string
|
PluginId string
|
||||||
ReturnAllVersions bool
|
ReturnAllVersions bool
|
||||||
|
RemoteOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyToURL modifies the given url to include query string parameters for the request.
|
// 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("enterprise_plugins", strconv.FormatBool(filter.EnterprisePlugins))
|
||||||
q.Add("cloud", strconv.FormatBool(filter.Cloud))
|
q.Add("cloud", strconv.FormatBool(filter.Cloud))
|
||||||
q.Add("local_only", strconv.FormatBool(filter.LocalOnly))
|
q.Add("local_only", strconv.FormatBool(filter.LocalOnly))
|
||||||
|
q.Add("remote_only", strconv.FormatBool(filter.RemoteOnly))
|
||||||
q.Add("platform", filter.Platform)
|
q.Add("platform", filter.Platform)
|
||||||
q.Add("plugin_id", filter.PluginId)
|
q.Add("plugin_id", filter.PluginId)
|
||||||
q.Add("return_all_versions", strconv.FormatBool(filter.ReturnAllVersions))
|
q.Add("return_all_versions", strconv.FormatBool(filter.ReturnAllVersions))
|
||||||
|
|||||||
Reference in New Issue
Block a user