mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Remove bus from datasource api (#44987)
* Remove bus from datasource api * Add DatasourcePermissionService and use it in api * Fix wire and rename * Fix import in wire * Fix bug * Rename Service to OSS service * Roll back fix
This commit is contained in:
parent
0282d5f9c3
commit
df282a42cb
@ -273,17 +273,17 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
// Data sources
|
||||
apiRoute.Group("/datasources", func(datasourceRoute routing.RouteRegister) {
|
||||
datasourceRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesRead)), routing.Wrap(hs.GetDataSources))
|
||||
datasourceRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesCreate)), quota("data_source"), routing.Wrap(AddDataSource))
|
||||
datasourceRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesCreate)), quota("data_source"), routing.Wrap(hs.AddDataSource))
|
||||
datasourceRoute.Put("/:id", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesWrite, ScopeDatasourceID)), routing.Wrap(hs.UpdateDataSource))
|
||||
datasourceRoute.Delete("/:id", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesDelete, ScopeDatasourceID)), routing.Wrap(hs.DeleteDataSourceById))
|
||||
datasourceRoute.Delete("/uid/:uid", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesDelete, ScopeDatasourceUID)), routing.Wrap(hs.DeleteDataSourceByUID))
|
||||
datasourceRoute.Delete("/name/:name", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesDelete, ScopeDatasourceName)), routing.Wrap(hs.DeleteDataSourceByName))
|
||||
datasourceRoute.Get("/:id", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesRead)), routing.Wrap(hs.GetDataSourceById))
|
||||
datasourceRoute.Get("/uid/:uid", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesRead)), routing.Wrap(hs.GetDataSourceByUID))
|
||||
datasourceRoute.Get("/name/:name", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesRead)), routing.Wrap(GetDataSourceByName))
|
||||
datasourceRoute.Get("/name/:name", authorize(reqOrgAdmin, ac.EvalPermission(ActionDatasourcesRead)), routing.Wrap(hs.GetDataSourceByName))
|
||||
})
|
||||
|
||||
apiRoute.Get("/datasources/id/:name", authorize(reqSignedIn, ac.EvalPermission(ActionDatasourcesIDRead, ScopeDatasourceName)), routing.Wrap(GetDataSourceIdByName))
|
||||
apiRoute.Get("/datasources/id/:name", authorize(reqSignedIn, ac.EvalPermission(ActionDatasourcesIDRead, ScopeDatasourceName)), routing.Wrap(hs.GetDataSourceIdByName))
|
||||
|
||||
apiRoute.Get("/plugins", routing.Wrap(hs.GetPluginList))
|
||||
apiRoute.Get("/plugins/:pluginId/settings", routing.Wrap(hs.GetPluginSettingByID))
|
||||
|
22
pkg/api/datasource_permissions.go
Normal file
22
pkg/api/datasource_permissions.go
Normal file
@ -0,0 +1,22 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
type DatasourcePermissionsService interface {
|
||||
FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *models.DatasourcesPermissionFilterQuery) error
|
||||
}
|
||||
|
||||
// dummy method
|
||||
func (hs *OSSDatasourcePermissionsService) FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *models.DatasourcesPermissionFilterQuery) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type OSSDatasourcePermissionsService struct{}
|
||||
|
||||
func ProvideDatasourcePermissionsService() *OSSDatasourcePermissionsService {
|
||||
return &OSSDatasourcePermissionsService{}
|
||||
}
|
20
pkg/api/datasource_permissions_mocks.go
Normal file
20
pkg/api/datasource_permissions_mocks.go
Normal file
@ -0,0 +1,20 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
type mockDatasourcePermissionService struct {
|
||||
dsResult []*models.DataSource
|
||||
}
|
||||
|
||||
func (m *mockDatasourcePermissionService) FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *models.DatasourcesPermissionFilterQuery) error {
|
||||
cmd.Result = m.dsResult
|
||||
return nil
|
||||
}
|
||||
|
||||
func newMockDatasourcePermissionService() *mockDatasourcePermissionService {
|
||||
return &mockDatasourcePermissionService{}
|
||||
}
|
@ -27,11 +27,11 @@ var datasourcesLogger = log.New("datasources")
|
||||
func (hs *HTTPServer) GetDataSources(c *models.ReqContext) response.Response {
|
||||
query := models.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSources(c.Req.Context(), &query); err != nil {
|
||||
return response.Error(500, "Failed to query datasources", err)
|
||||
}
|
||||
|
||||
filtered, err := filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, query.Result)
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, query.Result)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to query datasources", err)
|
||||
}
|
||||
@ -98,7 +98,7 @@ func (hs *HTTPServer) GetDataSourceById(c *models.ReqContext) response.Response
|
||||
OrgId: c.OrgId,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(c.Req.Context(), &query); err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
}
|
||||
@ -108,7 +108,7 @@ func (hs *HTTPServer) GetDataSourceById(c *models.ReqContext) response.Response
|
||||
return response.Error(500, "Failed to query datasources", err)
|
||||
}
|
||||
|
||||
filtered, err := filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, []*models.DataSource{query.Result})
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, []*models.DataSource{query.Result})
|
||||
if err != nil || len(filtered) != 1 {
|
||||
return response.Error(404, "Data source not found", err)
|
||||
}
|
||||
@ -135,7 +135,7 @@ func (hs *HTTPServer) DeleteDataSourceById(c *models.ReqContext) response.Respon
|
||||
return response.Error(400, "Missing valid datasource id", nil)
|
||||
}
|
||||
|
||||
ds, err := getRawDataSourceById(c.Req.Context(), id, c.OrgId)
|
||||
ds, err := hs.getRawDataSourceById(c.Req.Context(), id, c.OrgId)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
@ -149,7 +149,7 @@ func (hs *HTTPServer) DeleteDataSourceById(c *models.ReqContext) response.Respon
|
||||
|
||||
cmd := &models.DeleteDataSourceCommand{ID: id, OrgID: c.OrgId}
|
||||
|
||||
err = bus.Dispatch(c.Req.Context(), cmd)
|
||||
err = hs.SQLStore.DeleteDataSource(c.Req.Context(), cmd)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to delete datasource", err)
|
||||
}
|
||||
@ -161,7 +161,7 @@ func (hs *HTTPServer) DeleteDataSourceById(c *models.ReqContext) response.Respon
|
||||
|
||||
// GET /api/datasources/uid/:uid
|
||||
func (hs *HTTPServer) GetDataSourceByUID(c *models.ReqContext) response.Response {
|
||||
ds, err := getRawDataSourceByUID(c.Req.Context(), web.Params(c.Req)[":uid"], c.OrgId)
|
||||
ds, err := hs.getRawDataSourceByUID(c.Req.Context(), web.Params(c.Req)[":uid"], c.OrgId)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
@ -170,7 +170,7 @@ func (hs *HTTPServer) GetDataSourceByUID(c *models.ReqContext) response.Response
|
||||
return response.Error(http.StatusInternalServerError, "Failed to query datasource", err)
|
||||
}
|
||||
|
||||
filtered, err := filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, []*models.DataSource{ds})
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, []*models.DataSource{ds})
|
||||
if err != nil || len(filtered) != 1 {
|
||||
return response.Error(404, "Data source not found", err)
|
||||
}
|
||||
@ -195,7 +195,7 @@ func (hs *HTTPServer) DeleteDataSourceByUID(c *models.ReqContext) response.Respo
|
||||
return response.Error(400, "Missing datasource uid", nil)
|
||||
}
|
||||
|
||||
ds, err := getRawDataSourceByUID(c.Req.Context(), uid, c.OrgId)
|
||||
ds, err := hs.getRawDataSourceByUID(c.Req.Context(), uid, c.OrgId)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
@ -209,7 +209,7 @@ func (hs *HTTPServer) DeleteDataSourceByUID(c *models.ReqContext) response.Respo
|
||||
|
||||
cmd := &models.DeleteDataSourceCommand{UID: uid, OrgID: c.OrgId}
|
||||
|
||||
err = bus.Dispatch(c.Req.Context(), cmd)
|
||||
err = hs.SQLStore.DeleteDataSource(c.Req.Context(), cmd)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to delete datasource", err)
|
||||
}
|
||||
@ -231,7 +231,7 @@ func (hs *HTTPServer) DeleteDataSourceByName(c *models.ReqContext) response.Resp
|
||||
}
|
||||
|
||||
getCmd := &models.GetDataSourceQuery{Name: name, OrgId: c.OrgId}
|
||||
if err := bus.Dispatch(c.Req.Context(), getCmd); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(c.Req.Context(), getCmd); err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
}
|
||||
@ -243,7 +243,7 @@ func (hs *HTTPServer) DeleteDataSourceByName(c *models.ReqContext) response.Resp
|
||||
}
|
||||
|
||||
cmd := &models.DeleteDataSourceCommand{Name: name, OrgID: c.OrgId}
|
||||
err := bus.Dispatch(c.Req.Context(), cmd)
|
||||
err := hs.SQLStore.DeleteDataSource(c.Req.Context(), cmd)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to delete datasource", err)
|
||||
}
|
||||
@ -265,7 +265,7 @@ func validateURL(cmdType string, url string) response.Response {
|
||||
}
|
||||
|
||||
// POST /api/datasources/
|
||||
func AddDataSource(c *models.ReqContext) response.Response {
|
||||
func (hs *HTTPServer) AddDataSource(c *models.ReqContext) response.Response {
|
||||
cmd := models.AddDataSourceCommand{}
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
@ -279,7 +279,7 @@ func AddDataSource(c *models.ReqContext) response.Response {
|
||||
}
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil {
|
||||
if err := hs.SQLStore.AddDataSource(c.Req.Context(), &cmd); err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNameExists) || errors.Is(err, models.ErrDataSourceUidExists) {
|
||||
return response.Error(409, err.Error(), err)
|
||||
}
|
||||
@ -312,7 +312,7 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response {
|
||||
return resp
|
||||
}
|
||||
|
||||
ds, err := getRawDataSourceById(c.Req.Context(), cmd.Id, cmd.OrgId)
|
||||
ds, err := hs.getRawDataSourceById(c.Req.Context(), cmd.Id, cmd.OrgId)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
@ -329,7 +329,7 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response {
|
||||
return response.Error(500, "Failed to update datasource", err)
|
||||
}
|
||||
|
||||
err = bus.Dispatch(c.Req.Context(), &cmd)
|
||||
err = hs.SQLStore.UpdateDataSource(c.Req.Context(), &cmd)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceUpdatingOldVersion) {
|
||||
return response.Error(409, "Datasource has already been updated by someone else. Please reload and try again", err)
|
||||
@ -342,7 +342,7 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response {
|
||||
OrgId: c.OrgId,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(c.Req.Context(), &query); err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
}
|
||||
@ -366,7 +366,7 @@ func (hs *HTTPServer) fillWithSecureJSONData(ctx context.Context, cmd *models.Up
|
||||
return nil
|
||||
}
|
||||
|
||||
ds, err := getRawDataSourceById(ctx, cmd.Id, cmd.OrgId)
|
||||
ds, err := hs.getRawDataSourceById(ctx, cmd.Id, cmd.OrgId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -388,26 +388,26 @@ func (hs *HTTPServer) fillWithSecureJSONData(ctx context.Context, cmd *models.Up
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRawDataSourceById(ctx context.Context, id int64, orgID int64) (*models.DataSource, error) {
|
||||
func (hs *HTTPServer) getRawDataSourceById(ctx context.Context, id int64, orgID int64) (*models.DataSource, error) {
|
||||
query := models.GetDataSourceQuery{
|
||||
Id: id,
|
||||
OrgId: orgID,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(ctx, &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(ctx, &query); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return query.Result, nil
|
||||
}
|
||||
|
||||
func getRawDataSourceByUID(ctx context.Context, uid string, orgID int64) (*models.DataSource, error) {
|
||||
func (hs *HTTPServer) getRawDataSourceByUID(ctx context.Context, uid string, orgID int64) (*models.DataSource, error) {
|
||||
query := models.GetDataSourceQuery{
|
||||
Uid: uid,
|
||||
OrgId: orgID,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(ctx, &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(ctx, &query); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -415,17 +415,17 @@ func getRawDataSourceByUID(ctx context.Context, uid string, orgID int64) (*model
|
||||
}
|
||||
|
||||
// Get /api/datasources/name/:name
|
||||
func GetDataSourceByName(c *models.ReqContext) response.Response {
|
||||
func (hs *HTTPServer) GetDataSourceByName(c *models.ReqContext) response.Response {
|
||||
query := models.GetDataSourceQuery{Name: web.Params(c.Req)[":name"], OrgId: c.OrgId}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(c.Req.Context(), &query); err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
}
|
||||
return response.Error(500, "Failed to query datasources", err)
|
||||
}
|
||||
|
||||
filtered, err := filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, []*models.DataSource{query.Result})
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, []*models.DataSource{query.Result})
|
||||
if err != nil || len(filtered) != 1 {
|
||||
return response.Error(404, "Data source not found", err)
|
||||
}
|
||||
@ -435,10 +435,10 @@ func GetDataSourceByName(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
// Get /api/datasources/id/:name
|
||||
func GetDataSourceIdByName(c *models.ReqContext) response.Response {
|
||||
func (hs *HTTPServer) GetDataSourceIdByName(c *models.ReqContext) response.Response {
|
||||
query := models.GetDataSourceQuery{Name: web.Params(c.Req)[":name"], OrgId: c.OrgId}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDataSource(c.Req.Context(), &query); err != nil {
|
||||
if errors.Is(err, models.ErrDataSourceNotFound) {
|
||||
return response.Error(404, "Data source not found", nil)
|
||||
}
|
||||
@ -593,13 +593,14 @@ func (hs *HTTPServer) decryptSecureJsonDataFn() func(map[string][]byte) map[stri
|
||||
}
|
||||
}
|
||||
|
||||
func filterDatasourcesByQueryPermission(ctx context.Context, user *models.SignedInUser, datasources []*models.DataSource) ([]*models.DataSource, error) {
|
||||
func (hs *HTTPServer) filterDatasourcesByQueryPermission(ctx context.Context, user *models.SignedInUser, datasources []*models.DataSource) ([]*models.DataSource, error) {
|
||||
query := models.DatasourcesPermissionFilterQuery{
|
||||
User: user,
|
||||
Datasources: datasources,
|
||||
}
|
||||
query.Result = datasources
|
||||
|
||||
if err := bus.Dispatch(ctx, &query); err != nil {
|
||||
if err := hs.DatasourcePermissionsService.FilterDatasourcesBasedOnQueryPermissions(ctx, &query); err != nil {
|
||||
if !errors.Is(err, bus.ErrHandlerNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -12,7 +11,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
|
||||
@ -28,26 +26,25 @@ const (
|
||||
)
|
||||
|
||||
func TestDataSourcesProxy_userLoggedIn(t *testing.T) {
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockDatasourcePermissionService := newMockDatasourcePermissionService()
|
||||
loggedInUserScenario(t, "When calling GET on", "/api/datasources/", "/api/datasources/", func(sc *scenarioContext) {
|
||||
// Stubs the database query
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDataSourcesQuery) error {
|
||||
assert.Equal(t, testOrgID, query.OrgId)
|
||||
query.Result = []*models.DataSource{
|
||||
{Name: "mmm"},
|
||||
{Name: "ZZZ"},
|
||||
{Name: "BBB"},
|
||||
{Name: "aaa"},
|
||||
}
|
||||
return nil
|
||||
})
|
||||
ds := []*models.DataSource{
|
||||
{Name: "mmm"},
|
||||
{Name: "ZZZ"},
|
||||
{Name: "BBB"},
|
||||
{Name: "aaa"},
|
||||
}
|
||||
mockSQLStore.ExpectedDatasources = ds
|
||||
mockDatasourcePermissionService.dsResult = ds
|
||||
|
||||
// handler func being tested
|
||||
hs := &HTTPServer{
|
||||
Bus: bus.GetBus(),
|
||||
Cfg: setting.NewCfg(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mock,
|
||||
Cfg: setting.NewCfg(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockSQLStore,
|
||||
DatasourcePermissionsService: mockDatasourcePermissionService,
|
||||
}
|
||||
sc.handlerFunc = hs.GetDataSources
|
||||
sc.fakeReq("GET", "/api/datasources").exec()
|
||||
@ -60,27 +57,27 @@ func TestDataSourcesProxy_userLoggedIn(t *testing.T) {
|
||||
assert.Equal(t, "BBB", respJSON[1]["name"])
|
||||
assert.Equal(t, "mmm", respJSON[2]["name"])
|
||||
assert.Equal(t, "ZZZ", respJSON[3]["name"])
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenario(t, "Should be able to save a data source when calling DELETE on non-existing",
|
||||
"/api/datasources/name/12345", "/api/datasources/name/:name", func(sc *scenarioContext) {
|
||||
// handler func being tested
|
||||
hs := &HTTPServer{
|
||||
Bus: bus.GetBus(),
|
||||
Cfg: setting.NewCfg(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
}
|
||||
sc.handlerFunc = hs.DeleteDataSourceByName
|
||||
sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
}
|
||||
|
||||
// Adding data sources with invalid URLs should lead to an error.
|
||||
func TestAddDataSource_InvalidURL(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
sc := setupScenarioContext(t, "/api/datasources")
|
||||
hs := &HTTPServer{
|
||||
SQLStore: mockstore.NewSQLStoreMock(),
|
||||
}
|
||||
|
||||
sc.m.Post(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
c.Req.Body = mockRequestBody(models.AddDataSourceCommand{
|
||||
@ -89,7 +86,7 @@ func TestAddDataSource_InvalidURL(t *testing.T) {
|
||||
Access: "direct",
|
||||
Type: "test",
|
||||
})
|
||||
return AddDataSource(c)
|
||||
return hs.AddDataSource(c)
|
||||
}))
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
@ -99,19 +96,14 @@ func TestAddDataSource_InvalidURL(t *testing.T) {
|
||||
|
||||
// Adding data sources with URLs not specifying protocol should work.
|
||||
func TestAddDataSource_URLWithoutProtocol(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
const name = "Test"
|
||||
const url = "localhost:5432"
|
||||
|
||||
// Stub handler
|
||||
bus.AddHandler("sql", func(ctx context.Context, cmd *models.AddDataSourceCommand) error {
|
||||
assert.Equal(t, name, cmd.Name)
|
||||
assert.Equal(t, url, cmd.Url)
|
||||
|
||||
cmd.Result = &models.DataSource{}
|
||||
return nil
|
||||
})
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDatasource = &models.DataSource{}
|
||||
hs := &HTTPServer{
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, "/api/datasources")
|
||||
|
||||
@ -122,7 +114,7 @@ func TestAddDataSource_URLWithoutProtocol(t *testing.T) {
|
||||
Access: "direct",
|
||||
Type: "test",
|
||||
})
|
||||
return AddDataSource(c)
|
||||
return hs.AddDataSource(c)
|
||||
}))
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
@ -132,8 +124,9 @@ func TestAddDataSource_URLWithoutProtocol(t *testing.T) {
|
||||
|
||||
// Updating data sources with invalid URLs should lead to an error.
|
||||
func TestUpdateDataSource_InvalidURL(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
hs := &HTTPServer{
|
||||
SQLStore: mockstore.NewSQLStoreMock(),
|
||||
}
|
||||
sc := setupScenarioContext(t, "/api/datasources/1234")
|
||||
|
||||
sc.m.Put(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
@ -143,7 +136,7 @@ func TestUpdateDataSource_InvalidURL(t *testing.T) {
|
||||
Access: "direct",
|
||||
Type: "test",
|
||||
})
|
||||
return AddDataSource(c)
|
||||
return hs.AddDataSource(c)
|
||||
}))
|
||||
|
||||
sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec()
|
||||
@ -153,19 +146,15 @@ func TestUpdateDataSource_InvalidURL(t *testing.T) {
|
||||
|
||||
// Updating data sources with URLs not specifying protocol should work.
|
||||
func TestUpdateDataSource_URLWithoutProtocol(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
const name = "Test"
|
||||
const url = "localhost:5432"
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
hs := &HTTPServer{
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
// Stub handler
|
||||
bus.AddHandler("sql", func(ctx context.Context, cmd *models.AddDataSourceCommand) error {
|
||||
assert.Equal(t, name, cmd.Name)
|
||||
assert.Equal(t, url, cmd.Url)
|
||||
|
||||
cmd.Result = &models.DataSource{}
|
||||
return nil
|
||||
})
|
||||
mockSQLStore.ExpectedDatasource = &models.DataSource{}
|
||||
|
||||
sc := setupScenarioContext(t, "/api/datasources/1234")
|
||||
|
||||
@ -176,7 +165,7 @@ func TestUpdateDataSource_URLWithoutProtocol(t *testing.T) {
|
||||
Access: "direct",
|
||||
Type: "test",
|
||||
})
|
||||
return AddDataSource(c)
|
||||
return hs.AddDataSource(c)
|
||||
}))
|
||||
|
||||
sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec()
|
||||
@ -204,44 +193,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
Access: "Proxy",
|
||||
ReadOnly: true,
|
||||
}
|
||||
getDatasourceStub := func(ctx context.Context, query *models.GetDataSourceQuery) error {
|
||||
result := testDatasource
|
||||
result.Id = query.Id
|
||||
result.OrgId = query.OrgId
|
||||
query.Result = &result
|
||||
return nil
|
||||
}
|
||||
getDatasourcesStub := func(ctx context.Context, cmd *models.GetDataSourcesQuery) error {
|
||||
cmd.Result = []*models.DataSource{}
|
||||
return nil
|
||||
}
|
||||
addDatasourceStub := func(ctx context.Context, cmd *models.AddDataSourceCommand) error {
|
||||
cmd.Result = &testDatasource
|
||||
return nil
|
||||
}
|
||||
updateDatasourceStub := func(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
|
||||
cmd.Result = &testDatasource
|
||||
return nil
|
||||
}
|
||||
updateDatasourceReadOnlyStub := func(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
|
||||
cmd.Result = &testDatasourceReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
getDatasourceNotFoundStub := func(ctx context.Context, cmd *models.GetDataSourceQuery) error {
|
||||
cmd.Result = nil
|
||||
return models.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
getDatasourceReadOnlyStub := func(ctx context.Context, query *models.GetDataSourceQuery) error {
|
||||
query.Result = &testDatasourceReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
deleteDatasourceStub := func(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
|
||||
cmd.DeletedDatasourcesCount = 1
|
||||
return nil
|
||||
}
|
||||
addDatasourceBody := func() io.Reader {
|
||||
s, _ := json.Marshal(models.AddDataSourceCommand{
|
||||
Name: "test",
|
||||
@ -251,6 +203,14 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
})
|
||||
return bytes.NewReader(s)
|
||||
}
|
||||
|
||||
sqlStore := mockstore.NewSQLStoreMock()
|
||||
sqlStore.ExpectedDatasource = &testDatasource
|
||||
dsPermissionService := newMockDatasourcePermissionService()
|
||||
dsPermissionService.dsResult = []*models.DataSource{
|
||||
&testDatasource,
|
||||
}
|
||||
|
||||
updateDatasourceBody := func() io.Reader {
|
||||
s, _ := json.Marshal(models.UpdateDataSourceCommand{
|
||||
Name: "test",
|
||||
@ -261,14 +221,14 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
return bytes.NewReader(s)
|
||||
}
|
||||
type acTestCaseWithHandler struct {
|
||||
busStubs []bus.HandlerFunc
|
||||
body func() io.Reader
|
||||
body func() io.Reader
|
||||
accessControlTestCase
|
||||
expectedDS *models.DataSource
|
||||
expectedSQLError error
|
||||
}
|
||||
tests := []acTestCaseWithHandler{
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceNotFoundStub, updateDatasourceStub},
|
||||
body: updateDatasourceBody,
|
||||
body: updateDatasourceBody,
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusNotFound,
|
||||
desc: "DatasourcesPut should return 404 if datasource not found",
|
||||
@ -281,9 +241,9 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedSQLError: models.ErrDataSourceNotFound,
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourcesStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesGet should return 200 for user with correct permissions",
|
||||
@ -302,8 +262,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{addDatasourceStub},
|
||||
body: addDatasourceBody,
|
||||
body: addDatasourceBody,
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesPost should return 200 for user with correct permissions",
|
||||
@ -311,6 +270,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
method: http.MethodPost,
|
||||
permissions: []*accesscontrol.Permission{{Action: ActionDatasourcesCreate}},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -322,8 +282,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub, updateDatasourceStub},
|
||||
body: updateDatasourceBody,
|
||||
body: updateDatasourceBody,
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesPut should return 200 for user with correct permissions",
|
||||
@ -336,6 +295,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -347,8 +307,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceReadOnlyStub, updateDatasourceReadOnlyStub},
|
||||
body: updateDatasourceBody,
|
||||
body: updateDatasourceBody,
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusForbidden,
|
||||
desc: "DatasourcesPut should return 403 for read only datasource",
|
||||
@ -361,9 +320,9 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasourceReadOnly,
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub, deleteDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesDeleteByID should return 200 for user with correct permissions",
|
||||
@ -376,6 +335,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -387,7 +347,6 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub, deleteDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesDeleteByUID should return 200 for user with correct permissions",
|
||||
@ -400,6 +359,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -411,7 +371,6 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub, deleteDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesDeleteByName should return 200 for user with correct permissions",
|
||||
@ -424,6 +383,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -435,7 +395,6 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesGetByID should return 200 for user with correct permissions",
|
||||
@ -448,6 +407,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -459,7 +419,6 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesGetByUID should return 200 for user with correct permissions",
|
||||
@ -472,6 +431,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -483,7 +443,6 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesGetByName should return 200 for user with correct permissions",
|
||||
@ -496,6 +455,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -505,9 +465,9 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
permissions: []*accesscontrol.Permission{{Action: "wrong"}},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
busStubs: []bus.HandlerFunc{getDatasourceStub},
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
expectedCode: http.StatusOK,
|
||||
desc: "DatasourcesGetIdByName should return 200 for user with correct permissions",
|
||||
@ -520,6 +480,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
{
|
||||
accessControlTestCase: accessControlTestCase{
|
||||
@ -529,19 +490,26 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
permissions: []*accesscontrol.Permission{{Action: "wrong"}},
|
||||
},
|
||||
expectedDS: &testDatasource,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Cleanup(bus.ClearBusHandlers)
|
||||
for i, handler := range test.busStubs {
|
||||
bus.AddHandler(fmt.Sprintf("test_handler_%v", i), handler)
|
||||
}
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
sc, hs := setupAccessControlScenarioContext(t, cfg, test.url, test.permissions)
|
||||
|
||||
// mock sqlStore and datasource permission service
|
||||
sqlStore.ExpectedError = test.expectedSQLError
|
||||
sqlStore.ExpectedDatasource = test.expectedDS
|
||||
dsPermissionService.dsResult = []*models.DataSource{test.expectedDS}
|
||||
if test.expectedDS == nil {
|
||||
dsPermissionService.dsResult = nil
|
||||
}
|
||||
sc.sqlStore = sqlStore
|
||||
hs.SQLStore = sqlStore
|
||||
hs.DatasourcePermissionsService = dsPermissionService
|
||||
|
||||
// Create a middleware to pretend user is logged in
|
||||
pretendSignInMiddleware := func(c *models.ReqContext) {
|
||||
sc.context = c
|
||||
|
@ -23,7 +23,7 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins Enab
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filtered, err := filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, query.Result)
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, query.Result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -76,60 +76,61 @@ type HTTPServer struct {
|
||||
middlewares []web.Handler
|
||||
namedMiddlewares []routing.RegisterNamedMiddleware
|
||||
|
||||
PluginContextProvider *plugincontext.Provider
|
||||
RouteRegister routing.RouteRegister
|
||||
Bus bus.Bus
|
||||
RenderService rendering.Service
|
||||
Cfg *setting.Cfg
|
||||
Features *featuremgmt.FeatureManager
|
||||
SettingsProvider setting.Provider
|
||||
HooksService *hooks.HooksService
|
||||
CacheService *localcache.CacheService
|
||||
DataSourceCache datasources.CacheService
|
||||
AuthTokenService models.UserTokenService
|
||||
QuotaService *quota.QuotaService
|
||||
RemoteCacheService *remotecache.RemoteCache
|
||||
ProvisioningService provisioning.ProvisioningService
|
||||
Login login.Service
|
||||
License models.Licensing
|
||||
AccessControl accesscontrol.AccessControl
|
||||
DataProxy *datasourceproxy.DataSourceProxyService
|
||||
PluginRequestValidator models.PluginRequestValidator
|
||||
pluginClient plugins.Client
|
||||
pluginStore plugins.Store
|
||||
pluginDashboardManager plugins.PluginDashboardManager
|
||||
pluginStaticRouteResolver plugins.StaticRouteResolver
|
||||
pluginErrorResolver plugins.ErrorResolver
|
||||
SearchService search.Service
|
||||
ShortURLService shorturls.Service
|
||||
QueryHistoryService queryhistory.Service
|
||||
Live *live.GrafanaLive
|
||||
LivePushGateway *pushhttp.Gateway
|
||||
ThumbService thumbs.Service
|
||||
ContextHandler *contexthandler.ContextHandler
|
||||
SQLStore sqlstore.Store
|
||||
AlertEngine *alerting.AlertEngine
|
||||
LoadSchemaService *schemaloader.SchemaLoaderService
|
||||
AlertNG *ngalert.AlertNG
|
||||
LibraryPanelService librarypanels.Service
|
||||
LibraryElementService libraryelements.Service
|
||||
SocialService social.Service
|
||||
Listener net.Listener
|
||||
EncryptionService encryption.Internal
|
||||
SecretsService secrets.Service
|
||||
DataSourcesService *datasources.Service
|
||||
cleanUpService *cleanup.CleanUpService
|
||||
tracer tracing.Tracer
|
||||
grafanaUpdateChecker *updatechecker.GrafanaService
|
||||
pluginsUpdateChecker *updatechecker.PluginsService
|
||||
searchUsersService searchusers.Service
|
||||
ldapGroups ldap.Groups
|
||||
teamGuardian teamguardian.TeamGuardian
|
||||
queryDataService *query.Service
|
||||
serviceAccountsService serviceaccounts.Service
|
||||
authInfoService login.AuthInfoService
|
||||
TeamPermissionsService *resourcepermissions.Service
|
||||
NotificationService *notifications.NotificationService
|
||||
PluginContextProvider *plugincontext.Provider
|
||||
RouteRegister routing.RouteRegister
|
||||
Bus bus.Bus
|
||||
RenderService rendering.Service
|
||||
Cfg *setting.Cfg
|
||||
Features *featuremgmt.FeatureManager
|
||||
SettingsProvider setting.Provider
|
||||
HooksService *hooks.HooksService
|
||||
CacheService *localcache.CacheService
|
||||
DataSourceCache datasources.CacheService
|
||||
AuthTokenService models.UserTokenService
|
||||
QuotaService *quota.QuotaService
|
||||
RemoteCacheService *remotecache.RemoteCache
|
||||
ProvisioningService provisioning.ProvisioningService
|
||||
Login login.Service
|
||||
License models.Licensing
|
||||
AccessControl accesscontrol.AccessControl
|
||||
DataProxy *datasourceproxy.DataSourceProxyService
|
||||
PluginRequestValidator models.PluginRequestValidator
|
||||
pluginClient plugins.Client
|
||||
pluginStore plugins.Store
|
||||
pluginDashboardManager plugins.PluginDashboardManager
|
||||
pluginStaticRouteResolver plugins.StaticRouteResolver
|
||||
pluginErrorResolver plugins.ErrorResolver
|
||||
SearchService search.Service
|
||||
ShortURLService shorturls.Service
|
||||
QueryHistoryService queryhistory.Service
|
||||
Live *live.GrafanaLive
|
||||
LivePushGateway *pushhttp.Gateway
|
||||
ThumbService thumbs.Service
|
||||
ContextHandler *contexthandler.ContextHandler
|
||||
SQLStore sqlstore.Store
|
||||
AlertEngine *alerting.AlertEngine
|
||||
LoadSchemaService *schemaloader.SchemaLoaderService
|
||||
AlertNG *ngalert.AlertNG
|
||||
LibraryPanelService librarypanels.Service
|
||||
LibraryElementService libraryelements.Service
|
||||
SocialService social.Service
|
||||
Listener net.Listener
|
||||
EncryptionService encryption.Internal
|
||||
SecretsService secrets.Service
|
||||
DataSourcesService *datasources.Service
|
||||
cleanUpService *cleanup.CleanUpService
|
||||
tracer tracing.Tracer
|
||||
grafanaUpdateChecker *updatechecker.GrafanaService
|
||||
pluginsUpdateChecker *updatechecker.PluginsService
|
||||
searchUsersService searchusers.Service
|
||||
ldapGroups ldap.Groups
|
||||
teamGuardian teamguardian.TeamGuardian
|
||||
queryDataService *query.Service
|
||||
serviceAccountsService serviceaccounts.Service
|
||||
authInfoService login.AuthInfoService
|
||||
TeamPermissionsService *resourcepermissions.Service
|
||||
NotificationService *notifications.NotificationService
|
||||
DatasourcePermissionsService DatasourcePermissionsService
|
||||
}
|
||||
|
||||
type ServerOptions struct {
|
||||
@ -157,67 +158,68 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
dataSourcesService *datasources.Service, secretsService secrets.Service, queryDataService *query.Service,
|
||||
ldapGroups ldap.Groups, teamGuardian teamguardian.TeamGuardian, serviceaccountsService serviceaccounts.Service,
|
||||
authInfoService login.AuthInfoService, resourcePermissionServices *resourceservices.ResourceServices,
|
||||
notificationService *notifications.NotificationService) (*HTTPServer, error) {
|
||||
notificationService *notifications.NotificationService, datasourcePermissionsService DatasourcePermissionsService) (*HTTPServer, error) {
|
||||
web.Env = cfg.Env
|
||||
m := web.New()
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
RouteRegister: routeRegister,
|
||||
Bus: bus,
|
||||
RenderService: renderService,
|
||||
License: licensing,
|
||||
HooksService: hooksService,
|
||||
CacheService: cacheService,
|
||||
SQLStore: sqlStore,
|
||||
AlertEngine: alertEngine,
|
||||
PluginRequestValidator: pluginRequestValidator,
|
||||
pluginClient: pluginClient,
|
||||
pluginStore: pluginStore,
|
||||
pluginStaticRouteResolver: pluginStaticRouteResolver,
|
||||
pluginDashboardManager: pluginDashboardManager,
|
||||
pluginErrorResolver: pluginErrorResolver,
|
||||
grafanaUpdateChecker: grafanaUpdateChecker,
|
||||
pluginsUpdateChecker: pluginsUpdateChecker,
|
||||
SettingsProvider: settingsProvider,
|
||||
DataSourceCache: dataSourceCache,
|
||||
AuthTokenService: userTokenService,
|
||||
cleanUpService: cleanUpService,
|
||||
ShortURLService: shortURLService,
|
||||
QueryHistoryService: queryHistoryService,
|
||||
Features: features,
|
||||
ThumbService: thumbService,
|
||||
RemoteCacheService: remoteCache,
|
||||
ProvisioningService: provisioningService,
|
||||
Login: loginService,
|
||||
AccessControl: accessControl,
|
||||
DataProxy: dataSourceProxy,
|
||||
SearchService: searchService,
|
||||
Live: live,
|
||||
LivePushGateway: livePushGateway,
|
||||
PluginContextProvider: plugCtxProvider,
|
||||
ContextHandler: contextHandler,
|
||||
LoadSchemaService: schemaService,
|
||||
AlertNG: alertNG,
|
||||
LibraryPanelService: libraryPanelService,
|
||||
LibraryElementService: libraryElementService,
|
||||
QuotaService: quotaService,
|
||||
tracer: tracer,
|
||||
log: log.New("http.server"),
|
||||
web: m,
|
||||
Listener: opts.Listener,
|
||||
SocialService: socialService,
|
||||
EncryptionService: encryptionService,
|
||||
SecretsService: secretsService,
|
||||
DataSourcesService: dataSourcesService,
|
||||
searchUsersService: searchUsersService,
|
||||
ldapGroups: ldapGroups,
|
||||
teamGuardian: teamGuardian,
|
||||
queryDataService: queryDataService,
|
||||
serviceAccountsService: serviceaccountsService,
|
||||
authInfoService: authInfoService,
|
||||
TeamPermissionsService: resourcePermissionServices.GetTeamService(),
|
||||
NotificationService: notificationService,
|
||||
Cfg: cfg,
|
||||
RouteRegister: routeRegister,
|
||||
Bus: bus,
|
||||
RenderService: renderService,
|
||||
License: licensing,
|
||||
HooksService: hooksService,
|
||||
CacheService: cacheService,
|
||||
SQLStore: sqlStore,
|
||||
AlertEngine: alertEngine,
|
||||
PluginRequestValidator: pluginRequestValidator,
|
||||
pluginClient: pluginClient,
|
||||
pluginStore: pluginStore,
|
||||
pluginStaticRouteResolver: pluginStaticRouteResolver,
|
||||
pluginDashboardManager: pluginDashboardManager,
|
||||
pluginErrorResolver: pluginErrorResolver,
|
||||
grafanaUpdateChecker: grafanaUpdateChecker,
|
||||
pluginsUpdateChecker: pluginsUpdateChecker,
|
||||
SettingsProvider: settingsProvider,
|
||||
DataSourceCache: dataSourceCache,
|
||||
AuthTokenService: userTokenService,
|
||||
cleanUpService: cleanUpService,
|
||||
ShortURLService: shortURLService,
|
||||
QueryHistoryService: queryHistoryService,
|
||||
Features: features,
|
||||
ThumbService: thumbService,
|
||||
RemoteCacheService: remoteCache,
|
||||
ProvisioningService: provisioningService,
|
||||
Login: loginService,
|
||||
AccessControl: accessControl,
|
||||
DataProxy: dataSourceProxy,
|
||||
SearchService: searchService,
|
||||
Live: live,
|
||||
LivePushGateway: livePushGateway,
|
||||
PluginContextProvider: plugCtxProvider,
|
||||
ContextHandler: contextHandler,
|
||||
LoadSchemaService: schemaService,
|
||||
AlertNG: alertNG,
|
||||
LibraryPanelService: libraryPanelService,
|
||||
LibraryElementService: libraryElementService,
|
||||
QuotaService: quotaService,
|
||||
tracer: tracer,
|
||||
log: log.New("http.server"),
|
||||
web: m,
|
||||
Listener: opts.Listener,
|
||||
SocialService: socialService,
|
||||
EncryptionService: encryptionService,
|
||||
SecretsService: secretsService,
|
||||
DataSourcesService: dataSourcesService,
|
||||
searchUsersService: searchUsersService,
|
||||
ldapGroups: ldapGroups,
|
||||
teamGuardian: teamGuardian,
|
||||
queryDataService: queryDataService,
|
||||
serviceAccountsService: serviceaccountsService,
|
||||
authInfoService: authInfoService,
|
||||
TeamPermissionsService: resourcePermissionServices.GetTeamService(),
|
||||
NotificationService: notificationService,
|
||||
DatasourcePermissionsService: datasourcePermissionsService,
|
||||
}
|
||||
if hs.Listener != nil {
|
||||
hs.log.Debug("Using provided listener")
|
||||
|
@ -5,6 +5,7 @@ package server
|
||||
|
||||
import (
|
||||
"github.com/google/wire"
|
||||
"github.com/grafana/grafana/pkg/api"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
|
||||
@ -73,6 +74,8 @@ var wireExtsBasicSet = wire.NewSet(
|
||||
wire.Bind(new(kmsproviders.Service), new(osskmsproviders.Service)),
|
||||
ldap.ProvideGroupsService,
|
||||
wire.Bind(new(ldap.Groups), new(*ldap.OSSGroups)),
|
||||
api.ProvideDatasourcePermissionsService,
|
||||
wire.Bind(new(api.DatasourcePermissionsService), new(*api.OSSDatasourcePermissionsService)),
|
||||
)
|
||||
|
||||
var wireExtsSet = wire.NewSet(
|
||||
|
@ -28,7 +28,9 @@ type SQLStoreMock struct {
|
||||
ExpectedDashboardSnapshot *models.DashboardSnapshot
|
||||
ExpectedTeamsByUser []*models.TeamDTO
|
||||
ExpectedSearchOrgList []*models.OrgDTO
|
||||
ExpectedError error
|
||||
ExpectedDatasources []*models.DataSource
|
||||
|
||||
ExpectedError error
|
||||
}
|
||||
|
||||
func NewSQLStoreMock() *SQLStoreMock {
|
||||
@ -483,6 +485,7 @@ func (m *SQLStoreMock) GetDataSource(ctx context.Context, query *models.GetDataS
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error {
|
||||
query.Result = m.ExpectedDatasources
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@ -499,10 +502,12 @@ func (m *SQLStoreMock) DeleteDataSource(ctx context.Context, cmd *models.DeleteD
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
|
||||
cmd.Result = m.ExpectedDatasource
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
|
||||
cmd.Result = m.ExpectedDatasource
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user