Plugins: Automatically forward plugin request HTTP headers in outgoing HTTP requests (#60417)

Automatically forward core plugin request HTTP headers in outgoing HTTP requests. 
Core datasource plugin authors don't have to specifically handle forwarding of HTTP 
headers, e.g. do not have to "hardcode" the header-names in the datasource plugin, 
if not having custom needs.

Fixes #57065
This commit is contained in:
Marcus Efraimsson
2022-12-21 13:25:58 +01:00
committed by GitHub
parent aaab477594
commit c35c689a96
32 changed files with 816 additions and 1194 deletions
@@ -4,9 +4,7 @@ import (
"context"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/httpclient/httpclientprovider"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/datasources"
@@ -16,8 +14,8 @@ import (
const cookieHeaderName = "Cookie"
// NewCookiesMiddleware creates a new plugins.ClientMiddleware that will
// forward incoming HTTP request Cookies to outgoing plugins.Client and
// HTTP requests if the datasource has enabled forwarding of cookies (keepCookies).
// forward incoming HTTP request Cookies to outgoing plugins.Client requests
// if the datasource has enabled forwarding of cookies (keepCookies).
func NewCookiesMiddleware(skipCookiesNames []string) plugins.ClientMiddleware {
return plugins.ClientMiddlewareFunc(func(next plugins.Client) plugins.Client {
return &CookiesMiddleware{
@@ -32,17 +30,17 @@ type CookiesMiddleware struct {
skipCookiesNames []string
}
func (m *CookiesMiddleware) applyCookies(ctx context.Context, pCtx backend.PluginContext, req interface{}) (context.Context, error) {
func (m *CookiesMiddleware) applyCookies(ctx context.Context, pCtx backend.PluginContext, req interface{}) error {
reqCtx := contexthandler.FromContext(ctx)
// if request not for a datasource or no HTTP request context skip middleware
if req == nil || pCtx.DataSourceInstanceSettings == nil || reqCtx == nil || reqCtx.Req == nil {
return ctx, nil
return nil
}
settings := pCtx.DataSourceInstanceSettings
jsonDataBytes, err := simplejson.NewJson(settings.JSONData)
if err != nil {
return ctx, err
return err
}
ds := &datasources.DataSource{
@@ -54,20 +52,29 @@ func (m *CookiesMiddleware) applyCookies(ctx context.Context, pCtx backend.Plugi
proxyutil.ClearCookieHeader(reqCtx.Req, ds.AllowedCookies(), m.skipCookiesNames)
if cookieStr := reqCtx.Req.Header.Get(cookieHeaderName); cookieStr != "" {
switch t := req.(type) {
case *backend.QueryDataRequest:
cookieStr := reqCtx.Req.Header.Get(cookieHeaderName)
switch t := req.(type) {
case *backend.QueryDataRequest:
if cookieStr == "" {
delete(t.Headers, cookieHeaderName)
} else {
t.Headers[cookieHeaderName] = cookieStr
case *backend.CheckHealthRequest:
}
case *backend.CheckHealthRequest:
if cookieStr == "" {
delete(t.Headers, cookieHeaderName)
} else {
t.Headers[cookieHeaderName] = cookieStr
case *backend.CallResourceRequest:
}
case *backend.CallResourceRequest:
if cookieStr == "" {
delete(t.Headers, cookieHeaderName)
} else {
t.Headers[cookieHeaderName] = []string{cookieStr}
}
}
ctx = httpclient.WithContextualMiddleware(ctx, httpclientprovider.ForwardedCookiesMiddleware(reqCtx.Req.Cookies(), ds.AllowedCookies(), m.skipCookiesNames))
return ctx, nil
return nil
}
func (m *CookiesMiddleware) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
@@ -75,12 +82,12 @@ func (m *CookiesMiddleware) QueryData(ctx context.Context, req *backend.QueryDat
return m.next.QueryData(ctx, req)
}
newCtx, err := m.applyCookies(ctx, req.PluginContext, req)
err := m.applyCookies(ctx, req.PluginContext, req)
if err != nil {
return nil, err
}
return m.next.QueryData(newCtx, req)
return m.next.QueryData(ctx, req)
}
func (m *CookiesMiddleware) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
@@ -88,12 +95,12 @@ func (m *CookiesMiddleware) CallResource(ctx context.Context, req *backend.CallR
return m.next.CallResource(ctx, req, sender)
}
newCtx, err := m.applyCookies(ctx, req.PluginContext, req)
err := m.applyCookies(ctx, req.PluginContext, req)
if err != nil {
return err
}
return m.next.CallResource(newCtx, req, sender)
return m.next.CallResource(ctx, req, sender)
}
func (m *CookiesMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
@@ -101,12 +108,12 @@ func (m *CookiesMiddleware) CheckHealth(ctx context.Context, req *backend.CheckH
return m.next.CheckHealth(ctx, req)
}
newCtx, err := m.applyCookies(ctx, req.PluginContext, req)
err := m.applyCookies(ctx, req.PluginContext, req)
if err != nil {
return nil, err
}
return m.next.CheckHealth(newCtx, req)
return m.next.CheckHealth(ctx, req)
}
func (m *CookiesMiddleware) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) {