mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Datasource: Fix allowed cookies to be forwarded as header to backend datasources (#49541)
Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
This commit is contained in:
parent
e82784bff0
commit
1196b4a609
@ -3,6 +3,7 @@ package dtos
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -68,6 +69,8 @@ type MetricRequest struct {
|
|||||||
Queries []*simplejson.Json `json:"queries"`
|
Queries []*simplejson.Json `json:"queries"`
|
||||||
// required: false
|
// required: false
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
|
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGravatarUrl(text string) string {
|
func GetGravatarUrl(text string) string {
|
||||||
|
@ -44,6 +44,8 @@ func (hs *HTTPServer) QueryMetricsV2(c *models.ReqContext) response.Response {
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqDTO.HTTPRequest = c.Req
|
||||||
|
|
||||||
resp, err := hs.queryDataService.QueryData(c.Req.Context(), c.SignedInUser, c.SkipCache, reqDTO, true)
|
resp, err := hs.queryDataService.QueryData(c.Req.Context(), c.SignedInUser, c.SkipCache, reqDTO, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hs.handleQueryMetricsError(err)
|
return hs.handleQueryMetricsError(err)
|
||||||
|
@ -3,6 +3,7 @@ package query
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/grafanads"
|
"github.com/grafana/grafana/pkg/tsdb/grafanads"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/legacydata"
|
"github.com/grafana/grafana/pkg/tsdb/legacydata"
|
||||||
|
"github.com/grafana/grafana/pkg/util/proxyutil"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
)
|
)
|
||||||
@ -149,6 +151,19 @@ func (s *Service) handleQueryData(ctx context.Context, user *models.SignedInUser
|
|||||||
req.Headers[k] = v
|
req.Headers[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if parsedReq.httpRequest != nil && parsedReq.httpRequest.Header.Get("Cookie") != "" && ds.JsonData != nil {
|
||||||
|
keepCookieNames := []string{}
|
||||||
|
|
||||||
|
if keepCookies := ds.JsonData.Get("keepCookies"); keepCookies != nil {
|
||||||
|
keepCookieNames = keepCookies.MustStringArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyutil.ClearCookieHeader(parsedReq.httpRequest, keepCookieNames)
|
||||||
|
if cookieStr := parsedReq.httpRequest.Header.Get("Cookie"); cookieStr != "" {
|
||||||
|
req.Headers["Cookie"] = cookieStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, q := range parsedReq.parsedQueries {
|
for _, q := range parsedReq.parsedQueries {
|
||||||
req.Queries = append(req.Queries, q.query)
|
req.Queries = append(req.Queries, q.query)
|
||||||
}
|
}
|
||||||
@ -164,6 +179,7 @@ type parsedQuery struct {
|
|||||||
type parsedRequest struct {
|
type parsedRequest struct {
|
||||||
hasExpression bool
|
hasExpression bool
|
||||||
parsedQueries []parsedQuery
|
parsedQueries []parsedQuery
|
||||||
|
httpRequest *http.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
func customHeaders(jsonData *simplejson.Json, decryptedJsonData map[string]string) map[string]string {
|
func customHeaders(jsonData *simplejson.Json, decryptedJsonData map[string]string) map[string]string {
|
||||||
@ -243,6 +259,10 @@ func (s *Service) parseMetricRequest(ctx context.Context, user *models.SignedInU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if reqDTO.HTTPRequest != nil {
|
||||||
|
req.httpRequest = reqDTO.HTTPRequest
|
||||||
|
}
|
||||||
|
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,43 @@ func TestQueryData(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.Equal(t, expected, tc.pluginContext.req.Headers)
|
require.Equal(t, expected, tc.pluginContext.req.Headers)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("it doesn't add cookie header to the request when keepCookies configured and no cookies provided", func(t *testing.T) {
|
||||||
|
tc := setup(t)
|
||||||
|
json, err := simplejson.NewJson([]byte(`{"keepCookies": [ "foo", "bar" ]}`))
|
||||||
|
require.NoError(t, err)
|
||||||
|
tc.dataSourceCache.ds.JsonData = json
|
||||||
|
|
||||||
|
metricReq := metricRequest()
|
||||||
|
httpReq, err := http.NewRequest(http.MethodGet, "/", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
metricReq.HTTPRequest = httpReq
|
||||||
|
_, err = tc.queryService.QueryData(context.Background(), nil, true, metricReq, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Empty(t, tc.pluginContext.req.Headers)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("it adds cookie header to the request when keepCookies configured and cookie provided", func(t *testing.T) {
|
||||||
|
tc := setup(t)
|
||||||
|
json, err := simplejson.NewJson([]byte(`{"keepCookies": [ "foo", "bar" ]}`))
|
||||||
|
require.NoError(t, err)
|
||||||
|
tc.dataSourceCache.ds.JsonData = json
|
||||||
|
|
||||||
|
metricReq := metricRequest()
|
||||||
|
httpReq, err := http.NewRequest(http.MethodGet, "/", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
httpReq.AddCookie(&http.Cookie{Name: "a"})
|
||||||
|
httpReq.AddCookie(&http.Cookie{Name: "bar", Value: "rab"})
|
||||||
|
httpReq.AddCookie(&http.Cookie{Name: "b"})
|
||||||
|
httpReq.AddCookie(&http.Cookie{Name: "foo", Value: "oof"})
|
||||||
|
httpReq.AddCookie(&http.Cookie{Name: "c"})
|
||||||
|
metricReq.HTTPRequest = httpReq
|
||||||
|
_, err = tc.queryService.QueryData(context.Background(), nil, true, metricReq, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, map[string]string{"Cookie": "bar=rab; foo=oof"}, tc.pluginContext.req.Headers)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(t *testing.T) *testContext {
|
func setup(t *testing.T) *testContext {
|
||||||
|
Loading…
Reference in New Issue
Block a user