2020-06-17 00:39:50 -05:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-02-07 10:20:05 -06:00
|
|
|
"fmt"
|
2020-06-17 00:39:50 -05:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2020-10-19 10:35:31 -05:00
|
|
|
"path/filepath"
|
2020-06-17 00:39:50 -05:00
|
|
|
"testing"
|
|
|
|
|
2022-10-19 08:02:15 -05:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
2023-02-06 10:23:53 -06:00
|
|
|
"github.com/grafana/grafana/pkg/infra/usagestats"
|
2023-01-30 02:18:26 -06:00
|
|
|
"github.com/grafana/grafana/pkg/login/social"
|
2022-09-28 01:29:35 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins"
|
2023-01-30 02:18:26 -06:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/config"
|
|
|
|
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
2021-10-05 08:54:26 -05:00
|
|
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
2022-01-26 11:44:20 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
2020-06-17 00:39:50 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/licensing"
|
2023-03-07 10:22:30 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
2021-10-05 08:54:26 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/rendering"
|
2023-03-16 02:46:25 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
|
2021-11-01 04:53:33 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/updatechecker"
|
2020-06-17 00:39:50 -05:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2021-10-11 07:30:59 -05:00
|
|
|
"github.com/grafana/grafana/pkg/web"
|
2020-06-17 00:39:50 -05:00
|
|
|
)
|
|
|
|
|
2023-03-07 10:22:30 -06:00
|
|
|
func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features *featuremgmt.FeatureManager, pstore plugins.Store, psettings pluginsettings.Service) (*web.Mux, *HTTPServer) {
|
2020-06-17 00:39:50 -05:00
|
|
|
t.Helper()
|
2022-10-19 08:02:15 -05:00
|
|
|
db.InitTestDB(t)
|
2022-01-26 11:44:20 -06:00
|
|
|
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
2020-06-17 00:39:50 -05:00
|
|
|
|
|
|
|
{
|
|
|
|
oldVersion := setting.BuildVersion
|
|
|
|
oldCommit := setting.BuildCommit
|
|
|
|
oldEnv := setting.Env
|
|
|
|
t.Cleanup(func() {
|
|
|
|
setting.BuildVersion = oldVersion
|
|
|
|
setting.BuildCommit = oldCommit
|
|
|
|
setting.Env = oldEnv
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-07 10:20:05 -06:00
|
|
|
var pluginStore = pstore
|
|
|
|
if pluginStore == nil {
|
|
|
|
pluginStore = &plugins.FakePluginStore{}
|
|
|
|
}
|
|
|
|
|
|
|
|
var pluginsSettings = psettings
|
|
|
|
if pluginsSettings == nil {
|
2023-03-07 10:22:30 -06:00
|
|
|
pluginsSettings = &pluginsettings.FakePluginSettings{}
|
2023-02-07 10:20:05 -06:00
|
|
|
}
|
2020-06-17 00:39:50 -05:00
|
|
|
|
|
|
|
hs := &HTTPServer{
|
2022-01-26 11:44:20 -06:00
|
|
|
Cfg: cfg,
|
|
|
|
Features: features,
|
|
|
|
License: &licensing.OSSLicensingService{Cfg: cfg},
|
2021-11-01 04:53:33 -05:00
|
|
|
RenderService: &rendering.RenderingService{
|
|
|
|
Cfg: cfg,
|
|
|
|
RendererPluginManager: &fakeRendererManager{},
|
|
|
|
},
|
2023-02-07 10:20:05 -06:00
|
|
|
SQLStore: db.InitTestDB(t),
|
2022-01-31 09:06:16 -06:00
|
|
|
SettingsProvider: setting.ProvideProvider(cfg),
|
2023-02-07 10:20:05 -06:00
|
|
|
pluginStore: pluginStore,
|
2022-01-31 09:06:16 -06:00
|
|
|
grafanaUpdateChecker: &updatechecker.GrafanaService{},
|
|
|
|
AccessControl: accesscontrolmock.New().WithDisabled(),
|
2023-02-07 10:20:05 -06:00
|
|
|
PluginSettings: pluginsSettings,
|
2023-01-27 08:08:17 -06:00
|
|
|
pluginsCDNService: pluginscdn.ProvideService(&config.Cfg{
|
|
|
|
PluginsCDNURLTemplate: cfg.PluginsCDNURLTemplate,
|
|
|
|
PluginSettings: cfg.PluginSettings,
|
|
|
|
}),
|
2023-03-16 02:46:25 -05:00
|
|
|
SocialService: social.ProvideService(cfg, features, &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService()),
|
2020-06-17 00:39:50 -05:00
|
|
|
}
|
|
|
|
|
2021-10-11 07:30:59 -05:00
|
|
|
m := web.New()
|
2020-12-15 12:09:04 -06:00
|
|
|
m.Use(getContextHandler(t, cfg).Middleware)
|
2021-10-11 07:30:59 -05:00
|
|
|
m.UseMiddleware(web.Renderer(filepath.Join(setting.StaticRootPath, "views"), "[[", "]]"))
|
2020-06-17 00:39:50 -05:00
|
|
|
m.Get("/api/frontend/settings/", hs.GetFrontendSettings)
|
|
|
|
|
|
|
|
return m, hs
|
|
|
|
}
|
|
|
|
|
2021-11-01 04:53:33 -05:00
|
|
|
func TestHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testing.T) {
|
2020-06-17 00:39:50 -05:00
|
|
|
type buildInfo struct {
|
|
|
|
Version string `json:"version"`
|
|
|
|
Commit string `json:"commit"`
|
|
|
|
Env string `json:"env"`
|
|
|
|
}
|
|
|
|
type settings struct {
|
|
|
|
BuildInfo buildInfo `json:"buildInfo"`
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg := setting.NewCfg()
|
2021-02-10 06:31:47 -06:00
|
|
|
cfg.Env = "testing"
|
|
|
|
cfg.BuildVersion = "7.8.9"
|
|
|
|
cfg.BuildCommit = "01234567"
|
2022-01-26 11:44:20 -06:00
|
|
|
|
2023-02-07 10:20:05 -06:00
|
|
|
m, hs := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), nil, nil)
|
2020-06-17 00:39:50 -05:00
|
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
|
|
|
|
2021-02-10 06:31:47 -06:00
|
|
|
// TODO: Remove
|
|
|
|
setting.BuildVersion = cfg.BuildVersion
|
|
|
|
setting.BuildCommit = cfg.BuildCommit
|
|
|
|
setting.Env = cfg.Env
|
2020-06-17 00:39:50 -05:00
|
|
|
|
|
|
|
tests := []struct {
|
2020-12-11 04:44:44 -06:00
|
|
|
desc string
|
2020-06-17 00:39:50 -05:00
|
|
|
hideVersion bool
|
|
|
|
expected settings
|
|
|
|
}{
|
|
|
|
{
|
2020-12-11 04:44:44 -06:00
|
|
|
desc: "Not hiding version",
|
2020-06-17 00:39:50 -05:00
|
|
|
hideVersion: false,
|
|
|
|
expected: settings{
|
|
|
|
BuildInfo: buildInfo{
|
|
|
|
Version: setting.BuildVersion,
|
|
|
|
Commit: setting.BuildCommit,
|
|
|
|
Env: setting.Env,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2020-12-11 04:44:44 -06:00
|
|
|
desc: "Hiding version",
|
2020-06-17 00:39:50 -05:00
|
|
|
hideVersion: true,
|
|
|
|
expected: settings{
|
|
|
|
BuildInfo: buildInfo{
|
|
|
|
Version: "",
|
|
|
|
Commit: "",
|
|
|
|
Env: setting.Env,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
2020-12-11 04:44:44 -06:00
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
hs.Cfg.AnonymousHideVersion = test.hideVersion
|
|
|
|
expected := test.expected
|
|
|
|
|
|
|
|
recorder := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(recorder, req)
|
|
|
|
got := settings{}
|
|
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &got)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.GreaterOrEqual(t, 400, recorder.Code, "status codes higher than 400 indicate a failure")
|
|
|
|
|
|
|
|
assert.EqualValues(t, expected, got)
|
|
|
|
})
|
2020-06-17 00:39:50 -05:00
|
|
|
}
|
|
|
|
}
|
2023-01-27 08:08:17 -06:00
|
|
|
|
|
|
|
func TestHTTPServer_GetFrontendSettings_pluginsCDNBaseURL(t *testing.T) {
|
|
|
|
type settings struct {
|
|
|
|
PluginsCDNBaseURL string `json:"pluginsCDNBaseURL"`
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
desc string
|
|
|
|
mutateCfg func(*setting.Cfg)
|
|
|
|
expected settings
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "With CDN",
|
|
|
|
mutateCfg: func(cfg *setting.Cfg) {
|
2023-02-24 07:28:13 -06:00
|
|
|
cfg.PluginsCDNURLTemplate = "https://cdn.example.com"
|
2023-01-27 08:08:17 -06:00
|
|
|
},
|
|
|
|
expected: settings{PluginsCDNBaseURL: "https://cdn.example.com"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "Without CDN",
|
|
|
|
mutateCfg: func(cfg *setting.Cfg) {
|
|
|
|
cfg.PluginsCDNURLTemplate = ""
|
|
|
|
},
|
|
|
|
expected: settings{PluginsCDNBaseURL: ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "CDN is disabled by default",
|
|
|
|
expected: settings{PluginsCDNBaseURL: ""},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
cfg := setting.NewCfg()
|
|
|
|
if test.mutateCfg != nil {
|
|
|
|
test.mutateCfg(cfg)
|
|
|
|
}
|
2023-02-07 10:20:05 -06:00
|
|
|
m, _ := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), nil, nil)
|
2023-01-27 08:08:17 -06:00
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
|
|
|
|
|
|
|
recorder := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(recorder, req)
|
|
|
|
var got settings
|
|
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &got)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
|
|
require.EqualValues(t, test.expected, got)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2023-02-07 10:20:05 -06:00
|
|
|
|
|
|
|
func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|
|
|
type settings struct {
|
|
|
|
Apps map[string]*plugins.AppDTO `json:"apps"`
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
desc string
|
|
|
|
pluginStore func() plugins.Store
|
2023-03-07 10:22:30 -06:00
|
|
|
pluginSettings func() pluginsettings.Service
|
2023-02-07 10:20:05 -06:00
|
|
|
expected settings
|
|
|
|
}{
|
2023-02-08 07:41:49 -06:00
|
|
|
{
|
|
|
|
desc: "disabled app with preload",
|
|
|
|
pluginStore: func() plugins.Store {
|
|
|
|
return &plugins.FakePluginStore{
|
|
|
|
PluginList: []plugins.PluginDTO{
|
|
|
|
{
|
|
|
|
Module: fmt.Sprintf("/%s/module.js", "test-app"),
|
|
|
|
JSONData: plugins.JSONData{
|
2023-03-02 08:42:00 -06:00
|
|
|
ID: "test-app",
|
|
|
|
Info: plugins.Info{Version: "0.5.0"},
|
|
|
|
Type: plugins.App,
|
|
|
|
Preload: true,
|
2023-02-08 07:41:49 -06:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
2023-03-07 10:22:30 -06:00
|
|
|
pluginSettings: func() pluginsettings.Service {
|
|
|
|
return &pluginsettings.FakePluginSettings{
|
2023-02-08 07:41:49 -06:00
|
|
|
Plugins: newAppSettings("test-app", false),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
expected: settings{
|
|
|
|
Apps: map[string]*plugins.AppDTO{
|
|
|
|
"test-app": {
|
2023-03-02 08:42:00 -06:00
|
|
|
ID: "test-app",
|
|
|
|
Preload: false,
|
|
|
|
Path: "/test-app/module.js",
|
|
|
|
Version: "0.5.0",
|
2023-02-08 07:41:49 -06:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "enalbed app with preload",
|
|
|
|
pluginStore: func() plugins.Store {
|
|
|
|
return &plugins.FakePluginStore{
|
|
|
|
PluginList: []plugins.PluginDTO{
|
|
|
|
{
|
|
|
|
Module: fmt.Sprintf("/%s/module.js", "test-app"),
|
|
|
|
JSONData: plugins.JSONData{
|
2023-03-02 08:42:00 -06:00
|
|
|
ID: "test-app",
|
|
|
|
Info: plugins.Info{Version: "0.5.0"},
|
|
|
|
Type: plugins.App,
|
|
|
|
Preload: true,
|
2023-02-08 07:41:49 -06:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
2023-03-07 10:22:30 -06:00
|
|
|
pluginSettings: func() pluginsettings.Service {
|
|
|
|
return &pluginsettings.FakePluginSettings{
|
2023-02-08 07:41:49 -06:00
|
|
|
Plugins: newAppSettings("test-app", true),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
expected: settings{
|
|
|
|
Apps: map[string]*plugins.AppDTO{
|
|
|
|
"test-app": {
|
2023-03-02 08:42:00 -06:00
|
|
|
ID: "test-app",
|
|
|
|
Preload: true,
|
|
|
|
Path: "/test-app/module.js",
|
|
|
|
Version: "0.5.0",
|
2023-02-08 07:41:49 -06:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-05-12 05:51:11 -05:00
|
|
|
{
|
|
|
|
desc: "angular app plugin",
|
|
|
|
pluginStore: func() plugins.Store {
|
|
|
|
return &plugins.FakePluginStore{
|
|
|
|
PluginList: []plugins.PluginDTO{
|
|
|
|
{
|
|
|
|
Module: fmt.Sprintf("/%s/module.js", "test-app"),
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "test-app",
|
|
|
|
Info: plugins.Info{Version: "0.5.0"},
|
|
|
|
Type: plugins.App,
|
|
|
|
Preload: true,
|
|
|
|
},
|
|
|
|
AngularDetected: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
pluginSettings: func() pluginsettings.Service {
|
|
|
|
return &pluginsettings.FakePluginSettings{
|
|
|
|
Plugins: newAppSettings("test-app", true),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
expected: settings{
|
|
|
|
Apps: map[string]*plugins.AppDTO{
|
|
|
|
"test-app": {
|
|
|
|
ID: "test-app",
|
|
|
|
Preload: true,
|
|
|
|
Path: "/test-app/module.js",
|
|
|
|
Version: "0.5.0",
|
|
|
|
AngularDetected: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-02-07 10:20:05 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
cfg := setting.NewCfg()
|
|
|
|
m, _ := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), test.pluginStore(), test.pluginSettings())
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
|
|
|
|
|
|
|
recorder := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(recorder, req)
|
|
|
|
var got settings
|
|
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &got)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
|
|
require.EqualValues(t, test.expected, got)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-07 10:22:30 -06:00
|
|
|
func newAppSettings(id string, enabled bool) map[string]*pluginsettings.DTO {
|
|
|
|
return map[string]*pluginsettings.DTO{
|
2023-02-07 10:20:05 -06:00
|
|
|
id: {
|
|
|
|
ID: 0,
|
|
|
|
OrgID: 1,
|
|
|
|
PluginID: id,
|
|
|
|
Enabled: enabled,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|