@ -3,6 +3,7 @@ package pluginproxy
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
@ -24,6 +25,7 @@ import (
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
"github.com/grafana/grafana/pkg/services/secrets/kvstore"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
@ -90,6 +92,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
} )
setting . SecretKey = "password" //nolint:goconst
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
key , err := secretsService . Encrypt ( context . Background ( ) , [ ] byte ( "123" ) , secrets . WithoutScope ( ) )
require . NoError ( t , err )
@ -128,9 +131,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "When matching route path" , func ( t * testing . T ) {
ctx , req := setUp ( )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/v4/some/method" , cfg , httpClientProvider ,
& oauthtoken . Service { } , dsService , tracer , secretsService )
& oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . matchedRoute = routes [ 0 ]
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , proxy . matchedRoute , dsInfo , cfg )
@ -141,8 +144,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "When matching route path and has dynamic url" , func ( t * testing . T ) {
ctx , req := setUp ( )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/common/some/method" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/common/some/method" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . matchedRoute = routes [ 3 ]
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , proxy . matchedRoute , dsInfo , cfg )
@ -153,8 +156,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "When matching route path with no url" , func ( t * testing . T ) {
ctx , req := setUp ( )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . matchedRoute = routes [ 4 ]
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , proxy . matchedRoute , dsInfo , cfg )
@ -164,8 +167,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "When matching route path and has dynamic body" , func ( t * testing . T ) {
ctx , req := setUp ( )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/body" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/body" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . matchedRoute = routes [ 5 ]
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , proxy . matchedRoute , dsInfo , cfg )
@ -178,8 +181,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "Validating request" , func ( t * testing . T ) {
t . Run ( "plugin route with valid role" , func ( t * testing . T ) {
ctx , _ := setUp ( )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/v4/some/method" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/v4/some/method" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
err = proxy . validateRequest ( )
require . NoError ( t , err )
@ -187,8 +190,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "plugin route with admin role and user is editor" , func ( t * testing . T ) {
ctx , _ := setUp ( )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/admin" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/admin" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
err = proxy . validateRequest ( )
require . Error ( t , err )
@ -197,8 +200,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t . Run ( "plugin route with admin role and user is admin" , func ( t * testing . T ) {
ctx , _ := setUp ( )
ctx . SignedInUser . OrgRole = models . ROLE_ADMIN
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/admin" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "api/admin" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
err = proxy . validateRequest ( )
require . NoError ( t , err )
@ -242,6 +245,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
} )
setting . SecretKey = "password"
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
key , err := secretsService . Encrypt ( context . Background ( ) , [ ] byte ( "123" ) , secrets . WithoutScope ( ) )
require . NoError ( t , err )
@ -286,8 +290,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
} ,
}
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "pathwithtoken1" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "pathwithtoken1" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , routes [ 0 ] , dsInfo , cfg )
@ -302,8 +306,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req , err := http . NewRequest ( "GET" , "http://localhost/asd" , nil )
require . NoError ( t , err )
client = newFakeHTTPClient ( t , json2 )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "pathwithtoken2" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "pathwithtoken2" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , routes [ 1 ] , dsInfo , cfg )
@ -319,8 +323,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
require . NoError ( t , err )
client = newFakeHTTPClient ( t , [ ] byte { } )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "pathwithtoken1" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "pathwithtoken1" , cfg , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
ApplyRoute ( proxy . ctx . Req . Context ( ) , req , proxy . proxyPath , routes [ 0 ] , dsInfo , cfg )
@ -340,9 +344,10 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ds := & models . DataSource { Url : "htttp://graphite:8080" , Type : models . DS_GRAPHITE }
ctx := & models . ReqContext { }
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { BuildVersion : "5.3.0" } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { BuildVersion : "5.3.0" } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
req , err := http . NewRequest ( http . MethodGet , "http://grafana.com/sub" , nil )
require . NoError ( t , err )
@ -366,9 +371,10 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := & models . ReqContext { }
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
req , err := http . NewRequest ( http . MethodGet , "http://grafana.com/sub" , nil )
@ -390,9 +396,10 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := & models . ReqContext { }
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
requestURL , err := url . Parse ( "http://grafana.com/sub" )
@ -418,9 +425,10 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := & models . ReqContext { }
var pluginRoutes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , pluginRoutes , ctx , "" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , pluginRoutes , ctx , "" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
requestURL , err := url . Parse ( "http://grafana.com/sub" )
@ -441,9 +449,10 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
}
ctx := & models . ReqContext { }
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/to/folder/" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/to/folder/" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
req , err := http . NewRequest ( http . MethodGet , "http://grafana.com/sub" , nil )
req . Header . Set ( "Origin" , "grafana.com" )
@ -490,9 +499,10 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
}
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/to/folder/" , & setting . Cfg { } , httpClientProvider , & mockAuthToken , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/to/folder/" , & setting . Cfg { } , httpClientProvider , & mockAuthToken , dsService , tracer )
require . NoError ( t , err )
req , err = http . NewRequest ( http . MethodGet , "http://grafana.com/sub" , nil )
require . NoError ( t , err )
@ -543,24 +553,25 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
} )
t . Run ( "When proxying data source proxy should handle authentication" , func ( t * testing . T ) {
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
tests := [ ] * testCase {
createAuthTest ( t , secretsServic e , models . DS_INFLUXDB_08 , "http://localhost:9090" , authTypePassword , authCheckQuery , false ) ,
createAuthTest ( t , secretsServic e , models . DS_INFLUXDB_08 , "http://localhost:9090" , authTypePassword , authCheckQuery , true ) ,
createAuthTest ( t , secretsServic e , models . DS_INFLUXDB , "http://localhost:9090" , authTypePassword , authCheckHeader , true ) ,
createAuthTest ( t , secretsServic e , models . DS_INFLUXDB , "http://localhost:9090" , authTypePassword , authCheckHeader , false ) ,
createAuthTest ( t , secretsServic e , models . DS_INFLUXDB , "http://localhost:9090" , authTypeBasic , authCheckHeader , true ) ,
createAuthTest ( t , secretsServic e , models . DS_INFLUXDB , "http://localhost:9090" , authTypeBasic , authCheckHeader , false ) ,
createAuthTest ( t , secretsStor e , models . DS_INFLUXDB_08 , "http://localhost:9090" , authTypePassword , authCheckQuery , false ) ,
createAuthTest ( t , secretsStor e , models . DS_INFLUXDB_08 , "http://localhost:9090" , authTypePassword , authCheckQuery , true ) ,
createAuthTest ( t , secretsStor e , models . DS_INFLUXDB , "http://localhost:9090" , authTypePassword , authCheckHeader , true ) ,
createAuthTest ( t , secretsStor e , models . DS_INFLUXDB , "http://localhost:9090" , authTypePassword , authCheckHeader , false ) ,
createAuthTest ( t , secretsStor e , models . DS_INFLUXDB , "http://localhost:9090" , authTypeBasic , authCheckHeader , true ) ,
createAuthTest ( t , secretsStor e , models . DS_INFLUXDB , "http://localhost:9090" , authTypeBasic , authCheckHeader , false ) ,
// These two should be enough for any other datasource at the moment. Proxy has special handling
// only for Influx, others have the same path and only BasicAuth. Non BasicAuth datasources
// do not go through proxy but through TSDB API which is not tested here.
createAuthTest ( t , secretsServic e , models . DS_ES , "http://localhost:9200" , authTypeBasic , authCheckHeader , false ) ,
createAuthTest ( t , secretsServic e , models . DS_ES , "http://localhost:9200" , authTypeBasic , authCheckHeader , true ) ,
createAuthTest ( t , secretsStor e , models . DS_ES , "http://localhost:9200" , authTypeBasic , authCheckHeader , false ) ,
createAuthTest ( t , secretsStor e , models . DS_ES , "http://localhost:9200" , authTypeBasic , authCheckHeader , true ) ,
}
for _ , test := range tests {
runDatasourceAuthTest ( t , secretsService , cfg , test )
runDatasourceAuthTest ( t , secretsService , secretsStore , cfg , test )
}
} )
}
@ -624,9 +635,10 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
t . Run ( "When response header Set-Cookie is not set should remove proxied Set-Cookie header" , func ( t * testing . T ) {
ctx , ds := setUp ( t )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . HandleRequest ( )
@ -642,9 +654,10 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
} ,
} )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . HandleRequest ( )
@ -656,9 +669,10 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
t . Run ( "When response should set Content-Security-Policy header" , func ( t * testing . T ) {
ctx , ds := setUp ( t )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . HandleRequest ( )
@ -678,9 +692,10 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
} ,
} )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/render" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . HandleRequest ( )
@ -703,9 +718,10 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
ctx . Req = httptest . NewRequest ( "GET" , "/api/datasources/proxy/1/path/%2Ftest%2Ftest%2F?query=%2Ftest%2Ftest%2F" , nil )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/%2Ftest%2Ftest%2F" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/%2Ftest%2Ftest%2F" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . HandleRequest ( )
@ -727,9 +743,10 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
ctx . Req = httptest . NewRequest ( "GET" , "/api/datasources/proxy/1/path/%2Ftest%2Ftest%2F?query=%2Ftest%2Ftest%2F" , nil )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/%2Ftest%2Ftest%2F" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "/path/%2Ftest%2Ftest%2F" , & setting . Cfg { } , httpClientProvider , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
proxy . HandleRequest ( )
@ -752,9 +769,10 @@ func TestNewDataSourceProxy_InvalidURL(t *testing.T) {
tracer , err := tracing . InitializeTracerForTest ( )
require . NoError ( t , err )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
_ , err = NewDataSourceProxy ( & ds , routes , & ctx , "api/method" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
_ , err = NewDataSourceProxy ( & ds , routes , & ctx , "api/method" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer )
require . Error ( t , err )
assert . True ( t , strings . HasPrefix ( err . Error ( ) , ` validation of data source URL "://host/root" failed ` ) )
}
@ -773,9 +791,10 @@ func TestNewDataSourceProxy_ProtocolLessURL(t *testing.T) {
require . NoError ( t , err )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
_ , err = NewDataSourceProxy ( & ds , routes , & ctx , "api/method" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
_ , err = NewDataSourceProxy ( & ds , routes , & ctx , "api/method" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
}
@ -816,9 +835,10 @@ func TestNewDataSourceProxy_MSSQL(t *testing.T) {
}
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
p , err := NewDataSourceProxy ( & ds , routes , & ctx , "api/method" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
p , err := NewDataSourceProxy ( & ds , routes , & ctx , "api/method" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer )
if tc . err == nil {
require . NoError ( t , err )
assert . Equal ( t , & url . URL {
@ -843,9 +863,10 @@ func getDatasourceProxiedRequest(t *testing.T, ctx *models.ReqContext, cfg *sett
require . NoError ( t , err )
var routes [ ] * plugins . Route
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( ds , routes , ctx , "" , cfg , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
req , err := http . NewRequest ( http . MethodGet , "http://grafana.com/sub" , nil )
require . NoError ( t , err )
@ -897,15 +918,15 @@ const (
authCheckHeader = "header"
)
func createAuthTest ( t * testing . T , secretsService secrets . Service , dsType string , url string , authType string , authCheck string , useSecureJsonData bool ) * testCase {
ctx := context . Background ( )
func createAuthTest ( t * testing . T , secretsStore kvstore . SecretsKVStore , dsType string , url string , authType string , authCheck string , useSecureJsonData bool ) * testCase {
// Basic user:password
base64AuthHeader := "Basic dXNlcjpwYXNzd29yZA=="
test := & testCase {
datasource : & models . DataSource {
Id : 1 ,
OrgId : 1 ,
Name : fmt . Sprintf ( "%s,%s,%s,%s,%t" , dsType , url , authType , authCheck , useSecureJsonData ) ,
Type : dsType ,
JsonData : simplejson . New ( ) ,
Url : url ,
@ -917,11 +938,13 @@ func createAuthTest(t *testing.T, secretsService secrets.Service, dsType string,
message = fmt . Sprintf ( "%v should add username and password" , dsType )
test . datasource . User = "user"
if useSecureJsonData {
test . datasource . SecureJsonData , err = secretsService . EncryptJsonData (
ctx ,
map [ string ] string {
"password" : "password" ,
} , secrets . WithoutScope ( ) )
secureJsonData , err := json . Marshal ( map [ string ] string {
"password" : "password" ,
} )
require . NoError ( t , err )
err = secretsStore . Set ( context . Background ( ) , test . datasource . OrgId , test . datasource . Name , "datasource" , string ( secureJsonData ) )
require . NoError ( t , err )
} else {
test . datasource . Password = "password"
}
@ -930,11 +953,13 @@ func createAuthTest(t *testing.T, secretsService secrets.Service, dsType string,
test . datasource . BasicAuth = true
test . datasource . BasicAuthUser = "user"
if useSecureJsonData {
test . datasource . SecureJsonData , err = secretsService . EncryptJsonData (
ctx ,
map [ string ] string {
"basicAuthPassword" : "password" ,
} , secrets . WithoutScope ( ) )
secureJsonData , err := json . Marshal ( map [ string ] string {
"basicAuthPassword" : "password" ,
} )
require . NoError ( t , err )
err = secretsStore . Set ( context . Background ( ) , test . datasource . OrgId , test . datasource . Name , "datasource" , string ( secureJsonData ) )
require . NoError ( t , err )
} else {
test . datasource . BasicAuthPassword = "password"
}
@ -962,14 +987,14 @@ func createAuthTest(t *testing.T, secretsService secrets.Service, dsType string,
return test
}
func runDatasourceAuthTest ( t * testing . T , secretsService secrets . Service , cfg * setting . Cfg , test * testCase ) {
func runDatasourceAuthTest ( t * testing . T , secretsService secrets . Service , secretsStore kvstore . SecretsKVStore , cfg * setting . Cfg , test * testCase ) {
ctx := & models . ReqContext { }
tracer , err := tracing . InitializeTracerForTest ( )
require . NoError ( t , err )
var routes [ ] * plugins . Route
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( test . datasource , routes , ctx , "" , & setting . Cfg { } , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( test . datasource , routes , ctx , "" , & setting . Cfg { } , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
req , err := http . NewRequest ( http . MethodGet , "http://grafana.com/sub" , nil )
@ -1010,9 +1035,10 @@ func Test_PathCheck(t *testing.T) {
return ctx , req
}
ctx , _ := setUp ( )
secretsStore := kvstore . SetupTestService ( t )
secretsService := secretsManager . SetupTestService ( t , fakes . NewFakeSecretsStore ( ) )
dsService := datasourceservice . ProvideService ( nil , secretsService , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( & models . DataSource { } , routes , ctx , "b" , & setting . Cfg { } , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer , secretsService )
dsService := datasourceservice . ProvideService ( nil , secretsService , secretsStore , cfg , featuremgmt . WithFeatures ( ) , acmock . New ( ) , acmock . NewPermissionsServicesMock ( ) )
proxy , err := NewDataSourceProxy ( & models . DataSource { } , routes , ctx , "b" , & setting . Cfg { } , httpclient . NewProvider ( ) , & oauthtoken . Service { } , dsService , tracer )
require . NoError ( t , err )
require . Nil ( t , proxy . validateRequest ( ) )