Skip to content

Commit

Permalink
Merge branch 'main' into bump-grafana-plugin-sdk-go-251
Browse files Browse the repository at this point in the history
  • Loading branch information
zoltanbedi authored Oct 15, 2024
2 parents 276bcd4 + 9d6bf2c commit 7cf9949
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 40 deletions.
5 changes: 0 additions & 5 deletions .changeset/gorgeous-laws-hunt.md

This file was deleted.

10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Change Log

## 2.11.0

### Minor Changes

🚀 Remove base URL deprecation

### Patch Changes

🐛 Fix forward oauth for x-id-token header

## 2.10.0

🚀 **Improvement**: Remove deprecation for base URL and move it to URL, Headers & Params
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ require (
github.com/grafana/grafana-aws-sdk v0.31.2
github.com/grafana/grafana-plugin-sdk-go v0.252.0
github.com/grafana/infinity-libs/lib/go/csvframer v1.0.1
github.com/grafana/infinity-libs/lib/go/framesql v1.0.1
github.com/grafana/infinity-libs/lib/go/framesql v1.0.2
github.com/grafana/infinity-libs/lib/go/gframer v1.0.0
github.com/grafana/infinity-libs/lib/go/jsonframer v1.1.4
github.com/grafana/infinity-libs/lib/go/macros v1.0.0
github.com/grafana/infinity-libs/lib/go/transformations v1.0.1
github.com/grafana/infinity-libs/lib/go/transformations v1.0.3
github.com/grafana/infinity-libs/lib/go/xmlframer v1.0.0
github.com/icholy/digest v0.1.22
github.com/stretchr/testify v1.9.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,16 @@ github.com/grafana/grafana-plugin-sdk-go v0.252.0 h1:GEnMZOQl+yN96Cg9EPZAcPRKI65
github.com/grafana/grafana-plugin-sdk-go v0.252.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
github.com/grafana/infinity-libs/lib/go/csvframer v1.0.1 h1:SBL+Ix6E1Ec6QPdAkq/yhyqvicV5wyWlHKB0bH8jjIA=
github.com/grafana/infinity-libs/lib/go/csvframer v1.0.1/go.mod h1:gVqJA9np8h1RpZYemoVouIe/b3m2lUc5HVAbdM7K8sM=
github.com/grafana/infinity-libs/lib/go/framesql v1.0.1 h1:q8hqwHIcfWRxUq6YWGGXnim79WXHAjZOqUqRPGykJNU=
github.com/grafana/infinity-libs/lib/go/framesql v1.0.1/go.mod h1:Z1LC4OCGQ/Bc4w+bDt63vUWkLml5Q3m/Pim/TXFGHfg=
github.com/grafana/infinity-libs/lib/go/framesql v1.0.2 h1:fWTC2tG9nKx8xp9V/IXfeEC7auMEBTE/FxysEeKC1fg=
github.com/grafana/infinity-libs/lib/go/framesql v1.0.2/go.mod h1:Z1LC4OCGQ/Bc4w+bDt63vUWkLml5Q3m/Pim/TXFGHfg=
github.com/grafana/infinity-libs/lib/go/gframer v1.0.0 h1:TYKumCoWlf9KlXa6M9pi3s6H9bjl0V5XF8f73aitNWE=
github.com/grafana/infinity-libs/lib/go/gframer v1.0.0/go.mod h1:tCjLSNFQnuYiNeBIAyb51jNV8ad0eI/M69P1rxm77Fc=
github.com/grafana/infinity-libs/lib/go/jsonframer v1.1.4 h1:boSnUP+ZuFJByvfFozX7www10ApnAKPmsUfXcxl0YLI=
github.com/grafana/infinity-libs/lib/go/jsonframer v1.1.4/go.mod h1:HLkUysTFcEDE6E/j2OHcd2TcpROSlqX1N3l4DkVTzdE=
github.com/grafana/infinity-libs/lib/go/macros v1.0.0 h1:5IaWKGvY0zhli0MKfjKvS1Y+bzY758Yw8HELU4cqs6E=
github.com/grafana/infinity-libs/lib/go/macros v1.0.0/go.mod h1:6EE8D9bV9J9nC9gQSD1HirqCKHhWKaEaZYJsajM6PGk=
github.com/grafana/infinity-libs/lib/go/transformations v1.0.1 h1:PlV0NiWn9Lmfrodkjn91s/IRoIY4pL9jnuvtX4Hd3ZE=
github.com/grafana/infinity-libs/lib/go/transformations v1.0.1/go.mod h1:/WACyqQiCKo7lTezxRyMYaGYM/lVF8/u9b56z1amb40=
github.com/grafana/infinity-libs/lib/go/transformations v1.0.3 h1:1ruYu3D9IsfNF7o8jU4zIowbq99YnX77Lt/hmvIj3pg=
github.com/grafana/infinity-libs/lib/go/transformations v1.0.3/go.mod h1:/WACyqQiCKo7lTezxRyMYaGYM/lVF8/u9b56z1amb40=
github.com/grafana/infinity-libs/lib/go/utils v1.0.0 h1:jXlKDSay/S2tdaWghc0E7DzKugMQhEUcKtlVPmb69oc=
github.com/grafana/infinity-libs/lib/go/utils v1.0.0/go.mod h1:86US+G1Ujk61fibdPSEHWl+atBjXGGeibuEOMfMU2v4=
github.com/grafana/infinity-libs/lib/go/xmlframer v1.0.0 h1:I8aMygkFiaBQUktugOIOjaigO0p/DgS94/ikr5G+WRw=
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "grafana-infinity-datasource",
"version": "2.10.0",
"version": "2.11.0",
"description": "JSON, CSV, XML, GraphQL, HTML and REST API datasource for Grafana. Do infinite things with Grafana. Transform data with UQL/GROQ. Visualize data from many apis, RSS/ATOM feeds directly",
"keywords": [
"grafana",
Expand Down Expand Up @@ -49,7 +49,7 @@
"watch": "yarn dev"
},
"resolutions": {
"dompurify": "2.4.9"
"dompurify": "2.5.4"
},
"dependencies": {
"@emotion/css": "11.10.6",
Expand Down
28 changes: 19 additions & 9 deletions pkg/infinity/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const (
const (
headerKeyAccept = "Accept"
headerKeyContentType = "Content-Type"
headerKeyAuthorization = "Authorization"
headerKeyIdToken = "X-ID-Token"
HeaderKeyAuthorization = "Authorization"
HeaderKeyIdToken = "X-Id-Token"
)

func ApplyAcceptHeader(query models.Query, settings models.InfinitySettings, req *http.Request, includeSect bool) *http.Request {
Expand Down Expand Up @@ -103,7 +103,7 @@ func ApplyBasicAuth(settings models.InfinitySettings, req *http.Request, include
if includeSect {
basicAuthHeader = "Basic " + base64.StdEncoding.EncodeToString([]byte(settings.UserName+":"+settings.Password))
}
req.Header.Set(headerKeyAuthorization, basicAuthHeader)
req.Header.Set(HeaderKeyAuthorization, basicAuthHeader)
}
return req
}
Expand All @@ -114,7 +114,7 @@ func ApplyBearerToken(settings models.InfinitySettings, req *http.Request, inclu
if includeSect {
bearerAuthHeader = fmt.Sprintf("Bearer %s", settings.BearerToken)
}
req.Header.Add(headerKeyAuthorization, bearerAuthHeader)
req.Header.Add(HeaderKeyAuthorization, bearerAuthHeader)
}
return req
}
Expand All @@ -137,13 +137,23 @@ func ApplyForwardedOAuthIdentity(requestHeaders map[string]string, settings mode
authHeader := dummyHeader
token := dummyHeader
if includeSect {
authHeader = requestHeaders[headerKeyAuthorization]
token = requestHeaders[headerKeyIdToken]
authHeader = getQueryReqHeader(requestHeaders, HeaderKeyAuthorization)
token = getQueryReqHeader(requestHeaders, HeaderKeyIdToken)
}
req.Header.Add(headerKeyAuthorization, authHeader)
if requestHeaders[headerKeyIdToken] != "" {
req.Header.Add(headerKeyIdToken, token)
req.Header.Add(HeaderKeyAuthorization, authHeader)
if token != "" && token != dummyHeader {
req.Header.Add(HeaderKeyIdToken, token)
}
}
return req
}

func getQueryReqHeader(requestHeaders map[string]string, headerName string) string {
for name, value := range requestHeaders {
if strings.EqualFold(headerName, name) {
return value
}
}

return ""
}
65 changes: 65 additions & 0 deletions pkg/infinity/headers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package infinity

import (
"strings"
"testing"
)

func TestGetQueryReqHeader(t *testing.T) {
tests := []struct {
name string
requestHeaders map[string]string
headerName string
expected string
}{
{
name: "Authorization header exact match",
requestHeaders: map[string]string{
HeaderKeyAuthorization: "Bearer token",
},
headerName: HeaderKeyAuthorization,
expected: "Bearer token",
},
{
name: "Authorization header case insensitive match",
requestHeaders: map[string]string{
strings.ToLower(HeaderKeyAuthorization): "Bearer token",
},
headerName: HeaderKeyAuthorization,
expected: "Bearer token",
},
{
name: "X-Id-Token header exact match",
requestHeaders: map[string]string{
HeaderKeyIdToken: "some-id-token",
},
headerName: HeaderKeyIdToken,
expected: "some-id-token",
},
{
name: "X-Id-Token header case insensitive match",
requestHeaders: map[string]string{
strings.ToLower(HeaderKeyIdToken): "some-id-token",
},
headerName: HeaderKeyIdToken,
expected: "some-id-token",
},
{
name: "X-Id-Token header case with ID capitalization",
requestHeaders: map[string]string{
"X-ID-Token": "some-id-token",
},
headerName: HeaderKeyIdToken,
expected: "some-id-token",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := getQueryReqHeader(tt.requestHeaders, tt.headerName)
if got != tt.expected {
t.Errorf("getQueryReqHeader() = %v, expected %v", got, tt.expected)
}
})
}
}
2 changes: 1 addition & 1 deletion pkg/infinity/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func ApplyNotices(ctx context.Context, settings models.InfinitySettings, frame *
func GetSecureHeaderWarnings(query models.Query) []data.Notice {
notices := []data.Notice{}
for _, h := range query.URLOptions.Headers {
if strings.EqualFold(h.Key, headerKeyAuthorization) {
if strings.EqualFold(h.Key, HeaderKeyAuthorization) {
notices = append(notices, data.Notice{
Severity: data.NoticeSeverityWarning,
Text: fmt.Sprintf("for security reasons, don't include headers such as %s in the query. Instead, add them in the config where possible", h.Key),
Expand Down
11 changes: 11 additions & 0 deletions pkg/infinity/posprocess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/infinity-libs/lib/go/framesql"
"github.com/grafana/infinity-libs/lib/go/transformations"
"github.com/stretchr/testify/require"
)
Expand All @@ -32,6 +33,16 @@ tests := []struct {
inputError: errors.Join(transformations.ErrNotUniqueFieldNames, fmt.Errorf("some random error")),
isDownstream: true,
},
{
name: "Downstream error joined - ErrExpressionNotFoundInFields",
inputError: errors.Join(framesql.ErrExpressionNotFoundInFields, fmt.Errorf("some random error")),
isDownstream: true,
},
{
name: "Downstream error joined - ErrInvalidFilterExpression",
inputError: errors.Join(transformations.ErrInvalidFilterExpression, fmt.Errorf("some random error")),
isDownstream: true,
},
{
name: "Non-Downstream error",
inputError: errors.New("some random error"),
Expand Down
7 changes: 5 additions & 2 deletions pkg/infinity/postprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ func PostProcessFrame(ctx context.Context, frame *data.Frame, query models.Query
if err != nil {
logger.Error("error applying filter", "error", err.Error())
frame.Meta.Custom = &CustomMeta{Query: query, Error: err.Error()}
return frame, errorsource.PluginError(fmt.Errorf("error applying filter. %w", err), false)
err = addErrorSourceToTransformError(fmt.Errorf("error applying filter. %w", err))
return frame, err
}
if strings.TrimSpace(query.SummarizeExpression) != "" {
alias := query.SummarizeAlias
Expand Down Expand Up @@ -69,8 +70,10 @@ func addErrorSourceToTransformError(err error) error {
t.ErrMergeTransformationNoFrameSupplied,
t.ErrMergeTransformationDifferentFields,
t.ErrMergeTransformationDifferentFieldNames,
t.ErrMergeTransformationDifferentFieldTypes,
t.ErrMergeTransformationDifferentFieldTypes,
t.ErrInvalidFilterExpression,
framesql.ErrEmptySummarizeExpression,
framesql.ErrExpressionNotFoundInFields,
}

for _, e := range downstreamErrors {
Expand Down
22 changes: 11 additions & 11 deletions pkg/testsuite/handler_querydata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func TestAuthentication(t *testing.T) {
t.Run("should set basic auth headers when set the username and password", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "Basic "+base64.StdEncoding.EncodeToString([]byte("infinityUser:myPassword")), r.Header.Get("Authorization"))
assert.Equal(t, "", r.Header.Get("X-ID-Token"))
assert.Equal(t, "Basic "+base64.StdEncoding.EncodeToString([]byte("infinityUser:myPassword")), r.Header.Get(infinity.HeaderKeyAuthorization))
assert.Equal(t, "", r.Header.Get(infinity.HeaderKeyIdToken))
fmt.Fprintf(w, `{ "message" : "OK" }`)
}))
defer server.Close()
Expand Down Expand Up @@ -76,8 +76,8 @@ func TestAuthentication(t *testing.T) {
t.Run("should return error when incorrect credentials set", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "", r.Header.Get("X-ID-Token"))
if r.Header.Get("Authorization") == "Basic "+base64.StdEncoding.EncodeToString([]byte("infinityUser:myPassword")) {
assert.Equal(t, "", r.Header.Get(infinity.HeaderKeyIdToken))
if r.Header.Get(infinity.HeaderKeyAuthorization) == "Basic "+base64.StdEncoding.EncodeToString([]byte("infinityUser:myPassword")) {
fmt.Fprintf(w, "OK")
return
}
Expand Down Expand Up @@ -113,8 +113,8 @@ func TestAuthentication(t *testing.T) {
t.Run("should forward the oauth headers when forward oauth identity is set", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "foo", r.Header.Get("Authorization"))
assert.Equal(t, "bar", r.Header.Get("X-ID-Token"))
assert.Equal(t, "foo", r.Header.Get(infinity.HeaderKeyAuthorization))
assert.Equal(t, "bar", r.Header.Get(infinity.HeaderKeyIdToken))
fmt.Fprintf(w, `{ "message" : "OK" }`)
}))
defer server.Close()
Expand All @@ -137,8 +137,8 @@ func TestAuthentication(t *testing.T) {
t.Run("should not forward the oauth headers when forward oauth identity is not set", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "", r.Header.Get("Authorization"))
assert.Equal(t, "", r.Header.Get("X-ID-Token"))
assert.Equal(t, "", r.Header.Get(infinity.HeaderKeyAuthorization))
assert.Equal(t, "", r.Header.Get(infinity.HeaderKeyIdToken))
fmt.Fprintf(w, `{ "message" : "OK" }`)
}))
defer server.Close()
Expand Down Expand Up @@ -207,7 +207,7 @@ func TestAuthentication(t *testing.T) {
w.WriteHeader(http.StatusUnauthorized)
return
}
if r.Header.Get("Authorization") != "Bearer foo" {
if r.Header.Get(infinity.HeaderKeyAuthorization) != "Bearer foo" {
w.WriteHeader(http.StatusUnauthorized)
return
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func TestAuthentication(t *testing.T) {
t.Run("should error when CA cert verification failed", func(t *testing.T) {
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "", r.Header.Get("X-ID-Token"))
assert.Equal(t, "", r.Header.Get(infinity.HeaderKeyIdToken))
fmt.Fprintf(w, `{ "message" : "OK" }`)
}))
server.TLS = getServerCertificate(server.URL)
Expand Down Expand Up @@ -281,7 +281,7 @@ func TestAuthentication(t *testing.T) {
t.Run("should honour skip tls verify setting", func(t *testing.T) {
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "", r.Header.Get("X-ID-Token"))
assert.Equal(t, "", r.Header.Get(infinity.HeaderKeyIdToken))
fmt.Fprintf(w, `{ "message" : "OK" }`)
}))
server.TLS = getServerCertificate(server.URL)
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4535,10 +4535,10 @@ domhandler@^5.0.2, domhandler@^5.0.3:
dependencies:
domelementtype "^2.3.0"

dompurify@2.4.9, dompurify@^2.4.3:
version "2.4.9"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.9.tgz#9ccdd9e1780653156b09de873f5372bc1eaf2c40"
integrity sha512-iHtnxYMotKgOTvxIqq677JsKHvCOkAFqj9x8Mek2zdeHW1XjuFKwjpmZeMaXQRQ8AbJZDbcRz/+r1QhwvFtmQg==
dompurify@2.5.4, dompurify@^2.4.3:
version "2.5.4"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.5.4.tgz#347e91070963b22db31c7c8d0ce9a0a2c3c08746"
integrity sha512-l5NNozANzaLPPe0XaAwvg3uZcHtDBnziX/HjsY1UcDj1MxTK8Dd0Kv096jyPK5HRzs/XM5IMj20dW8Fk+HnbUA==

domutils@^3.0.1:
version "3.1.0"
Expand Down

0 comments on commit 7cf9949

Please sign in to comment.