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-azure-sdk-go/azsettings"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||||
|
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
@ -107,7 +108,7 @@ func TestIntegrationPluginManager(t *testing.T) {
|
|||||||
ms := mssql.ProvideService(cfg)
|
ms := mssql.ProvideService(cfg)
|
||||||
sv2 := searchV2.ProvideService(cfg, db.InitTestDB(t), nil, nil, tracer, features, nil, nil, nil)
|
sv2 := searchV2.ProvideService(cfg, db.InitTestDB(t), nil, nil, tracer, features, nil, nil, nil)
|
||||||
graf := grafanads.ProvideService(sv2, nil)
|
graf := grafanads.ProvideService(sv2, nil)
|
||||||
phlare := phlare.ProvideService(hcp)
|
phlare := phlare.ProvideService(hcp, acimpl.ProvideAccessControl(cfg))
|
||||||
parca := parca.ProvideService(hcp)
|
parca := parca.ProvideService(hcp)
|
||||||
|
|
||||||
coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf, phlare, parca)
|
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/backend/instancemgmt"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
"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 (
|
var (
|
||||||
@ -27,6 +30,7 @@ type PhlareDatasource struct {
|
|||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
client ProfilingClient
|
client ProfilingClient
|
||||||
settings backend.DataSourceInstanceSettings
|
settings backend.DataSourceInstanceSettings
|
||||||
|
ac accesscontrol.AccessControl
|
||||||
}
|
}
|
||||||
|
|
||||||
type JsonData struct {
|
type JsonData struct {
|
||||||
@ -34,7 +38,7 @@ type JsonData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewPhlareDatasource creates a new datasource instance.
|
// 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()
|
opt, err := settings.HTTPClientOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -54,6 +58,7 @@ func NewPhlareDatasource(httpClientProvider httpclient.Provider, settings backen
|
|||||||
httpClient: httpClient,
|
httpClient: httpClient,
|
||||||
client: getClient(jsonData.BackendType, httpClient, settings.URL),
|
client: getClient(jsonData.BackendType, httpClient, settings.URL),
|
||||||
settings: settings,
|
settings: settings,
|
||||||
|
ac: ac,
|
||||||
}, nil
|
}, 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
|
// 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 {
|
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)
|
u, err := url.Parse(req.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -194,11 +210,26 @@ func (d *PhlareDatasource) backendType(ctx context.Context, req *backend.CallRes
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
|
return sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
return 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.
|
// 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-plugin-sdk-go/backend/instancemgmt"
|
||||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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
|
// 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
|
return in, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideService(httpClientProvider httpclient.Provider) *Service {
|
func ProvideService(httpClientProvider httpclient.Provider, ac accesscontrol.AccessControl) *Service {
|
||||||
return &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 func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
||||||
return NewPhlareDatasource(httpClientProvider, settings)
|
return NewPhlareDatasource(httpClientProvider, settings, ac)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user