diff --git a/CHANGELOG.md b/CHANGELOG.md index 560469515b7..93e8f846506 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ + + +# 8.3.4 (2022-01-17) + +### Features and enhancements + +- **Alerting:** Allow configuration of non-ready alertmanagers. [#43063](https://github.com/grafana/grafana/pull/43063), [@alexweav](https://github.com/alexweav) +- **Alerting:** Allow customization of Google chat message. [#43568](https://github.com/grafana/grafana/pull/43568), [@alexweav](https://github.com/alexweav) +- **Alerting:** Allow customization of Google chat message (#43568). [#43723](https://github.com/grafana/grafana/pull/43723), [@alexweav](https://github.com/alexweav) +- **AppPlugins:** Support app plugins with only default nav. [#43016](https://github.com/grafana/grafana/pull/43016), [@torkelo](https://github.com/torkelo) +- **InfluxDB:** InfluxQL: query editor: skip fields in metadata queries. [#42543](https://github.com/grafana/grafana/pull/42543), [@gabor](https://github.com/gabor) +- **Postgres/MySQL/MSSQL:** Cancel in-flight SQL query if user cancels query in grafana. [#43890](https://github.com/grafana/grafana/pull/43890), [@mdvictor](https://github.com/mdvictor) +- **Prometheus:** Forward oauth tokens after prometheus datasource migration. [#43686](https://github.com/grafana/grafana/pull/43686), [@MasslessParticle](https://github.com/MasslessParticle) + +### Bug fixes + +- **Azure Monitor:** Bug fix for variable interpolations in metrics dropdowns. [#43251](https://github.com/grafana/grafana/pull/43251), [@sarahzinger](https://github.com/sarahzinger) +- **Azure Monitor:** Improved error messages for variable queries. [#43213](https://github.com/grafana/grafana/pull/43213), [@sunker](https://github.com/sunker) +- **CloudMonitoring:** Fixes broken variable queries that use group bys. [#43914](https://github.com/grafana/grafana/pull/43914), [@sunker](https://github.com/sunker) +- **Configuration:** You can now see your expired API keys if you have no active ones. [#42452](https://github.com/grafana/grafana/pull/42452), [@ashharrison90](https://github.com/ashharrison90) +- **Elasticsearch:** Fix handling multiple datalinks for a single field. [#44029](https://github.com/grafana/grafana/pull/44029), [@Elfo404](https://github.com/Elfo404) +- **Export:** Fix error being thrown when exporting dashboards using query variables that reference the default datasource. [#44034](https://github.com/grafana/grafana/pull/44034), [@ashharrison90](https://github.com/ashharrison90) +- **ImportDashboard:** Fixes issue with importing dashboard and name ending up in uid. [#43451](https://github.com/grafana/grafana/pull/43451), [@torkelo](https://github.com/torkelo) +- **Login:** Page no longer overflows on mobile. [#43739](https://github.com/grafana/grafana/pull/43739), [@ashharrison90](https://github.com/ashharrison90) +- **Plugins:** Set backend metadata property for core plugins. [#43349](https://github.com/grafana/grafana/pull/43349), [@marefr](https://github.com/marefr) +- **Prometheus:** Fill missing steps with null values. [#43622](https://github.com/grafana/grafana/pull/43622), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Fix interpolation of $\_\_rate_interval variable. [#44035](https://github.com/grafana/grafana/pull/44035), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Interpolate variables with curly brackets syntax. [#42927](https://github.com/grafana/grafana/pull/42927), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Respect the http-method data source setting. [#42753](https://github.com/grafana/grafana/pull/42753), [@gabor](https://github.com/gabor) +- **Table:** Fixes issue with field config applied to wrong fields when hiding columns. [#43376](https://github.com/grafana/grafana/pull/43376), [@torkelo](https://github.com/torkelo) +- **Toolkit:** Fix bug with rootUrls not being properly parsed when signing a private plugin. [#43014](https://github.com/grafana/grafana/pull/43014), [@dessen-xu](https://github.com/dessen-xu) +- **Variables:** Fix so data source variables are added to adhoc configuration. [#43881](https://github.com/grafana/grafana/pull/43881), [@hugohaggmark](https://github.com/hugohaggmark) + +### Plugin development fixes & changes + +- **Toolkit:** Revert build config so tslib is bundled with plugins to prevent plugins from crashing. [#43556](https://github.com/grafana/grafana/pull/43556), [@mckn](https://github.com/mckn) + + # 8.3.3 (2021-12-10) diff --git a/docs/sources/release-notes/_index.md b/docs/sources/release-notes/_index.md index 99a5c4f406b..8d078e1dbd2 100644 --- a/docs/sources/release-notes/_index.md +++ b/docs/sources/release-notes/_index.md @@ -8,6 +8,7 @@ weight = 10000 Here you can find detailed release notes that list everything that is included in every release as well as notices about deprecations, breaking changes as well as changes that relate to plugin development. +- [Release notes for 8.3.4]({{< relref "release-notes-8-3-4" >}}) - [Release notes for 8.3.3]({{< relref "release-notes-8-3-3" >}}) - [Release notes for 8.3.2]({{< relref "release-notes-8-3-2" >}}) - [Release notes for 8.3.1]({{< relref "release-notes-8-3-1" >}}) diff --git a/docs/sources/release-notes/release-notes-8-3-4.md b/docs/sources/release-notes/release-notes-8-3-4.md new file mode 100644 index 00000000000..f4bb71d04d4 --- /dev/null +++ b/docs/sources/release-notes/release-notes-8-3-4.md @@ -0,0 +1,42 @@ ++++ +title = "Release notes for Grafana 8.3.4" +[_build] +list = false ++++ + + + +# Release notes for Grafana 8.3.4 + +### Features and enhancements + +- **Alerting:** Allow configuration of non-ready alertmanagers. [#43063](https://github.com/grafana/grafana/pull/43063), [@alexweav](https://github.com/alexweav) +- **Alerting:** Allow customization of Google chat message. [#43568](https://github.com/grafana/grafana/pull/43568), [@alexweav](https://github.com/alexweav) +- **Alerting:** Allow customization of Google chat message (#43568). [#43723](https://github.com/grafana/grafana/pull/43723), [@alexweav](https://github.com/alexweav) +- **AppPlugins:** Support app plugins with only default nav. [#43016](https://github.com/grafana/grafana/pull/43016), [@torkelo](https://github.com/torkelo) +- **InfluxDB:** InfluxQL: query editor: skip fields in metadata queries. [#42543](https://github.com/grafana/grafana/pull/42543), [@gabor](https://github.com/gabor) +- **Postgres/MySQL/MSSQL:** Cancel in-flight SQL query if user cancels query in grafana. [#43890](https://github.com/grafana/grafana/pull/43890), [@mdvictor](https://github.com/mdvictor) +- **Prometheus:** Forward oauth tokens after prometheus datasource migration. [#43686](https://github.com/grafana/grafana/pull/43686), [@MasslessParticle](https://github.com/MasslessParticle) + +### Bug fixes + +- **Azure Monitor:** Bug fix for variable interpolations in metrics dropdowns. [#43251](https://github.com/grafana/grafana/pull/43251), [@sarahzinger](https://github.com/sarahzinger) +- **Azure Monitor:** Improved error messages for variable queries. [#43213](https://github.com/grafana/grafana/pull/43213), [@sunker](https://github.com/sunker) +- **CloudMonitoring:** Fixes broken variable queries that use group bys. [#43914](https://github.com/grafana/grafana/pull/43914), [@sunker](https://github.com/sunker) +- **Configuration:** You can now see your expired API keys if you have no active ones. [#42452](https://github.com/grafana/grafana/pull/42452), [@ashharrison90](https://github.com/ashharrison90) +- **Elasticsearch:** Fix handling multiple datalinks for a single field. [#44029](https://github.com/grafana/grafana/pull/44029), [@Elfo404](https://github.com/Elfo404) +- **Export:** Fix error being thrown when exporting dashboards using query variables that reference the default datasource. [#44034](https://github.com/grafana/grafana/pull/44034), [@ashharrison90](https://github.com/ashharrison90) +- **ImportDashboard:** Fixes issue with importing dashboard and name ending up in uid. [#43451](https://github.com/grafana/grafana/pull/43451), [@torkelo](https://github.com/torkelo) +- **Login:** Page no longer overflows on mobile. [#43739](https://github.com/grafana/grafana/pull/43739), [@ashharrison90](https://github.com/ashharrison90) +- **Plugins:** Set backend metadata property for core plugins. [#43349](https://github.com/grafana/grafana/pull/43349), [@marefr](https://github.com/marefr) +- **Prometheus:** Fill missing steps with null values. [#43622](https://github.com/grafana/grafana/pull/43622), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Fix interpolation of $\_\_rate_interval variable. [#44035](https://github.com/grafana/grafana/pull/44035), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Interpolate variables with curly brackets syntax. [#42927](https://github.com/grafana/grafana/pull/42927), [@ivanahuckova](https://github.com/ivanahuckova) +- **Prometheus:** Respect the http-method data source setting. [#42753](https://github.com/grafana/grafana/pull/42753), [@gabor](https://github.com/gabor) +- **Table:** Fixes issue with field config applied to wrong fields when hiding columns. [#43376](https://github.com/grafana/grafana/pull/43376), [@torkelo](https://github.com/torkelo) +- **Toolkit:** Fix bug with rootUrls not being properly parsed when signing a private plugin. [#43014](https://github.com/grafana/grafana/pull/43014), [@dessen-xu](https://github.com/dessen-xu) +- **Variables:** Fix so data source variables are added to adhoc configuration. [#43881](https://github.com/grafana/grafana/pull/43881), [@hugohaggmark](https://github.com/hugohaggmark) + +### Plugin development fixes & changes + +- **Toolkit:** Revert build config so tslib is bundled with plugins to prevent plugins from crashing. [#43556](https://github.com/grafana/grafana/pull/43556), [@mckn](https://github.com/mckn) diff --git a/pkg/api/pluginproxy/ds_proxy.go b/pkg/api/pluginproxy/ds_proxy.go index deb1409ef36..bf04c5b6fc8 100644 --- a/pkg/api/pluginproxy/ds_proxy.go +++ b/pkg/api/pluginproxy/ds_proxy.go @@ -54,6 +54,7 @@ func (t *handleResponseTransport) RoundTrip(req *http.Request) (*http.Response, return nil, err } res.Header.Del("Set-Cookie") + proxyutil.SetProxyResponseHeaders(res.Header) return res, nil } diff --git a/pkg/api/pluginproxy/ds_proxy_test.go b/pkg/api/pluginproxy/ds_proxy_test.go index 19af483396a..b03b4e461a1 100644 --- a/pkg/api/pluginproxy/ds_proxy_test.go +++ b/pkg/api/pluginproxy/ds_proxy_test.go @@ -663,6 +663,20 @@ func TestDataSourceProxy_requestHandling(t *testing.T) { assert.Equal(t, "important_cookie=important_value", proxy.ctx.Resp.Header().Get("Set-Cookie")) }) + t.Run("When response should set Content-Security-Policy header", func(t *testing.T) { + ctx, ds := setUp(t) + var routes []*plugins.Route + secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) + dsService := datasources.ProvideService(bus.New(), nil, secretsService) + proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService) + require.NoError(t, err) + + proxy.HandleRequest() + + require.NoError(t, writeErr) + assert.Equal(t, "sandbox", proxy.ctx.Resp.Header().Get("Content-Security-Policy")) + }) + t.Run("Data source returns status code 401", func(t *testing.T) { ctx, ds := setUp(t, setUpCfg{ writeCb: func(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/api/pluginproxy/pluginproxy.go b/pkg/api/pluginproxy/pluginproxy.go index a972d3d500a..f66cc32ddac 100644 --- a/pkg/api/pluginproxy/pluginproxy.go +++ b/pkg/api/pluginproxy/pluginproxy.go @@ -83,5 +83,11 @@ func NewApiPluginProxy(ctx *models.ReqContext, proxyPath string, route *plugins. } } - return &httputil.ReverseProxy{Director: director} + return &httputil.ReverseProxy{Director: director, ModifyResponse: modifyResponse} +} + +func modifyResponse(resp *http.Response) error { + proxyutil.SetProxyResponseHeaders(resp.Header) + + return nil } diff --git a/pkg/api/pluginproxy/pluginproxy_test.go b/pkg/api/pluginproxy/pluginproxy_test.go index e6585f038a6..0aaf1d0d1b3 100644 --- a/pkg/api/pluginproxy/pluginproxy_test.go +++ b/pkg/api/pluginproxy/pluginproxy_test.go @@ -4,6 +4,7 @@ import ( "context" "io/ioutil" "net/http" + "net/http/httptest" "testing" "github.com/grafana/grafana/pkg/bus" @@ -13,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/macaron.v1" @@ -245,6 +247,41 @@ func TestPluginProxy(t *testing.T) { require.NoError(t, err) require.Equal(t, `{ "url": "https://dynamic.grafana.com", "secret": "123" }`, string(content)) }) + + t.Run("When proxying a request should set expected response headers", func(t *testing.T) { + requestHandled := false + backendServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + _, _ = w.Write([]byte("I am the backend")) + requestHandled = true + })) + t.Cleanup(backendServer.Close) + + responseWriter := web.NewResponseWriter("GET", httptest.NewRecorder()) + + route := &plugins.Route{ + Path: "/", + URL: backendServer.URL, + } + + ctx := &models.ReqContext{ + SignedInUser: &models.SignedInUser{}, + Context: &web.Context{ + Req: httptest.NewRequest("GET", "/", nil), + Resp: responseWriter, + }, + } + proxy := NewApiPluginProxy(ctx, "", route, "", &setting.Cfg{}, secretsService) + proxy.ServeHTTP(ctx.Resp, ctx.Req) + + for { + if requestHandled { + break + } + } + + require.Equal(t, "sandbox", ctx.Resp.Header().Get("Content-Security-Policy")) + }) } // getPluginProxiedRequest is a helper for easier setup of tests based on global config and ReqContext. diff --git a/pkg/plugins/manager/manager.go b/pkg/plugins/manager/manager.go index 991b7474362..c2fb041da87 100644 --- a/pkg/plugins/manager/manager.go +++ b/pkg/plugins/manager/manager.go @@ -392,6 +392,8 @@ func flushStream(plugin backendplugin.Plugin, stream callResourceClientResponseS w.Header().Add(k, v) } } + + proxyutil.SetProxyResponseHeaders(w.Header()) w.WriteHeader(resp.Status) } diff --git a/pkg/plugins/manager/manager_test.go b/pkg/plugins/manager/manager_test.go index f996bc45a9f..6a515c54af6 100644 --- a/pkg/plugins/manager/manager_test.go +++ b/pkg/plugins/manager/manager_test.go @@ -447,7 +447,8 @@ func TestPluginManager_lifecycle_managed(t *testing.T) { ctx.pluginClient.CallResourceHandlerFunc = func(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { return sender.Send(&backend.CallResourceResponse{ - Status: http.StatusOK, + Status: http.StatusOK, + Headers: map[string][]string{}, }) } @@ -456,7 +457,13 @@ func TestPluginManager_lifecycle_managed(t *testing.T) { w := httptest.NewRecorder() err = ctx.manager.callResourceInternal(w, req, backend.PluginContext{PluginID: testPluginID}) require.NoError(t, err) + for { + if w.Flushed { + break + } + } require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, "sandbox", w.Header().Get("Content-Security-Policy")) }) }) }) diff --git a/pkg/services/login/authinfoservice/database.go b/pkg/services/login/authinfoservice/database.go index 24ad631d521..75431745a7f 100644 --- a/pkg/services/login/authinfoservice/database.go +++ b/pkg/services/login/authinfoservice/database.go @@ -38,6 +38,10 @@ func (s *Implementation) GetExternalUserInfoByLogin(ctx context.Context, query * } func (s *Implementation) GetAuthInfo(query *models.GetAuthInfoQuery) error { + if query.UserId == 0 && query.AuthId == "" { + return models.ErrUserNotFound + } + userAuth := &models.UserAuth{ UserId: query.UserId, AuthModule: query.AuthModule, diff --git a/pkg/util/proxyutil/proxyutil.go b/pkg/util/proxyutil/proxyutil.go index d6e35721333..3db22a1426e 100644 --- a/pkg/util/proxyutil/proxyutil.go +++ b/pkg/util/proxyutil/proxyutil.go @@ -42,3 +42,9 @@ func ClearCookieHeader(req *http.Request, keepCookiesNames []string) { req.AddCookie(c) } } + +// SetProxyResponseHeaders sets proxy response headers. +// Sets Content-Security-Policy: sandbox +func SetProxyResponseHeaders(header http.Header) { + header.Set("Content-Security-Policy", "sandbox") +} diff --git a/yarn.lock b/yarn.lock index 940d8df50e0..ecd94902446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2329,9 +2329,9 @@ __metadata: version: 0.0.0-use.local resolution: "@grafana-plugins/input-datasource@workspace:plugins-bundled/internal/input-datasource" dependencies: - "@grafana/data": 8.3.3 - "@grafana/toolkit": 8.3.3 - "@grafana/ui": 8.3.3 + "@grafana/data": 8.3.4 + "@grafana/toolkit": 8.3.4 + "@grafana/ui": 8.3.4 "@types/jest": 26.0.15 "@types/lodash": 4.14.149 "@types/react": 17.0.30 @@ -2372,12 +2372,12 @@ __metadata: languageName: node linkType: hard -"@grafana/data@8.3.3, @grafana/data@workspace:*, @grafana/data@workspace:packages/grafana-data": +"@grafana/data@8.3.4, @grafana/data@workspace:*, @grafana/data@workspace:packages/grafana-data": version: 0.0.0-use.local resolution: "@grafana/data@workspace:packages/grafana-data" dependencies: "@braintree/sanitize-url": 5.0.2 - "@grafana/schema": 8.3.3 + "@grafana/schema": 8.3.4 "@grafana/tsconfig": ^1.0.0-rc1 "@rollup/plugin-commonjs": 21.0.1 "@rollup/plugin-json": 4.1.0 @@ -2432,7 +2432,7 @@ __metadata: languageName: unknown linkType: soft -"@grafana/e2e-selectors@8.3.3, @grafana/e2e-selectors@workspace:*, @grafana/e2e-selectors@workspace:packages/grafana-e2e-selectors": +"@grafana/e2e-selectors@8.3.4, @grafana/e2e-selectors@workspace:*, @grafana/e2e-selectors@workspace:packages/grafana-e2e-selectors": version: 0.0.0-use.local resolution: "@grafana/e2e-selectors@workspace:packages/grafana-e2e-selectors" dependencies: @@ -2464,7 +2464,7 @@ __metadata: "@babel/core": 7.14.6 "@babel/preset-env": 7.14.7 "@cypress/webpack-preprocessor": 5.9.1 - "@grafana/e2e-selectors": 8.3.3 + "@grafana/e2e-selectors": 8.3.4 "@grafana/tsconfig": ^1.0.0-rc1 "@mochajs/json-file-reporter": ^1.2.0 "@rollup/plugin-commonjs": 21.0.1 @@ -2522,10 +2522,10 @@ __metadata: resolution: "@grafana/runtime@workspace:packages/grafana-runtime" dependencies: "@emotion/css": 11.1.3 - "@grafana/data": 8.3.3 - "@grafana/e2e-selectors": 8.3.3 + "@grafana/data": 8.3.4 + "@grafana/e2e-selectors": 8.3.4 "@grafana/tsconfig": ^1.0.0-rc1 - "@grafana/ui": 8.3.3 + "@grafana/ui": 8.3.4 "@rollup/plugin-commonjs": 21.0.1 "@rollup/plugin-node-resolve": 13.0.6 "@sentry/browser": 5.25.0 @@ -2557,7 +2557,7 @@ __metadata: languageName: unknown linkType: soft -"@grafana/schema@8.3.3, @grafana/schema@workspace:*, @grafana/schema@workspace:packages/grafana-schema": +"@grafana/schema@8.3.4, @grafana/schema@workspace:*, @grafana/schema@workspace:packages/grafana-schema": version: 0.0.0-use.local resolution: "@grafana/schema@workspace:packages/grafana-schema" dependencies: @@ -2607,16 +2607,16 @@ __metadata: languageName: node linkType: hard -"@grafana/toolkit@8.3.3, @grafana/toolkit@workspace:*, @grafana/toolkit@workspace:packages/grafana-toolkit": +"@grafana/toolkit@8.3.4, @grafana/toolkit@workspace:*, @grafana/toolkit@workspace:packages/grafana-toolkit": version: 0.0.0-use.local resolution: "@grafana/toolkit@workspace:packages/grafana-toolkit" dependencies: "@babel/core": 7.13.14 "@babel/preset-env": 7.13.12 - "@grafana/data": 8.3.3 + "@grafana/data": 8.3.4 "@grafana/eslint-config": 2.5.1 "@grafana/tsconfig": ^1.0.0-rc1 - "@grafana/ui": 8.3.3 + "@grafana/ui": 8.3.4 "@jest/core": 26.6.3 "@rushstack/eslint-patch": 1.0.6 "@types/command-exists": ^1.2.0 @@ -2700,7 +2700,7 @@ __metadata: languageName: node linkType: hard -"@grafana/ui@8.3.3, @grafana/ui@workspace:*, @grafana/ui@workspace:packages/grafana-ui": +"@grafana/ui@8.3.4, @grafana/ui@workspace:*, @grafana/ui@workspace:packages/grafana-ui": version: 0.0.0-use.local resolution: "@grafana/ui@workspace:packages/grafana-ui" dependencies: @@ -2708,9 +2708,9 @@ __metadata: "@emotion/css": 11.1.3 "@emotion/react": 11.1.5 "@grafana/aws-sdk": 0.0.3 - "@grafana/data": 8.3.3 - "@grafana/e2e-selectors": 8.3.3 - "@grafana/schema": 8.3.3 + "@grafana/data": 8.3.4 + "@grafana/e2e-selectors": 8.3.4 + "@grafana/schema": 8.3.4 "@grafana/slate-react": 0.22.10-grafana "@grafana/tsconfig": ^1.0.0-rc1 "@mdx-js/react": 1.6.22 @@ -2923,9 +2923,9 @@ __metadata: dependencies: "@emotion/css": 11.1.3 "@emotion/react": 11.1.5 - "@grafana/data": 8.3.3 + "@grafana/data": 8.3.4 "@grafana/tsconfig": ^1.0.0-rc1 - "@grafana/ui": 8.3.3 + "@grafana/ui": 8.3.4 "@types/classnames": ^2.2.7 "@types/deep-freeze": ^0.1.1 "@types/grafana__slate-react": "npm:@types/slate-react@0.22.5"