Skip to content

Commit

Permalink
Dashboards: Use dashboard service in access control (grafana#99053)
Browse files Browse the repository at this point in the history
  • Loading branch information
toddtreece authored Jan 21, 2025
1 parent 45e2f95 commit 2622449
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 59 deletions.
5 changes: 3 additions & 2 deletions pkg/api/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,14 +836,15 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
if dashboardService == nil {
dashboardService, err = service.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions,
cfg, dashboardStore, folderStore, features, folderPermissions,
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil,
)
require.NoError(t, err)
dashboardService.(dashboards.PermissionsRegistrationService).RegisterDashboardPermissions(dashboardPermissions)
}

dashboardProvisioningService, err := service.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions,
cfg, dashboardStore, folderStore, features, folderPermissions,
ac, folderSvc, fStore, nil, nil, nil, nil, quotaService, nil,
)
require.NoError(t, err)
Expand Down
11 changes: 5 additions & 6 deletions pkg/api/folder_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,18 +469,17 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets)
require.NoError(b, err)

dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets)
require.NoError(b, err)

dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl(
sc.cfg, dashStore, folderStore,
features, folderPermissions, dashboardPermissions, ac,
features, folderPermissions, ac,
folderServiceWithFlagOn, fStore, nil, nil, nil, nil, quotaSrv, nil,
)
require.NoError(b, err)

_, err = ossaccesscontrol.ProvideDashboardPermissions(
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, dashboardSvc, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets, dashboardSvc)
require.NoError(b, err)

starSvc := startest.NewStarServiceFake()
starSvc.ExpectedUserStars = &star.GetUserStarsResult{UserStars: make(map[string]bool)}

