RBAC: Add scope resolvers for dashboards (#50110)

* Inject access control into dashboard service

* Add function to parse id scopes

* Add dashboard as return value

* Update mock

* Return only err to keep service interface

* Add scope resolvers for dashboard id scopes

* Add function to parse uid scopes

* Add dashboard uid scope resolver

* Register scope resolvers for dashboards

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
pull/50291/head
Karl Persson 3 years ago committed by GitHub
parent 9f6afb3475
commit c4a75f9eb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 66
      pkg/api/common_test.go
  2. 5
      pkg/api/dashboard_permission_test.go
  3. 10
      pkg/api/dashboard_test.go
  4. 3
      pkg/api/folder_permission_test.go
  5. 6
      pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go
  6. 21
      pkg/services/accesscontrol/scope.go
  7. 69
      pkg/services/dashboards/accesscontrol.go
  8. 93
      pkg/services/dashboards/accesscontrol_test.go
  9. 2
      pkg/services/dashboards/dashboard.go
  10. 6
      pkg/services/dashboards/database/database.go
  11. 10
      pkg/services/dashboards/database/database_test.go
  12. 10
      pkg/services/dashboards/service/dashboard_service.go
  13. 37
      pkg/services/dashboards/service/dashboard_service_integration_test.go
  14. 2
      pkg/services/dashboards/service/folder_service.go
  15. 14
      pkg/services/dashboards/service/folder_service_test.go
  16. 19
      pkg/services/dashboards/store_mock.go
  17. 11
      pkg/services/libraryelements/libraryelements_test.go
  18. 9
      pkg/services/librarypanels/librarypanels_test.go
  19. 2
      pkg/services/ngalert/tests/util.go

@ -362,28 +362,12 @@ func setupHTTPServerWithCfgDb(t *testing.T, useFakeAccessControl, enableAccessCo
db.Cfg.RBACEnabled = false
}
var acmock *accesscontrolmock.Mock
dashboardsStore := dashboardsstore.ProvideDashboardStore(db)
license := &licensing.OSSLicensingService{}
routeRegister := routing.NewRouteRegister()
dashboardsStore := dashboardsstore.ProvideDashboardStore(db)
// Create minimal HTTP Server
hs := &HTTPServer{
Cfg: cfg,
Features: features,
Live: newTestLive(t, db),
QuotaService: &quota.QuotaService{Cfg: cfg},
RouteRegister: routeRegister,
SQLStore: store,
License: &licensing.OSSLicensingService{},
searchUsersService: searchusers.ProvideUsersService(db, filters.ProvideOSSSearchUserFilter()),
dashboardService: dashboardservice.ProvideDashboardService(
cfg, dashboardsStore, nil, features,
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
),
preferenceService: preftest.NewPreferenceServiceFake(),
}
var acmock *accesscontrolmock.Mock
var ac accesscontrol.AccessControl
// Defining the accesscontrol service has to be done before registering routes
if useFakeAccessControl {
@ -391,24 +375,38 @@ func setupHTTPServerWithCfgDb(t *testing.T, useFakeAccessControl, enableAccessCo
if !enableAccessControl {
acmock = acmock.WithDisabled()
}
hs.AccessControl = acmock
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, acmock, database.ProvideService(db), hs.License)
require.NoError(t, err)
hs.teamPermissionsService = teamPermissionService
ac = acmock
} else {
ac, errInitAc := ossaccesscontrol.ProvideService(hs.Features, hs.Cfg, database.ProvideService(db), routing.NewRouteRegister())
require.NoError(t, errInitAc)
hs.AccessControl = ac
// Perform role registration
err := hs.declareFixedRoles()
require.NoError(t, err)
err = ac.RegisterFixedRoles(context.Background())
require.NoError(t, err)
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, ac, database.ProvideService(db), hs.License)
var err error
ac, err = ossaccesscontrol.ProvideService(features, cfg, database.ProvideService(db), routeRegister)
require.NoError(t, err)
hs.teamPermissionsService = teamPermissionService
}
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, ac, database.ProvideService(db), license)
require.NoError(t, err)
// Create minimal HTTP Server
hs := &HTTPServer{
Cfg: cfg,
Features: features,
Live: newTestLive(t, db),
QuotaService: &quota.QuotaService{Cfg: cfg},
RouteRegister: routeRegister,
SQLStore: store,
License: &licensing.OSSLicensingService{},
AccessControl: ac,
teamPermissionsService: teamPermissionService,
searchUsersService: searchusers.ProvideUsersService(db, filters.ProvideOSSSearchUserFilter()),
dashboardService: dashboardservice.ProvideDashboardService(
cfg, dashboardsStore, nil, features,
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(), ac,
),
preferenceService: preftest.NewPreferenceServiceFake(),
}
require.NoError(t, hs.declareFixedRoles())
require.NoError(t, hs.AccessControl.(accesscontrol.RoleRegistry).RegisterFixedRoles(context.Background()))
// Instantiate a new Server
m := web.New()

