IDforwarding: forward signed id to plugins (#75651)

* Plugins: Add client middlware that forwards the signed grafana id token if present

* DsProxy: Set grafana id header if id token exists

* Add util function to apply id token to header

* Only add id forwarding middleware if feature toggle is enabled

* Add feature toggles to ds proxy and check if id forwarding is enabled

* Clean up test setup

* Change to use backend.ForwardHTTPHeaders interface

* PluginProxy: Forward signed identity when feature toggle is enabled

* PluginProxy: forrward signed id header
This commit is contained in:
Karl Persson
2023-10-02 09:14:10 +02:00
committed by GitHub
parent 5892353bbd
commit 684d68365e
10 changed files with 280 additions and 257 deletions
@@ -0,0 +1,50 @@
package clientmiddleware
import (
"context"
"net/http"
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins/manager/client/clienttest"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/user"
)
func TestForwardIDMiddleware(t *testing.T) {
t.Run("Should set forwarded id header if present", func(t *testing.T) {
cdt := clienttest.NewClientDecoratorTest(t, clienttest.WithMiddlewares(NewForwardIDMiddleware()))
ctx := context.WithValue(context.Background(), ctxkey.Key{}, &contextmodel.ReqContext{
Context: &web.Context{Req: &http.Request{}},
SignedInUser: &user.SignedInUser{IDToken: "some-token"},
})
err := cdt.Decorator.CallResource(ctx, &backend.CallResourceRequest{
PluginContext: backend.PluginContext{},
}, nopCallResourceSender)
require.NoError(t, err)
require.Equal(t, "some-token", cdt.CallResourceReq.Headers[forwardIDHeaderName][0])
})
t.Run("Should not set forwarded id header if not present", func(t *testing.T) {
cdt := clienttest.NewClientDecoratorTest(t, clienttest.WithMiddlewares(NewForwardIDMiddleware()))
ctx := context.WithValue(context.Background(), ctxkey.Key{}, &contextmodel.ReqContext{
Context: &web.Context{Req: &http.Request{}},
SignedInUser: &user.SignedInUser{},
})
err := cdt.Decorator.CallResource(ctx, &backend.CallResourceRequest{
PluginContext: backend.PluginContext{},
}, nopCallResourceSender)
require.NoError(t, err)
require.Len(t, cdt.CallResourceReq.Headers[forwardIDHeaderName], 0)
})
}