RBAC: cascaded nested folder permissions for search v2 (#62608)

* fetch inherited folder scopes for search v2

* fix error and don't fetch parents for the general folder

* remove feature toggle check and lower log level
This commit is contained in:
Ieva 2023-02-06 17:38:15 +00:00 committed by GitHub
parent 161ff6d310
commit 49ccae7489
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 14 deletions

View File

@ -104,7 +104,7 @@ func TestIntegrationPluginManager(t *testing.T) {
pg := postgres.ProvideService(cfg)
my := mysql.ProvideService(cfg, hcp)
ms := mssql.ProvideService(cfg)
sv2 := searchV2.ProvideService(cfg, db.InitTestDB(t), nil, nil, tracer, features, nil, nil, nil)
sv2 := searchV2.ProvideService(cfg, db.InitTestDB(t), nil, nil, tracer, features, nil, nil, nil, nil)
graf := grafanads.ProvideService(sv2, nil)
phlare := phlare.ProvideService(hcp)
parca := parca.ProvideService(hcp)

View File

@ -86,7 +86,7 @@ var (
func service(t *testing.T) *StandardSearchService {
service, ok := ProvideService(&setting.Cfg{Search: setting.SearchSettings{}},
nil, nil, accesscontrolmock.New(), tracing.InitializeTracerForTest(), featuremgmt.WithFeatures(),
nil, nil, nil).(*StandardSearchService)
nil, nil, nil, nil).(*StandardSearchService)
require.True(t, ok)
return service
}

View File

@ -4,8 +4,10 @@ import (
"context"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/sqlstore/permissions"
"github.com/grafana/grafana/pkg/services/user"
)
@ -15,28 +17,41 @@ type ResourceFilter func(kind entityKind, uid, parentUID string) bool
// FutureAuthService eventually implemented by the security service
type FutureAuthService interface {
GetDashboardReadFilter(user *user.SignedInUser) (ResourceFilter, error)
GetDashboardReadFilter(ctx context.Context, orgID int64, user *user.SignedInUser) (ResourceFilter, error)
}
var _ FutureAuthService = (*simpleAuthService)(nil)
type simpleAuthService struct {
sql db.DB
ac accesscontrol.Service
sql db.DB
ac accesscontrol.Service
folderService folder.Service
logger log.Logger
}
type dashIdQueryResult struct {
UID string `xorm:"uid"`
}
func (a *simpleAuthService) GetDashboardReadFilter(user *user.SignedInUser) (ResourceFilter, error) {
func (a *simpleAuthService) GetDashboardReadFilter(ctx context.Context, orgID int64, user *user.SignedInUser) (ResourceFilter, error) {
if !a.ac.IsDisabled() {
canReadDashboard, canReadFolder := accesscontrol.Checker(user, dashboards.ActionDashboardsRead), accesscontrol.Checker(user, dashboards.ActionFoldersRead)
return func(kind entityKind, uid, parent string) bool {
if kind == entityKindFolder {
return canReadFolder(dashboards.ScopeFoldersProvider.GetResourceScopeUID(uid))
scopes, err := dashboards.GetInheritedScopes(ctx, orgID, uid, a.folderService)
if err != nil {
a.logger.Debug("could not retrieve inherited folder scopes:", "err", err)
}
scopes = append(scopes, dashboards.ScopeFoldersProvider.GetResourceScopeUID(uid))
return canReadFolder(scopes...)
} else if kind == entityKindDashboard {
return canReadDashboard(dashboards.ScopeDashboardsProvider.GetResourceScopeUID(uid), dashboards.ScopeFoldersProvider.GetResourceScopeUID(parent))
scopes, err := dashboards.GetInheritedScopes(ctx, orgID, parent, a.folderService)
if err != nil {
a.logger.Debug("could not retrieve inherited folder scopes:", "err", err)
}
scopes = append(scopes, dashboards.ScopeDashboardsProvider.GetResourceScopeUID(uid))
scopes = append(scopes, dashboards.ScopeFoldersProvider.GetResourceScopeUID(parent))
return canReadDashboard(scopes...)
}
return false
}, nil

View File

@ -16,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/querylibrary"
"github.com/grafana/grafana/pkg/services/store"
@ -84,15 +85,18 @@ func (s *StandardSearchService) IsReady(ctx context.Context, orgId int64) IsSear
func ProvideService(cfg *setting.Cfg, sql db.DB, entityEventStore store.EntityEventsService,
ac accesscontrol.Service, tracer tracing.Tracer, features featuremgmt.FeatureToggles, orgService org.Service,
userService user.Service, queries querylibrary.Service) SearchService {
userService user.Service, queries querylibrary.Service, folderService folder.Service) SearchService {
extender := &NoopExtender{}
logger := log.New("searchV2")
s := &StandardSearchService{
cfg: cfg,
sql: sql,
ac: ac,
auth: &simpleAuthService{
sql: sql,
ac: ac,
sql: sql,
ac: ac,
folderService: folderService,
logger: logger,
},
dashboardIndex: newSearchIndex(
newSQLDashboardLoader(sql, tracer, cfg.Search),
@ -103,7 +107,7 @@ func ProvideService(cfg *setting.Cfg, sql db.DB, entityEventStore store.EntityEv
features,
cfg.Search,
),
logger: log.New("searchV2"),
logger: logger,
extender: extender,
reIndexCh: make(chan struct{}, 1),
orgService: orgService,
@ -244,7 +248,7 @@ func (s *StandardSearchService) doDashboardQuery(ctx context.Context, signedInUs
rsp := &backend.DataResponse{}
filter, err := s.auth.GetDashboardReadFilter(signedInUser)
filter, err := s.auth.GetDashboardReadFilter(ctx, orgID, signedInUser)
if err != nil {
dashboardSearchFailureRequestsCounter.With(prometheus.Labels{
"reason": "get_dashboard_filter_error",

View File

@ -39,7 +39,7 @@ func setupBenchEnv(b *testing.B, folderCount, dashboardsPerFolder int) (*Standar
}
querySvc := querylibraryimpl.ProvideService(cfg, features)
searchService, ok := ProvideService(cfg, sqlStore, store.NewDummyEntityEventsService(), actest.FakeService{},
tracing.InitializeTracerForTest(), features, orgSvc, nil, querySvc).(*StandardSearchService)
tracing.InitializeTracerForTest(), features, orgSvc, nil, querySvc, nil).(*StandardSearchService)
require.True(b, ok)
err = runSearchService(searchService)