Expand Down
2 changes: 2 additions & 0 deletions pkg/server/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import (
"github.com/grafana/grafana/pkg/services/correlations"
"github.com/grafana/grafana/pkg/services/dashboardimport"
dashboardimportservice "github.com/grafana/grafana/pkg/services/dashboardimport/service"
"github.com/grafana/grafana/pkg/services/dashboards"
dashboardstore "github.com/grafana/grafana/pkg/services/dashboards/database"
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
Expand Down Expand Up @@ -295,6 +296,7 @@ var wireBasicSet = wire.NewSet(
featuremgmt.ProvideManagerService,
featuremgmt.ProvideToggles,
dashboardservice.ProvideDashboardServiceImpl,
wire.Bind(new(dashboards.PermissionsRegistrationService), new(*dashboardservice.DashboardServiceImpl)),
dashboardservice.ProvideDashboardService,
dashboardservice.ProvideDashboardProvisioningService,
dashboardservice.ProvideDashboardPluginService,
Expand Down
11 changes: 7 additions & 4 deletions pkg/services/accesscontrol/ossaccesscontrol/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ func registerDashboardRoles(cfg *setting.Cfg, features featuremgmt.FeatureToggle

func ProvideDashboardPermissions(
cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl,
license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service,
license licensing.Licensing, dashboardService dashboards.DashboardService, folderService folder.Service, service accesscontrol.Service,
teamService team.Service, userService user.Service, actionSetService resourcepermissions.ActionSetService,
dashboardPermissionsRegistration dashboards.PermissionsRegistrationService,
) (*DashboardPermissionsService, error) {
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*dashboards.Dashboard, error) {
query := &dashboards.GetDashboardQuery{UID: resourceID, OrgID: orgID}
queryResult, err := dashboardStore.GetDashboard(ctx, query)
queryResult, err := dashboardService.GetDashboard(ctx, query)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -139,7 +140,7 @@ func ProvideDashboardPermissions(
// nolint:staticcheck
if dashboard.FolderUID != "" {
query := &dashboards.GetDashboardQuery{UID: dashboard.FolderUID, OrgID: orgID}
queryResult, err := dashboardStore.GetDashboard(ctx, query)
queryResult, err := dashboardService.GetDashboard(ctx, query)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -176,5 +177,7 @@ func ProvideDashboardPermissions(
if err != nil {
return nil, err
}
return &DashboardPermissionsService{srv}, nil
s := &DashboardPermissionsService{srv}
dashboardPermissionsRegistration.RegisterDashboardPermissions(s)
return s, nil
}
3 changes: 2 additions & 1 deletion pkg/services/annotations/accesscontrol/accesscontrol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ func TestIntegrationAuthorize(t *testing.T) {
folderSvc := folderimpl.ProvideService(fStore, accesscontrolmock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()),
dashStore, folderStore, sql, featuremgmt.WithFeatures(),
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), accesscontrolmock.NewMockedPermissionsService(),
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
require.NoError(t, err)
dashSvc.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())

u := &user.SignedInUser{
UserID: 1,
Expand Down
8 changes: 4 additions & 4 deletions pkg/services/annotations/annotationsimpl/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
folderSvc := folderimpl.ProvideService(fStore, accesscontrolmock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()),
dashStore, folderStore, sql, featuremgmt.WithFeatures(),
supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuremgmt.WithFeatures(), accesscontrolmock.NewMockedPermissionsService(),
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
require.NoError(t, err)

dashSvc.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
repo := ProvideService(sql, cfg, features, tagService, tracing.InitializeTracerForTest(), ruleStore, dashSvc)

dashboard1 := testutil.CreateDashboard(t, sql, cfg, features, dashboards.SaveDashboardCommand{
Expand Down Expand Up @@ -244,10 +244,10 @@ func TestIntegrationAnnotationListingWithInheritedRBAC(t *testing.T) {
folderStore := folderimpl.ProvideDashboardFolderStore(sql)
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
folderStore, sql, features, supportbundlestest.NewFakeBundleService(), cfg, nil, tracing.InitializeTracerForTest())
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, features, accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
dashSvc, err := dashboardsservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, features, accesscontrolmock.NewMockedPermissionsService(),
ac, folderSvc, fStore, nil, nil, nil, nil, quotatest.New(false, nil), nil)
require.NoError(t, err)

dashSvc.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
cfg.AnnotationMaximumTagsLength = 60

store := NewXormStore(cfg, log.New("annotation.test"), sql, tagService)
Expand Down
5 changes: 5 additions & 0 deletions pkg/services/dashboards/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/search/model"
Expand Down Expand Up @@ -39,6 +40,10 @@ type DashboardService interface {
CountDashboardsInOrg(ctx context.Context, orgID int64) (int64, error)
}

type PermissionsRegistrationService interface {
RegisterDashboardPermissions(service accesscontrol.DashboardPermissionsService)
}

// PluginService is a service for operating on plugin dashboards.
type PluginService interface {
GetDashboardsByPluginID(ctx context.Context, query *GetDashboardsByPluginIDQuery) ([]*Dashboard, error)
Expand Down
52 changes: 32 additions & 20 deletions pkg/services/dashboards/service/dashboard_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,33 +95,36 @@ type DashboardServiceImpl struct {
ac accesscontrol.AccessControl
k8sclient client.K8sHandler
metrics *dashboardsMetrics

dashboardPermissionsReady chan struct{}
}

var _ dashboards.PermissionsRegistrationService = (*DashboardServiceImpl)(nil)

// This is the uber service that implements a three smaller services
func ProvideDashboardServiceImpl(
cfg *setting.Cfg, dashboardStore dashboards.Store, folderStore folder.FolderStore,
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService, ac accesscontrol.AccessControl,
folderSvc folder.Service, fStore folder.Store, r prometheus.Registerer,
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,
) (*DashboardServiceImpl, error) {
k8sHandler := client.NewK8sHandler(request.GetNamespaceMapper(cfg), v0alpha1.DashboardResourceInfo.GroupVersionResource(), restConfigProvider, unified)

dashSvc := &DashboardServiceImpl{
cfg: cfg,
log: log.New("dashboard-service"),
dashboardStore: dashboardStore,
features: features,
folderPermissions: folderPermissionsService,
dashboardPermissions: dashboardPermissionsService,
ac: ac,
folderStore: folderStore,
folderService: folderSvc,
orgService: orgService,
userService: userService,
k8sclient: k8sHandler,
metrics: newDashboardsMetrics(r),
cfg: cfg,
log: log.New("dashboard-service"),
dashboardStore: dashboardStore,
features: features,
folderPermissions: folderPermissionsService,
ac: ac,
folderStore: folderStore,
folderService: folderSvc,
orgService: orgService,
userService: userService,
k8sclient: k8sHandler,
metrics: newDashboardsMetrics(r),
dashboardPermissionsReady: make(chan struct{}),
}

defaultLimits, err := readQuotaConfig(cfg)
Expand All @@ -146,6 +149,19 @@ func ProvideDashboardServiceImpl(
return dashSvc, nil
}

func (dr *DashboardServiceImpl) RegisterDashboardPermissions(service accesscontrol.DashboardPermissionsService) {
dr.dashboardPermissions = service
close(dr.dashboardPermissionsReady)
}

func (dr *DashboardServiceImpl) getPermissionsService(isFolder bool) accesscontrol.PermissionsService {
if isFolder {
return dr.folderPermissions
}
<-dr.dashboardPermissionsReady
return dr.dashboardPermissions
}

func (dr *DashboardServiceImpl) Count(ctx context.Context, scopeParams *quota.ScopeParameters) (*quota.Map, error) {
if dr.features.IsEnabledGlobally(featuremgmt.FlagKubernetesCliDashboards) {
u := &quota.Map{}
Expand Down Expand Up @@ -986,11 +1002,7 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
}...)
}

svc := dr.dashboardPermissions
if dash.IsFolder {
svc = dr.folderPermissions
}

svc := dr.getPermissionsService(dash.IsFolder)
if _, err := svc.SetPermissions(ctx, dto.OrgID, dash.UID, permissions...); err != nil {
dr.log.Error("Could not set default permissions", "dashboard", dash.Title, "error", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,6 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
cfg, dashboardStore, folderStore,
featuremgmt.WithFeatures(),
folderPermissions,
dashboardPermissions,
ac,
folderService,
folder.NewFakeStore(),
Expand All @@ -895,6 +894,7 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
quotaService,
nil,
)
dashboardService.RegisterDashboardPermissions(dashboardPermissions)
require.NoError(t, err)
guardian.InitAccessControlGuardian(cfg, ac, dashboardService)

Expand Down Expand Up @@ -957,7 +957,6 @@ func callSaveWithResult(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSt
cfg, dashboardStore, folderStore,
featuremgmt.WithFeatures(),
folderPermissions,
dashboardPermissions,
actest.FakeAccessControl{},
folderService,
folder.NewFakeStore(),
Expand All @@ -969,6 +968,7 @@ func callSaveWithResult(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSt
nil,
)
require.NoError(t, err)
service.RegisterDashboardPermissions(dashboardPermissions)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)

Expand All @@ -990,7 +990,6 @@ func callSaveWithError(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSto
cfg, dashboardStore, folderStore,
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
actest.FakeAccessControl{},
folderService,
folder.NewFakeStore(),
Expand All @@ -1002,6 +1001,7 @@ func callSaveWithError(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSto
nil,
)
require.NoError(t, err)
service.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
_, err = service.SaveDashboard(context.Background(), &dto, false)
return err
}
Expand Down Expand Up @@ -1042,7 +1042,6 @@ func saveTestDashboard(t *testing.T, title string, orgID int64, folderUID string
cfg, dashboardStore, folderStore,
features,
accesscontrolmock.NewMockedPermissionsService(),
dashboardPermissions,
actest.FakeAccessControl{},
folderService,
folder.NewFakeStore(),
Expand All @@ -1054,6 +1053,7 @@ func saveTestDashboard(t *testing.T, title string, orgID int64, folderUID string
nil,
)
require.NoError(t, err)
service.RegisterDashboardPermissions(dashboardPermissions)
res, err := service.SaveDashboard(context.Background(), &dto, false)

require.NoError(t, err)
Expand Down Expand Up @@ -1101,7 +1101,6 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore db.DB) *da
cfg, dashboardStore, folderStore,
featuremgmt.WithFeatures(),
folderPermissions,
accesscontrolmock.NewMockedPermissionsService(),
actest.FakeAccessControl{},
folderService,
folder.NewFakeStore(),
Expand All @@ -1113,6 +1112,7 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore db.DB) *da
nil,
)
require.NoError(t, err)
service.RegisterDashboardPermissions(accesscontrolmock.NewMockedPermissionsService())
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)

Expand Down
17 changes: 16 additions & 1 deletion pkg/services/dashboardsnapshots/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,22 @@ func TestValidateDashboardExists(t *testing.T) {
feats := featuremgmt.WithFeatures()
dashboardStore, err := dashdb.ProvideDashboardStore(sqlStore, cfg, feats, tagimpl.ProvideService(sqlStore))
require.NoError(t, err)
dashSvc, err := dashsvc.ProvideDashboardServiceImpl(cfg, dashboardStore, folderimpl.ProvideDashboardFolderStore(sqlStore), feats, nil, nil, acmock.New(), foldertest.NewFakeService(), folder.NewFakeStore(), nil, nil, nil, nil, quotatest.New(false, nil), nil)
dashSvc, err := dashsvc.ProvideDashboardServiceImpl(
cfg,
dashboardStore,
folderimpl.ProvideDashboardFolderStore(sqlStore),
feats,
nil,
acmock.New(),
foldertest.NewFakeService(),
folder.NewFakeStore(),
nil,
nil,
nil,
nil,
quotatest.New(false, nil),
nil,
)
require.NoError(t, err)
s := ProvideService(dsStore, secretsService, dashSvc)
ctx := context.Background()
Expand Down
14 changes: 8 additions & 6 deletions pkg/services/folder/folderimpl/folder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,9 @@ func TestIntegrationNestedFolderService(t *testing.T) {
CanEditValue: true,
})

dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOn, folderPermissions, dashboardPermissions, 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)
require.NoError(t, err)
dashSrv.RegisterDashboardPermissions(dashboardPermissions)

alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOn, db, serviceWithFlagOn, dashSrv, ac, b)
require.NoError(t, err)
Expand Down Expand Up @@ -568,9 +569,9 @@ func TestIntegrationNestedFolderService(t *testing.T) {
})

dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOff,
folderPermissions, dashboardPermissions, ac, serviceWithFlagOff, nestedFolderStore, nil, nil, nil, nil, quotaService, nil)
folderPermissions, ac, serviceWithFlagOff, nestedFolderStore, nil, nil, nil, nil, quotaService, nil)
require.NoError(t, err)

dashSrv.RegisterDashboardPermissions(dashboardPermissions)
alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOff, db, serviceWithFlagOff, dashSrv, ac, b)
require.NoError(t, err)

Expand Down Expand Up @@ -713,8 +714,10 @@ func TestIntegrationNestedFolderService(t *testing.T) {
tc.service.dashboardStore = dashStore
tc.service.store = nestedFolderStore

dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, tc.featuresFlag, folderPermissions, dashboardPermissions, 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)
require.NoError(t, err)
dashSrv.RegisterDashboardPermissions(dashboardPermissions)

alertStore, err := ngstore.ProvideDBStore(cfg, tc.featuresFlag, db, tc.service, dashSrv, ac, b)
require.NoError(t, err)

Expand Down Expand Up @@ -1490,7 +1493,6 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) {
cfg, dashStore, folderStore,
featuresFlagOn,
acmock.NewMockedPermissionsService(),
dashboardPermissions,
actest.FakeAccessControl{},
serviceWithFlagOn,
nestedFolderStore,
Expand All @@ -1502,7 +1504,7 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) {
nil,
)
require.NoError(t, err)

dashboardService.RegisterDashboardPermissions(dashboardPermissions)
signedInUser := user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{
orgID: {
dashboards.ActionFoldersRead: {},
Expand Down
Loading

0 comments on commit 2622449

Please sign in to comment.