@ -26,11 +26,12 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
t.Run("Dashboard permissions test", func(t *testing.T) {
settings := setting.NewCfg()
dashboardStore := &dashboards.FakeDashboardStore{}
dashboardStore.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Return(nil)
dashboardStore.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Return(nil, nil)
defer dashboardStore.AssertExpectations(t)
features := featuremgmt.WithFeatures()
mockSQLStore := mockstore.NewSQLStoreMock()
ac := accesscontrolmock.New()
folderPermissions := accesscontrolmock.NewMockedPermissionsService()
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
@ -39,7 +40,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
SQLStore: mockSQLStore,
Features: features,
dashboardService: dashboardservice.ProvideDashboardService(
settings, dashboardStore, nil, features, folderPermissions, dashboardPermissions,
settings, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac,
),
AccessControl: accesscontrolmock.New().WithDisabled(),
}

@ -953,10 +953,16 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
libraryPanelsService := mockLibraryPanelService{}
libraryElementsService := mockLibraryElementService{}
cfg := setting.NewCfg()
ac := accesscontrolmock.New()
folderPermissions := accesscontrolmock.NewMockedPermissionsService()
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
features := featuremgmt.WithFeatures()
if dashboardService == nil {
dashboardService = service.ProvideDashboardService(cfg, dashboardStore, nil, features, nil, accesscontrolmock.NewMockedPermissionsService())
dashboardService = service.ProvideDashboardService(
cfg, dashboardStore, nil, features,
folderPermissions, dashboardPermissions, ac,
)
}
hs := &HTTPServer{
@ -969,7 +975,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
AccessControl: accesscontrolmock.New(),
dashboardProvisioningService: service.ProvideDashboardService(
cfg, dashboardStore, nil, features,
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
folderPermissions, dashboardPermissions, ac,
),
dashboardService: dashboardService,
}

@ -32,6 +32,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
defer dashboardStore.AssertExpectations(t)
features := featuremgmt.WithFeatures()
ac := accesscontrolmock.New()
folderPermissions := accesscontrolmock.NewMockedPermissionsService()
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
@ -42,7 +43,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
folderPermissionsService: folderPermissions,
dashboardPermissionsService: dashboardPermissions,
dashboardService: service.ProvideDashboardService(
settings, dashboardStore, nil, features, folderPermissions, dashboardPermissions,
settings, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac,
),
AccessControl: accesscontrolmock.New().WithDisabled(),
}

