mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboards: Refactor service to make it injectable by wire (#44588)
* Add providers to folder and dashboard services * Refactor folder and dashboard services * Move store implementation to its own file due wire cannot allow us to cast to SQLStore * Add store in some places and more missing dependencies * Bad merge fix * Remove old functions from tests and few fixes * Fix provisioning * Remove store from http server and some test fixes * Test fixes * Fix dashboard and folder tests * Fix library tests * Fix provisioning tests * Fix plugins manager tests * Fix alert and org users tests * Refactor service package and more test fixes * Fix dashboard_test tets * Fix api tests * Some lint fixes * Fix lint * More lint :/ * Move dashboard integration tests to dashboards service and fix dependencies * Lint + tests * More integration tests fixes * Lint * Lint again * Fix tests again and again anda again * Update searchstore_test * Fix goimports * More go imports * More imports fixes * Fix lint * Move UnprovisionDashboard function into dashboard service and remove bus * Use search service instead of bus * Fix test * Fix go imports * Use nil in tests
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
// updateDashboardACL updates a dashboard's ACL items.
|
||||
//
|
||||
// Stubbable by tests.
|
||||
var updateDashboardACL = func(ctx context.Context, s dashboards.Store, dashID int64, items []*models.DashboardAcl) error {
|
||||
return s.UpdateDashboardACLCtx(ctx, dashID, items)
|
||||
}
|
||||
@@ -28,6 +28,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourceservices"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
dashboardsstore "github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/ldap"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
@@ -276,6 +279,8 @@ type accessControlScenarioContext struct {
|
||||
|
||||
// cfg is the setting provider
|
||||
cfg *setting.Cfg
|
||||
|
||||
dashboardsStore dashboards.Store
|
||||
}
|
||||
|
||||
func setAccessControlPermissions(acmock *accesscontrolmock.Mock, perms []*accesscontrol.Permission, org int64) {
|
||||
@@ -347,6 +352,8 @@ func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessCont
|
||||
|
||||
bus := bus.GetBus()
|
||||
|
||||
dashboardsStore := dashboardsstore.ProvideDashboardStore(db)
|
||||
|
||||
routeRegister := routing.NewRouteRegister()
|
||||
// Create minimal HTTP Server
|
||||
hs := &HTTPServer{
|
||||
@@ -358,6 +365,7 @@ func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessCont
|
||||
RouteRegister: routeRegister,
|
||||
SQLStore: db,
|
||||
searchUsersService: searchusers.ProvideUsersService(bus, filters.ProvideOSSSearchUserFilter()),
|
||||
dashboardService: dashboardservice.ProvideDashboardService(dashboardsStore),
|
||||
}
|
||||
|
||||
// Defining the accesscontrol service has to be done before registering routes
|
||||
@@ -402,12 +410,13 @@ func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessCont
|
||||
hs.RouteRegister.Register(m.Router)
|
||||
|
||||
return accessControlScenarioContext{
|
||||
server: m,
|
||||
initCtx: initCtx,
|
||||
hs: hs,
|
||||
acmock: acmock,
|
||||
db: db,
|
||||
cfg: cfg,
|
||||
server: m,
|
||||
initCtx: initCtx,
|
||||
hs: hs,
|
||||
acmock: acmock,
|
||||
db: db,
|
||||
cfg: cfg,
|
||||
dashboardsStore: dashboardsStore,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,8 +148,7 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
meta.FolderUrl = query.Result.GetUrl()
|
||||
}
|
||||
|
||||
svc := dashboards.NewProvisioningService(hs.SQLStore)
|
||||
provisioningData, err := svc.GetProvisionedDashboardDataByDashboardID(dash.Id)
|
||||
provisioningData, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(dash.Id)
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking if dashboard is provisioned", err)
|
||||
}
|
||||
@@ -233,8 +232,8 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
if err != nil {
|
||||
hs.log.Error("Failed to disconnect library elements", "dashboard", dash.Id, "user", c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
svc := dashboards.NewService(hs.SQLStore)
|
||||
err = svc.DeleteDashboard(c.Req.Context(), dash.Id, c.OrgId)
|
||||
|
||||
err = hs.dashboardService.DeleteDashboard(c.Req.Context(), dash.Id, c.OrgId)
|
||||
if err != nil {
|
||||
var dashboardErr models.DashboardErr
|
||||
if ok := errors.As(err, &dashboardErr); ok {
|
||||
@@ -271,8 +270,7 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
cmd.OrgId = c.OrgId
|
||||
cmd.UserId = c.UserId
|
||||
if cmd.FolderUid != "" {
|
||||
folders := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := folders.GetFolderByUID(ctx, cmd.FolderUid)
|
||||
folder, err := hs.folderService.GetFolderByUID(ctx, c.SignedInUser, c.OrgId, cmd.FolderUid)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrFolderNotFound) {
|
||||
return response.Error(400, "Folder not found", err)
|
||||
@@ -294,18 +292,17 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
}
|
||||
}
|
||||
|
||||
svc := dashboards.NewProvisioningService(hs.SQLStore)
|
||||
var provisioningData *models.DashboardProvisioning
|
||||
if dash.Id != 0 {
|
||||
data, err := svc.GetProvisionedDashboardDataByDashboardID(dash.Id)
|
||||
data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(dash.Id)
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking if dashboard is provisioned using ID", err)
|
||||
}
|
||||
provisioningData = data
|
||||
} else if dash.Uid != "" {
|
||||
data, err := svc.GetProvisionedDashboardDataByDashboardUID(dash.OrgId, dash.Uid)
|
||||
if err != nil && (!errors.Is(err, models.ErrProvisionedDashboardNotFound) && !errors.Is(err, models.ErrDashboardNotFound)) {
|
||||
return response.Error(500, "Error while checking if dashboard is provisioned using UID", err)
|
||||
data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardUID(dash.OrgId, dash.Uid)
|
||||
if err != nil && !errors.Is(err, models.ErrProvisionedDashboardNotFound) && !errors.Is(err, models.ErrDashboardNotFound) {
|
||||
return response.Error(500, "Error while checking if dashboard is provisioned", err)
|
||||
}
|
||||
provisioningData = data
|
||||
}
|
||||
@@ -329,8 +326,7 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
Overwrite: cmd.Overwrite,
|
||||
}
|
||||
|
||||
dashSvc := dashboards.NewService(hs.SQLStore)
|
||||
dashboard, err := dashSvc.SaveDashboard(alerting.WithUAEnabled(ctx, hs.Cfg.UnifiedAlerting.IsEnabled()), dashItem, allowUiUpdate)
|
||||
dashboard, err := hs.dashboardService.SaveDashboard(alerting.WithUAEnabled(ctx, hs.Cfg.UnifiedAlerting.IsEnabled()), dashItem, allowUiUpdate)
|
||||
|
||||
if hs.Live != nil {
|
||||
// Tell everyone listening that the dashboard changed
|
||||
@@ -362,7 +358,7 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
|
||||
if hs.Cfg.EditorsCanAdmin && newDashboard {
|
||||
inFolder := cmd.FolderId > 0
|
||||
err := dashSvc.MakeUserAdmin(ctx, cmd.OrgId, cmd.UserId, dashboard.Id, !inFolder)
|
||||
err := hs.dashboardService.MakeUserAdmin(ctx, cmd.OrgId, cmd.UserId, dashboard.Id, !inFolder)
|
||||
if err != nil {
|
||||
hs.log.Error("Could not make user admin", "dashboard", dashboard.Title, "user", c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext) response.
|
||||
return response.Error(403, "Cannot remove own admin permission for a folder", nil)
|
||||
}
|
||||
|
||||
if err := updateDashboardACL(c.Req.Context(), hs.SQLStore, dashID, items); err != nil {
|
||||
if err := hs.dashboardService.UpdateDashboardACL(c.Req.Context(), dashID, items); err != nil {
|
||||
if errors.Is(err, models.ErrDashboardAclInfoMissing) ||
|
||||
errors.Is(err, models.ErrDashboardPermissionDashboardEmpty) {
|
||||
return response.Error(409, err.Error(), err)
|
||||
|
||||
@@ -1,59 +1,38 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
t.Run("Dashboard permissions test", func(t *testing.T) {
|
||||
settings := setting.NewCfg()
|
||||
dashboardStore := &database.FakeDashboardStore{}
|
||||
defer dashboardStore.AssertExpectations(t)
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: settings,
|
||||
SQLStore: mockSQLStore,
|
||||
Cfg: settings,
|
||||
dashboardService: dashboardservice.ProvideDashboardService(dashboardStore),
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
|
||||
t.Run("Given dashboard not exists", func(t *testing.T) {
|
||||
mockSQLStore.ExpectedError = models.ErrDashboardNotFound
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
|
||||
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
callGetDashboardPermissions(sc, hs)
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
{UserID: 1000, Permission: models.PERMISSION_ADMIN},
|
||||
},
|
||||
}
|
||||
|
||||
updateDashboardPermissionScenario(t, updatePermissionContext{
|
||||
desc: "When calling POST on",
|
||||
url: "/api/dashboards/id/1/permissions",
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
})
|
||||
|
||||
t.Run("Given user has no admin permissions", func(t *testing.T) {
|
||||
origNewGuardian := guardian.New
|
||||
t.Cleanup(func() {
|
||||
@@ -63,7 +42,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false})
|
||||
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = getDashboardQueryResult
|
||||
mockSQLStore.ExpectedError = nil
|
||||
@@ -80,6 +58,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
updateDashboardPermissionScenario(t, updatePermissionContext{
|
||||
desc: "When calling POST on",
|
||||
url: "/api/dashboards/id/1/permissions",
|
||||
@@ -324,26 +303,20 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
}
|
||||
assert.Len(t, cmd.Items, 3)
|
||||
|
||||
var numOfItems []*models.DashboardAcl
|
||||
dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
||||
items := args.Get(2).([]*models.DashboardAcl)
|
||||
numOfItems = items
|
||||
}).Return(nil).Once()
|
||||
updateDashboardPermissionScenario(t, updatePermissionContext{
|
||||
desc: "When calling POST on",
|
||||
url: "/api/dashboards/id/1/permissions",
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
// TODO: Replace this fake with a fake SQLStore instead (once we can use an interface in its stead)
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
var gotItems []*models.DashboardAcl
|
||||
updateDashboardACL = func(_ context.Context, _ dashboards.Store, folderID int64, items []*models.DashboardAcl) error {
|
||||
gotItems = items
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Len(t, gotItems, 4)
|
||||
assert.Len(t, numOfItems, 4)
|
||||
},
|
||||
}, hs)
|
||||
})
|
||||
@@ -357,15 +330,6 @@ func callGetDashboardPermissions(sc *scenarioContext, hs *HTTPServer) {
|
||||
|
||||
func callUpdateDashboardPermissions(t *testing.T, sc *scenarioContext) {
|
||||
t.Helper()
|
||||
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
updateDashboardACL = func(_ context.Context, _ dashboards.Store, dashID int64, items []*models.DashboardAcl) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
@@ -15,11 +14,12 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
dboards "github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
service "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||
"github.com/grafana/grafana/pkg/services/live"
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -145,7 +146,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
dash := getDashboardShouldReturn200(t, sc)
|
||||
|
||||
assert.False(t, dash.Meta.CanEdit)
|
||||
assert.False(t, dash.Meta.CanSave)
|
||||
@@ -177,7 +178,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
dash := getDashboardShouldReturn200(t, sc)
|
||||
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.True(t, dash.Meta.CanSave)
|
||||
@@ -212,11 +213,13 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = fakeDash
|
||||
|
||||
dashboardStore := database.ProvideDashboardStore(sqlstore.InitTestDB(t))
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
Live: newTestLive(t),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
dashboardService: service.ProvideDashboardService(dashboardStore),
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
hs.SQLStore = mockSQLStore
|
||||
@@ -345,7 +348,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
dash := getDashboardShouldReturn200(t, sc)
|
||||
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.True(t, dash.Meta.CanSave)
|
||||
@@ -412,7 +415,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
require.True(t, setting.ViewersCanEdit)
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
dash := getDashboardShouldReturn200(t, sc)
|
||||
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.False(t, dash.Meta.CanSave)
|
||||
@@ -445,7 +448,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
dash := getDashboardShouldReturn200(t, sc)
|
||||
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.True(t, dash.Meta.CanSave)
|
||||
@@ -493,7 +496,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
dash := getDashboardShouldReturn200(t, sc)
|
||||
|
||||
assert.False(t, dash.Meta.CanEdit)
|
||||
assert.False(t, dash.Meta.CanSave)
|
||||
@@ -535,6 +538,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Post dashboard response tests", func(t *testing.T) {
|
||||
dashboardStore := &database.FakeDashboardStore{}
|
||||
defer dashboardStore.AssertExpectations(t)
|
||||
// This tests that a valid request returns correct response
|
||||
t.Run("Given a correct request for creating a dashboard", func(t *testing.T) {
|
||||
const folderID int64 = 3
|
||||
@@ -562,7 +567,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", mock, nil, cmd, func(sc *scenarioContext) {
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, mock, nil, func(sc *scenarioContext) {
|
||||
callPostDashboardShouldReturnSuccess(sc)
|
||||
|
||||
dto := mock.SavedDashboards[0]
|
||||
@@ -612,7 +617,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
GetFolderByUIDResult: &models.Folder{Id: 1, Uid: "folderUID", Title: "Folder"},
|
||||
}
|
||||
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", mock, mockFolder, cmd, func(sc *scenarioContext) {
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, mock, mockFolder, func(sc *scenarioContext) {
|
||||
callPostDashboardShouldReturnSuccess(sc)
|
||||
|
||||
dto := mock.SavedDashboards[0]
|
||||
@@ -661,7 +666,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
GetFolderByUIDError: errors.New("Error while searching Folder ID"),
|
||||
}
|
||||
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", mock, mockFolder, cmd, func(sc *scenarioContext) {
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, mock, mockFolder, func(sc *scenarioContext) {
|
||||
callPostDashboard(sc)
|
||||
assert.Equal(t, 500, sc.resp.Code)
|
||||
})
|
||||
@@ -706,7 +711,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
}
|
||||
|
||||
postDashboardScenario(t, fmt.Sprintf("Expect '%s' error when calling POST on", tc.SaveError.Error()),
|
||||
"/api/dashboards", "/api/dashboards", mock, nil, cmd, func(sc *scenarioContext) {
|
||||
"/api/dashboards", "/api/dashboards", cmd, mock, nil, func(sc *scenarioContext) {
|
||||
callPostDashboard(sc)
|
||||
assert.Equal(t, tc.ExpectedStatusCode, sc.resp.Code)
|
||||
})
|
||||
@@ -852,14 +857,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("Given provisioned dashboard", func(t *testing.T) {
|
||||
setUp := func() {
|
||||
origGetProvisionedData := dashboards.GetProvisionedData
|
||||
t.Cleanup(func() {
|
||||
dashboards.GetProvisionedData = origGetProvisionedData
|
||||
})
|
||||
dashboards.GetProvisionedData = func(dboards.Store, int64) (*models.DashboardProvisioning, error) {
|
||||
return &models.DashboardProvisioning{ExternalId: "/tmp/grafana/dashboards/test/dashboard1.json"}, nil
|
||||
}
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = []*models.DashboardAclInfoDTO{
|
||||
{OrgId: testOrgID, DashboardId: 1, UserId: testUserID, Permission: models.PERMISSION_EDIT},
|
||||
@@ -867,6 +864,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "editable": true, "style": "dark"}`))
|
||||
require.NoError(t, err)
|
||||
@@ -874,37 +872,39 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "editable": true, "style": "dark"}`))
|
||||
require.NoError(t, err)
|
||||
mockSQLStore.ExpectedDashboard = &models.Dashboard{Id: 1, Data: dataValue}
|
||||
sc.sqlStore = mockSQLStore
|
||||
mock := provisioning.NewProvisioningServiceMock(context.Background())
|
||||
mock.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
|
||||
fakeProvisioningService := provisioning.NewProvisioningServiceMock(context.Background())
|
||||
fakeProvisioningService.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
|
||||
return "/tmp/grafana/dashboards"
|
||||
}
|
||||
|
||||
dash := getDashboardShouldReturn200WithConfig(sc, mock)
|
||||
dashboardStore := &database.FakeDashboardStore{}
|
||||
defer dashboardStore.AssertExpectations(t)
|
||||
|
||||
assert.Equal(t, filepath.Join("test", "dashboard1.json"), dash.Meta.ProvisionedExternalId)
|
||||
dashboardStore.On("GetProvisionedDataByDashboardID", mock.Anything).Return(&models.DashboardProvisioning{ExternalId: "/dashboard1.json"}, nil).Once()
|
||||
|
||||
dash := getDashboardShouldReturn200WithConfig(t, sc, fakeProvisioningService, dashboardStore)
|
||||
|
||||
assert.Equal(t, "../../../dashboard1.json", dash.Meta.ProvisionedExternalId, mockSQLStore)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When allowUiUpdates is true and calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
mock := provisioning.NewProvisioningServiceMock(context.Background())
|
||||
mock.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
|
||||
fakeProvisioningService := provisioning.NewProvisioningServiceMock(context.Background())
|
||||
fakeProvisioningService.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
|
||||
return "/tmp/grafana/dashboards"
|
||||
}
|
||||
mock.GetAllowUIUpdatesFromConfigFunc = func(name string) bool {
|
||||
|
||||
fakeProvisioningService.GetAllowUIUpdatesFromConfigFunc = func(name string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
ProvisioningService: mock,
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: mockSQLStore,
|
||||
Cfg: setting.NewCfg(),
|
||||
ProvisioningService: fakeProvisioningService,
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
dashboardProvisioningService: mockDashboardProvisioningService{},
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
hs.callGetDashboard(sc)
|
||||
|
||||
@@ -919,21 +919,28 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func getDashboardShouldReturn200WithConfig(sc *scenarioContext, provisioningService provisioning.ProvisioningService) dtos.
|
||||
DashboardFullWithMeta {
|
||||
func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, provisioningService provisioning.ProvisioningService, dashboardStore dashboards.Store) dtos.DashboardFullWithMeta {
|
||||
t.Helper()
|
||||
|
||||
if provisioningService == nil {
|
||||
provisioningService = provisioning.NewProvisioningServiceMock(context.Background())
|
||||
}
|
||||
|
||||
if dashboardStore == nil {
|
||||
sql := sqlstore.InitTestDB(t)
|
||||
dashboardStore = database.ProvideDashboardStore(sql)
|
||||
}
|
||||
|
||||
libraryPanelsService := mockLibraryPanelService{}
|
||||
libraryElementsService := mockLibraryElementService{}
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
LibraryPanelService: &libraryPanelsService,
|
||||
LibraryElementService: &libraryElementsService,
|
||||
ProvisioningService: provisioningService,
|
||||
SQLStore: sc.sqlStore,
|
||||
Cfg: setting.NewCfg(),
|
||||
LibraryPanelService: &libraryPanelsService,
|
||||
LibraryElementService: &libraryElementsService,
|
||||
ProvisioningService: provisioningService,
|
||||
dashboardProvisioningService: service.ProvideDashboardService(dashboardStore),
|
||||
SQLStore: sc.sqlStore,
|
||||
}
|
||||
|
||||
hs.callGetDashboard(sc)
|
||||
@@ -947,8 +954,8 @@ func getDashboardShouldReturn200WithConfig(sc *scenarioContext, provisioningServ
|
||||
return dash
|
||||
}
|
||||
|
||||
func getDashboardShouldReturn200(sc *scenarioContext) dtos.DashboardFullWithMeta {
|
||||
return getDashboardShouldReturn200WithConfig(sc, nil)
|
||||
func getDashboardShouldReturn200(t *testing.T, sc *scenarioContext) dtos.DashboardFullWithMeta {
|
||||
return getDashboardShouldReturn200WithConfig(t, sc, nil, nil)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) callGetDashboard(sc *scenarioContext) {
|
||||
@@ -976,17 +983,13 @@ func (hs *HTTPServer) callGetDashboardVersions(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) callDeleteDashboardByUID(t *testing.T, sc *scenarioContext, mockDashboard *dashboards.FakeDashboardService) {
|
||||
func (hs *HTTPServer) callDeleteDashboardByUID(t *testing.T,
|
||||
sc *scenarioContext, mockDashboard *dashboards.FakeDashboardService) {
|
||||
bus.AddHandler("test", func(ctx context.Context, cmd *models.DeleteDashboardCommand) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
origNewDashboardService := dashboards.NewService
|
||||
t.Cleanup(func() {
|
||||
dashboards.NewService = origNewDashboardService
|
||||
})
|
||||
dashboards.MockDashboardService(mockDashboard)
|
||||
|
||||
hs.dashboardService = mockDashboard
|
||||
sc.handlerFunc = hs.DeleteDashboardByUID
|
||||
sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
@@ -1005,9 +1008,7 @@ func callPostDashboardShouldReturnSuccess(sc *scenarioContext) {
|
||||
assert.Equal(sc.t, 200, sc.resp.Code)
|
||||
}
|
||||
|
||||
func postDashboardScenario(t *testing.T, desc string, url string, routePattern string,
|
||||
mock *dashboards.FakeDashboardService, mockFolder *fakeFolderService, cmd models.SaveDashboardCommand,
|
||||
fn scenarioFunc) {
|
||||
func postDashboardScenario(t *testing.T, desc string, url string, routePattern string, cmd models.SaveDashboardCommand, dashboardService dashboards.DashboardService, folderService dashboards.FolderService, fn scenarioFunc) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
t.Cleanup(bus.ClearBusHandlers)
|
||||
|
||||
@@ -1023,6 +1024,8 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
||||
pluginStore: &fakePluginStore{},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
dashboardService: dashboardService,
|
||||
folderService: folderService,
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
@@ -1035,20 +1038,6 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
||||
return hs.PostDashboard(c)
|
||||
})
|
||||
|
||||
origNewDashboardService := dashboards.NewService
|
||||
origProvisioningService := dashboards.NewProvisioningService
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
dashboards.NewService = origNewDashboardService
|
||||
dashboards.NewProvisioningService = origProvisioningService
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
dashboards.MockDashboardService(mock)
|
||||
dashboards.NewProvisioningService = func(dboards.Store) dashboards.DashboardProvisioningService {
|
||||
return mockDashboardProvisioningService{}
|
||||
}
|
||||
mockFolderService(mockFolder)
|
||||
|
||||
sc.m.Post(routePattern, sc.defaultHandler)
|
||||
|
||||
fn(sc)
|
||||
@@ -1091,9 +1080,7 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
|
||||
})
|
||||
}
|
||||
|
||||
func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string,
|
||||
mock *dashboards.FakeDashboardService, cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc,
|
||||
sqlStore sqlstore.Store) {
|
||||
func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string, mock *dashboards.FakeDashboardService, cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc, sqlStore sqlstore.Store) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
@@ -1107,6 +1094,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
dashboardService: mock,
|
||||
SQLStore: sqlStore,
|
||||
}
|
||||
|
||||
@@ -1125,17 +1113,6 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
|
||||
return hs.RestoreDashboardVersion(c)
|
||||
})
|
||||
|
||||
origProvisioningService := dashboards.NewProvisioningService
|
||||
origNewDashboardService := dashboards.NewService
|
||||
t.Cleanup(func() {
|
||||
dashboards.NewService = origNewDashboardService
|
||||
dashboards.NewProvisioningService = origProvisioningService
|
||||
})
|
||||
dashboards.NewProvisioningService = func(dboards.Store) dashboards.DashboardProvisioningService {
|
||||
return mockDashboardProvisioningService{}
|
||||
}
|
||||
dashboards.MockDashboardService(mock)
|
||||
|
||||
sc.m.Post(routePattern, sc.defaultHandler)
|
||||
|
||||
fn(sc)
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
@@ -19,8 +18,7 @@ import (
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) GetFolders(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folders, err := s.GetFolders(c.Req.Context(), c.QueryInt64("limit"), c.QueryInt64("page"))
|
||||
folders, err := hs.folderService.GetFolders(c.Req.Context(), c.SignedInUser, c.OrgId, c.QueryInt64("limit"), c.QueryInt64("page"))
|
||||
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
@@ -40,8 +38,7 @@ func (hs *HTTPServer) GetFolders(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Req.Context(), web.Params(c.Req)[":uid"])
|
||||
folder, err := hs.folderService.GetFolderByUID(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"])
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@@ -51,14 +48,11 @@ func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
|
||||
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "id is invalid", err)
|
||||
}
|
||||
|
||||
folder, err := s.GetFolderByID(c.Req.Context(), id)
|
||||
folder, err := hs.folderService.GetFolderByID(c.Req.Context(), c.SignedInUser, c.OrgId, id)
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@@ -72,14 +66,13 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.CreateFolder(c.Req.Context(), cmd.Title, cmd.Uid)
|
||||
folder, err := hs.folderService.CreateFolder(c.Req.Context(), c.SignedInUser, c.OrgId, cmd.Title, cmd.Uid)
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
if hs.Cfg.EditorsCanAdmin {
|
||||
if err := s.MakeUserAdmin(c.Req.Context(), c.OrgId, c.SignedInUser.UserId, folder.Id, true); err != nil {
|
||||
if err := hs.folderService.MakeUserAdmin(c.Req.Context(), c.OrgId, c.SignedInUser.UserId, folder.Id, true); err != nil {
|
||||
hs.log.Error("Could not make user admin", "folder", folder.Title, "user",
|
||||
c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
@@ -94,8 +87,7 @@ func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
err := s.UpdateFolder(c.Req.Context(), web.Params(c.Req)[":uid"], &cmd)
|
||||
err := hs.folderService.UpdateFolder(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"], &cmd)
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@@ -105,7 +97,6 @@ func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // temporarily adding this function to HTTPServer, will be removed from HTTPServer when librarypanels featuretoggle is removed
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
err := hs.LibraryElementService.DeleteLibraryElementsInFolder(c.Req.Context(), c.SignedInUser, web.Params(c.Req)[":uid"])
|
||||
if err != nil {
|
||||
if errors.Is(err, libraryelements.ErrFolderHasConnectedLibraryElements) {
|
||||
@@ -114,7 +105,7 @@ func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { //
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
f, err := s.DeleteFolder(c.Req.Context(), web.Params(c.Req)[":uid"], c.QueryBool("forceDeleteRules"))
|
||||
f, err := hs.folderService.DeleteFolder(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"], c.QueryBool("forceDeleteRules"))
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
@@ -9,15 +9,13 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) GetFolderPermissionList(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Req.Context(), web.Params(c.Req)[":uid"])
|
||||
folder, err := hs.folderService.GetFolderByUID(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"])
|
||||
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
@@ -68,8 +66,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext) response.Res
|
||||
return response.Error(400, err.Error(), err)
|
||||
}
|
||||
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Req.Context(), web.Params(c.Req)[":uid"])
|
||||
folder, err := hs.folderService.GetFolderByUID(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"])
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@@ -117,7 +114,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext) response.Res
|
||||
return response.Error(403, "Cannot remove own admin permission for a folder", nil)
|
||||
}
|
||||
|
||||
if err := updateDashboardACL(c.Req.Context(), hs.SQLStore, folder.Id, items); err != nil {
|
||||
if err := hs.dashboardService.UpdateDashboardACL(c.Req.Context(), folder.Id, items); err != nil {
|
||||
if errors.Is(err, models.ErrDashboardAclInfoMissing) {
|
||||
err = models.ErrFolderAclInfoMissing
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
@@ -13,28 +12,28 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
dashboardifaces "github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
service "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
settings := setting.NewCfg()
|
||||
hs := &HTTPServer{Cfg: settings}
|
||||
folderService := &dashboards.FakeFolderService{}
|
||||
defer folderService.AssertExpectations(t)
|
||||
|
||||
dashboardStore := &database.FakeDashboardStore{}
|
||||
defer dashboardStore.AssertExpectations(t)
|
||||
|
||||
hs := &HTTPServer{Cfg: settings, folderService: folderService, dashboardService: service.ProvideDashboardService(dashboardStore)}
|
||||
|
||||
t.Run("Given folder not exists", func(t *testing.T) {
|
||||
mock := &fakeFolderService{
|
||||
GetFolderByUIDError: models.ErrFolderNotFound,
|
||||
}
|
||||
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
mockFolderService(mock)
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, models.ErrFolderNotFound).Twice()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
callGetFolderPermissions(sc, hs)
|
||||
@@ -61,24 +60,14 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("Given user has no admin permissions", func(t *testing.T) {
|
||||
origNewGuardian := guardian.New
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
guardian.New = origNewGuardian
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
|
||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false})
|
||||
|
||||
mock := &fakeFolderService{
|
||||
GetFolderByUIDResult: &models.Folder{
|
||||
Id: 1,
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
},
|
||||
}
|
||||
|
||||
mockFolderService(mock)
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, models.ErrFolderAccessDenied).Twice()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
callGetFolderPermissions(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
@@ -104,10 +93,8 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("Given user has admin permissions and permissions to update", func(t *testing.T) {
|
||||
origNewGuardian := guardian.New
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
guardian.New = origNewGuardian
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
|
||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
|
||||
@@ -122,16 +109,11 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
mock := &fakeFolderService{
|
||||
GetFolderByUIDResult: &models.Folder{
|
||||
Id: 1,
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
},
|
||||
}
|
||||
|
||||
mockFolderService(mock)
|
||||
folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"}
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Twice()
|
||||
dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
|
||||
callGetFolderPermissions(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
@@ -175,10 +157,8 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("When trying to update permissions with duplicate permissions", func(t *testing.T) {
|
||||
origNewGuardian := guardian.New
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
guardian.New = origNewGuardian
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
|
||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
|
||||
@@ -187,15 +167,8 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
CheckPermissionBeforeUpdateError: guardian.ErrGuardianPermissionExists,
|
||||
})
|
||||
|
||||
mock := &fakeFolderService{
|
||||
GetFolderByUIDResult: &models.Folder{
|
||||
Id: 1,
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
},
|
||||
}
|
||||
|
||||
mockFolderService(mock)
|
||||
folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"}
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Once()
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
@@ -249,10 +222,8 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("When trying to override inherited permissions with lower precedence", func(t *testing.T) {
|
||||
origNewGuardian := guardian.New
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
guardian.New = origNewGuardian
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
|
||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
|
||||
@@ -261,15 +232,8 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
CheckPermissionBeforeUpdateError: guardian.ErrGuardianOverride},
|
||||
)
|
||||
|
||||
mock := &fakeFolderService{
|
||||
GetFolderByUIDResult: &models.Folder{
|
||||
Id: 1,
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
},
|
||||
}
|
||||
|
||||
mockFolderService(mock)
|
||||
folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"}
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Once()
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
@@ -291,14 +255,12 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("Getting and updating folder permissions with hidden users", func(t *testing.T) {
|
||||
origNewGuardian := guardian.New
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
settings.HiddenUsers = map[string]struct{}{
|
||||
"hiddenUser": {},
|
||||
testUserLogin: {},
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
guardian.New = origNewGuardian
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
settings.HiddenUsers = make(map[string]struct{})
|
||||
})
|
||||
|
||||
@@ -315,15 +277,13 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
mock := &fakeFolderService{
|
||||
GetFolderByUIDResult: &models.Folder{
|
||||
Id: 1,
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
},
|
||||
}
|
||||
var gotItems []*models.DashboardAcl
|
||||
|
||||
mockFolderService(mock)
|
||||
folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"}
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Twice()
|
||||
dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
||||
gotItems = args.Get(2).([]*models.DashboardAcl)
|
||||
}).Return(nil).Once()
|
||||
|
||||
var resp []*models.DashboardAclInfoDTO
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
@@ -360,16 +320,6 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
var gotItems []*models.DashboardAcl
|
||||
updateDashboardACL = func(_ context.Context, _ dashboardifaces.Store, _ int64, items []*models.DashboardAcl) error {
|
||||
gotItems = items
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Len(t, gotItems, 4)
|
||||
@@ -385,21 +335,12 @@ func callGetFolderPermissions(sc *scenarioContext, hs *HTTPServer) {
|
||||
|
||||
func callUpdateFolderPermissions(t *testing.T, sc *scenarioContext) {
|
||||
t.Helper()
|
||||
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
updateDashboardACL = func(_ context.Context, _ dashboardifaces.Store, dashID int64, items []*models.DashboardAcl) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func updateFolderPermissionScenario(t *testing.T, ctx updatePermissionContext, hs *HTTPServer) {
|
||||
t.Run(fmt.Sprintf("%s %s", ctx.desc, ctx.url), func(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
t.Cleanup(bus.ClearBusHandlers)
|
||||
|
||||
sc := setupScenarioContext(t, ctx.url)
|
||||
|
||||
|
||||
@@ -10,26 +10,28 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
dboards "github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFoldersAPIEndpoint(t *testing.T) {
|
||||
folderService := &dashboards.FakeFolderService{}
|
||||
defer folderService.AssertExpectations(t)
|
||||
|
||||
t.Run("Given a correct request for creating a folder", func(t *testing.T) {
|
||||
cmd := models.CreateFolderCommand{
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
}
|
||||
|
||||
mock := &fakeFolderService{
|
||||
CreateFolderResult: &models.Folder{Id: 1, Uid: "uid", Title: "Folder"},
|
||||
}
|
||||
folderResult := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"}
|
||||
folderService.On("CreateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResult, nil).Once()
|
||||
|
||||
createFolderScenario(t, "When calling POST on", "/api/folders", "/api/folders", mock, cmd,
|
||||
createFolderScenario(t, "When calling POST on", "/api/folders", "/api/folders", folderService, cmd,
|
||||
func(sc *scenarioContext) {
|
||||
callCreateFolder(sc)
|
||||
|
||||
@@ -64,12 +66,10 @@ func TestFoldersAPIEndpoint(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock := &fakeFolderService{
|
||||
CreateFolderError: tc.Error,
|
||||
}
|
||||
folderService.On("CreateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, tc.Error).Once()
|
||||
|
||||
createFolderScenario(t, fmt.Sprintf("Expect '%s' error when calling POST on", tc.Error.Error()),
|
||||
"/api/folders", "/api/folders", mock, cmd, func(sc *scenarioContext) {
|
||||
"/api/folders", "/api/folders", folderService, cmd, func(sc *scenarioContext) {
|
||||
callCreateFolder(sc)
|
||||
assert.Equalf(t, tc.ExpectedStatusCode, sc.resp.Code, "Wrong status code for error %s", tc.Error)
|
||||
})
|
||||
@@ -81,11 +81,12 @@ func TestFoldersAPIEndpoint(t *testing.T) {
|
||||
Title: "Folder upd",
|
||||
}
|
||||
|
||||
mock := &fakeFolderService{
|
||||
UpdateFolderResult: &models.Folder{Id: 1, Uid: "uid", Title: "Folder upd"},
|
||||
}
|
||||
folderService.On("UpdateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
||||
cmd := args.Get(4).(*models.UpdateFolderCommand)
|
||||
cmd.Result = &models.Folder{Id: 1, Uid: "uid", Title: "Folder upd"}
|
||||
}).Return(nil).Once()
|
||||
|
||||
updateFolderScenario(t, "When calling PUT on", "/api/folders/uid", "/api/folders/:uid", mock, cmd,
|
||||
updateFolderScenario(t, "When calling PUT on", "/api/folders/uid", "/api/folders/:uid", folderService, cmd,
|
||||
func(sc *scenarioContext) {
|
||||
callUpdateFolder(sc)
|
||||
|
||||
@@ -119,12 +120,9 @@ func TestFoldersAPIEndpoint(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock := &fakeFolderService{
|
||||
UpdateFolderError: tc.Error,
|
||||
}
|
||||
|
||||
folderService.On("UpdateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.Error).Once()
|
||||
updateFolderScenario(t, fmt.Sprintf("Expect '%s' error when calling PUT on", tc.Error.Error()),
|
||||
"/api/folders/uid", "/api/folders/:uid", mock, cmd, func(sc *scenarioContext) {
|
||||
"/api/folders/uid", "/api/folders/:uid", folderService, cmd, func(sc *scenarioContext) {
|
||||
callUpdateFolder(sc)
|
||||
assert.Equalf(t, tc.ExpectedStatusCode, sc.resp.Code, "Wrong status code for %s", tc.Error)
|
||||
})
|
||||
@@ -136,14 +134,15 @@ func callCreateFolder(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func createFolderScenario(t *testing.T, desc string, url string, routePattern string, mock *fakeFolderService,
|
||||
func createFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService dashboards.FolderService,
|
||||
cmd models.CreateFolderCommand, fn scenarioFunc) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
t.Cleanup(bus.ClearBusHandlers)
|
||||
|
||||
hs := HTTPServer{
|
||||
Bus: bus.GetBus(),
|
||||
Cfg: setting.NewCfg(),
|
||||
Bus: bus.GetBus(),
|
||||
Cfg: setting.NewCfg(),
|
||||
folderService: folderService,
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
@@ -156,15 +155,8 @@ func createFolderScenario(t *testing.T, desc string, url string, routePattern st
|
||||
return hs.CreateFolder(c)
|
||||
})
|
||||
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
mockFolderService(mock)
|
||||
|
||||
sc.m.Post(routePattern, sc.defaultHandler)
|
||||
|
||||
defer func() {
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
}()
|
||||
|
||||
fn(sc)
|
||||
})
|
||||
}
|
||||
@@ -173,13 +165,14 @@ func callUpdateFolder(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func updateFolderScenario(t *testing.T, desc string, url string, routePattern string, mock *fakeFolderService,
|
||||
func updateFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService dashboards.FolderService,
|
||||
cmd models.UpdateFolderCommand, fn scenarioFunc) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
hs := HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
Cfg: setting.NewCfg(),
|
||||
folderService: folderService,
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
@@ -192,12 +185,6 @@ func updateFolderScenario(t *testing.T, desc string, url string, routePattern st
|
||||
return hs.UpdateFolder(c)
|
||||
})
|
||||
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
t.Cleanup(func() {
|
||||
dashboards.NewFolderService = origNewFolderService
|
||||
})
|
||||
mockFolderService(mock)
|
||||
|
||||
sc.m.Put(routePattern, sc.defaultHandler)
|
||||
|
||||
fn(sc)
|
||||
@@ -222,35 +209,28 @@ type fakeFolderService struct {
|
||||
DeletedFolderUids []string
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) GetFolders(ctx context.Context, limit int64, page int64) ([]*models.Folder, error) {
|
||||
func (s *fakeFolderService) GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
|
||||
return s.GetFoldersResult, s.GetFoldersError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) GetFolderByID(ctx context.Context, id int64) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
|
||||
return s.GetFolderByIDResult, s.GetFolderByIDError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) GetFolderByUID(ctx context.Context, uid string) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
|
||||
return s.GetFolderByUIDResult, s.GetFolderByUIDError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) CreateFolder(ctx context.Context, title, uid string) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) {
|
||||
return s.CreateFolderResult, s.CreateFolderError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) UpdateFolder(ctx context.Context, existingUID string, cmd *models.UpdateFolderCommand) error {
|
||||
func (s *fakeFolderService) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
|
||||
cmd.Result = s.UpdateFolderResult
|
||||
return s.UpdateFolderError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) DeleteFolder(ctx context.Context, uid string, forceDeleteRules bool) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
|
||||
s.DeletedFolderUids = append(s.DeletedFolderUids, uid)
|
||||
return s.DeleteFolderResult, s.DeleteFolderError
|
||||
}
|
||||
|
||||
func mockFolderService(mock *fakeFolderService) {
|
||||
dashboards.NewFolderService = func(orgId int64, user *models.SignedInUser,
|
||||
dashboardStore dboards.Store) dashboards.FolderService {
|
||||
return mock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/cleanup"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/datasourceproxy"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/encryption"
|
||||
@@ -130,6 +131,9 @@ type HTTPServer struct {
|
||||
authInfoService login.AuthInfoService
|
||||
TeamPermissionsService *resourcepermissions.Service
|
||||
NotificationService *notifications.NotificationService
|
||||
dashboardService dashboards.DashboardService
|
||||
dashboardProvisioningService dashboards.DashboardProvisioningService
|
||||
folderService dashboards.FolderService
|
||||
DatasourcePermissionsService DatasourcePermissionsService
|
||||
}
|
||||
|
||||
@@ -158,7 +162,8 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
dataSourcesService datasources.DataSourceService, secretsService secrets.Service, queryDataService *query.Service,
|
||||
ldapGroups ldap.Groups, teamGuardian teamguardian.TeamGuardian, serviceaccountsService serviceaccounts.Service,
|
||||
authInfoService login.AuthInfoService, resourcePermissionServices *resourceservices.ResourceServices,
|
||||
notificationService *notifications.NotificationService, datasourcePermissionsService DatasourcePermissionsService) (*HTTPServer, error) {
|
||||
notificationService *notifications.NotificationService, dashboardService dashboards.DashboardService, dashboardProvisioningService dashboards.DashboardProvisioningService,
|
||||
folderService dashboards.FolderService, datasourcePermissionsService DatasourcePermissionsService) (*HTTPServer, error) {
|
||||
web.Env = cfg.Env
|
||||
m := web.New()
|
||||
|
||||
@@ -219,6 +224,9 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
authInfoService: authInfoService,
|
||||
TeamPermissionsService: resourcePermissionServices.GetTeamService(),
|
||||
NotificationService: notificationService,
|
||||
dashboardService: dashboardService,
|
||||
dashboardProvisioningService: dashboardProvisioningService,
|
||||
folderService: folderService,
|
||||
DatasourcePermissionsService: datasourcePermissionsService,
|
||||
}
|
||||
if hs.Listener != nil {
|
||||
|
||||
@@ -150,7 +150,7 @@ func TestOrgUsersAPIEndpoint_LegacyAccessControl_FolderAdmin(t *testing.T) {
|
||||
"tags": "prod",
|
||||
}),
|
||||
}
|
||||
folder, err := sc.db.SaveDashboard(cmd)
|
||||
folder, err := sc.dashboardsStore.SaveDashboard(cmd)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, folder)
|
||||
|
||||
@@ -165,7 +165,7 @@ func TestOrgUsersAPIEndpoint_LegacyAccessControl_FolderAdmin(t *testing.T) {
|
||||
Updated: time.Now(),
|
||||
},
|
||||
}
|
||||
err = sc.db.UpdateDashboardACL(context.Background(), folder.Id, acls)
|
||||
err = sc.dashboardsStore.UpdateDashboardACL(context.Background(), folder.Id, acls)
|
||||
require.NoError(t, err)
|
||||
|
||||
response := callAPI(sc.server, http.MethodGet, "/api/org/users/lookup", nil, t)
|
||||
|
||||
Reference in New Issue
Block a user