Plugins: Register management endpoints only when external managed is also false (#51802) (#51816)

* Only define plugin install endpoints when catalog enabled

* add external check

(cherry picked from commit 40dff288cd)

Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
This commit is contained in:
Grot (@grafanabot)
2022-07-07 04:58:51 -04:00
committed by GitHub
co-authored by Will Browne
parent e347be769f
commit 14e622414b
4 changed files with 108 additions and 7 deletions
+1 -1
View File
@@ -310,7 +310,7 @@ func (hs *HTTPServer) registerRoutes() {
apiRoute.Any("/plugins/:pluginId/resources/*", hs.CallResource)
apiRoute.Get("/plugins/errors", routing.Wrap(hs.GetPluginErrorsList))
if hs.Cfg.PluginAdminEnabled {
if hs.Cfg.PluginAdminEnabled && !hs.Cfg.PluginAdminExternalManageEnabled {
apiRoute.Group("/plugins", func(pluginRoute routing.RouteRegister) {
pluginRoute.Post("/:pluginId/install", routing.Wrap(hs.InstallPlugin))
pluginRoute.Post("/:pluginId/uninstall", routing.Wrap(hs.UninstallPlugin))
+21 -6
View File
@@ -7,20 +7,18 @@ import (
)
type fakePluginStore struct {
plugins.Store
plugins map[string]plugins.PluginDTO
}
func (pr fakePluginStore) Plugin(_ context.Context, pluginID string) (plugins.PluginDTO, bool) {
p, exists := pr.plugins[pluginID]
func (ps fakePluginStore) Plugin(_ context.Context, pluginID string) (plugins.PluginDTO, bool) {
p, exists := ps.plugins[pluginID]
return p, exists
}
func (pr fakePluginStore) Plugins(_ context.Context, pluginTypes ...plugins.Type) []plugins.PluginDTO {
func (ps fakePluginStore) Plugins(_ context.Context, pluginTypes ...plugins.Type) []plugins.PluginDTO {
var result []plugins.PluginDTO
for _, v := range pr.plugins {
for _, v := range ps.plugins {
for _, t := range pluginTypes {
if v.Type == t {
result = append(result, v)
@@ -31,6 +29,23 @@ func (pr fakePluginStore) Plugins(_ context.Context, pluginTypes ...plugins.Type
return result
}
func (ps fakePluginStore) Add(_ context.Context, pluginID, version string) error {
ps.plugins[pluginID] = plugins.PluginDTO{
JSONData: plugins.JSONData{
ID: pluginID,
Info: plugins.Info{
Version: version,
},
},
}
return nil
}
func (ps fakePluginStore) Remove(_ context.Context, pluginID string) error {
delete(ps.plugins, pluginID)
return nil
}
type fakeRendererManager struct {
plugins.RendererManager
}
+79
View File
@@ -4,11 +4,13 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -19,8 +21,85 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web/webtest"
)
func Test_PluginsInstallAndUninstall(t *testing.T) {
type tc struct {
pluginAdminEnabled bool
pluginAdminExternalManageEnabled bool
expectedHTTPStatus int
expectedHTTPBody string
}
tcs := []tc{
{pluginAdminEnabled: true, pluginAdminExternalManageEnabled: true, expectedHTTPStatus: 404, expectedHTTPBody: "404 page not found\n"},
{pluginAdminEnabled: true, pluginAdminExternalManageEnabled: false, expectedHTTPStatus: 200, expectedHTTPBody: ""},
{pluginAdminEnabled: false, pluginAdminExternalManageEnabled: true, expectedHTTPStatus: 404, expectedHTTPBody: "404 page not found\n"},
{pluginAdminEnabled: false, pluginAdminExternalManageEnabled: false, expectedHTTPStatus: 404, expectedHTTPBody: "404 page not found\n"},
}
testName := func(action string, testCase tc) string {
return fmt.Sprintf("%s request returns %d when adminEnabled: %t and externalEnabled: %t",
action, testCase.expectedHTTPStatus, testCase.pluginAdminEnabled, testCase.pluginAdminExternalManageEnabled)
}
ps := fakePluginStore{
plugins: make(map[string]plugins.PluginDTO),
}
for _, tc := range tcs {
srv := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = &setting.Cfg{
PluginAdminEnabled: tc.pluginAdminEnabled,
PluginAdminExternalManageEnabled: tc.pluginAdminExternalManageEnabled,
}
hs.pluginStore = ps
})
t.Run(testName("Install", tc), func(t *testing.T) {
req := srv.NewPostRequest("/api/plugins/test/install", strings.NewReader("{ \"version\": \"1.0.2\" }"))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_EDITOR, IsGrafanaAdmin: true})
resp, err := srv.SendJSON(req)
require.NoError(t, err)
body := new(strings.Builder)
_, err = io.Copy(body, resp.Body)
require.NoError(t, err)
require.Equal(t, tc.expectedHTTPBody, body.String())
require.NoError(t, resp.Body.Close())
require.Equal(t, tc.expectedHTTPStatus, resp.StatusCode)
if tc.expectedHTTPStatus == 200 {
require.Equal(t, plugins.PluginDTO{
JSONData: plugins.JSONData{
ID: "test",
Info: plugins.Info{
Version: "1.0.2",
},
},
}, ps.plugins["test"])
}
})
t.Run(testName("Uninstall", tc), func(t *testing.T) {
req := srv.NewPostRequest("/api/plugins/test/uninstall", strings.NewReader("{}"))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_VIEWER, IsGrafanaAdmin: true})
resp, err := srv.SendJSON(req)
require.NoError(t, err)
body := new(strings.Builder)
_, err = io.Copy(body, resp.Body)
require.NoError(t, err)
require.Equal(t, tc.expectedHTTPBody, body.String())
require.NoError(t, resp.Body.Close())
require.Equal(t, tc.expectedHTTPStatus, resp.StatusCode)
if tc.expectedHTTPStatus == 200 {
require.Empty(t, ps.plugins)
}
})
}
}
func Test_GetPluginAssets(t *testing.T) {
pluginID := "test-plugin"
pluginDir := "."
+7
View File
@@ -262,6 +262,12 @@ func CreateGrafDir(t *testing.T, opts ...GrafanaOpts) (string, string) {
_, err = anonSect.NewKey("plugin_admin_enabled", "true")
require.NoError(t, err)
}
if o.PluginAdminExternalManageEnabled {
anonSect, err := cfg.NewSection("plugins")
require.NoError(t, err)
_, err = anonSect.NewKey("plugin_admin_external_manage_enabled", "true")
require.NoError(t, err)
}
if o.ViewersCanEdit {
usersSection, err := cfg.NewSection("users")
require.NoError(t, err)
@@ -311,6 +317,7 @@ type GrafanaOpts struct {
CatalogAppEnabled bool
ViewersCanEdit bool
PluginAdminEnabled bool
PluginAdminExternalManageEnabled bool
AppModeProduction bool
DisableLegacyAlerting bool
EnableUnifiedAlerting bool