@ -113,7 +113,7 @@ func ProvideDashboardPermissions(
) (*DashboardPermissionsService, error) {
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*models.Dashboard, error) {
query := &models.GetDashboardQuery{Uid: resourceID, OrgId: orgID}
if err := dashboardStore.GetDashboard(ctx, query); err != nil {
if _, err := dashboardStore.GetDashboard(ctx, query); err != nil {
return nil, err
}
return query.Result, nil
@ -142,7 +142,7 @@ func ProvideDashboardPermissions(
}
if dashboard.FolderId > 0 {
query := &models.GetDashboardQuery{Id: dashboard.FolderId, OrgId: orgID}
if err := dashboardStore.GetDashboard(ctx, query); err != nil {
if _, err := dashboardStore.GetDashboard(ctx, query); err != nil {
return nil, err
}
return []string{dashboards.ScopeFoldersProvider.GetResourceScopeUID(query.Result.Uid)}, nil
@ -196,7 +196,7 @@ func ProvideFolderPermissions(
ResourceAttribute: "uid",
ResourceValidator: func(ctx context.Context, orgID int64, resourceID string) error {
query := &models.GetDashboardQuery{Uid: resourceID, OrgId: orgID}
if err := dashboardStore.GetDashboard(ctx, query); err != nil {
if _, err := dashboardStore.GetDashboard(ctx, query); err != nil {
return err
}

@ -2,6 +2,7 @@ package accesscontrol
import (
"fmt"
"strconv"
"strings"
)
@ -9,6 +10,26 @@ const (
maxPrefixParts = 2
)
func ParseScopeID(scope string) (int64, error) {
id, err := strconv.ParseInt(ScopeSuffix(scope), 10, 64)
if err != nil {
return 0, ErrInvalidScope
}
return id, nil
}
func ParseScopeUID(scope string) (string, error) {
uid := ScopeSuffix(scope)
if len(uid) == 0 {
return "", ErrInvalidScope
}
return uid, nil
}
func ScopeSuffix(scope string) string {
return scope[len(ScopePrefix(scope)):]
}
func GetResourceScope(resource string, resourceID string) string {
return Scope(resource, "id", resourceID)
}

@ -2,9 +2,9 @@ package dashboards
import (
"context"
"strconv"
"strings"
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
)
@ -64,9 +64,9 @@ func NewFolderIDScopeResolver(db Store) (string, ac.ScopeAttributeResolver) {
return nil, ac.ErrInvalidScope
}
id, err := strconv.ParseInt(scope[len(prefix):], 10, 64)
id, err := ac.ParseScopeID(scope)
if err != nil {
return nil, ac.ErrInvalidScope
return nil, err
}
if id == 0 {
@ -81,3 +81,66 @@ func NewFolderIDScopeResolver(db Store) (string, ac.ScopeAttributeResolver) {
return []string{ScopeFoldersProvider.GetResourceScopeUID(folder.Uid)}, nil
})
}
// NewDashboardIDScopeResolver provides an ScopeAttributeResolver that is able to convert a scope prefixed with "dashboards:id:"
// into uid based scopes for both dashboard and folder
func NewDashboardIDScopeResolver(db Store) (string, ac.ScopeAttributeResolver) {
prefix := ScopeDashboardsProvider.GetResourceScope("")
return prefix, ac.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
if !strings.HasPrefix(scope, prefix) {
return nil, ac.ErrInvalidScope
}
id, err := ac.ParseScopeID(scope)
if err != nil {
return nil, err
}
dashboard, err := db.GetDashboard(ctx, &models.GetDashboardQuery{Id: id, OrgId: orgID})
if err != nil {
return nil, err
}
return resolveDashboardScope(ctx, db, orgID, dashboard)
})
}
// NewDashboardUIDScopeResolver provides an ScopeAttributeResolver that is able to convert a scope prefixed with "dashboards:uid:"
// into uid based scopes for both dashboard and folder
func NewDashboardUIDScopeResolver(db Store) (string, ac.ScopeAttributeResolver) {
prefix := ScopeDashboardsProvider.GetResourceScopeUID("")
return prefix, ac.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
if !strings.HasPrefix(scope, prefix) {
return nil, ac.ErrInvalidScope
}
uid, err := ac.ParseScopeUID(scope)
if err != nil {
return nil, err
}
dashboard, err := db.GetDashboard(ctx, &models.GetDashboardQuery{Uid: uid, OrgId: orgID})
if err != nil {
return nil, err
}
return resolveDashboardScope(ctx, db, orgID, dashboard)
})
}
func resolveDashboardScope(ctx context.Context, db Store, orgID int64, dashboard *models.Dashboard) ([]string, error) {
var folderUID string
if dashboard.FolderId == 0 {
folderUID = ac.GeneralFolderUID
} else {
folder, err := db.GetFolderByID(ctx, orgID, dashboard.FolderId)
if err != nil {
return nil, err
}
folderUID = folder.Uid
}
return []string{
ScopeDashboardsProvider.GetResourceScopeUID(dashboard.Uid),
ScopeFoldersProvider.GetResourceScopeUID(folderUID),
}, nil
}

@ -144,3 +144,96 @@ func TestNewFolderIDScopeResolver(t *testing.T) {
require.Nil(t, resolvedScopes)
})
}
func TestNewDashboardIDScopeResolver(t *testing.T) {
t.Run("prefix should be expected", func(t *testing.T) {
prefix, _ := NewDashboardIDScopeResolver(&FakeDashboardStore{})
require.Equal(t, "dashboards:id:", prefix)
})
t.Run("resolver should convert to uid dashboard and folder scope", func(t *testing.T) {
store := &FakeDashboardStore{}
_, resolver := NewDashboardIDScopeResolver(store)
orgID := rand.Int63()
folder := &models.Folder{Id: 2, Uid: "2"}
dashboard := &models.Dashboard{Id: 1, FolderId: folder.Id, Uid: "1"}
store.On("GetDashboard", mock.Anything, mock.Anything).Return(dashboard, nil).Once()
store.On("GetFolderByID", mock.Anything, orgID, folder.Id).Return(folder, nil).Once()
scope := ac.Scope("dashboards", "id", strconv.FormatInt(dashboard.Id, 10))
resolvedScopes, err := resolver.Resolve(context.Background(), orgID, scope)
require.NoError(t, err)
require.Len(t, resolvedScopes, 2)
require.Equal(t, fmt.Sprintf("dashboards:uid:%s", dashboard.Uid), resolvedScopes[0])
require.Equal(t, fmt.Sprintf("folders:uid:%s", folder.Uid), resolvedScopes[1])
})
t.Run("resolver should fail if input scope is not expected", func(t *testing.T) {
_, resolver := NewDashboardIDScopeResolver(&FakeDashboardStore{})
_, err := resolver.Resolve(context.Background(), rand.Int63(), "dashboards:uid:123")
require.ErrorIs(t, err, ac.ErrInvalidScope)
})
t.Run("resolver should convert folderID 0 to general uid scope for the folder scope", func(t *testing.T) {
store := &FakeDashboardStore{}
_, resolver := NewDashboardIDScopeResolver(store)
dashboard := &models.Dashboard{Id: 1, FolderId: 0, Uid: "1"}
store.On("GetDashboard", mock.Anything, mock.Anything).Return(dashboard, nil)
resolved, err := resolver.Resolve(context.Background(), 1, ac.Scope("dashboards", "id", "1"))
require.NoError(t, err)
require.Len(t, resolved, 2)
require.Equal(t, "dashboards:uid:1", resolved[0])
require.Equal(t, "folders:uid:general", resolved[1])
})
}
func TestNewDashboardUIDScopeResolver(t *testing.T) {
t.Run("prefix should be expected", func(t *testing.T) {
prefix, _ := NewDashboardUIDScopeResolver(&FakeDashboardStore{})
require.Equal(t, "dashboards:uid:", prefix)
})
t.Run("resolver should convert to uid dashboard and folder scope", func(t *testing.T) {
store := &FakeDashboardStore{}
_, resolver := NewDashboardUIDScopeResolver(store)
orgID := rand.Int63()
folder := &models.Folder{Id: 2, Uid: "2"}
dashboard := &models.Dashboard{Id: 1, FolderId: folder.Id, Uid: "1"}
store.On("GetDashboard", mock.Anything, mock.Anything).Return(dashboard, nil).Once()
store.On("GetFolderByID", mock.Anything, orgID, folder.Id).Return(folder, nil).Once()
scope := ac.Scope("dashboards", "uid", dashboard.Uid)
resolvedScopes, err := resolver.Resolve(context.Background(), orgID, scope)
require.NoError(t, err)
require.Len(t, resolvedScopes, 2)
require.Equal(t, fmt.Sprintf("dashboards:uid:%s", dashboard.Uid), resolvedScopes[0])
require.Equal(t, fmt.Sprintf("folders:uid:%s", folder.Uid), resolvedScopes[1])
})
t.Run("resolver should fail if input scope is not expected", func(t *testing.T) {
_, resolver := NewDashboardUIDScopeResolver(&FakeDashboardStore{})
_, err := resolver.Resolve(context.Background(), rand.Int63(), "dashboards:id:123")
require.ErrorIs(t, err, ac.ErrInvalidScope)
})
t.Run("resolver should convert folderID 0 to general uid scope for the folder scope", func(t *testing.T) {
store := &FakeDashboardStore{}
_, resolver := NewDashboardUIDScopeResolver(store)
dashboard := &models.Dashboard{Id: 1, FolderId: 0, Uid: "1"}
store.On("GetDashboard", mock.Anything, mock.Anything).Return(dashboard, nil)
resolved, err := resolver.Resolve(context.Background(), 1, ac.Scope("dashboards", "uid", "1"))
require.NoError(t, err)
require.Len(t, resolved, 2)
require.Equal(t, "dashboards:uid:1", resolved[0])
require.Equal(t, "folders:uid:general", resolved[1])
})
}

