diff --git a/pkg/services/publicdashboards/api/query_test.go b/pkg/services/publicdashboards/api/query_test.go index 27b80eeb167..b92f142a1e0 100644 --- a/pkg/services/publicdashboards/api/query_test.go +++ b/pkg/services/publicdashboards/api/query_test.go @@ -334,7 +334,7 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T) license := licensingtest.NewFakeLicensing() license.On("FeatureEnabled", FeaturePublicDashboardsEmailSharing).Return(false) - pds := publicdashboardsService.ProvideService(cfg, store, qds, annotationsService, ac, ws, dashService, license) + pds := publicdashboardsService.ProvideService(cfg, featuremgmt.WithFeatures(), 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/service/common_test.go b/pkg/services/publicdashboards/service/common_test.go index 5840346d5a8..f5492324dde 100644 --- a/pkg/services/publicdashboards/service/common_test.go +++ b/pkg/services/publicdashboards/service/common_test.go @@ -47,5 +47,6 @@ func newPublicDashboardServiceImpl( store: publicDashboardStore, serviceWrapper: serviceWrapper, license: license, + features: featuremgmt.WithFeatures(), }, sqlStore } diff --git a/pkg/services/publicdashboards/service/query.go b/pkg/services/publicdashboards/service/query.go index 1857d33c236..5c9465e279f 100644 --- a/pkg/services/publicdashboards/service/query.go +++ b/pkg/services/publicdashboards/service/query.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/publicdashboards/validation" "github.com/grafana/grafana/pkg/services/user" @@ -36,7 +37,7 @@ func (pd *PublicDashboardServiceImpl) FindAnnotations(ctx context.Context, reqDT return nil, models.ErrInternalServerError.Errorf("FindAnnotations: failed to unmarshal dashboard annotations: %w", err) } - anonymousUser := buildAnonymousUser(ctx, dash) + anonymousUser := buildAnonymousUser(ctx, dash, pd.features) uniqueEvents := make(map[int64]models.AnnotationEvent, 0) for _, anno := range annoDto.Annotations.List { @@ -138,7 +139,7 @@ func (pd *PublicDashboardServiceImpl) GetQueryDataResponse(ctx context.Context, return nil, models.ErrPanelQueriesNotFound.Errorf("GetQueryDataResponse: failed to extract queries from panel") } - anonymousUser := buildAnonymousUser(ctx, dashboard) + anonymousUser := buildAnonymousUser(ctx, dashboard, pd.features) res, err := pd.QueryDataService.QueryData(ctx, anonymousUser, skipDSCache, metricReq) reqDatasources := metricReq.GetUniqueDatasourceTypes() @@ -180,7 +181,7 @@ func (pd *PublicDashboardServiceImpl) buildMetricRequest(dashboard *dashboards.D } // buildAnonymousUser creates a user with permissions to read from all datasources used in the dashboard -func buildAnonymousUser(ctx context.Context, dashboard *dashboards.Dashboard) *user.SignedInUser { +func buildAnonymousUser(ctx context.Context, dashboard *dashboards.Dashboard, features featuremgmt.FeatureToggles) *user.SignedInUser { datasourceUids := getUniqueDashboardDatasourceUids(dashboard.Data) // Create a user with blank permissions @@ -204,8 +205,12 @@ func buildAnonymousUser(ctx context.Context, dashboard *dashboards.Dashboard) *u permissions := make(map[string][]string) permissions[datasources.ActionQuery] = queryScopes permissions[datasources.ActionRead] = readScopes - permissions[accesscontrol.ActionAnnotationsRead] = annotationScopes permissions[dashboards.ActionDashboardsRead] = dashboardScopes + permissions[accesscontrol.ActionAnnotationsRead] = annotationScopes + + if features.IsEnabled(ctx, featuremgmt.FlagAnnotationPermissionUpdate) { + permissions[accesscontrol.ActionAnnotationsRead] = dashboardScopes + } anonymousUser.Permissions[dashboard.OrgID] = permissions diff --git a/pkg/services/publicdashboards/service/query_test.go b/pkg/services/publicdashboards/service/query_test.go index ec1eaa0c21a..89012138375 100644 --- a/pkg/services/publicdashboards/service/query_test.go +++ b/pkg/services/publicdashboards/service/query_test.go @@ -732,6 +732,7 @@ func TestGetQueryDataResponse(t *testing.T) { func TestFindAnnotations(t *testing.T) { color := "red" name := "annoName" + features := featuremgmt.WithFeatures(featuremgmt.FlagAnnotationPermissionUpdate) t.Run("will build anonymous user with correct permissions to get annotations", func(t *testing.T) { fakeStore := &FakePublicDashboardStore{} fakeStore.On("FindByAccessToken", mock.Anything, mock.AnythingOfType("string")). @@ -747,7 +748,7 @@ func TestFindAnnotations(t *testing.T) { dash := dashboards.NewDashboard("testDashboard") items, _ := service.FindAnnotations(context.Background(), reqDTO, "abc123") - anonUser := buildAnonymousUser(context.Background(), dash) + anonUser := buildAnonymousUser(context.Background(), dash, features) assert.Equal(t, "dashboards:*", anonUser.Permissions[0]["dashboards:read"][0]) assert.Len(t, items, 0) @@ -1323,9 +1324,10 @@ func TestBuildAnonymousUser(t *testing.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]interface{}{}, nil) + features := featuremgmt.WithFeatures() t.Run("will add datasource read and query permissions to user for each datasource in dashboard", func(t *testing.T) { - user := buildAnonymousUser(context.Background(), dashboard) + user := buildAnonymousUser(context.Background(), dashboard, features) require.Equal(t, dashboard.OrgID, user.OrgID) require.Equal(t, "datasources:uid:ds1", user.Permissions[user.OrgID]["datasources:query"][0]) @@ -1334,12 +1336,20 @@ func TestBuildAnonymousUser(t *testing.T) { require.Equal(t, "datasources:uid:ds3", user.Permissions[user.OrgID]["datasources:read"][1]) }) t.Run("will add dashboard and annotation permissions needed for getting annotations", func(t *testing.T) { - user := buildAnonymousUser(context.Background(), dashboard) + user := buildAnonymousUser(context.Background(), dashboard, features) require.Equal(t, dashboard.OrgID, user.OrgID) require.Equal(t, "annotations:type:dashboard", user.Permissions[user.OrgID]["annotations:read"][0]) require.Equal(t, "dashboards:*", user.Permissions[user.OrgID]["dashboards:read"][0]) }) + t.Run("will add dashboard and annotation permissions needed for getting annotations when FlagAnnotationPermissionUpdate is enabled", func(t *testing.T) { + features = featuremgmt.WithFeatures(featuremgmt.FlagAnnotationPermissionUpdate) + user := buildAnonymousUser(context.Background(), dashboard, features) + + require.Equal(t, dashboard.OrgID, user.OrgID) + require.Equal(t, "dashboards:*", user.Permissions[user.OrgID]["annotations:read"][0]) + require.Equal(t, "dashboards:*", user.Permissions[user.OrgID]["dashboards:read"][0]) + }) } func TestGroupQueriesByPanelId(t *testing.T) { diff --git a/pkg/services/publicdashboards/service/service.go b/pkg/services/publicdashboards/service/service.go index b0aff99150b..4df8e849cd1 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/featuremgmt" "github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/services/publicdashboards" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" @@ -32,6 +33,7 @@ import ( type PublicDashboardServiceImpl struct { log log.Logger cfg *setting.Cfg + features featuremgmt.FeatureToggles store publicdashboards.Store intervalCalculator intervalv2.Calculator QueryDataService query.Service @@ -52,6 +54,7 @@ var _ publicdashboards.Service = (*PublicDashboardServiceImpl)(nil) // builds the service, and api, and configures routes func ProvideService( cfg *setting.Cfg, + features featuremgmt.FeatureToggles, store publicdashboards.Store, qds query.Service, anno annotations.Repository, @@ -63,6 +66,7 @@ func ProvideService( return &PublicDashboardServiceImpl{ log: log.New(LogPrefix), cfg: cfg, + features: features, store: store, intervalCalculator: intervalv2.NewCalculator(), QueryDataService: qds,