PublicDashboards: Delete on folder deletion (#99040)
This commit is contained in:
@@ -500,12 +500,6 @@ func (hs *HTTPServer) deleteDashboard(c *contextmodel.ReqContext) response.Respo
|
||||
"error", err)
|
||||
}
|
||||
|
||||
// deletes all related public dashboard entities
|
||||
err = hs.PublicDashboardsApi.PublicDashboardService.DeleteByDashboard(c.Req.Context(), dash)
|
||||
if err != nil {
|
||||
hs.log.Error("Failed to delete public dashboard")
|
||||
}
|
||||
|
||||
err = hs.DashboardService.DeleteDashboard(c.Req.Context(), dash.ID, dash.UID, c.SignedInUser.GetOrgID())
|
||||
if err != nil {
|
||||
var dashboardErr dashboards.DashboardErr
|
||||
|
||||
@@ -272,12 +272,10 @@ func TestHTTPServer_DeleteDashboardByUID_AccessControl(t *testing.T) {
|
||||
hs.LibraryPanelService = &mockLibraryPanelService{}
|
||||
hs.LibraryElementService = &libraryelementsfake.LibraryElementService{}
|
||||
|
||||
pubDashService := publicdashboards.NewFakePublicDashboardService(t)
|
||||
pubDashService.On("DeleteByDashboard", mock.Anything, mock.Anything).Return(nil).Maybe()
|
||||
middleware := publicdashboards.NewFakePublicDashboardMiddleware(t)
|
||||
license := licensingtest.NewFakeLicensing()
|
||||
license.On("FeatureEnabled", publicdashboardModels.FeaturePublicDashboardsEmailSharing).Return(false)
|
||||
hs.PublicDashboardsApi = api.ProvideApi(pubDashService, nil, hs.AccessControl, featuremgmt.WithFeatures(), middleware, hs.Cfg, license)
|
||||
hs.PublicDashboardsApi = api.ProvideApi(nil, nil, hs.AccessControl, featuremgmt.WithFeatures(), middleware, hs.Cfg, license)
|
||||
|
||||
guardian.InitAccessControlGuardian(hs.Cfg, hs.AccessControl, hs.DashboardService, hs.folderService, log.NewNopLogger())
|
||||
})
|
||||
@@ -833,11 +831,11 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
|
||||
quotaService := quotatest.New(false, nil)
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
dashboardStore, folderStore, db, features,
|
||||
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
if dashboardService == nil {
|
||||
dashboardService, err = service.ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore, features, folderPermissions,
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil,
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
dashboardService.(dashboards.PermissionsRegistrationService).RegisterDashboardPermissions(dashboardPermissions)
|
||||
@@ -845,7 +843,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
|
||||
|
||||
dashboardProvisioningService, err := service.ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore, features, folderPermissions,
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil,
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
|
||||
actionSets := resourcepermissions.NewActionSetService(features)
|
||||
fStore := folderimpl.ProvideStore(sc.db)
|
||||
folderServiceWithFlagOn := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
|
||||
folderStore, sc.db, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sc.db, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
acSvc := acimpl.ProvideOSSService(
|
||||
sc.cfg, acdb.ProvideService(sc.db), actionSets, localcache.ProvideService(),
|
||||
features, tracing.InitializeTracerForTest(), zanzana.NewNoopClient(), sc.db, permreg.ProvidePermissionRegistry(), nil, folderServiceWithFlagOn,
|
||||
@@ -472,7 +472,7 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
|
||||
dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl(
|
||||
sc.cfg, dashStore, folderStore,
|
||||
features, folderPermissions, ac,
|
||||
folderServiceWithFlagOn, fStore, nil, nil, nil, nil, quotaSrv, nil,
|
||||
folderServiceWithFlagOn, fStore, nil, nil, nil, nil, quotaSrv, nil, nil,
|
||||
)
|
||||
require.NoError(b, err)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ func ProvideFolderPermissions(
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
fService := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
dashboardStore, folderStore, sqlStore, features,
|
||||
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
acSvc := acimpl.ProvideOSSService(
|
||||
cfg, acdb.ProvideService(sqlStore), actionSets, localcache.ProvideService(),
|
||||
|
||||
@@ -49,9 +49,9 @@ func TestIntegrationAuthorize(t *testing.T) {
|
||||
ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures())
|
||||
folderSvc := folderimpl.ProvideService(fStore, accesscontrolmock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
dashStore, folderStore, sql, featuremgmt.WithFeatures(),
|
||||
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), accesscontrolmock.NewMockedPermissionsService(),
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil, nil)
|
||||
require.NoError(t, err)
|
||||
dashSvc.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
|
||||
ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures())
|
||||
folderSvc := folderimpl.ProvideService(fStore, accesscontrolmock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
dashStore, folderStore, sql, featuremgmt.WithFeatures(),
|
||||
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), accesscontrolmock.NewMockedPermissionsService(),
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil, nil)
|
||||
require.NoError(t, err)
|
||||
dashSvc.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
|
||||
repo := ProvideService(sql, cfg, features, tagService, tracing.InitializeTracerForTest(), ruleStore, dashSvc)
|
||||
@@ -243,9 +243,9 @@ func TestIntegrationAnnotationListingWithInheritedRBAC(t *testing.T) {
|
||||
fStore := folderimpl.ProvideStore(sql)
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sql)
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
|
||||
folderStore, sql, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sql, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, features, accesscontrolmock.NewMockedPermissionsService(),
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil, nil)
|
||||
require.NoError(t, err)
|
||||
dashSvc.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
|
||||
cfg.AnnotationMaximumTagsLength = 60
|
||||
|
||||
@@ -300,7 +300,7 @@ func TestIntegrationDashboardInheritedFolderRBAC(t *testing.T) {
|
||||
})
|
||||
|
||||
folderStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderSvc := folderimpl.ProvideService(folderStore, mock.New(), bus.ProvideBus(tracer), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(sqlStore), sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderSvc := folderimpl.ProvideService(folderStore, mock.New(), bus.ProvideBus(tracer), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(sqlStore), sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
parentUID := ""
|
||||
for i := 0; ; i++ {
|
||||
|
||||
@@ -902,7 +902,7 @@ func TestIntegrationFindDashboardsByTitle(t *testing.T) {
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderServiceWithFlagOn := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
user := &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
@@ -1021,7 +1021,7 @@ func TestIntegrationFindDashboardsByFolder(t *testing.T) {
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
|
||||
folderServiceWithFlagOn := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
user := &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
|
||||
@@ -360,6 +360,11 @@ type DeleteDashboardsInFolderRequest struct {
|
||||
OrgID int64
|
||||
}
|
||||
|
||||
type GetAllDashboardsInFolderRequest struct {
|
||||
FolderUIDs []string
|
||||
OrgID int64
|
||||
}
|
||||
|
||||
//
|
||||
// DASHBOARD ACL
|
||||
//
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/search/model"
|
||||
"github.com/grafana/grafana/pkg/services/store/entity"
|
||||
@@ -71,19 +72,20 @@ var (
|
||||
)
|
||||
|
||||
type DashboardServiceImpl struct {
|
||||
cfg *setting.Cfg
|
||||
log log.Logger
|
||||
dashboardStore dashboards.Store
|
||||
folderStore folder.FolderStore
|
||||
folderService folder.Service
|
||||
userService user.Service
|
||||
orgService org.Service
|
||||
features featuremgmt.FeatureToggles
|
||||
folderPermissions accesscontrol.FolderPermissionsService
|
||||
dashboardPermissions accesscontrol.DashboardPermissionsService
|
||||
ac accesscontrol.AccessControl
|
||||
k8sclient client.K8sHandler
|
||||
metrics *dashboardsMetrics
|
||||
cfg *setting.Cfg
|
||||
log log.Logger
|
||||
dashboardStore dashboards.Store
|
||||
folderStore folder.FolderStore
|
||||
folderService folder.Service
|
||||
userService user.Service
|
||||
orgService org.Service
|
||||
features featuremgmt.FeatureToggles
|
||||
folderPermissions accesscontrol.FolderPermissionsService
|
||||
dashboardPermissions accesscontrol.DashboardPermissionsService
|
||||
ac accesscontrol.AccessControl
|
||||
k8sclient client.K8sHandler
|
||||
metrics *dashboardsMetrics
|
||||
publicDashboardService publicdashboards.ServiceWrapper
|
||||
|
||||
dashboardPermissionsReady chan struct{}
|
||||
}
|
||||
@@ -96,7 +98,7 @@ func ProvideDashboardServiceImpl(
|
||||
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
|
||||
ac accesscontrol.AccessControl, folderSvc folder.Service, fStore folder.Store, r prometheus.Registerer,
|
||||
restConfigProvider apiserver.RestConfigProvider, userService user.Service, unified resource.ResourceClient,
|
||||
quotaService quota.Service, orgService org.Service,
|
||||
quotaService quota.Service, orgService org.Service, publicDashboardService publicdashboards.ServiceWrapper,
|
||||
) (*DashboardServiceImpl, error) {
|
||||
k8sHandler := client.NewK8sHandler(request.GetNamespaceMapper(cfg), v0alpha1.DashboardResourceInfo.GroupVersionResource(), restConfigProvider, unified)
|
||||
|
||||
@@ -114,6 +116,7 @@ func ProvideDashboardServiceImpl(
|
||||
k8sclient: k8sHandler,
|
||||
metrics: newDashboardsMetrics(r),
|
||||
dashboardPermissionsReady: make(chan struct{}),
|
||||
publicDashboardService: publicDashboardService,
|
||||
}
|
||||
|
||||
defaultLimits, err := readQuotaConfig(cfg)
|
||||
@@ -879,7 +882,13 @@ func (dr *DashboardServiceImpl) deleteDashboard(ctx context.Context, dashboardId
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// cleanup things related to dashboards that are not stored in unistore yet
|
||||
err = dr.publicDashboardService.DeleteByDashboardUIDs(ctx, orgId, []string{dashboardUID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dr.dashboardStore.CleanupAfterDelete(ctx, cmd)
|
||||
}
|
||||
|
||||
@@ -894,6 +903,12 @@ func (dr *DashboardServiceImpl) deleteDashboard(ctx context.Context, dashboardId
|
||||
}
|
||||
}
|
||||
|
||||
// deletes all related public dashboard entities
|
||||
err := dr.publicDashboardService.DeleteByDashboardUIDs(ctx, orgId, []string{dashboardUID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dr.dashboardStore.DeleteDashboard(ctx, cmd)
|
||||
}
|
||||
|
||||
@@ -1389,6 +1404,22 @@ func (dr *DashboardServiceImpl) DeleteInFolders(ctx context.Context, orgID int64
|
||||
return dr.dashboardStore.SoftDeleteDashboardsInFolders(ctx, orgID, folderUIDs)
|
||||
}
|
||||
|
||||
// We need a list of dashboard uids inside the folder to delete related public dashboards
|
||||
dashes, err := dr.dashboardStore.FindDashboards(ctx, &dashboards.FindPersistedDashboardsQuery{SignedInUser: u, FolderUIDs: folderUIDs, OrgId: orgID})
|
||||
if err != nil {
|
||||
return folder.ErrInternal.Errorf("failed to fetch dashboards: %w", err)
|
||||
}
|
||||
|
||||
dashboardUIDs := make([]string, 0, len(dashes))
|
||||
for _, dashboard := range dashes {
|
||||
dashboardUIDs = append(dashboardUIDs, dashboard.UID)
|
||||
}
|
||||
|
||||
err = dr.publicDashboardService.DeleteByDashboardUIDs(ctx, orgID, dashboardUIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dr.dashboardStore.DeleteDashboardsInFolders(ctx, &dashboards.DeleteDashboardsInFolderRequest{FolderUIDs: folderUIDs, OrgID: orgID})
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/folder/folderimpl"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
|
||||
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
|
||||
@@ -878,8 +879,9 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
|
||||
folderPermissions := accesscontrolmock.NewMockedPermissionsService()
|
||||
folderPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
folderStore2 := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracer)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), publicDashboardFakeService, cfg, nil, tracer)
|
||||
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
|
||||
dashboardService, err := ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore,
|
||||
@@ -894,6 +896,7 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
dashboardService.RegisterDashboardPermissions(dashboardPermissions)
|
||||
require.NoError(t, err)
|
||||
@@ -950,8 +953,9 @@ func callSaveWithResult(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSt
|
||||
folderPermissions := accesscontrolmock.NewMockedPermissionsService()
|
||||
folderPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
folderStore2 := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracer)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), publicDashboardFakeService, cfg, nil, tracer)
|
||||
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
|
||||
dashboardPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
service, err := ProvideDashboardServiceImpl(
|
||||
@@ -967,6 +971,7 @@ func callSaveWithResult(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSt
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
service.RegisterDashboardPermissions(dashboardPermissions)
|
||||
@@ -985,8 +990,9 @@ func callSaveWithError(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSto
|
||||
require.NoError(t, err)
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
folderStore2 := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracer)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), publicDashboardFakeService, cfg, nil, tracer)
|
||||
service, err := ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore,
|
||||
featuremgmt.WithFeatures(),
|
||||
@@ -1000,6 +1006,7 @@ func callSaveWithError(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSto
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
service.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
|
||||
@@ -1037,8 +1044,9 @@ func saveTestDashboard(t *testing.T, title string, orgID int64, folderUID string
|
||||
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
|
||||
dashboardPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
folderStore2 := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracer)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), publicDashboardFakeService, cfg, nil, tracer)
|
||||
service, err := ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore,
|
||||
features,
|
||||
@@ -1052,6 +1060,7 @@ func saveTestDashboard(t *testing.T, title string, orgID int64, folderUID string
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
service.RegisterDashboardPermissions(dashboardPermissions)
|
||||
@@ -1095,8 +1104,9 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore db.DB) *da
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
folderPermissions := accesscontrolmock.NewMockedPermissionsService()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
folderStore2 := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracer)
|
||||
folderService := folderimpl.ProvideService(folderStore2, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), publicDashboardFakeService, cfg, nil, tracer)
|
||||
folderPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
service, err := ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore,
|
||||
@@ -1111,6 +1121,7 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore db.DB) *da
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
service.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/search/model"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
@@ -35,15 +36,17 @@ import (
|
||||
func TestDashboardService(t *testing.T) {
|
||||
t.Run("Dashboard service tests", func(t *testing.T) {
|
||||
fakeStore := dashboards.FakeDashboardStore{}
|
||||
fakePublicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
defer fakeStore.AssertExpectations(t)
|
||||
|
||||
folderSvc := foldertest.NewFakeService()
|
||||
service := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
log: log.New("test.logger"),
|
||||
dashboardStore: &fakeStore,
|
||||
folderService: folderSvc,
|
||||
features: featuremgmt.WithFeatures(),
|
||||
cfg: setting.NewCfg(),
|
||||
log: log.New("test.logger"),
|
||||
dashboardStore: &fakeStore,
|
||||
folderService: folderSvc,
|
||||
features: featuremgmt.WithFeatures(),
|
||||
publicDashboardService: fakePublicDashboardService,
|
||||
}
|
||||
folderStore := foldertest.FakeFolderStore{}
|
||||
folderStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(nil, dashboards.ErrFolderNotFound).Once()
|
||||
@@ -197,6 +200,7 @@ func TestDashboardService(t *testing.T) {
|
||||
t.Run("DeleteProvisionedDashboard should delete it", func(t *testing.T) {
|
||||
args := &dashboards.DeleteDashboardCommand{OrgID: 1, ID: 1}
|
||||
fakeStore.On("DeleteDashboard", mock.Anything, args).Return(nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
err := service.DeleteProvisionedDashboard(context.Background(), 1, 1)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
@@ -212,6 +216,7 @@ func TestDashboardService(t *testing.T) {
|
||||
t.Run("DeleteProvisionedDashboard should delete the dashboard", func(t *testing.T) {
|
||||
args := &dashboards.DeleteDashboardCommand{OrgID: 1, ID: 1}
|
||||
fakeStore.On("DeleteDashboard", mock.Anything, args).Return(nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
err := service.DeleteProvisionedDashboard(context.Background(), 1, 1)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
@@ -220,6 +225,7 @@ func TestDashboardService(t *testing.T) {
|
||||
args := &dashboards.DeleteDashboardCommand{OrgID: 1, ID: 1}
|
||||
fakeStore.On("DeleteDashboard", mock.Anything, args).Return(nil).Once()
|
||||
fakeStore.On("GetProvisionedDataByDashboardID", mock.Anything, mock.AnythingOfType("int64")).Return(nil, nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
err := service.DeleteDashboard(context.Background(), 1, "", 1)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
@@ -240,6 +246,8 @@ func TestDashboardService(t *testing.T) {
|
||||
t.Run("Delete dashboards in folder", func(t *testing.T) {
|
||||
args := &dashboards.DeleteDashboardsInFolderRequest{OrgID: 1, FolderUIDs: []string{"uid"}}
|
||||
fakeStore.On("DeleteDashboardsInFolders", mock.Anything, args).Return(nil).Once()
|
||||
fakeStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
err := service.DeleteInFolders(context.Background(), 1, []string{"uid"}, nil)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
@@ -775,6 +783,7 @@ func TestGetProvisionedDashboardDataByDashboardUID(t *testing.T) {
|
||||
|
||||
func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
fakeStore := dashboards.FakeDashboardStore{}
|
||||
fakePublicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
defer fakeStore.AssertExpectations(t)
|
||||
service := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
@@ -782,6 +791,7 @@ func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
orgService: &orgtest.FakeOrgService{
|
||||
ExpectedOrgs: []*org.OrgDTO{{ID: 1}, {ID: 2}},
|
||||
},
|
||||
publicDashboardService: fakePublicDashboardService,
|
||||
}
|
||||
|
||||
t.Run("Should fallback to dashboard store if Kubernetes feature flags are not enabled", func(t *testing.T) {
|
||||
@@ -801,6 +811,7 @@ func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
k8sCliMock.On("Delete", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
fakeStore.On("CleanupAfterDelete", mock.Anything, &dashboards.DeleteDashboardCommand{UID: "uid", OrgID: 1}).Return(nil).Once()
|
||||
fakeStore.On("CleanupAfterDelete", mock.Anything, &dashboards.DeleteDashboardCommand{UID: "uid3", OrgID: 2}).Return(nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
k8sCliMock.On("Get", mock.Anything, "uid", mock.Anything, mock.Anything).Return(&unstructured.Unstructured{Object: map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"name": "uid",
|
||||
@@ -1201,16 +1212,20 @@ func TestSaveDashboard(t *testing.T) {
|
||||
|
||||
func TestDeleteDashboard(t *testing.T) {
|
||||
fakeStore := dashboards.FakeDashboardStore{}
|
||||
fakePublicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
defer fakeStore.AssertExpectations(t)
|
||||
service := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
dashboardStore: &fakeStore,
|
||||
cfg: setting.NewCfg(),
|
||||
dashboardStore: &fakeStore,
|
||||
publicDashboardService: fakePublicDashboardService,
|
||||
}
|
||||
|
||||
t.Run("Should fallback to dashboard store if Kubernetes feature flags are not enabled", func(t *testing.T) {
|
||||
service.features = featuremgmt.WithFeatures()
|
||||
fakeStore.On("DeleteDashboard", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
fakeStore.On("GetProvisionedDataByDashboardID", mock.Anything, mock.Anything).Return(nil, nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
|
||||
err := service.DeleteDashboard(context.Background(), 1, "uid", 1)
|
||||
require.NoError(t, err)
|
||||
fakeStore.AssertExpectations(t)
|
||||
@@ -1220,6 +1235,7 @@ func TestDeleteDashboard(t *testing.T) {
|
||||
ctx, k8sCliMock := setupK8sDashboardTests(service)
|
||||
k8sCliMock.On("Delete", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
fakeStore.On("CleanupAfterDelete", mock.Anything, mock.Anything).Return(nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
|
||||
err := service.DeleteDashboard(ctx, 1, "uid", 1)
|
||||
require.NoError(t, err)
|
||||
@@ -1230,6 +1246,7 @@ func TestDeleteDashboard(t *testing.T) {
|
||||
ctx, k8sCliMock := setupK8sDashboardTests(service)
|
||||
k8sCliMock.On("Delete", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
fakeStore.On("CleanupAfterDelete", mock.Anything, mock.Anything).Return(nil).Once()
|
||||
fakePublicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
k8sCliMock.On("Search", mock.Anything, mock.Anything, mock.Anything).Return(&resource.ResourceSearchResponse{
|
||||
Results: &resource.ResourceTable{
|
||||
Columns: []*resource.ResourceTableColumnDefinition{
|
||||
|
||||
@@ -18,6 +18,24 @@ type FakeDashboardStore struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CleanupAfterDelete provides a mock function with given fields: ctx, cmd
|
||||
func (_m *FakeDashboardStore) CleanupAfterDelete(ctx context.Context, cmd *DeleteDashboardCommand) error {
|
||||
ret := _m.Called(ctx, cmd)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CleanupAfterDelete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *DeleteDashboardCommand) error); ok {
|
||||
r0 = rf(ctx, cmd)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Count provides a mock function with given fields: _a0, _a1
|
||||
func (_m *FakeDashboardStore) Count(_a0 context.Context, _a1 *quota.ScopeParameters) (*quota.Map, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
@@ -106,6 +124,24 @@ func (_m *FakeDashboardStore) CountDashboardsInFolders(ctx context.Context, requ
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// DeleteAllDashboards provides a mock function with given fields: ctx, orgID
|
||||
func (_m *FakeDashboardStore) DeleteAllDashboards(ctx context.Context, orgID int64) error {
|
||||
ret := _m.Called(ctx, orgID)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteAllDashboards")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, orgID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteDashboard provides a mock function with given fields: ctx, cmd
|
||||
func (_m *FakeDashboardStore) DeleteDashboard(ctx context.Context, cmd *DeleteDashboardCommand) error {
|
||||
ret := _m.Called(ctx, cmd)
|
||||
@@ -124,42 +160,6 @@ func (_m *FakeDashboardStore) DeleteDashboard(ctx context.Context, cmd *DeleteDa
|
||||
return r0
|
||||
}
|
||||
|
||||
// CleanupAfterDelete provides a mock function with given fields: ctx, cmd
|
||||
func (_m *FakeDashboardStore) CleanupAfterDelete(ctx context.Context, cmd *DeleteDashboardCommand) error {
|
||||
ret := _m.Called(ctx, cmd)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CleanupAfterDelete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *DeleteDashboardCommand) error); ok {
|
||||
r0 = rf(ctx, cmd)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteAllDashboards provides a mock function with given fields: ctx, orgID
|
||||
func (_m *FakeDashboardStore) DeleteAllDashboards(ctx context.Context, orgID int64) error {
|
||||
ret := _m.Called(ctx, orgID)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteDashboard")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, orgID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteDashboardsInFolders provides a mock function with given fields: ctx, request
|
||||
func (_m *FakeDashboardStore) DeleteDashboardsInFolders(ctx context.Context, request *DeleteDashboardsInFolderRequest) error {
|
||||
ret := _m.Called(ctx, request)
|
||||
@@ -256,7 +256,7 @@ func (_m *FakeDashboardStore) GetAllDashboards(ctx context.Context) ([]*Dashboar
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetAllDashboardsByOrgId provides a mock function with given fields: ctx
|
||||
// GetAllDashboardsByOrgId provides a mock function with given fields: ctx, orgID
|
||||
func (_m *FakeDashboardStore) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*Dashboard, error) {
|
||||
ret := _m.Called(ctx, orgID)
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ func TestValidateDashboardExists(t *testing.T) {
|
||||
nil,
|
||||
quotatest.New(false, nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
s := ProvideService(dsStore, secretsService, dashSvc)
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
"github.com/grafana/grafana/pkg/services/store/entity"
|
||||
@@ -46,15 +47,16 @@ import (
|
||||
const FULLPATH_SEPARATOR = "/"
|
||||
|
||||
type Service struct {
|
||||
store folder.Store
|
||||
unifiedStore folder.Store
|
||||
db db.DB
|
||||
log *slog.Logger
|
||||
dashboardStore dashboards.Store
|
||||
dashboardFolderStore folder.FolderStore
|
||||
features featuremgmt.FeatureToggles
|
||||
accessControl accesscontrol.AccessControl
|
||||
k8sclient folderK8sHandler
|
||||
store folder.Store
|
||||
unifiedStore folder.Store
|
||||
db db.DB
|
||||
log *slog.Logger
|
||||
dashboardStore dashboards.Store
|
||||
dashboardFolderStore folder.FolderStore
|
||||
features featuremgmt.FeatureToggles
|
||||
accessControl accesscontrol.AccessControl
|
||||
k8sclient folderK8sHandler
|
||||
publicDashboardService publicdashboards.ServiceWrapper
|
||||
// bus is currently used to publish event in case of folder full path change.
|
||||
// For example when a folder is moved to another folder or when a folder is renamed.
|
||||
bus bus.Bus
|
||||
@@ -74,22 +76,24 @@ func ProvideService(
|
||||
db db.DB, // DB for the (new) nested folder store
|
||||
features featuremgmt.FeatureToggles,
|
||||
supportBundles supportbundles.Service,
|
||||
publicDashboardService publicdashboards.ServiceWrapper,
|
||||
cfg *setting.Cfg,
|
||||
r prometheus.Registerer,
|
||||
tracer tracing.Tracer,
|
||||
) *Service {
|
||||
srv := &Service{
|
||||
log: slog.Default().With("logger", "folder-service"),
|
||||
dashboardStore: dashboardStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: store,
|
||||
features: features,
|
||||
accessControl: ac,
|
||||
bus: bus,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(r),
|
||||
tracer: tracer,
|
||||
log: slog.Default().With("logger", "folder-service"),
|
||||
dashboardStore: dashboardStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: store,
|
||||
features: features,
|
||||
accessControl: ac,
|
||||
bus: bus,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(r),
|
||||
tracer: tracer,
|
||||
publicDashboardService: publicDashboardService,
|
||||
}
|
||||
srv.DBMigration(db)
|
||||
|
||||
@@ -1008,7 +1012,28 @@ func (s *Service) deleteChildrenInFolder(ctx context.Context, orgID int64, folde
|
||||
}
|
||||
|
||||
func (s *Service) legacyDelete(ctx context.Context, cmd *folder.DeleteFolderCommand, folderUIDs []string) error {
|
||||
// if dashboard restore is on we don't delete public dashboards, the hard delete will take care of it later
|
||||
if !s.features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) {
|
||||
// We need a list of dashboard uids inside the folder to delete related public dashboards
|
||||
dashes, err := s.dashboardStore.FindDashboards(ctx, &dashboards.FindPersistedDashboardsQuery{SignedInUser: cmd.SignedInUser, FolderUIDs: folderUIDs, OrgId: cmd.OrgID})
|
||||
if err != nil {
|
||||
return folder.ErrInternal.Errorf("failed to fetch dashboards: %w", err)
|
||||
}
|
||||
|
||||
dashboardUIDs := make([]string, 0, len(dashes))
|
||||
for _, dashboard := range dashes {
|
||||
dashboardUIDs = append(dashboardUIDs, dashboard.UID)
|
||||
}
|
||||
|
||||
// Delete all public dashboards in the folders
|
||||
err = s.publicDashboardService.DeleteByDashboardUIDs(ctx, cmd.OrgID, dashboardUIDs)
|
||||
if err != nil {
|
||||
return folder.ErrInternal.Errorf("failed to delete public dashboards: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO use bulk delete
|
||||
// Delete all dashboards in the folders
|
||||
for _, folderUID := range folderUIDs {
|
||||
// nolint:staticcheck
|
||||
deleteCmd := dashboards.DeleteDashboardCommand{OrgID: cmd.OrgID, UID: folderUID, ForceDeleteFolderRules: cmd.ForceDeleteRules}
|
||||
@@ -1016,6 +1041,7 @@ func (s *Service) legacyDelete(ctx context.Context, cmd *folder.DeleteFolderComm
|
||||
return toFolderError(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
ngstore "github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/store/entity"
|
||||
@@ -64,7 +65,7 @@ func TestIntegrationProvideFolderService(t *testing.T) {
|
||||
db, cfg := db.InitTestDBWithCfg(t)
|
||||
store := ProvideStore(db)
|
||||
ProvideService(store, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), nil, nil, db,
|
||||
featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
|
||||
})
|
||||
@@ -80,7 +81,7 @@ func TestIntegrationFolderService(t *testing.T) {
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
|
||||
folderStore := foldertest.NewFakeFolderStore(t)
|
||||
|
||||
publicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
features := featuremgmt.WithFeatures()
|
||||
|
||||
alertingStore := ngstore.DBstore{
|
||||
@@ -91,17 +92,18 @@ func TestIntegrationFolderService(t *testing.T) {
|
||||
}
|
||||
|
||||
service := &Service{
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardStore: dashStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: nestedFolderStore,
|
||||
features: features,
|
||||
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
db: db,
|
||||
accessControl: acimpl.ProvideAccessControl(features),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardStore: dashStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: nestedFolderStore,
|
||||
publicDashboardService: publicDashboardService,
|
||||
features: features,
|
||||
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
db: db,
|
||||
accessControl: acimpl.ProvideAccessControl(features),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
}
|
||||
|
||||
require.NoError(t, service.RegisterService(alertingStore))
|
||||
@@ -263,11 +265,13 @@ func TestIntegrationFolderService(t *testing.T) {
|
||||
f := folder.NewFolder(util.GenerateShortUID(), "")
|
||||
f.UID = util.GenerateShortUID()
|
||||
folderStore.On("GetFolderByUID", mock.Anything, orgID, f.UID).Return(f, nil)
|
||||
publicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||
|
||||
var actualCmd *dashboards.DeleteDashboardCommand
|
||||
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
||||
actualCmd = args.Get(1).(*dashboards.DeleteDashboardCommand)
|
||||
}).Return(nil).Once()
|
||||
dashStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil).Once()
|
||||
|
||||
expectedForceDeleteRules := rand.Int63()%2 == 0
|
||||
err := service.Delete(context.Background(), &folder.DeleteFolderCommand{
|
||||
@@ -427,22 +431,24 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
dashStore, err := database.ProvideDashboardStore(db, cfg, featuresFlagOn, tagimpl.ProvideService(db))
|
||||
require.NoError(t, err)
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
|
||||
b := bus.ProvideBus(tracing.InitializeTracerForTest())
|
||||
ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures())
|
||||
|
||||
serviceWithFlagOn := &Service{
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardStore: dashStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: nestedFolderStore,
|
||||
features: featuresFlagOn,
|
||||
bus: b,
|
||||
db: db,
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardStore: dashStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: nestedFolderStore,
|
||||
features: featuresFlagOn,
|
||||
bus: b,
|
||||
db: db,
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
publicDashboardService: publicDashboardFakeService,
|
||||
}
|
||||
|
||||
signedInUser := user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{
|
||||
@@ -485,8 +491,9 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
// CanEditValue is required to create library elements
|
||||
CanEditValue: true,
|
||||
})
|
||||
publicDashboardFakeService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOn, folderPermissions, ac, serviceWithFlagOn, nestedFolderStore, nil, nil, nil, nil, quotaService, nil)
|
||||
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOn, folderPermissions, ac, serviceWithFlagOn, nestedFolderStore, nil, nil, nil, nil, quotaService, nil, publicDashboardFakeService)
|
||||
require.NoError(t, err)
|
||||
dashSrv.RegisterDashboardPermissions(dashboardPermissions)
|
||||
|
||||
@@ -548,16 +555,17 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
|
||||
serviceWithFlagOff := &Service{
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardStore: dashStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: nestedFolderStore,
|
||||
features: featuresFlagOff,
|
||||
bus: b,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardStore: dashStore,
|
||||
dashboardFolderStore: folderStore,
|
||||
store: nestedFolderStore,
|
||||
features: featuresFlagOff,
|
||||
bus: b,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
publicDashboardService: publicDashboardFakeService,
|
||||
}
|
||||
|
||||
origNewGuardian := guardian.New
|
||||
@@ -568,8 +576,10 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
CanEditValue: true,
|
||||
})
|
||||
|
||||
publicDashboardFakeService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOff,
|
||||
folderPermissions, ac, serviceWithFlagOff, nestedFolderStore, nil, nil, nil, nil, quotaService, nil)
|
||||
folderPermissions, ac, serviceWithFlagOff, nestedFolderStore, nil, nil, nil, nil, quotaService, nil, publicDashboardFakeService)
|
||||
require.NoError(t, err)
|
||||
dashSrv.RegisterDashboardPermissions(dashboardPermissions)
|
||||
alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOff, db, serviceWithFlagOff, dashSrv, ac, b)
|
||||
@@ -628,14 +638,15 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
t.Run("Should delete folders", func(t *testing.T) {
|
||||
featuresFlagOff := featuremgmt.WithFeatures()
|
||||
serviceWithFlagOff := &Service{
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardFolderStore: folderStore,
|
||||
features: featuresFlagOff,
|
||||
bus: b,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
dashboardFolderStore: folderStore,
|
||||
features: featuresFlagOff,
|
||||
bus: b,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
publicDashboardService: publicDashboardFakeService,
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
@@ -713,8 +724,9 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
tc.service.dashboardStore = dashStore
|
||||
tc.service.store = nestedFolderStore
|
||||
publicDashboardFakeService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, tc.featuresFlag, folderPermissions, ac, tc.service, tc.service.store, nil, nil, nil, nil, quotaService, nil)
|
||||
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, tc.featuresFlag, folderPermissions, ac, tc.service, tc.service.store, nil, nil, nil, nil, quotaService, nil, publicDashboardFakeService)
|
||||
require.NoError(t, err)
|
||||
dashSrv.RegisterDashboardPermissions(dashboardPermissions)
|
||||
|
||||
@@ -1502,6 +1514,7 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) {
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
dashboardService.RegisterDashboardPermissions(dashboardPermissions)
|
||||
|
||||
@@ -586,6 +586,26 @@ func (s *Service) deleteFromApiServer(ctx context.Context, cmd *folder.DeleteFol
|
||||
if alertRulesInFolder > 0 {
|
||||
return folder.ErrFolderNotEmpty.Errorf("folder contains %d alert rules", alertRulesInFolder)
|
||||
}
|
||||
|
||||
// if dashboard restore is on we don't delete public dashboards, the hard delete will take care of it later
|
||||
if !s.features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) {
|
||||
// We need a list of dashboard uids inside the folder to delete related public dashboards
|
||||
dashes, err := s.dashboardStore.FindDashboards(ctx, &dashboards.FindPersistedDashboardsQuery{SignedInUser: cmd.SignedInUser, FolderUIDs: folders, OrgId: cmd.OrgID})
|
||||
if err != nil {
|
||||
return folder.ErrInternal.Errorf("failed to fetch dashboards: %w", err)
|
||||
}
|
||||
|
||||
dashboardUIDs := make([]string, 0, len(dashes))
|
||||
for _, dashboard := range dashes {
|
||||
dashboardUIDs = append(dashboardUIDs, dashboard.UID)
|
||||
}
|
||||
|
||||
// Delete all public dashboards in the folders
|
||||
err = s.publicDashboardService.DeleteByDashboardUIDs(ctx, cmd.OrgID, dashboardUIDs)
|
||||
if err != nil {
|
||||
return folder.ErrInternal.Errorf("failed to delete public dashboards: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = s.unifiedStore.Delete(ctx, folders, cmd.OrgID)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc"
|
||||
clientrest "k8s.io/client-go/rest"
|
||||
@@ -31,6 +32,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
ngstore "github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
@@ -202,18 +204,21 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
|
||||
featuresArr := []any{
|
||||
featuremgmt.FlagKubernetesFoldersServiceV2}
|
||||
features := featuremgmt.WithFeatures(featuresArr...)
|
||||
dashboardStore := dashboards.NewFakeDashboardStore(t)
|
||||
publicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
|
||||
folderService := &Service{
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
unifiedStore: unifiedStore,
|
||||
features: features,
|
||||
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
// db: db,
|
||||
accessControl: acimpl.ProvideAccessControl(features),
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
k8sclient: k8sHandler,
|
||||
log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"),
|
||||
unifiedStore: unifiedStore,
|
||||
features: features,
|
||||
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
accessControl: acimpl.ProvideAccessControl(features),
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
k8sclient: k8sHandler,
|
||||
dashboardStore: dashboardStore,
|
||||
publicDashboardService: publicDashboardService,
|
||||
}
|
||||
|
||||
require.NoError(t, folderService.RegisterService(alertingStore))
|
||||
@@ -345,6 +350,9 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("When deleting folder by uid should not return access denied error - ForceDeleteRules false", func(t *testing.T) {
|
||||
dashboardStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil)
|
||||
publicDashboardService.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
err := folderService.Delete(ctx, &folder.DeleteFolderCommand{
|
||||
UID: "deletefolder",
|
||||
OrgID: orgID,
|
||||
|
||||
@@ -305,7 +305,7 @@ func createDashboard(t *testing.T, sqlStore db.DB, user user.SignedInUser, dash
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
_, err = folderSvc.Create(context.Background(), &folder.CreateFolderCommand{UID: folderUID, SignedInUser: &user, Title: folderUID + "-title"})
|
||||
require.NoError(t, err)
|
||||
service, err := dashboardservice.ProvideDashboardServiceImpl(
|
||||
@@ -319,6 +319,7 @@ func createDashboard(t *testing.T, sqlStore db.DB, user user.SignedInUser, dash
|
||||
nil,
|
||||
quotaService,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
service.RegisterDashboardPermissions(dashboardPermissions)
|
||||
@@ -341,7 +342,7 @@ func createFolder(t *testing.T, sc scenarioContext, title string, folderSvc fold
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore)
|
||||
store := folderimpl.ProvideStore(sc.sqlStore)
|
||||
folderSvc = folderimpl.ProvideService(store, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore,
|
||||
features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
t.Logf("Creating folder with title and UID %q", title)
|
||||
}
|
||||
ctx := identity.WithRequester(context.Background(), &sc.user)
|
||||
@@ -404,12 +405,12 @@ func scenarioWithPanel(t *testing.T, desc string, fn func(t *testing.T, sc scena
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
dashboardService, svcErr := dashboardservice.ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore,
|
||||
features, folderPermissions, ac,
|
||||
folderSvc, fStore,
|
||||
nil, nil, nil, nil, quotaService, nil,
|
||||
nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(t, svcErr)
|
||||
dashboardService.RegisterDashboardPermissions(dashboardPermissions)
|
||||
@@ -470,12 +471,12 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
dashService, dashSvcErr := dashboardservice.ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStore, folderStore,
|
||||
features, folderPermissions, ac,
|
||||
folderSvc, fStore,
|
||||
nil, nil, nil, nil, quotaService, nil,
|
||||
nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(t, dashSvcErr)
|
||||
dashService.RegisterDashboardPermissions(dashboardPermissions)
|
||||
|
||||
@@ -735,7 +735,7 @@ func createDashboard(t *testing.T, sqlStore db.DB, user *user.SignedInUser, dash
|
||||
cfg, dashboardStore, folderStore,
|
||||
features, acmock.NewMockedPermissionsService(), ac,
|
||||
foldertest.NewFakeService(), folder.NewFakeStore(),
|
||||
nil, nil, nil, nil, quotaService, nil,
|
||||
nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
service.RegisterDashboardPermissions(dashPermissionService)
|
||||
@@ -756,7 +756,7 @@ func createFolder(t *testing.T, sc scenarioContext, title string) *folder.Folder
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore)
|
||||
fStore := folderimpl.ProvideStore(sc.sqlStore)
|
||||
s := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore,
|
||||
features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
t.Logf("Creating folder with title and UID %q", title)
|
||||
ctx := identity.WithRequester(context.Background(), sc.user)
|
||||
@@ -832,7 +832,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
||||
cfg, dashStore, folderStore,
|
||||
features, acmock.NewMockedPermissionsService(), ac,
|
||||
folderSvc, folder.NewFakeStore(),
|
||||
nil, nil, nil, nil, quotaService, nil,
|
||||
nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
dashService.RegisterDashboardPermissions(dashPermissionService)
|
||||
@@ -843,7 +843,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
|
||||
folderService := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore,
|
||||
features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService, features, ac)
|
||||
service := LibraryPanelService{
|
||||
|
||||
@@ -1920,7 +1920,7 @@ func createTestEnv(t *testing.T, testConfig string) testEnvironment {
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(fStore, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore,
|
||||
featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
store := store.DBstore{
|
||||
Logger: log,
|
||||
SQLStore: sqlStore,
|
||||
|
||||
@@ -1604,7 +1604,7 @@ func TestProvisiongWithFullpath(t *testing.T) {
|
||||
features := featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)
|
||||
fStore := folderimpl.ProvideStore(sqlStore)
|
||||
folderService := folderimpl.ProvideService(fStore, ac, inProcBus, dashboardStore, folderStore, sqlStore,
|
||||
features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
ruleService := createAlertRuleService(t, folderService)
|
||||
var orgID int64 = 1
|
||||
|
||||
@@ -29,7 +29,7 @@ func SetupFolderService(tb testing.TB, cfg *setting.Cfg, db db.DB, dashboardStor
|
||||
tb.Helper()
|
||||
fStore := folderimpl.ProvideStore(db)
|
||||
return folderimpl.ProvideService(fStore, ac, bus, dashboardStore, folderStore, db,
|
||||
features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
}
|
||||
|
||||
func SetupDashboardService(tb testing.TB, sqlStore db.DB, fs *folderimpl.DashboardFolderStoreImpl, cfg *setting.Cfg) (*dashboardservice.DashboardServiceImpl, dashboards.Store) {
|
||||
@@ -60,7 +60,7 @@ func SetupDashboardService(tb testing.TB, sqlStore db.DB, fs *folderimpl.Dashboa
|
||||
cfg, dashboardStore, fs,
|
||||
features, folderPermissions, ac,
|
||||
foldertest.NewFakeService(), folder.NewFakeStore(),
|
||||
nil, nil, nil, nil, quotaService, nil,
|
||||
nil, nil, nil, nil, quotaService, nil, nil,
|
||||
)
|
||||
require.NoError(tb, err)
|
||||
dashboardService.RegisterDashboardPermissions(dashboardPermissions)
|
||||
|
||||
@@ -325,7 +325,7 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T)
|
||||
dashService, err := service.ProvideDashboardServiceImpl(
|
||||
cfg, dashboardStoreService, folderStore,
|
||||
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), ac,
|
||||
foldertest.NewFakeService(), folder.NewFakeStore(), nil, nil, nil, nil, quotatest.New(false, nil), nil,
|
||||
foldertest.NewFakeService(), folder.NewFakeStore(), nil, nil, nil, nil, quotatest.New(false, nil), nil, nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
dashService.RegisterDashboardPermissions(dashPermissionService)
|
||||
|
||||
@@ -3,6 +3,8 @@ package database
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@@ -10,7 +12,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@@ -256,7 +257,7 @@ func (d *PublicDashboardStoreImpl) Update(ctx context.Context, cmd SavePublicDas
|
||||
return affectedRows, err
|
||||
}
|
||||
|
||||
// Deletes a public dashboard
|
||||
// Delete deletes a public dashboard
|
||||
func (d *PublicDashboardStoreImpl) Delete(ctx context.Context, uid string) (int64, error) {
|
||||
dashboard := &PublicDashboard{Uid: uid}
|
||||
var affectedRows int64
|
||||
@@ -270,17 +271,28 @@ func (d *PublicDashboardStoreImpl) Delete(ctx context.Context, uid string) (int6
|
||||
return affectedRows, err
|
||||
}
|
||||
|
||||
func (d *PublicDashboardStoreImpl) FindByFolder(ctx context.Context, orgId int64, folderUid string) ([]*PublicDashboard, error) {
|
||||
var pubdashes []*PublicDashboard
|
||||
|
||||
err := d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return sess.SQL("SELECT * from dashboard_public WHERE (dashboard_uid, org_id) IN (SELECT uid, org_id FROM dashboard WHERE org_id = ? AND folder_uid = ?)", orgId, folderUid).Find(&pubdashes)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// DeleteByDashboardUIDs deletes public dashboards by dashboard uids
|
||||
func (d *PublicDashboardStoreImpl) DeleteByDashboardUIDs(ctx context.Context, orgId int64, dashboardUIDs []string) error {
|
||||
if len(dashboardUIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pubdashes, nil
|
||||
return d.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
s := strings.Builder{}
|
||||
s.WriteString("DELETE FROM dashboard_public WHERE org_id = ? AND ")
|
||||
s.WriteString(fmt.Sprintf("dashboard_uid IN (%s)", strings.Repeat("?,", len(dashboardUIDs)-1)+"?"))
|
||||
sql := s.String()
|
||||
args := make([]any, 0, len(dashboardUIDs)+2)
|
||||
args = append(args, sql)
|
||||
args = append(args, orgId)
|
||||
for _, dashboardUID := range dashboardUIDs {
|
||||
args = append(args, dashboardUID)
|
||||
}
|
||||
|
||||
_, err := sess.Exec(args...)
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (d *PublicDashboardStoreImpl) GetMetrics(ctx context.Context) (*Metrics, error) {
|
||||
|
||||
@@ -682,48 +682,53 @@ func TestIntegrationDelete(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestFindByFolder(t *testing.T) {
|
||||
t.Run("returns nil when dashboard is not a folder", func(t *testing.T) {
|
||||
sqlStore, cfg := db.InitTestDBWithCfg(t)
|
||||
dashboard := &dashboards.Dashboard{OrgID: 1, UID: "dashboarduid", IsFolder: false}
|
||||
func TestDeleteByDashboardUIDs(t *testing.T) {
|
||||
var sqlStore db.DB
|
||||
var cfg *setting.Cfg
|
||||
var dashboardStore dashboards.Store
|
||||
var publicdashboardStore *PublicDashboardStoreImpl
|
||||
var savedDashboard *dashboards.Dashboard
|
||||
//var savedPublicDashboard *PublicDashboard
|
||||
var err error
|
||||
|
||||
setup := func() {
|
||||
sqlStore, cfg = db.InitTestDBWithCfg(t)
|
||||
dashboardStore, err = dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, "", true)
|
||||
_ = insertPublicDashboard(t, publicdashboardStore, savedDashboard.UID, savedDashboard.OrgID, true, PublicShareType)
|
||||
}
|
||||
|
||||
t.Run("returns nil when dashboardUIDs is empty", func(t *testing.T) {
|
||||
setup()
|
||||
var dashboardUIDs []string
|
||||
store := ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
pubdashes, err := store.FindByFolder(context.Background(), dashboard.OrgID, dashboard.UID)
|
||||
err := store.DeleteByDashboardUIDs(context.Background(), 1, dashboardUIDs)
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, pubdashes)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("returns nil when parameters are empty", func(t *testing.T) {
|
||||
sqlStore, cfg := db.InitTestDBWithCfg(t)
|
||||
store := ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
pubdashes, err := store.FindByFolder(context.Background(), 0, "")
|
||||
t.Run("deletes public dashboards with provided dashboard uids", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
// confirm the pubdash exists
|
||||
pubdash, err := publicdashboardStore.FindByDashboardUid(context.Background(), savedDashboard.OrgID, savedDashboard.UID)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, pubdashes)
|
||||
})
|
||||
assert.NotNil(t, pubdash)
|
||||
|
||||
t.Run("can get all pubdashes for dashboard folder and org", func(t *testing.T) {
|
||||
sqlStore, cfg := db.InitTestDBWithCfg(t)
|
||||
dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
|
||||
dashboardUIDs := []string{savedDashboard.UID}
|
||||
|
||||
// delete the pubdash by dashboard uid
|
||||
err = publicdashboardStore.DeleteByDashboardUIDs(context.Background(), 1, dashboardUIDs)
|
||||
require.NoError(t, err)
|
||||
pubdashStore := ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
// insert folders
|
||||
folder := insertTestDashboard(t, dashboardStore, "This is a folder", 1, "", true, PublicShareType)
|
||||
folder2 := insertTestDashboard(t, dashboardStore, "This is another folder", 1, "", true, PublicShareType)
|
||||
// insert dashboard in a folder
|
||||
dashboard := insertTestDashboard(t, dashboardStore, "Dashboard in a folder", 1, folder.UID, false, PublicShareType)
|
||||
// insert a dashboard in a different folder
|
||||
dashboard2 := insertTestDashboard(t, dashboardStore, "Another Dashboard in a different folder", 1, folder2.UID, false, PublicShareType)
|
||||
|
||||
// create 2 public dashboards
|
||||
pubdash := insertPublicDashboard(t, pubdashStore, dashboard.UID, dashboard.OrgID, true, PublicShareType)
|
||||
_ = insertPublicDashboard(t, pubdashStore, dashboard2.UID, dashboard2.OrgID, true, PublicShareType)
|
||||
|
||||
pubdashes, err := pubdashStore.FindByFolder(context.Background(), folder.OrgID, folder.UID)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// confirm the pubdash was deleted
|
||||
pubdash, err = publicdashboardStore.FindByDashboardUid(context.Background(), savedDashboard.OrgID, savedDashboard.UID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pubdashes, 1)
|
||||
assert.Equal(t, pubdash, pubdashes[0])
|
||||
assert.Nil(t, pubdash)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.36.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.42.2. DO NOT EDIT.
|
||||
|
||||
package publicdashboards
|
||||
|
||||
@@ -27,6 +27,10 @@ type FakePublicDashboardService struct {
|
||||
func (_m *FakePublicDashboardService) Create(ctx context.Context, u *user.SignedInUser, dto *models.SavePublicDashboardDTO) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, u, dto)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Create")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, *models.SavePublicDashboardDTO) (*models.PublicDashboard, error)); ok {
|
||||
@@ -53,6 +57,10 @@ func (_m *FakePublicDashboardService) Create(ctx context.Context, u *user.Signed
|
||||
func (_m *FakePublicDashboardService) Delete(ctx context.Context, uid string, dashboardUid string) error {
|
||||
ret := _m.Called(ctx, uid, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
|
||||
r0 = rf(ctx, uid, dashboardUid)
|
||||
@@ -63,24 +71,14 @@ func (_m *FakePublicDashboardService) Delete(ctx context.Context, uid string, da
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteByDashboard provides a mock function with given fields: ctx, dashboard
|
||||
func (_m *FakePublicDashboardService) DeleteByDashboard(ctx context.Context, dashboard *dashboards.Dashboard) error {
|
||||
ret := _m.Called(ctx, dashboard)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *dashboards.Dashboard) error); ok {
|
||||
r0 = rf(ctx, dashboard)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// ExistsEnabledByAccessToken provides a mock function with given fields: ctx, accessToken
|
||||
func (_m *FakePublicDashboardService) ExistsEnabledByAccessToken(ctx context.Context, accessToken string) (bool, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ExistsEnabledByAccessToken")
|
||||
}
|
||||
|
||||
var r0 bool
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok {
|
||||
@@ -105,6 +103,10 @@ func (_m *FakePublicDashboardService) ExistsEnabledByAccessToken(ctx context.Con
|
||||
func (_m *FakePublicDashboardService) ExistsEnabledByDashboardUid(ctx context.Context, dashboardUid string) (bool, error) {
|
||||
ret := _m.Called(ctx, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ExistsEnabledByDashboardUid")
|
||||
}
|
||||
|
||||
var r0 bool
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok {
|
||||
@@ -129,6 +131,10 @@ func (_m *FakePublicDashboardService) ExistsEnabledByDashboardUid(ctx context.Co
|
||||
func (_m *FakePublicDashboardService) Find(ctx context.Context, uid string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, uid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Find")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.PublicDashboard, error)); ok {
|
||||
@@ -155,6 +161,10 @@ func (_m *FakePublicDashboardService) Find(ctx context.Context, uid string) (*mo
|
||||
func (_m *FakePublicDashboardService) FindAllWithPagination(ctx context.Context, query *models.PublicDashboardListQuery) (*models.PublicDashboardListResponseWithPagination, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindAllWithPagination")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboardListResponseWithPagination
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.PublicDashboardListQuery) (*models.PublicDashboardListResponseWithPagination, error)); ok {
|
||||
@@ -181,6 +191,10 @@ func (_m *FakePublicDashboardService) FindAllWithPagination(ctx context.Context,
|
||||
func (_m *FakePublicDashboardService) FindAnnotations(ctx context.Context, reqDTO models.AnnotationsQueryDTO, accessToken string) ([]models.AnnotationEvent, error) {
|
||||
ret := _m.Called(ctx, reqDTO, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindAnnotations")
|
||||
}
|
||||
|
||||
var r0 []models.AnnotationEvent
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, models.AnnotationsQueryDTO, string) ([]models.AnnotationEvent, error)); ok {
|
||||
@@ -207,6 +221,10 @@ func (_m *FakePublicDashboardService) FindAnnotations(ctx context.Context, reqDT
|
||||
func (_m *FakePublicDashboardService) FindByAccessToken(ctx context.Context, accessToken string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindByAccessToken")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.PublicDashboard, error)); ok {
|
||||
@@ -233,6 +251,10 @@ func (_m *FakePublicDashboardService) FindByAccessToken(ctx context.Context, acc
|
||||
func (_m *FakePublicDashboardService) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, orgId, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindByDashboardUid")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*models.PublicDashboard, error)); ok {
|
||||
@@ -259,6 +281,10 @@ func (_m *FakePublicDashboardService) FindByDashboardUid(ctx context.Context, or
|
||||
func (_m *FakePublicDashboardService) FindDashboard(ctx context.Context, orgId int64, dashboardUid string) (*dashboards.Dashboard, error) {
|
||||
ret := _m.Called(ctx, orgId, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindDashboard")
|
||||
}
|
||||
|
||||
var r0 *dashboards.Dashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*dashboards.Dashboard, error)); ok {
|
||||
@@ -285,6 +311,10 @@ func (_m *FakePublicDashboardService) FindDashboard(ctx context.Context, orgId i
|
||||
func (_m *FakePublicDashboardService) FindEnabledPublicDashboardAndDashboardByAccessToken(ctx context.Context, accessToken string) (*models.PublicDashboard, *dashboards.Dashboard, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindEnabledPublicDashboardAndDashboardByAccessToken")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 *dashboards.Dashboard
|
||||
var r2 error
|
||||
@@ -320,6 +350,10 @@ func (_m *FakePublicDashboardService) FindEnabledPublicDashboardAndDashboardByAc
|
||||
func (_m *FakePublicDashboardService) FindPublicDashboardAndDashboardByAccessToken(ctx context.Context, accessToken string) (*models.PublicDashboard, *dashboards.Dashboard, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindPublicDashboardAndDashboardByAccessToken")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 *dashboards.Dashboard
|
||||
var r2 error
|
||||
@@ -355,6 +389,10 @@ func (_m *FakePublicDashboardService) FindPublicDashboardAndDashboardByAccessTok
|
||||
func (_m *FakePublicDashboardService) GetMetricRequest(ctx context.Context, dashboard *dashboards.Dashboard, publicDashboard *models.PublicDashboard, panelId int64, reqDTO models.PublicDashboardQueryDTO) (dtos.MetricRequest, error) {
|
||||
ret := _m.Called(ctx, dashboard, publicDashboard, panelId, reqDTO)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetMetricRequest")
|
||||
}
|
||||
|
||||
var r0 dtos.MetricRequest
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *dashboards.Dashboard, *models.PublicDashboard, int64, models.PublicDashboardQueryDTO) (dtos.MetricRequest, error)); ok {
|
||||
@@ -379,6 +417,10 @@ func (_m *FakePublicDashboardService) GetMetricRequest(ctx context.Context, dash
|
||||
func (_m *FakePublicDashboardService) GetOrgIdByAccessToken(ctx context.Context, accessToken string) (int64, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetOrgIdByAccessToken")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (int64, error)); ok {
|
||||
@@ -403,6 +445,10 @@ func (_m *FakePublicDashboardService) GetOrgIdByAccessToken(ctx context.Context,
|
||||
func (_m *FakePublicDashboardService) GetPublicDashboardForView(ctx context.Context, accessToken string) (*dtos.DashboardFullWithMeta, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetPublicDashboardForView")
|
||||
}
|
||||
|
||||
var r0 *dtos.DashboardFullWithMeta
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*dtos.DashboardFullWithMeta, error)); ok {
|
||||
@@ -429,6 +475,10 @@ func (_m *FakePublicDashboardService) GetPublicDashboardForView(ctx context.Cont
|
||||
func (_m *FakePublicDashboardService) GetQueryDataResponse(ctx context.Context, skipDSCache bool, reqDTO models.PublicDashboardQueryDTO, panelId int64, accessToken string) (*backend.QueryDataResponse, error) {
|
||||
ret := _m.Called(ctx, skipDSCache, reqDTO, panelId, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetQueryDataResponse")
|
||||
}
|
||||
|
||||
var r0 *backend.QueryDataResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool, models.PublicDashboardQueryDTO, int64, string) (*backend.QueryDataResponse, error)); ok {
|
||||
@@ -455,6 +505,10 @@ func (_m *FakePublicDashboardService) GetQueryDataResponse(ctx context.Context,
|
||||
func (_m *FakePublicDashboardService) NewPublicDashboardAccessToken(ctx context.Context) (string, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for NewPublicDashboardAccessToken")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context) (string, error)); ok {
|
||||
@@ -479,6 +533,10 @@ func (_m *FakePublicDashboardService) NewPublicDashboardAccessToken(ctx context.
|
||||
func (_m *FakePublicDashboardService) NewPublicDashboardUid(ctx context.Context) (string, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for NewPublicDashboardUid")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context) (string, error)); ok {
|
||||
@@ -503,6 +561,10 @@ func (_m *FakePublicDashboardService) NewPublicDashboardUid(ctx context.Context)
|
||||
func (_m *FakePublicDashboardService) Update(ctx context.Context, u *user.SignedInUser, dto *models.SavePublicDashboardDTO) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, u, dto)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Update")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, *models.SavePublicDashboardDTO) (*models.PublicDashboard, error)); ok {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.36.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.42.2. DO NOT EDIT.
|
||||
|
||||
package publicdashboards
|
||||
|
||||
@@ -18,6 +18,10 @@ type FakePublicDashboardServiceWrapper struct {
|
||||
func (_m *FakePublicDashboardServiceWrapper) Delete(ctx context.Context, uid string) error {
|
||||
ret := _m.Called(ctx, uid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, uid)
|
||||
@@ -28,10 +32,32 @@ func (_m *FakePublicDashboardServiceWrapper) Delete(ctx context.Context, uid str
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteByDashboardUIDs provides a mock function with given fields: ctx, orgId, dashboardUIDs
|
||||
func (_m *FakePublicDashboardServiceWrapper) DeleteByDashboardUIDs(ctx context.Context, orgId int64, dashboardUIDs []string) error {
|
||||
ret := _m.Called(ctx, orgId, dashboardUIDs)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteByDashboardUIDs")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, []string) error); ok {
|
||||
r0 = rf(ctx, orgId, dashboardUIDs)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// FindByDashboardUid provides a mock function with given fields: ctx, orgId, dashboardUid
|
||||
func (_m *FakePublicDashboardServiceWrapper) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, orgId, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindByDashboardUid")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*models.PublicDashboard, error)); ok {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.36.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.42.2. DO NOT EDIT.
|
||||
|
||||
package publicdashboards
|
||||
|
||||
@@ -18,6 +18,10 @@ type FakePublicDashboardStore struct {
|
||||
func (_m *FakePublicDashboardStore) Create(ctx context.Context, cmd models.SavePublicDashboardCommand) (int64, error) {
|
||||
ret := _m.Called(ctx, cmd)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Create")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, models.SavePublicDashboardCommand) (int64, error)); ok {
|
||||
@@ -42,6 +46,10 @@ func (_m *FakePublicDashboardStore) Create(ctx context.Context, cmd models.SaveP
|
||||
func (_m *FakePublicDashboardStore) Delete(ctx context.Context, uid string) (int64, error) {
|
||||
ret := _m.Called(ctx, uid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (int64, error)); ok {
|
||||
@@ -62,10 +70,32 @@ func (_m *FakePublicDashboardStore) Delete(ctx context.Context, uid string) (int
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// DeleteByDashboardUIDs provides a mock function with given fields: ctx, orgId, dashboardUIDs
|
||||
func (_m *FakePublicDashboardStore) DeleteByDashboardUIDs(ctx context.Context, orgId int64, dashboardUIDs []string) error {
|
||||
ret := _m.Called(ctx, orgId, dashboardUIDs)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteByDashboardUIDs")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, []string) error); ok {
|
||||
r0 = rf(ctx, orgId, dashboardUIDs)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// ExistsEnabledByAccessToken provides a mock function with given fields: ctx, accessToken
|
||||
func (_m *FakePublicDashboardStore) ExistsEnabledByAccessToken(ctx context.Context, accessToken string) (bool, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ExistsEnabledByAccessToken")
|
||||
}
|
||||
|
||||
var r0 bool
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok {
|
||||
@@ -90,6 +120,10 @@ func (_m *FakePublicDashboardStore) ExistsEnabledByAccessToken(ctx context.Conte
|
||||
func (_m *FakePublicDashboardStore) ExistsEnabledByDashboardUid(ctx context.Context, dashboardUid string) (bool, error) {
|
||||
ret := _m.Called(ctx, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ExistsEnabledByDashboardUid")
|
||||
}
|
||||
|
||||
var r0 bool
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok {
|
||||
@@ -114,6 +148,10 @@ func (_m *FakePublicDashboardStore) ExistsEnabledByDashboardUid(ctx context.Cont
|
||||
func (_m *FakePublicDashboardStore) Find(ctx context.Context, uid string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, uid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Find")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.PublicDashboard, error)); ok {
|
||||
@@ -140,6 +178,10 @@ func (_m *FakePublicDashboardStore) Find(ctx context.Context, uid string) (*mode
|
||||
func (_m *FakePublicDashboardStore) FindAll(ctx context.Context, query *models.PublicDashboardListQuery) (*models.PublicDashboardListResponseWithPagination, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindAll")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboardListResponseWithPagination
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.PublicDashboardListQuery) (*models.PublicDashboardListResponseWithPagination, error)); ok {
|
||||
@@ -166,6 +208,10 @@ func (_m *FakePublicDashboardStore) FindAll(ctx context.Context, query *models.P
|
||||
func (_m *FakePublicDashboardStore) FindByAccessToken(ctx context.Context, accessToken string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindByAccessToken")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.PublicDashboard, error)); ok {
|
||||
@@ -192,6 +238,10 @@ func (_m *FakePublicDashboardStore) FindByAccessToken(ctx context.Context, acces
|
||||
func (_m *FakePublicDashboardStore) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, orgId, dashboardUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindByDashboardUid")
|
||||
}
|
||||
|
||||
var r0 *models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*models.PublicDashboard, error)); ok {
|
||||
@@ -218,6 +268,10 @@ func (_m *FakePublicDashboardStore) FindByDashboardUid(ctx context.Context, orgI
|
||||
func (_m *FakePublicDashboardStore) FindByFolder(ctx context.Context, orgId int64, folderUid string) ([]*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, orgId, folderUid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for FindByFolder")
|
||||
}
|
||||
|
||||
var r0 []*models.PublicDashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, string) ([]*models.PublicDashboard, error)); ok {
|
||||
@@ -244,6 +298,10 @@ func (_m *FakePublicDashboardStore) FindByFolder(ctx context.Context, orgId int6
|
||||
func (_m *FakePublicDashboardStore) GetMetrics(ctx context.Context) (*models.Metrics, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetMetrics")
|
||||
}
|
||||
|
||||
var r0 *models.Metrics
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context) (*models.Metrics, error)); ok {
|
||||
@@ -270,6 +328,10 @@ func (_m *FakePublicDashboardStore) GetMetrics(ctx context.Context) (*models.Met
|
||||
func (_m *FakePublicDashboardStore) GetOrgIdByAccessToken(ctx context.Context, accessToken string) (int64, error) {
|
||||
ret := _m.Called(ctx, accessToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetOrgIdByAccessToken")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (int64, error)); ok {
|
||||
@@ -294,6 +356,10 @@ func (_m *FakePublicDashboardStore) GetOrgIdByAccessToken(ctx context.Context, a
|
||||
func (_m *FakePublicDashboardStore) Update(ctx context.Context, cmd models.SavePublicDashboardCommand) (int64, error) {
|
||||
ret := _m.Called(ctx, cmd)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Update")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, models.SavePublicDashboardCommand) (int64, error)); ok {
|
||||
|
||||
@@ -28,7 +28,6 @@ type Service interface {
|
||||
Create(ctx context.Context, u *user.SignedInUser, dto *SavePublicDashboardDTO) (*PublicDashboard, error)
|
||||
Update(ctx context.Context, u *user.SignedInUser, dto *SavePublicDashboardDTO) (*PublicDashboard, error)
|
||||
Delete(ctx context.Context, uid string, dashboardUid string) error
|
||||
DeleteByDashboard(ctx context.Context, dashboard *dashboards.Dashboard) error
|
||||
|
||||
GetMetricRequest(ctx context.Context, dashboard *dashboards.Dashboard, publicDashboard *PublicDashboard, panelId int64, reqDTO PublicDashboardQueryDTO) (dtos.MetricRequest, error)
|
||||
GetQueryDataResponse(ctx context.Context, skipDSCache bool, reqDTO PublicDashboardQueryDTO, panelId int64, accessToken string) (*backend.QueryDataResponse, error)
|
||||
@@ -46,6 +45,7 @@ type Service interface {
|
||||
type ServiceWrapper interface {
|
||||
FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error)
|
||||
Delete(ctx context.Context, uid string) error
|
||||
DeleteByDashboardUIDs(ctx context.Context, orgId int64, dashboardUIDs []string) error
|
||||
}
|
||||
|
||||
//go:generate mockery --name Store --structname FakePublicDashboardStore --inpackage --filename public_dashboard_store_mock.go
|
||||
@@ -57,9 +57,9 @@ type Store interface {
|
||||
Create(ctx context.Context, cmd SavePublicDashboardCommand) (int64, error)
|
||||
Update(ctx context.Context, cmd SavePublicDashboardCommand) (int64, error)
|
||||
Delete(ctx context.Context, uid string) (int64, error)
|
||||
DeleteByDashboardUIDs(ctx context.Context, orgId int64, dashboardUIDs []string) error
|
||||
|
||||
GetOrgIdByAccessToken(ctx context.Context, accessToken string) (int64, error)
|
||||
FindByFolder(ctx context.Context, orgId int64, folderUid string) ([]*PublicDashboard, error)
|
||||
ExistsEnabledByAccessToken(ctx context.Context, accessToken string) (bool, error)
|
||||
ExistsEnabledByDashboardUid(ctx context.Context, dashboardUid string) (bool, error)
|
||||
GetMetrics(ctx context.Context) (*Metrics, error)
|
||||
|
||||
@@ -459,37 +459,6 @@ func (pd *PublicDashboardServiceImpl) Delete(ctx context.Context, uid string, da
|
||||
return pd.serviceWrapper.Delete(ctx, uid)
|
||||
}
|
||||
|
||||
func (pd *PublicDashboardServiceImpl) DeleteByDashboard(ctx context.Context, dashboard *dashboards.Dashboard) error {
|
||||
ctx, span := tracer.Start(ctx, "publicdashboards.DeleteByDashboard")
|
||||
defer span.End()
|
||||
if dashboard.IsFolder {
|
||||
// get all pubdashes for the folder
|
||||
pubdashes, err := pd.store.FindByFolder(ctx, dashboard.OrgID, dashboard.UID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// delete each pubdash
|
||||
for _, pubdash := range pubdashes {
|
||||
err = pd.serviceWrapper.Delete(ctx, pubdash.Uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
pubdash, err := pd.store.FindByDashboardUid(ctx, dashboard.OrgID, dashboard.UID)
|
||||
if err != nil {
|
||||
return ErrInternalServerError.Errorf("DeleteByDashboard: error finding a public dashboard by dashboard orgId: %d and Uid: %s %w", dashboard.OrgID, dashboard.UID, err)
|
||||
}
|
||||
if pubdash == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pd.serviceWrapper.Delete(ctx, pubdash.Uid)
|
||||
}
|
||||
|
||||
// intervalMS and maxQueryData values are being calculated on the frontend for regular dashboards
|
||||
// we are doing the same for public dashboards but because this access would be public, we need a way to keep this
|
||||
// values inside reasonable bounds to avoid an attack that could hit data sources with a small interval and a big
|
||||
|
||||
@@ -1394,9 +1394,9 @@ func TestPublicDashboardServiceImpl_ListPublicDashboards(t *testing.T) {
|
||||
fStore := folderimpl.ProvideStore(testDB)
|
||||
folderPermissions := acmock.NewMockedPermissionsService()
|
||||
folderStore := folderimpl.ProvideDashboardFolderStore(testDB)
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderStore, testDB, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderStore, testDB, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
dashboardService, err := dashsvc.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), folderPermissions, ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
|
||||
dashboardService, err := dashsvc.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), folderPermissions, ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil, nil)
|
||||
require.NoError(t, err)
|
||||
dashboardService.RegisterDashboardPermissions(&actest.FakePermissionsService{})
|
||||
fakeGuardian := &guardian.FakeDashboardGuardian{
|
||||
@@ -2053,42 +2053,6 @@ func TestPublicDashboardServiceImpl_NewPublicDashboardAccessToken(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteByDashboard(t *testing.T) {
|
||||
t.Run("will return nil when pubdash not found", func(t *testing.T) {
|
||||
store := NewFakePublicDashboardStore(t)
|
||||
pd := &PublicDashboardServiceImpl{store: store, serviceWrapper: ProvideServiceWrapper(store)}
|
||||
dashboard := &dashboards.Dashboard{UID: "1", OrgID: 1, IsFolder: false}
|
||||
store.On("FindByDashboardUid", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
|
||||
err := pd.DeleteByDashboard(context.Background(), dashboard)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run("will delete pubdash when dashboard deleted", func(t *testing.T) {
|
||||
store := NewFakePublicDashboardStore(t)
|
||||
pd := &PublicDashboardServiceImpl{store: store, serviceWrapper: ProvideServiceWrapper(store)}
|
||||
dashboard := &dashboards.Dashboard{UID: "1", OrgID: 1, IsFolder: false}
|
||||
pubdash := &PublicDashboard{Uid: "2", OrgId: 1, DashboardUid: dashboard.UID}
|
||||
store.On("FindByDashboardUid", mock.Anything, mock.Anything, mock.Anything).Return(pubdash, nil)
|
||||
store.On("Delete", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||
|
||||
err := pd.DeleteByDashboard(context.Background(), dashboard)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("will delete pubdashes when dashboard folder deleted", func(t *testing.T) {
|
||||
store := NewFakePublicDashboardStore(t)
|
||||
pd := &PublicDashboardServiceImpl{store: store, serviceWrapper: ProvideServiceWrapper(store)}
|
||||
dashboard := &dashboards.Dashboard{UID: "1", OrgID: 1, IsFolder: true}
|
||||
pubdash1 := &PublicDashboard{Uid: "2", OrgId: 1, DashboardUid: dashboard.UID}
|
||||
pubdash2 := &PublicDashboard{Uid: "3", OrgId: 1, DashboardUid: dashboard.UID}
|
||||
store.On("FindByFolder", mock.Anything, mock.Anything, mock.Anything).Return([]*PublicDashboard{pubdash1, pubdash2}, nil)
|
||||
store.On("Delete", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||
|
||||
err := pd.DeleteByDashboard(context.Background(), dashboard)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGenerateAccessToken(t *testing.T) {
|
||||
accessToken, err := GenerateAccessToken()
|
||||
|
||||
|
||||
@@ -52,3 +52,12 @@ func (pd *PublicDashboardServiceWrapperImpl) Delete(ctx context.Context, uid str
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pd *PublicDashboardServiceWrapperImpl) DeleteByDashboardUIDs(ctx context.Context, orgId int64, dashboardUIDs []string) error {
|
||||
err := pd.store.DeleteByDashboardUIDs(ctx, orgId, dashboardUIDs)
|
||||
if err != nil {
|
||||
return ErrInternalServerError.Errorf("DeleteByDashboardUIDs: failed to delete public dashboards by dashboard UIDs: %v %w", dashboardUIDs, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -493,9 +493,9 @@ func setupEnv(t *testing.T, sqlStore db.DB, cfg *setting.Cfg, b bus.Bus, quotaSe
|
||||
ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures())
|
||||
folderSvc := folderimpl.ProvideService(fStore, acmock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
dashStore, folderStore, sqlStore, featuremgmt.WithFeatures(),
|
||||
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
dashService, err := dashService.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(),
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil)
|
||||
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil, nil)
|
||||
require.NoError(t, err)
|
||||
dashService.RegisterDashboardPermissions(acmock.NewMockedPermissionsService())
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
|
||||
@@ -823,7 +823,7 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol
|
||||
|
||||
fStore := folderimpl.ProvideStore(db)
|
||||
folderSvc := folderimpl.ProvideService(fStore, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
|
||||
folderimpl.ProvideDashboardFolderStore(db), db, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
folderimpl.ProvideDashboardFolderStore(db), db, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
// create parent folder
|
||||
parent, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{
|
||||
|
||||
@@ -80,7 +80,7 @@ func setupBenchMark(b *testing.B, usr user.SignedInUser, features featuremgmt.Fe
|
||||
|
||||
fStore := folderimpl.ProvideStore(store)
|
||||
folderSvc := folderimpl.ProvideService(fStore, mock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(store),
|
||||
store, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
store, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
origNewGuardian := guardian.New
|
||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanViewValue: true, CanSaveValue: true})
|
||||
|
||||
@@ -52,7 +52,7 @@ func TestDirectSQLStats(t *testing.T) {
|
||||
fStore := folderimpl.ProvideStore(db)
|
||||
folderSvc := folderimpl.ProvideService(fStore, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
|
||||
folderimpl.ProvideDashboardFolderStore(db), db, featuremgmt.WithFeatures(),
|
||||
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
|
||||
supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
|
||||
|
||||
// create parent folder
|
||||
|
||||
|
||||
Reference in New Issue
Block a user