@ -53,7 +53,7 @@ type Store interface {
DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error
DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *models.DeleteOrphanedProvisionedDashboardsCommand) error
FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error)
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) (*models.Dashboard, error)
GetDashboardAclInfoList(ctx context.Context, query *models.GetDashboardAclInfoListQuery) error
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error

@ -832,8 +832,8 @@ func (d *DashboardStore) deleteAlertDefinition(dashboardId int64, sess *sqlstore
return nil
}
func (d *DashboardStore) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
return d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
func (d *DashboardStore) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) (*models.Dashboard, error) {
err := d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
if query.Id == 0 && len(query.Slug) == 0 && len(query.Uid) == 0 {
return models.ErrDashboardIdentifierNotSet
}
@ -852,6 +852,8 @@ func (d *DashboardStore) GetDashboard(ctx context.Context, query *models.GetDash
query.Result = &dashboard
return nil
})
return query.Result, err
}
func (d *DashboardStore) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {

@ -62,7 +62,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
}
err := dashboardStore.GetDashboard(context.Background(), &query)
_, err := dashboardStore.GetDashboard(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.Title, "test dash 23")
@ -79,7 +79,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
}
err := dashboardStore.GetDashboard(context.Background(), &query)
_, err := dashboardStore.GetDashboard(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.Title, "test dash 23")
@ -96,7 +96,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
}
err := dashboardStore.GetDashboard(context.Background(), &query)
_, err := dashboardStore.GetDashboard(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.Title, "test dash 23")
@ -120,7 +120,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
}
err := dashboardStore.GetDashboard(context.Background(), &query)
_, err := dashboardStore.GetDashboard(context.Background(), &query)
require.Equal(t, err, models.ErrDashboardIdentifierNotSet)
})
@ -202,7 +202,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
}
err = dashboardStore.GetDashboard(context.Background(), &query)
_, err = dashboardStore.GetDashboard(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.FolderId, int64(0))
require.Equal(t, query.Result.CreatedBy, savedDash.CreatedBy)

