mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Pyroscope: Add authentication when calling backendType resource API (#67667)
This commit is contained in:
parent
c9ce1a28c3
commit
8da90f624d
@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana-azure-sdk-go/azsettings"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
@ -107,7 +108,7 @@ func TestIntegrationPluginManager(t *testing.T) {
|
||||
ms := mssql.ProvideService(cfg)
|
||||
sv2 := searchV2.ProvideService(cfg, db.InitTestDB(t), nil, nil, tracer, features, nil, nil, nil)
|
||||
graf := grafanads.ProvideService(sv2, nil)
|
||||
phlare := phlare.ProvideService(hcp)
|
||||
phlare := phlare.ProvideService(hcp, acimpl.ProvideAccessControl(cfg))
|
||||
parca := parca.ProvideService(hcp)
|
||||
|
||||
coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf, phlare, parca)
|
||||
|
@ -13,6 +13,9 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -27,6 +30,7 @@ type PhlareDatasource struct {
|
||||
httpClient *http.Client
|
||||
client ProfilingClient
|
||||
settings backend.DataSourceInstanceSettings
|
||||
ac accesscontrol.AccessControl
|
||||
}
|
||||
|
||||
type JsonData struct {
|
||||
@ -34,7 +38,7 @@ type JsonData struct {
|
||||
}
|
||||
|
||||
// NewPhlareDatasource creates a new datasource instance.
|
||||
func NewPhlareDatasource(httpClientProvider httpclient.Provider, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
||||
func NewPhlareDatasource(httpClientProvider httpclient.Provider, settings backend.DataSourceInstanceSettings, ac accesscontrol.AccessControl) (instancemgmt.Instance, error) {
|
||||
opt, err := settings.HTTPClientOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -54,6 +58,7 @@ func NewPhlareDatasource(httpClientProvider httpclient.Provider, settings backen
|
||||
httpClient: httpClient,
|
||||
client: getClient(jsonData.BackendType, httpClient, settings.URL),
|
||||
settings: settings,
|
||||
ac: ac,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -165,6 +170,17 @@ type BackendTypeRespBody struct {
|
||||
|
||||
// backendType is a simplistic test to figure out if we are speaking to phlare or pyroscope backend
|
||||
func (d *PhlareDatasource) backendType(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
// To prevent any user sending arbitrary URL for us to test with we allow this only for users who can edit the datasource
|
||||
// as config page is where this is meant to be used.
|
||||
ok, err := d.isUserAllowedToEditDatasource(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return sender.Send(&backend.CallResourceResponse{Headers: req.Headers, Status: 401})
|
||||
}
|
||||
|
||||
u, err := url.Parse(req.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -194,11 +210,26 @@ func (d *PhlareDatasource) backendType(ctx context.Context, req *backend.CallRes
|
||||
return err
|
||||
}
|
||||
|
||||
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
|
||||
if err != nil {
|
||||
return err
|
||||
return sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
|
||||
}
|
||||
return nil
|
||||
|
||||
func (d *PhlareDatasource) isUserAllowedToEditDatasource(ctx context.Context) (bool, error) {
|
||||
reqCtx := contexthandler.FromContext(ctx)
|
||||
uidScope := datasources.ScopeProvider.GetResourceScopeUID(accesscontrol.Parameter(":uid"))
|
||||
|
||||
if reqCtx == nil || reqCtx.SignedInUser == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
ok, err := d.ac.Evaluate(ctx, reqCtx.SignedInUser, accesscontrol.EvalPermission(datasources.ActionWrite, uidScope))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// QueryData handles multiple queries and returns multiple responses.
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
)
|
||||
|
||||
// Make sure PhlareDatasource implements required interfaces. This is important to do
|
||||
@ -41,15 +42,15 @@ func (s *Service) getInstance(pluginCtx backend.PluginContext) (*PhlareDatasourc
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func ProvideService(httpClientProvider httpclient.Provider) *Service {
|
||||
func ProvideService(httpClientProvider httpclient.Provider, ac accesscontrol.AccessControl) *Service {
|
||||
return &Service{
|
||||
im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)),
|
||||
im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider, ac)),
|
||||
}
|
||||
}
|
||||
|
||||
func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc {
|
||||
func newInstanceSettings(httpClientProvider httpclient.Provider, ac accesscontrol.AccessControl) datasource.InstanceFactoryFunc {
|
||||
return func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
||||
return NewPhlareDatasource(httpClientProvider, settings)
|
||||
return NewPhlareDatasource(httpClientProvider, settings, ac)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user