From 8d68159b523f96aadbb8c811d3125577df0a89db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agn=C3=A8s=20Toulet?= <35176601+AgnesToulet@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:34:14 +0100 Subject: [PATCH] Public Dashboards: Disable email-sharing when there is no license (#80887) * PublicDashboards: Disable email-shared dashboards when feature is disabled * fix pubdash creation when it was email-shared * add feature name const in OSS * update doc * Update service.go * fix test & linter * fix test * Update query_test.go * update tests * fix imports * fix doc linter issues * Update docs/sources/administration/enterprise-licensing/_index.md * fix after merge --- .../enterprise-licensing/_index.md | 7 + pkg/api/dashboard.go | 2 +- pkg/api/dashboard_test.go | 6 +- pkg/services/publicdashboards/api/api.go | 8 +- .../publicdashboards/api/common_test.go | 6 +- .../publicdashboards/api/query_test.go | 5 +- .../publicdashboards/models/models.go | 9 +- .../publicdashboards/service/common_test.go | 51 ++++ .../publicdashboards/service/query_test.go | 141 +++-------- .../publicdashboards/service/service.go | 14 ++ .../publicdashboards/service/service_test.go | 223 ++++-------------- 11 files changed, 174 insertions(+), 298 deletions(-) create mode 100644 pkg/services/publicdashboards/service/common_test.go diff --git a/docs/sources/administration/enterprise-licensing/_index.md b/docs/sources/administration/enterprise-licensing/_index.md index 6dd8c9e2f70..5d793097684 100644 --- a/docs/sources/administration/enterprise-licensing/_index.md +++ b/docs/sources/administration/enterprise-licensing/_index.md @@ -196,6 +196,13 @@ The active users limit is turned off immediately. Settings updates at runtime are not affected by an expired license. +#### Email sharing + +External users can't access dashboards shared via email anymore. +These dashboards are now private but you can make them public and accessible to everyone if you want to. + +Grafana keeps your sharing configurations and restores them after you update your license. + ## Grafana Enterprise license restrictions When you become a Grafana Enterprise customer, you receive a license that governs your use of Grafana Enterprise. diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 1462e330b32..03cb854a382 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -98,7 +98,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response return response.Error(http.StatusInternalServerError, "Error while retrieving public dashboards", err) } - if publicDashboard != nil { + if publicDashboard != nil && (hs.License.FeatureEnabled(publicdashboardModels.FeaturePublicDashboardsEmailSharing) || publicDashboard.Share != publicdashboardModels.EmailShareType) { publicDashboardEnabled = publicDashboard.IsEnabled } } diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index 2f41f7b7ad2..4f759ae1009 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -44,6 +44,7 @@ import ( "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/libraryelements/model" "github.com/grafana/grafana/pkg/services/librarypanels" + "github.com/grafana/grafana/pkg/services/licensing/licensingtest" "github.com/grafana/grafana/pkg/services/live" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" @@ -52,6 +53,7 @@ import ( "github.com/grafana/grafana/pkg/services/provisioning" "github.com/grafana/grafana/pkg/services/publicdashboards" "github.com/grafana/grafana/pkg/services/publicdashboards/api" + publicdashboardModels "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/star/startest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" @@ -272,7 +274,9 @@ func TestHTTPServer_DeleteDashboardByUID_AccessControl(t *testing.T) { pubDashService := publicdashboards.NewFakePublicDashboardService(t) pubDashService.On("DeleteByDashboard", mock.Anything, mock.Anything).Return(nil).Maybe() middleware := publicdashboards.NewFakePublicDashboardMiddleware(t) - hs.PublicDashboardsApi = api.ProvideApi(pubDashService, nil, hs.AccessControl, featuremgmt.WithFeatures(), middleware, hs.Cfg) + license := licensingtest.NewFakeLicensing() + license.On("FeatureEnabled", publicdashboardModels.FeaturePublicDashboardsEmailSharing).Return(false) + hs.PublicDashboardsApi = api.ProvideApi(pubDashService, nil, hs.AccessControl, featuremgmt.WithFeatures(), middleware, hs.Cfg, license) guardian.InitAccessControlGuardian(hs.Cfg, hs.AccessControl, hs.DashboardService) }) diff --git a/pkg/services/publicdashboards/api/api.go b/pkg/services/publicdashboards/api/api.go index d65ac5b13e5..2aa8dea58d9 100644 --- a/pkg/services/publicdashboards/api/api.go +++ b/pkg/services/publicdashboards/api/api.go @@ -14,6 +14,7 @@ import ( contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/services/publicdashboards" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/publicdashboards/validation" @@ -28,6 +29,7 @@ type Api struct { accessControl accesscontrol.AccessControl cfg *setting.Cfg features featuremgmt.FeatureToggles + license licensing.Licensing log log.Logger routeRegister routing.RouteRegister } @@ -39,6 +41,7 @@ func ProvideApi( features featuremgmt.FeatureToggles, md publicdashboards.Middleware, cfg *setting.Cfg, + license licensing.Licensing, ) *Api { api := &Api{ PublicDashboardService: pd, @@ -46,6 +49,7 @@ func ProvideApi( accessControl: ac, cfg: cfg, features: features, + license: license, log: log.New("publicdashboards.api"), routeRegister: rr, } @@ -158,8 +162,8 @@ func (api *Api) GetPublicDashboard(c *contextmodel.ReqContext) response.Response return response.Err(err) } - if pd == nil { - response.Err(ErrPublicDashboardNotFound.Errorf("GetPublicDashboard: public dashboard not found")) + if pd == nil || (!api.license.FeatureEnabled(FeaturePublicDashboardsEmailSharing) && pd.Share == EmailShareType) { + return response.Err(ErrPublicDashboardNotFound.Errorf("GetPublicDashboard: public dashboard not found")) } return response.JSON(http.StatusOK, pd) diff --git a/pkg/services/publicdashboards/api/common_test.go b/pkg/services/publicdashboards/api/common_test.go index 7a857bc6f14..5e07e1ecff1 100644 --- a/pkg/services/publicdashboards/api/common_test.go +++ b/pkg/services/publicdashboards/api/common_test.go @@ -26,10 +26,12 @@ import ( "github.com/grafana/grafana/pkg/services/datasources/guardian" datasourceService "github.com/grafana/grafana/pkg/services/datasources/service" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/licensing/licensingtest" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" "github.com/grafana/grafana/pkg/services/publicdashboards" + publicdashboardModels "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/query" fakeSecrets "github.com/grafana/grafana/pkg/services/secrets/fakes" "github.com/grafana/grafana/pkg/services/user" @@ -73,7 +75,9 @@ func setupTestServer( } // build api, this will mount the routes at the same time if the feature is enabled - ProvideApi(service, rr, ac, features, &Middleware{}, cfg) + license := licensingtest.NewFakeLicensing() + license.On("FeatureEnabled", publicdashboardModels.FeaturePublicDashboardsEmailSharing).Return(false) + ProvideApi(service, rr, ac, features, &Middleware{}, cfg, license) // connect routes to mux rr.Register(m.Router) diff --git a/pkg/services/publicdashboards/api/query_test.go b/pkg/services/publicdashboards/api/query_test.go index 7371d036591..b2a456d84e5 100644 --- a/pkg/services/publicdashboards/api/query_test.go +++ b/pkg/services/publicdashboards/api/query_test.go @@ -32,6 +32,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/folder/foldertest" + "github.com/grafana/grafana/pkg/services/licensing/licensingtest" "github.com/grafana/grafana/pkg/services/publicdashboards" publicdashboardsStore "github.com/grafana/grafana/pkg/services/publicdashboards/database" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" @@ -331,7 +332,9 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T) ) require.NoError(t, err) - pds := publicdashboardsService.ProvideService(cfg, store, qds, annotationsService, ac, ws, dashService) + license := licensingtest.NewFakeLicensing() + license.On("FeatureEnabled", FeaturePublicDashboardsEmailSharing).Return(false) + pds := publicdashboardsService.ProvideService(cfg, store, qds, annotationsService, ac, ws, dashService, license) pubdash, err := pds.Create(context.Background(), &user.SignedInUser{}, savePubDashboardCmd) require.NoError(t, err) diff --git a/pkg/services/publicdashboards/models/models.go b/pkg/services/publicdashboards/models/models.go index e646be7f548..676eb96c966 100644 --- a/pkg/services/publicdashboards/models/models.go +++ b/pkg/services/publicdashboards/models/models.go @@ -24,10 +24,11 @@ func (e PublicDashboardErr) Error() string { } const ( - QuerySuccess = "success" - QueryFailure = "failure" - EmailShareType ShareType = "email" - PublicShareType ShareType = "public" + QuerySuccess = "success" + QueryFailure = "failure" + EmailShareType ShareType = "email" + PublicShareType ShareType = "public" + FeaturePublicDashboardsEmailSharing = "publicDashboardsEmailSharing" ) var ( diff --git a/pkg/services/publicdashboards/service/common_test.go b/pkg/services/publicdashboards/service/common_test.go new file mode 100644 index 00000000000..5840346d5a8 --- /dev/null +++ b/pkg/services/publicdashboards/service/common_test.go @@ -0,0 +1,51 @@ +package service + +import ( + "testing" + + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/services/annotations" + "github.com/grafana/grafana/pkg/services/annotations/annotationsimpl" + "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/licensing/licensingtest" + "github.com/grafana/grafana/pkg/services/publicdashboards" + "github.com/grafana/grafana/pkg/services/publicdashboards/database" + . "github.com/grafana/grafana/pkg/services/publicdashboards/models" + "github.com/grafana/grafana/pkg/services/publicdashboards/service/intervalv2" + "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/tag/tagimpl" +) + +func newPublicDashboardServiceImpl( + t *testing.T, + publicDashboardStore publicdashboards.Store, + dashboardService dashboards.DashboardService, + annotationsRepo annotations.Repository, +) (*PublicDashboardServiceImpl, *sqlstore.SQLStore) { + t.Helper() + + sqlStore := sqlstore.InitTestDB(t) + tagService := tagimpl.ProvideService(sqlStore) + if annotationsRepo == nil { + annotationsRepo = annotationsimpl.ProvideService(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagService) + } + + if publicDashboardStore == nil { + publicDashboardStore = database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) + } + serviceWrapper := ProvideServiceWrapper(publicDashboardStore) + + license := licensingtest.NewFakeLicensing() + license.On("FeatureEnabled", FeaturePublicDashboardsEmailSharing).Return(false) + + return &PublicDashboardServiceImpl{ + AnnotationsRepo: annotationsRepo, + log: log.New("test.logger"), + intervalCalculator: intervalv2.NewCalculator(), + dashboardService: dashboardService, + store: publicDashboardStore, + serviceWrapper: serviceWrapper, + license: license, + }, sqlStore +} diff --git a/pkg/services/publicdashboards/service/query_test.go b/pkg/services/publicdashboards/service/query_test.go index f33a3cfaf55..ec1eaa0c21a 100644 --- a/pkg/services/publicdashboards/service/query_test.go +++ b/pkg/services/publicdashboards/service/query_test.go @@ -12,23 +12,17 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/infra/log" dashboard2 "github.com/grafana/grafana/pkg/kinds/dashboard" "github.com/grafana/grafana/pkg/services/annotations" - "github.com/grafana/grafana/pkg/services/annotations/annotationsimpl" "github.com/grafana/grafana/pkg/services/dashboards" dashboardsDB "github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/featuremgmt" . "github.com/grafana/grafana/pkg/services/publicdashboards" - "github.com/grafana/grafana/pkg/services/publicdashboards/database" "github.com/grafana/grafana/pkg/services/publicdashboards/internal" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" - "github.com/grafana/grafana/pkg/services/publicdashboards/service/intervalv2" "github.com/grafana/grafana/pkg/services/query" "github.com/grafana/grafana/pkg/services/quota/quotatest" - "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/tag/tagimpl" - "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/legacydata" "github.com/grafana/grafana/pkg/util" @@ -682,23 +676,14 @@ const ( ) func TestGetQueryDataResponse(t *testing.T) { - sqlStore := sqlstore.InitTestDB(t) - dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) - require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) fakeQueryService := &query.FakeQueryService{} fakeQueryService.On("QueryData", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&backend.QueryDataResponse{}, nil) - fakeDashboardService := &dashboards.FakeDashboardService{} + service.QueryDataService = fakeQueryService - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - intervalCalculator: intervalv2.NewCalculator(), - QueryDataService: fakeQueryService, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } + dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) + require.NoError(t, err) publicDashboardQueryDTO := PublicDashboardQueryDTO{ IntervalMs: int64(1), @@ -748,21 +733,12 @@ func TestFindAnnotations(t *testing.T) { color := "red" name := "annoName" t.Run("will build anonymous user with correct permissions to get annotations", func(t *testing.T) { - sqlStore := sqlstore.InitTestDB(t) - config := setting.NewCfg() - tagService := tagimpl.ProvideService(sqlStore) - annotationsRepo := annotationsimpl.ProvideService(sqlStore, config, featuremgmt.WithFeatures(), tagService) - fakeStore := FakePublicDashboardStore{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")). Return(&PublicDashboard{Uid: "uid1", IsEnabled: true}, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboards.NewDashboard("dash1"), nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, nil) reqDTO := AnnotationsQueryDTO{ From: 1, @@ -807,20 +783,15 @@ func TestFindAnnotations(t *testing.T) { annos := []DashAnnotation{grafanaAnnotation, grafanaTagAnnotation} dashboard := AddAnnotationsToDashboard(t, dash, annos) - annotationsRepo := annotations.FakeAnnotationsRepo{} pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.UID, AnnotationsEnabled: true} - fakeStore := FakePublicDashboardStore{} + annotationsRepo := &annotations.FakeAnnotationsRepo{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, annotationsRepo) annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{ { @@ -870,19 +841,14 @@ func TestFindAnnotations(t *testing.T) { annos := []DashAnnotation{grafanaAnnotation} dashboard := AddAnnotationsToDashboard(t, dash, annos) - annotationsRepo := annotations.FakeAnnotationsRepo{} - fakeStore := FakePublicDashboardStore{} + annotationsRepo := &annotations.FakeAnnotationsRepo{} + fakeStore := &FakePublicDashboardStore{} pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.UID, AnnotationsEnabled: true} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, annotationsRepo) annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{ { @@ -944,19 +910,14 @@ func TestFindAnnotations(t *testing.T) { annos := []DashAnnotation{grafanaAnnotation, queryAnnotation, disabledGrafanaAnnotation} dashboard := AddAnnotationsToDashboard(t, dash, annos) - annotationsRepo := annotations.FakeAnnotationsRepo{} + annotationsRepo := &annotations.FakeAnnotationsRepo{} pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.UID, AnnotationsEnabled: true} - fakeStore := FakePublicDashboardStore{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, annotationsRepo) annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{ { @@ -990,19 +951,13 @@ func TestFindAnnotations(t *testing.T) { }) t.Run("test will return nothing when dashboard has no annotations", func(t *testing.T) { - annotationsRepo := annotations.FakeAnnotationsRepo{} dashboard := dashboards.NewDashboard("dashWithNoAnnotations") pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.UID, AnnotationsEnabled: true} - fakeStore := FakePublicDashboardStore{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, nil) items, err := service.FindAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123") @@ -1028,17 +983,11 @@ func TestFindAnnotations(t *testing.T) { annos := []DashAnnotation{grafanaAnnotation} dashboard := AddAnnotationsToDashboard(t, dash, annos) pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.UID, AnnotationsEnabled: false} - annotationsRepo := annotations.FakeAnnotationsRepo{} - fakeStore := FakePublicDashboardStore{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, nil) items, err := service.FindAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123") @@ -1060,23 +1009,17 @@ func TestFindAnnotations(t *testing.T) { }, } dash := dashboards.NewDashboard("test") - annotationsRepo := annotations.FakeAnnotationsRepo{} + annotationsRepo := &annotations.FakeAnnotationsRepo{} + annotationsRepo.On("Find", mock.Anything, mock.Anything).Return(nil, errors.New("failed")).Maybe() annos := []DashAnnotation{grafanaAnnotation} dash = AddAnnotationsToDashboard(t, dash, annos) pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dash.UID, AnnotationsEnabled: true} - fakeStore := FakePublicDashboardStore{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dash, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } - - annotationsRepo.On("Find", mock.Anything, mock.Anything).Return(nil, errors.New("failed")).Maybe() + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, annotationsRepo) items, err := service.FindAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123") @@ -1099,12 +1042,12 @@ func TestFindAnnotations(t *testing.T) { dashboard := AddAnnotationsToDashboard(t, dash, annos) pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.UID, AnnotationsEnabled: true} - fakeStore := FakePublicDashboardStore{} + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, nil) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - annotationsRepo := annotations.FakeAnnotationsRepo{} + annotationsRepo := &annotations.FakeAnnotationsRepo{} annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{ { ID: 1, @@ -1117,12 +1060,7 @@ func TestFindAnnotations(t *testing.T) { }, }, nil).Maybe() - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - AnnotationsRepo: &annotationsRepo, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, annotationsRepo) items, err := service.FindAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123") @@ -1145,22 +1083,17 @@ func TestFindAnnotations(t *testing.T) { } func TestGetMetricRequest(t *testing.T) { - sqlStore := db.InitTestDB(t) + service, sqlStore := newPublicDashboardServiceImpl(t, nil, nil, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]interface{}{}, nil) + publicDashboard := &PublicDashboard{ Uid: "1", DashboardUid: dashboard.UID, IsEnabled: true, AccessToken: "abc123", } - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - intervalCalculator: intervalv2.NewCalculator(), - } t.Run("will return an error when validation fails", func(t *testing.T) { publicDashboardQueryDTO := PublicDashboardQueryDTO{ @@ -1230,24 +1163,16 @@ func TestGetUniqueDashboardDatasourceUids(t *testing.T) { } func TestBuildMetricRequest(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) + dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) publicDashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]interface{}{}, nil) nonPublicDashboard := insertTestDashboard(t, dashboardStore, "testNonPublicDashie", 1, 0, "", true, []map[string]interface{}{}, nil) - fakeDashboardService := &dashboards.FakeDashboardService{} - fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(publicDashboard, nil) from, to := internal.GetTimeRangeFromDashboard(t, publicDashboard.Data) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - intervalCalculator: intervalv2.NewCalculator(), - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } + fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(publicDashboard, nil) publicDashboardQueryDTO := PublicDashboardQueryDTO{ IntervalMs: int64(10000000), diff --git a/pkg/services/publicdashboards/service/service.go b/pkg/services/publicdashboards/service/service.go index eb8b3fcb0ad..b0aff99150b 100644 --- a/pkg/services/publicdashboards/service/service.go +++ b/pkg/services/publicdashboards/service/service.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/services/publicdashboards" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/publicdashboards/service/intervalv2" @@ -38,6 +39,7 @@ type PublicDashboardServiceImpl struct { ac accesscontrol.AccessControl serviceWrapper publicdashboards.ServiceWrapper dashboardService dashboards.DashboardService + license licensing.Licensing } var LogPrefix = "publicdashboards.service" @@ -56,6 +58,7 @@ func ProvideService( ac accesscontrol.AccessControl, serviceWrapper publicdashboards.ServiceWrapper, dashboardService dashboards.DashboardService, + license licensing.Licensing, ) *PublicDashboardServiceImpl { return &PublicDashboardServiceImpl{ log: log.New(LogPrefix), @@ -67,6 +70,7 @@ func ProvideService( ac: ac, serviceWrapper: serviceWrapper, dashboardService: dashboardService, + license: license, } } @@ -154,6 +158,10 @@ func (pd *PublicDashboardServiceImpl) FindEnabledPublicDashboardAndDashboardByAc return nil, nil, ErrPublicDashboardNotEnabled.Errorf("FindEnabledPublicDashboardAndDashboardByAccessToken: Public dashboard is not enabled accessToken: %s", accessToken) } + if !pd.license.FeatureEnabled(FeaturePublicDashboardsEmailSharing) && pubdash.Share == EmailShareType { + return nil, nil, ErrPublicDashboardNotFound.Errorf("FindEnabledPublicDashboardAndDashboardByAccessToken: Dashboard not found accessToken: %s", accessToken) + } + return pubdash, dash, err } @@ -197,6 +205,12 @@ func (pd *PublicDashboardServiceImpl) Create(ctx context.Context, u *user.Signed } if existingPubdash != nil { + // If there is no license and the public dashboard was email-shared, we should update it to public + if !pd.license.FeatureEnabled(FeaturePublicDashboardsEmailSharing) && existingPubdash.Share == EmailShareType { + dto.Uid = existingPubdash.Uid + dto.PublicDashboard.Share = PublicShareType + return pd.Update(ctx, u, dto) + } return nil, ErrDashboardIsPublic.Errorf("Create: public dashboard for dashboard %s already exists", dto.DashboardUid) } diff --git a/pkg/services/publicdashboards/service/service_test.go b/pkg/services/publicdashboards/service/service_test.go index bf982dcd5d8..6216e926adb 100644 --- a/pkg/services/publicdashboards/service/service_test.go +++ b/pkg/services/publicdashboards/service/service_test.go @@ -16,14 +16,11 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/dashboards" dashboardsDB "github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/featuremgmt" . "github.com/grafana/grafana/pkg/services/publicdashboards" - "github.com/grafana/grafana/pkg/services/publicdashboards/database" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/publicdashboards/service/intervalv2" "github.com/grafana/grafana/pkg/services/publicdashboards/validation" @@ -386,16 +383,11 @@ func TestGetPublicDashboardForView(t *testing.T) { for _, test := range testCases { t.Run(test.Name, func(t *testing.T) { - fakeStore := FakePublicDashboardStore{} - fakeDashboardService := &dashboards.FakeDashboardService{} - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - dashboardService: fakeDashboardService, - } - + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.Anything).Return(test.StoreResp.pd, test.StoreResp.err) + fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(test.StoreResp.d, test.StoreResp.err) + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, nil) dashboardFullWithMeta, err := service.GetPublicDashboardForView(context.Background(), test.AccessToken) if test.ErrResp != nil { @@ -501,15 +493,10 @@ func TestGetPublicDashboard(t *testing.T) { for _, test := range testCases { t.Run(test.Name, func(t *testing.T) { fakeDashboardService := &dashboards.FakeDashboardService{} - fakeStore := FakePublicDashboardStore{} - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - dashboardService: fakeDashboardService, - } - - fakeStore.On("FindByAccessToken", mock.Anything, mock.Anything).Return(test.StoreResp.pd, test.StoreResp.err) fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(test.StoreResp.d, test.StoreResp.err) + fakeStore := &FakePublicDashboardStore{} + fakeStore.On("FindByAccessToken", mock.Anything, mock.Anything).Return(test.StoreResp.pd, test.StoreResp.err) + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, nil) pdc, dash, err := service.FindPublicDashboardAndDashboardByAccessToken(context.Background(), test.AccessToken) if test.ErrResp != nil { @@ -568,16 +555,11 @@ func TestGetEnabledPublicDashboard(t *testing.T) { for _, test := range testCases { t.Run(test.Name, func(t *testing.T) { - fakeStore := FakePublicDashboardStore{} - fakeDashboardService := &dashboards.FakeDashboardService{} - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: &fakeStore, - dashboardService: fakeDashboardService, - } - + fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.Anything).Return(test.StoreResp.pd, test.StoreResp.err) + fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(test.StoreResp.d, test.StoreResp.err) + service, _ := newPublicDashboardServiceImpl(t, fakeStore, fakeDashboardService, nil) pdc, dash, err := service.FindEnabledPublicDashboardAndDashboardByAccessToken(context.Background(), test.AccessToken) if test.ErrResp != nil { @@ -600,24 +582,15 @@ func TestGetEnabledPublicDashboard(t *testing.T) { // the correct order is convoluted. func TestCreatePublicDashboard(t *testing.T) { t.Run("Create public dashboard", func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) + quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled, annotationsEnabled, timeSelectionEnabled := true, false, true dto := &SavePublicDashboardDTO{ @@ -690,23 +663,14 @@ func TestCreatePublicDashboard(t *testing.T) { for _, tt := range testCases { t.Run(fmt.Sprintf("Create public dashboard with %s null boolean fields stores them as false", tt.Name), func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - dto := &SavePublicDashboardDTO{ DashboardUid: dashboard.UID, UserId: 7, @@ -731,24 +695,14 @@ func TestCreatePublicDashboard(t *testing.T) { } t.Run("Validate pubdash has default time setting value", func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled := true dto := &SavePublicDashboardDTO{ DashboardUid: dashboard.UID, @@ -768,24 +722,16 @@ func TestCreatePublicDashboard(t *testing.T) { }) t.Run("Creates pubdash whose dashboard has template variables successfully", func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) + templateVars := make([]map[string]any, 1) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, templateVars, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled := true dto := &SavePublicDashboardDTO{ DashboardUid: dashboard.UID, @@ -823,14 +769,7 @@ func TestCreatePublicDashboard(t *testing.T) { fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - serviceWrapper := ProvideServiceWrapper(publicDashboardStore) - - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicDashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, publicDashboardStore, fakeDashboardService, nil) isEnabled := true dto := &SavePublicDashboardDTO{ @@ -849,23 +788,14 @@ func TestCreatePublicDashboard(t *testing.T) { }) t.Run("Create public dashboard with given pubdash uid", func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled := true dto := &SavePublicDashboardDTO{ @@ -905,14 +835,7 @@ func TestCreatePublicDashboard(t *testing.T) { publicDashboardStore.On("FindByDashboardUid", mock.Anything, mock.Anything, mock.Anything).Return(nil, ErrPublicDashboardNotFound.Errorf("")) fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - serviceWrapper := ProvideServiceWrapper(publicDashboardStore) - - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicDashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } + service, _ := newPublicDashboardServiceImpl(t, publicDashboardStore, fakeDashboardService, nil) isEnabled := true dto := &SavePublicDashboardDTO{ @@ -931,23 +854,14 @@ func TestCreatePublicDashboard(t *testing.T) { }) t.Run("Create public dashboard with given pubdash access token", func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]interface{}{}, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled := true dto := &SavePublicDashboardDTO{ @@ -981,14 +895,7 @@ func TestCreatePublicDashboard(t *testing.T) { publicDashboardStore := &FakePublicDashboardStore{} publicDashboardStore.On("FindByAccessToken", mock.Anything, mock.Anything).Return(pubdash, nil) - - serviceWrapper := ProvideServiceWrapper(publicDashboardStore) - - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicDashboardStore, - serviceWrapper: serviceWrapper, - } + service, _ := newPublicDashboardServiceImpl(t, publicDashboardStore, nil, nil) _, err := service.NewPublicDashboardAccessToken(context.Background()) require.Error(t, err) @@ -996,25 +903,16 @@ func TestCreatePublicDashboard(t *testing.T) { }) t.Run("Returns error if public dashboard exists", func(t *testing.T) { - sqlStore := db.InitTestDB(t) - dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) - require.NoError(t, err) - - dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - publicdashboardStore := &FakePublicDashboardStore{} publicdashboardStore.On("FindByDashboardUid", mock.Anything, mock.Anything, mock.Anything).Return(&PublicDashboard{Uid: "newPubdashUid"}, nil) publicdashboardStore.On("Find", mock.Anything, mock.Anything).Return(nil, nil) fakeDashboardService := &dashboards.FakeDashboardService{} - fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) + service, sqlStore := newPublicDashboardServiceImpl(t, publicdashboardStore, fakeDashboardService, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } + dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) + require.NoError(t, err) + dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) + fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) isEnabled, annotationsEnabled := true, false dto := &SavePublicDashboardDTO{ @@ -1033,23 +931,15 @@ func TestCreatePublicDashboard(t *testing.T) { }) t.Run("Validate pubdash has default share value", func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) + quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled := true dto := &SavePublicDashboardDTO{ DashboardUid: dashboard.UID, @@ -1079,22 +969,15 @@ func assertFalseIfNull(t *testing.T, expectedValue bool, nullableValue *bool) { } func TestUpdatePublicDashboard(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) + quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) dashboard2 := insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, "", true, []map[string]any{}, nil) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } t.Run("Updating public dashboard", func(t *testing.T) { isEnabled, annotationsEnabled, timeSelectionEnabled := true, false, false @@ -1269,23 +1152,15 @@ func TestUpdatePublicDashboard(t *testing.T) { for _, tt := range testCases { t.Run(fmt.Sprintf("Update public dashboard with %s null boolean fields let those fields with old persisted value", tt.Name), func(t *testing.T) { - sqlStore := db.InitTestDB(t) + fakeDashboardService := &dashboards.FakeDashboardService{} + service, sqlStore := newPublicDashboardServiceImpl(t, nil, fakeDashboardService, nil) + quotaService := quotatest.New(false, nil) dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - publicdashboardStore := database.ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures()) - serviceWrapper := ProvideServiceWrapper(publicdashboardStore) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, "", true, []map[string]any{}, nil) - fakeDashboardService := &dashboards.FakeDashboardService{} fakeDashboardService.On("GetDashboard", mock.Anything, mock.Anything, mock.Anything).Return(dashboard, nil) - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: publicdashboardStore, - serviceWrapper: serviceWrapper, - dashboardService: fakeDashboardService, - } - isEnabled, annotationsEnabled, timeSelectionEnabled := true, true, false dto := &SavePublicDashboardDTO{ @@ -1398,15 +1273,7 @@ func TestDeletePublicDashboard(t *testing.T) { if tt.ExpectedErrResp == nil || tt.mockDeleteStore.StoreRespErr != nil { store.On("Delete", mock.Anything, mock.Anything).Return(tt.mockDeleteStore.AffectedRowsResp, tt.mockDeleteStore.StoreRespErr) } - serviceWrapper := &PublicDashboardServiceWrapperImpl{ - log: log.New("test.logger"), - store: store, - } - service := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: store, - serviceWrapper: serviceWrapper, - } + service, _ := newPublicDashboardServiceImpl(t, store, nil, nil) err := service.Delete(context.Background(), "pubdashUID", "uid") if tt.ExpectedErrResp != nil { @@ -1623,12 +1490,8 @@ func TestPublicDashboardServiceImpl_ListPublicDashboards(t *testing.T) { store := NewFakePublicDashboardStore(t) store.On("FindAllWithPagination", mock.Anything, mock.Anything). Return(tt.mockResponse.PublicDashboardListResponseWithPagination, tt.mockResponse.Err) - - pd := &PublicDashboardServiceImpl{ - log: log.New("test.logger"), - store: store, - ac: ac, - } + pd, _ := newPublicDashboardServiceImpl(t, store, nil, nil) + pd.ac = ac got, err := pd.FindAllWithPagination(tt.args.ctx, tt.args.query) if !tt.wantErr(t, err, fmt.Sprintf("FindAllWithPagination(%v, %v)", tt.args.ctx, tt.args.query)) {