@ -38,13 +38,17 @@ type DashboardServiceImpl struct {
features featuremgmt.FeatureToggles
folderPermissions accesscontrol.FolderPermissionsService
dashboardPermissions accesscontrol.DashboardPermissionsService
ac accesscontrol.AccessControl
}
func ProvideDashboardService(
cfg *setting.Cfg, store dashboards.Store, dashAlertExtractor alerting.DashAlertExtractor,
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService, ac accesscontrol.AccessControl,
) *DashboardServiceImpl {
ac.RegisterScopeAttributeResolver(dashboards.NewDashboardIDScopeResolver(store))
ac.RegisterScopeAttributeResolver(dashboards.NewDashboardUIDScopeResolver(store))
return &DashboardServiceImpl{
cfg: cfg,
log: log.New("dashboard-service"),
@ -53,6 +57,7 @@ func ProvideDashboardService(
features: features,
folderPermissions: folderPermissionsService,
dashboardPermissions: dashboardPermissionsService,
ac: ac,
}
}
@ -484,7 +489,8 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
}
func (dr *DashboardServiceImpl) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
return dr.dashboardStore.GetDashboard(ctx, query)
_, err := dr.dashboardStore.GetDashboard(ctx, query)
return err
}
func (dr *DashboardServiceImpl) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {

@ -74,7 +74,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
OrgId: otherOrgId,
Uid: sc.savedDashInFolder.Uid,
})
@ -314,7 +314,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -339,7 +339,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
assert.NotEqual(t, sc.savedDashInGeneralFolder.Id, res.Id)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -364,7 +364,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
assert.NotEqual(t, sc.savedDashInGeneralFolder.Id, res.Id)
assert.True(t, res.IsFolder)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -386,7 +386,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
assert.Greater(t, res.Id, int64(0))
assert.NotEmpty(t, res.Uid)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -407,7 +407,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -461,7 +461,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: sc.savedDashInGeneralFolder.Id,
OrgId: cmd.OrgId,
})
@ -501,7 +501,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: sc.savedDashInFolder.Id,
OrgId: cmd.OrgId,
})
@ -575,7 +575,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: sc.savedDashInGeneralFolder.Id,
OrgId: cmd.OrgId,
})
@ -597,7 +597,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
res := callSaveWithResult(t, cmd, sc.sqlStore)
require.NotNil(t, res)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: sc.savedDashInFolder.Id,
OrgId: cmd.OrgId,
})
@ -621,7 +621,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
assert.Equal(t, sc.savedDashInFolder.Id, res.Id)
assert.Equal(t, "new-uid", res.Uid)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: sc.savedDashInFolder.Id,
OrgId: cmd.OrgId,
})
@ -661,7 +661,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
assert.Equal(t, sc.savedDashInFolder.Id, res.Id)
assert.Equal(t, sc.savedDashInFolder.Uid, res.Uid)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -685,7 +685,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
assert.Equal(t, sc.savedDashInGeneralFolder.Id, res.Id)
assert.Equal(t, sc.savedDashInGeneralFolder.Uid, res.Uid)
err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
_, err := sc.dashboardStore.GetDashboard(context.Background(), &models.GetDashboardQuery{
Id: res.Id,
OrgId: cmd.OrgId,
})
@ -817,6 +817,7 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.New(),
)
guardian.InitLegacyGuardian(sqlStore, service)
@ -872,6 +873,7 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.New(),
)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
@ -889,6 +891,7 @@ func callSaveWithError(cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLSt
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.New(),
)
_, err := service.SaveDashboard(context.Background(), &dto, false)
return err
@ -922,7 +925,9 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.New(),
)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
@ -957,7 +962,9 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.New(),
)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)

