|
|
|
@ -6,12 +6,13 @@ import ( |
|
|
|
|
"net/http" |
|
|
|
|
"testing" |
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/bus" |
|
|
|
|
"github.com/grafana/grafana/pkg/models" |
|
|
|
|
"github.com/grafana/grafana/pkg/plugins" |
|
|
|
|
"github.com/grafana/grafana/pkg/services/secrets" |
|
|
|
|
"github.com/grafana/grafana/pkg/services/secrets/fakes" |
|
|
|
|
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" |
|
|
|
|
"github.com/grafana/grafana/pkg/services/sqlstore" |
|
|
|
|
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore" |
|
|
|
|
"github.com/grafana/grafana/pkg/setting" |
|
|
|
|
"github.com/grafana/grafana/pkg/web" |
|
|
|
|
"github.com/stretchr/testify/assert" |
|
|
|
@ -28,20 +29,13 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
{Name: "x-header", Content: "my secret {{.SecureJsonData.key}}"}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bus.AddHandler("test", func(ctx context.Context, query *models.GetPluginSettingByIdQuery) error { |
|
|
|
|
key, err := secretsService.Encrypt(ctx, []byte("123"), secrets.WithoutScope()) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
query.Result = &models.PluginSetting{ |
|
|
|
|
SecureJsonData: map[string][]byte{ |
|
|
|
|
"key": key, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
key, _ := secretsService.Encrypt(context.Background(), []byte("123"), secrets.WithoutScope()) |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{ |
|
|
|
|
SecureJsonData: map[string][]byte{ |
|
|
|
|
"key": key, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -59,6 +53,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: true}, |
|
|
|
|
route, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
assert.Equal(t, "my secret 123", req.Header.Get("x-header")) |
|
|
|
@ -67,6 +62,8 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
t.Run("When SendUserHeader config is enabled", func(t *testing.T) { |
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{} |
|
|
|
|
|
|
|
|
|
req := getPluginProxiedRequest( |
|
|
|
|
t, |
|
|
|
@ -81,6 +78,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: true}, |
|
|
|
|
nil, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Get will return empty string even if header is not set
|
|
|
|
@ -90,6 +88,8 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
t.Run("When SendUserHeader config is disabled", func(t *testing.T) { |
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{} |
|
|
|
|
|
|
|
|
|
req := getPluginProxiedRequest( |
|
|
|
|
t, |
|
|
|
@ -104,6 +104,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: false}, |
|
|
|
|
nil, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
// Get will return empty string even if header is not set
|
|
|
|
|
assert.Equal(t, "", req.Header.Get("X-Grafana-User")) |
|
|
|
@ -112,6 +113,8 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
t.Run("When SendUserHeader config is enabled but user is anonymous", func(t *testing.T) { |
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{} |
|
|
|
|
|
|
|
|
|
req := getPluginProxiedRequest( |
|
|
|
|
t, |
|
|
|
@ -124,6 +127,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: true}, |
|
|
|
|
nil, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Get will return empty string even if header is not set
|
|
|
|
@ -135,15 +139,12 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
URL: "{{.JsonData.dynamicUrl}}", |
|
|
|
|
Method: "GET", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bus.AddHandler("test", func(_ context.Context, query *models.GetPluginSettingByIdQuery) error { |
|
|
|
|
query.Result = &models.PluginSetting{ |
|
|
|
|
JsonData: map[string]interface{}{ |
|
|
|
|
"dynamicUrl": "https://dynamic.grafana.com", |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{ |
|
|
|
|
JsonData: map[string]interface{}{ |
|
|
|
|
"dynamicUrl": "https://dynamic.grafana.com", |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -161,6 +162,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: true}, |
|
|
|
|
route, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
assert.Equal(t, "https://dynamic.grafana.com", req.URL.String()) |
|
|
|
|
assert.Equal(t, "{{.JsonData.dynamicUrl}}", route.URL) |
|
|
|
@ -171,11 +173,8 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
URL: "{{if .JsonData.apiHost}}{{.JsonData.apiHost}}{{else}}https://example.com{{end}}", |
|
|
|
|
Method: "GET", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bus.AddHandler("test", func(_ context.Context, query *models.GetPluginSettingByIdQuery) error { |
|
|
|
|
query.Result = &models.PluginSetting{} |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{} |
|
|
|
|
|
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -193,6 +192,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: true}, |
|
|
|
|
route, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
assert.Equal(t, "https://example.com", req.URL.String()) |
|
|
|
|
}) |
|
|
|
@ -204,25 +204,17 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
Body: []byte(`{ "url": "{{.JsonData.dynamicUrl}}", "secret": "{{.SecureJsonData.key}}" }`), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bus.AddHandler("test", func(ctx context.Context, query *models.GetPluginSettingByIdQuery) error { |
|
|
|
|
encryptedJsonData, err := secretsService.EncryptJsonData( |
|
|
|
|
ctx, |
|
|
|
|
map[string]string{"key": "123"}, |
|
|
|
|
secrets.WithoutScope(), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
store := mockstore.NewSQLStoreMock() |
|
|
|
|
|
|
|
|
|
query.Result = &models.PluginSetting{ |
|
|
|
|
JsonData: map[string]interface{}{ |
|
|
|
|
"dynamicUrl": "https://dynamic.grafana.com", |
|
|
|
|
}, |
|
|
|
|
SecureJsonData: encryptedJsonData, |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
encryptedJsonData, _ := secretsService.EncryptJsonData( |
|
|
|
|
context.Background(), |
|
|
|
|
map[string]string{"key": "123"}, |
|
|
|
|
secrets.WithoutScope(), |
|
|
|
|
) |
|
|
|
|
store.ExpectedPluginSetting = &models.PluginSetting{ |
|
|
|
|
JsonData: map[string]interface{}{"dynamicUrl": "https://dynamic.grafana.com"}, |
|
|
|
|
SecureJsonData: encryptedJsonData, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
httpReq, err := http.NewRequest(http.MethodGet, "", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -240,6 +232,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
&setting.Cfg{SendUserHeader: true}, |
|
|
|
|
route, |
|
|
|
|
store, |
|
|
|
|
) |
|
|
|
|
content, err := ioutil.ReadAll(req.Body) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -248,7 +241,7 @@ func TestPluginProxy(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// getPluginProxiedRequest is a helper for easier setup of tests based on global config and ReqContext.
|
|
|
|
|
func getPluginProxiedRequest(t *testing.T, secretsService secrets.Service, ctx *models.ReqContext, cfg *setting.Cfg, route *plugins.Route) *http.Request { |
|
|
|
|
func getPluginProxiedRequest(t *testing.T, secretsService secrets.Service, ctx *models.ReqContext, cfg *setting.Cfg, route *plugins.Route, store sqlstore.Store) *http.Request { |
|
|
|
|
// insert dummy route if none is specified
|
|
|
|
|
if route == nil { |
|
|
|
|
route = &plugins.Route{ |
|
|
|
@ -257,7 +250,7 @@ func getPluginProxiedRequest(t *testing.T, secretsService secrets.Service, ctx * |
|
|
|
|
ReqRole: models.ROLE_EDITOR, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
proxy := NewApiPluginProxy(ctx, "", route, "", cfg, secretsService) |
|
|
|
|
proxy := NewApiPluginProxy(ctx, "", route, "", cfg, store, secretsService) |
|
|
|
|
|
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/api/plugin-proxy/grafana-simple-app/api/v4/alerts", nil) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|