@ -187,7 +187,7 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.Signe
func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
query := models.GetDashboardQuery{OrgId: orgID, Uid: existingUid}
if err := f.dashboardStore.GetDashboard(ctx, &query); err != nil {
if _, err := f.dashboardStore.GetDashboard(ctx, &query); err != nil {
return toFolderError(err)
}

@ -24,18 +24,10 @@ var user = &models.SignedInUser{UserId: 1}
func TestIntegrationProvideFolderService(t *testing.T) {
t.Run("should register scope resolvers", func(t *testing.T) {
store := &dashboards.FakeDashboardStore{}
cfg := setting.NewCfg()
features := featuremgmt.WithFeatures()
cfg.IsFeatureToggleEnabled = features.IsEnabled
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions)
ac := acmock.New()
ProvideFolderService(
cfg, dashboardService, store, nil, features, folderPermissions, ac,
)
ProvideFolderService(cfg, nil, nil, nil, nil, nil, ac)
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
})
@ -49,7 +41,7 @@ func TestIntegrationFolderService(t *testing.T) {
cfg.IsFeatureToggleEnabled = features.IsEnabled
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions)
dashboardService := ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions, acmock.New())
service := FolderServiceImpl{
cfg: cfg,
@ -102,7 +94,7 @@ func TestIntegrationFolderService(t *testing.T) {
folder := args.Get(1).(*models.GetDashboardQuery)
folder.Result = models.NewDashboard("dashboard-test")
folder.Result.IsFolder = true
}).Return(nil)
}).Return(&models.Dashboard{}, nil)
err := service.UpdateFolder(context.Background(), user, orgID, folderUID, &models.UpdateFolderCommand{
Uid: folderUID,
Title: "Folder-TEST",

@ -68,17 +68,26 @@ func (_m *FakeDashboardStore) FindDashboards(ctx context.Context, query *models.
}
// GetDashboard provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
func (_m *FakeDashboardStore) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) (*models.Dashboard, error) {
ret := _m.Called(ctx, query)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.GetDashboardQuery) error); ok {
var r0 *models.Dashboard
if rf, ok := ret.Get(0).(func(context.Context, *models.GetDashboardQuery) *models.Dashboard); ok {
r0 = rf(ctx, query)
} else {
r0 = ret.Error(0)
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Dashboard)
}
}
return r0
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.GetDashboardQuery) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetDashboardAclInfoList provides a mock function with given fields: ctx, query

@ -205,11 +205,12 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.Sign
features := featuremgmt.WithFeatures()
cfg := setting.NewCfg()
cfg.IsFeatureToggleEnabled = features.IsEnabled
ac := acmock.New()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
service := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, dashAlertExtractor,
features, folderPermissions, dashboardPermissions,
features, folderPermissions, dashboardPermissions, ac,
)
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
require.NoError(t, err)
@ -224,15 +225,15 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
cfg := setting.NewCfg()
features := featuremgmt.WithFeatures()
cfg.IsFeatureToggleEnabled = features.IsEnabled
ac := acmock.New()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardStore := database.ProvideDashboardStore(sqlStore)
d := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
features, folderPermissions, dashboardPermissions,
features, folderPermissions, dashboardPermissions, ac,
)
ac := acmock.New()
s := dashboardservice.ProvideFolderService(
cfg, d, dashboardStore, nil,
features, folderPermissions, ac,
@ -326,14 +327,14 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
features := featuremgmt.WithFeatures()
cfg := setting.NewCfg()
cfg.IsFeatureToggleEnabled = features.IsEnabled
ac := acmock.New()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
features, folderPermissions, dashboardPermissions,
features, folderPermissions, dashboardPermissions, ac,
)
guardian.InitLegacyGuardian(sqlStore, dashboardService)
ac := acmock.New()
service := LibraryElementService{
Cfg: cfg,
SQLStore: sqlStore,

@ -1370,9 +1370,10 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.Sig
dashAlertService := alerting.ProvideDashAlertExtractorService(nil, nil, nil)
cfg := setting.NewCfg()
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
ac := acmock.New()
service := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, dashAlertService,
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), acmock.NewMockedPermissionsService(),
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), acmock.NewMockedPermissionsService(), ac,
)
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
require.NoError(t, err)
@ -1391,7 +1392,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardStore := database.ProvideDashboardStore(sqlStore)
d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions)
d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac)
s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, folderPermissions, ac)
t.Logf("Creating folder with title and UID %q", title)
@ -1485,14 +1486,14 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
dashboardStore := database.ProvideDashboardStore(sqlStore)
features := featuremgmt.WithFeatures()
ac := acmock.New()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, &alerting.DashAlertExtractorService{},
features, folderPermissions, dashboardPermissions,
features, folderPermissions, dashboardPermissions, ac,
)
ac := acmock.New()
folderService := dashboardservice.ProvideFolderService(
cfg, dashboardService, dashboardStore, nil,

@ -52,7 +52,7 @@ func SetupTestEnv(t *testing.T, baseInterval time.Duration) (*ngalert.AlertNG, *
dashboardService := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
features, folderPermissions, dashboardPermissions,
features, folderPermissions, dashboardPermissions, ac,
)
folderService := dashboardservice.ProvideFolderService(
cfg, dashboardService, dashboardStore, nil,

Loading…
Cancel
Save