AccessControl: Create own interface and impl for each permission service (#48871)

* Create own interfaces for team, folder, dashboard and data source permissions services
* Remove service container and inject them individually
This commit is contained in:
Karl Persson
2022-05-10 15:48:47 +02:00
committed by GitHub
parent 31ff23f542
commit 61772a66b6
31 changed files with 266 additions and 255 deletions
+15 -5
View File
@@ -43,11 +43,21 @@ type PermissionsProvider interface {
GetUserPermissions(ctx context.Context, query GetUserPermissionsQuery) ([]*Permission, error)
}
type PermissionsServices interface {
GetTeamService() PermissionsService
GetFolderService() PermissionsService
GetDashboardService() PermissionsService
GetDataSourceService() PermissionsService
type TeamPermissionsService interface {
GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]ResourcePermission, error)
SetUserPermission(ctx context.Context, orgID int64, user User, resourceID, permission string) (*ResourcePermission, error)
}
type FolderPermissionsService interface {
PermissionsService
}
type DashboardPermissionsService interface {
PermissionsService
}
type DatasourcePermissionsService interface {
PermissionsService
}
type PermissionsService interface {
@@ -1,39 +0,0 @@
package mock
import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
)
var _ accesscontrol.PermissionsServices = new(PermissionsServicesMock)
func NewPermissionsServicesMock() *PermissionsServicesMock {
return &PermissionsServicesMock{
Teams: &MockPermissionsService{},
Folders: &MockPermissionsService{},
Dashboards: &MockPermissionsService{},
Datasources: &MockPermissionsService{},
}
}
type PermissionsServicesMock struct {
Teams *MockPermissionsService
Folders *MockPermissionsService
Dashboards *MockPermissionsService
Datasources *MockPermissionsService
}
func (p PermissionsServicesMock) GetTeamService() accesscontrol.PermissionsService {
return p.Teams
}
func (p PermissionsServicesMock) GetFolderService() accesscontrol.PermissionsService {
return p.Folders
}
func (p PermissionsServicesMock) GetDashboardService() accesscontrol.PermissionsService {
return p.Dashboards
}
func (p PermissionsServicesMock) GetDataSourceService() accesscontrol.PermissionsService {
return p.Datasources
}
@@ -11,6 +11,10 @@ import (
var _ accesscontrol.PermissionsService = new(MockPermissionsService)
func NewMockedPermissionsService() *MockPermissionsService {
return &MockPermissionsService{}
}
type MockPermissionsService struct {
mock.Mock
}
@@ -15,52 +15,8 @@ import (
"github.com/grafana/grafana/pkg/setting"
)
func ProvidePermissionsServices(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
ac accesscontrol.AccessControl, store resourcepermissions.Store,
) (*PermissionsServices, error) {
teamPermissions, err := ProvideTeamPermissions(cfg, router, sql, ac, store)
if err != nil {
return nil, err
}
folderPermissions, err := ProvideFolderPermissions(cfg, router, sql, ac, store)
if err != nil {
return nil, err
}
dashboardPermissions, err := ProvideDashboardPermissions(cfg, router, sql, ac, store)
if err != nil {
return nil, err
}
return &PermissionsServices{
teams: teamPermissions,
folder: folderPermissions,
dashboard: dashboardPermissions,
datasources: provideEmptyPermissionsService(),
}, nil
}
type PermissionsServices struct {
teams accesscontrol.PermissionsService
folder accesscontrol.PermissionsService
dashboard accesscontrol.PermissionsService
datasources accesscontrol.PermissionsService
}
func (s *PermissionsServices) GetTeamService() accesscontrol.PermissionsService {
return s.teams
}
func (s *PermissionsServices) GetFolderService() accesscontrol.PermissionsService {
return s.folder
}
func (s *PermissionsServices) GetDashboardService() accesscontrol.PermissionsService {
return s.dashboard
}
func (s *PermissionsServices) GetDataSourceService() accesscontrol.PermissionsService {
return s.datasources
type TeamPermissionsService struct {
*resourcepermissions.Service
}
var (
@@ -80,7 +36,7 @@ var (
func ProvideTeamPermissions(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
ac accesscontrol.AccessControl, store resourcepermissions.Store,
) (*resourcepermissions.Service, error) {
) (*TeamPermissionsService, error) {
options := resourcepermissions.Options{
Resource: "teams",
ResourceAttribute: "id",
@@ -135,7 +91,15 @@ func ProvideTeamPermissions(
},
}
return resourcepermissions.New(options, cfg, router, ac, store, sql)
srv, err := resourcepermissions.New(options, cfg, router, ac, store, sql)
if err != nil {
return nil, err
}
return &TeamPermissionsService{srv}, nil
}
type DashboardPermissionsService struct {
*resourcepermissions.Service
}
var DashboardViewActions = []string{dashboards.ActionDashboardsRead}
@@ -145,7 +109,7 @@ var DashboardAdminActions = append(DashboardEditActions, []string{dashboards.Act
func ProvideDashboardPermissions(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
ac accesscontrol.AccessControl, store resourcepermissions.Store,
) (*resourcepermissions.Service, error) {
) (*DashboardPermissionsService, error) {
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*models.Dashboard, error) {
query := &models.GetDashboardQuery{Uid: resourceID, OrgId: orgID}
if err := sql.GetDashboard(ctx, query); err != nil {
@@ -199,7 +163,15 @@ func ProvideDashboardPermissions(
RoleGroup: "Dashboards",
}
return resourcepermissions.New(options, cfg, router, ac, store, sql)
srv, err := resourcepermissions.New(options, cfg, router, ac, store, sql)
if err != nil {
return nil, err
}
return &DashboardPermissionsService{srv}, nil
}
type FolderPermissionsService struct {
*resourcepermissions.Service
}
var FolderViewActions = []string{dashboards.ActionFoldersRead}
@@ -209,7 +181,7 @@ var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFol
func ProvideFolderPermissions(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
accesscontrol accesscontrol.AccessControl, store resourcepermissions.Store,
) (*resourcepermissions.Service, error) {
) (*FolderPermissionsService, error) {
options := resourcepermissions.Options{
Resource: "folders",
ResourceAttribute: "uid",
@@ -239,38 +211,41 @@ func ProvideFolderPermissions(
WriterRoleName: "Folder permission writer",
RoleGroup: "Folders",
}
return resourcepermissions.New(options, cfg, router, accesscontrol, store, sql)
srv, err := resourcepermissions.New(options, cfg, router, accesscontrol, store, sql)
if err != nil {
return nil, err
}
return &FolderPermissionsService{srv}, nil
}
func provideEmptyPermissionsService() accesscontrol.PermissionsService {
return &emptyPermissionsService{}
func ProvideDatasourcePermissionsService() *DatasourcePermissionsService {
return &DatasourcePermissionsService{}
}
var _ accesscontrol.PermissionsService = new(emptyPermissionsService)
var _ accesscontrol.DatasourcePermissionsService = new(DatasourcePermissionsService)
type emptyPermissionsService struct{}
type DatasourcePermissionsService struct{}
func (e emptyPermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetUserPermission(ctx context.Context, orgID int64, user accesscontrol.User, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetUserPermission(ctx context.Context, orgID int64, user accesscontrol.User, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetTeamPermission(ctx context.Context, orgID, teamID int64, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetTeamPermission(ctx context.Context, orgID, teamID int64, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetBuiltInRolePermission(ctx context.Context, orgID int64, builtInRole string, resourceID string, permission string) (*accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetBuiltInRolePermission(ctx context.Context, orgID int64, builtInRole string, resourceID string, permission string) (*accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetPermissions(ctx context.Context, orgID int64, resourceID string, commands ...accesscontrol.SetResourcePermissionCommand) ([]accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetPermissions(ctx context.Context, orgID int64, resourceID string, commands ...accesscontrol.SetResourcePermissionCommand) ([]accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) MapActions(permission accesscontrol.ResourcePermission) string {
func (e DatasourcePermissionsService) MapActions(permission accesscontrol.ResourcePermission) string {
return ""
}
@@ -65,9 +65,15 @@ func (a *api) registerEndpoints() {
readEvaluator, writeEvaluator := a.getEvaluators(actionRead, actionWrite, scope)
r.Get("/description", auth(disable, accesscontrol.EvalPermission(actionRead)), routing.Wrap(a.getDescription))
r.Get("/:resourceID", inheritanceSolver, auth(disable, readEvaluator), routing.Wrap(a.getPermissions))
r.Post("/:resourceID/users/:userID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setUserPermission))
r.Post("/:resourceID/teams/:teamID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setTeamPermission))
r.Post("/:resourceID/builtInRoles/:builtInRole", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setBuiltinRolePermission))
if a.service.options.Assignments.Users {
r.Post("/:resourceID/users/:userID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setUserPermission))
}
if a.service.options.Assignments.Teams {
r.Post("/:resourceID/teams/:teamID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setTeamPermission))
}
if a.service.options.Assignments.BuiltInRoles {
r.Post("/:resourceID/builtInRoles/:builtInRole", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setBuiltinRolePermission))
}
})
}
@@ -35,13 +35,14 @@ type DashboardServiceImpl struct {
dashboardStore m.Store
dashAlertExtractor alerting.DashAlertExtractor
features featuremgmt.FeatureToggles
folderPermissions accesscontrol.PermissionsService
dashboardPermissions accesscontrol.PermissionsService
folderPermissions accesscontrol.FolderPermissionsService
dashboardPermissions accesscontrol.DashboardPermissionsService
}
func ProvideDashboardService(
cfg *setting.Cfg, store m.Store, dashAlertExtractor alerting.DashAlertExtractor,
features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService,
) *DashboardServiceImpl {
return &DashboardServiceImpl{
cfg: cfg,
@@ -49,8 +50,8 @@ func ProvideDashboardService(
dashboardStore: store,
dashAlertExtractor: dashAlertExtractor,
features: features,
folderPermissions: permissionsServices.GetFolderService(),
dashboardPermissions: permissionsServices.GetDashboardService(),
folderPermissions: folderPermissionsService,
dashboardPermissions: dashboardPermissionsService,
}
}
@@ -862,7 +862,9 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
@@ -877,7 +879,9 @@ func callSaveWithError(cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLSt
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(),
accesscontrolmock.NewMockedPermissionsService(),
)
_, err := service.SaveDashboard(context.Background(), &dto, false)
return err
@@ -910,7 +914,8 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
@@ -944,7 +949,8 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
featuremgmt.WithFeatures(),
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
)
res, err := service.SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
@@ -23,13 +23,13 @@ type FolderServiceImpl struct {
dashboardStore dashboards.Store
searchService *search.SearchService
features featuremgmt.FeatureToggles
permissions accesscontrol.PermissionsService
permissions accesscontrol.FolderPermissionsService
sqlStore sqlstore.Store
}
func ProvideFolderService(
cfg *setting.Cfg, dashboardService dashboards.DashboardService, dashboardStore dashboards.Store,
searchService *search.SearchService, features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
searchService *search.SearchService, features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
ac accesscontrol.AccessControl, sqlStore sqlstore.Store,
) *FolderServiceImpl {
ac.RegisterScopeAttributeResolver(dashboards.NewFolderNameScopeResolver(dashboardStore))
@@ -42,7 +42,7 @@ func ProvideFolderService(
dashboardStore: dashboardStore,
searchService: searchService,
features: features,
permissions: permissionsServices.GetFolderService(),
permissions: folderPermissionsService,
sqlStore: sqlStore,
}
}
@@ -32,13 +32,14 @@ func TestProvideFolderService(t *testing.T) {
cfg := setting.NewCfg()
features := featuremgmt.WithFeatures()
cfg.IsFeatureToggleEnabled = features.IsEnabled
permissionsServices := acmock.NewPermissionsServicesMock()
dashboardService := ProvideDashboardService(cfg, store, nil, features, permissionsServices)
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions)
ac := acmock.New()
ProvideFolderService(
cfg, &dashboards.FakeDashboardService{DashboardService: dashboardService},
store, nil, features, permissionsServices, ac, mockstore.NewSQLStoreMock(),
store, nil, features, folderPermissions, ac, mockstore.NewSQLStoreMock(),
)
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
@@ -51,8 +52,9 @@ func TestFolderService(t *testing.T) {
cfg := setting.NewCfg()
features := featuremgmt.WithFeatures()
cfg.IsFeatureToggleEnabled = features.IsEnabled
permissionsServices := acmock.NewPermissionsServicesMock()
dashboardService := ProvideDashboardService(cfg, store, nil, features, permissionsServices)
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions)
mockStore := mockstore.NewSQLStoreMock()
service := FolderServiceImpl{
@@ -62,7 +64,7 @@ func TestFolderService(t *testing.T) {
dashboardStore: store,
searchService: nil,
features: features,
permissions: permissionsServices.GetFolderService(),
permissions: folderPermissions,
sqlStore: mockStore,
}
@@ -35,7 +35,7 @@ type Service struct {
SecretsService secrets.Service
cfg *setting.Cfg
features featuremgmt.FeatureToggles
permissionsService accesscontrol.PermissionsService
permissionsService accesscontrol.DatasourcePermissionsService
ac accesscontrol.AccessControl
ptc proxyTransportCache
@@ -53,7 +53,7 @@ type cachedRoundTripper struct {
func ProvideService(
store *sqlstore.SQLStore, secretsService secrets.Service, secretsStore kvstore.SecretsKVStore, cfg *setting.Cfg,
features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, permissionsServices accesscontrol.PermissionsServices,
features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, datasourcePermissionsService accesscontrol.DatasourcePermissionsService,
) *Service {
s := &Service{
SQLStore: store,
@@ -64,7 +64,7 @@ func ProvideService(
},
cfg: cfg,
features: features,
permissionsService: permissionsServices.GetDataSourceService(),
permissionsService: datasourcePermissionsService,
ac: ac,
}
@@ -198,7 +198,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
rt1, err := dsService.GetHTTPTransport(context.Background(), &ds, provider)
require.NoError(t, err)
@@ -232,7 +232,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Id: 1,
@@ -280,7 +280,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Id: 1,
@@ -325,7 +325,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Id: 1,
@@ -367,7 +367,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Id: 1,
@@ -399,7 +399,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Id: 1,
@@ -465,7 +465,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Id: 1,
@@ -499,7 +499,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Type: models.DS_ES,
@@ -535,7 +535,7 @@ func TestService_getTimeout(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
for _, tc := range testCases {
ds := &models.DataSource{
@@ -576,7 +576,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
@@ -594,7 +594,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
@@ -614,7 +614,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
_, err := dsService.httpClientOptions(context.Background(), &ds)
assert.Error(t, err)
@@ -633,7 +633,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
@@ -652,7 +652,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
@@ -675,7 +675,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
_, err := dsService.httpClientOptions(context.Background(), &ds)
assert.Error(t, err)
@@ -696,7 +696,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
@@ -719,7 +719,7 @@ func TestService_GetDecryptedValues(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
jsonData := map[string]string{
"password": "securePassword",
@@ -744,7 +744,7 @@ func TestService_GetDecryptedValues(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
dsService := ProvideService(nil, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
jsonData := map[string]string{
"password": "securePassword",
+25 -19
View File
@@ -22,29 +22,33 @@ var _ DashboardGuardian = new(AccessControlDashboardGuardian)
func NewAccessControlDashboardGuardian(
ctx context.Context, dashboardId int64, user *models.SignedInUser,
store sqlstore.Store, ac accesscontrol.AccessControl, permissionsServices accesscontrol.PermissionsServices,
store sqlstore.Store, ac accesscontrol.AccessControl,
folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService,
) *AccessControlDashboardGuardian {
return &AccessControlDashboardGuardian{
ctx: ctx,
log: log.New("dashboard.permissions"),
dashboardID: dashboardId,
user: user,
store: store,
ac: ac,
permissionServices: permissionsServices,
ctx: ctx,
log: log.New("dashboard.permissions"),
dashboardID: dashboardId,
user: user,
store: store,
ac: ac,
folderPermissionsService: folderPermissionsService,
dashboardPermissionsService: dashboardPermissionsService,
}
}
type AccessControlDashboardGuardian struct {
ctx context.Context
log log.Logger
dashboardID int64
dashboard *models.Dashboard
parentFolderUID string
user *models.SignedInUser
store sqlstore.Store
ac accesscontrol.AccessControl
permissionServices accesscontrol.PermissionsServices
ctx context.Context
log log.Logger
dashboardID int64
dashboard *models.Dashboard
parentFolderUID string
user *models.SignedInUser
store sqlstore.Store
ac accesscontrol.AccessControl
folderPermissionsService accesscontrol.FolderPermissionsService
dashboardPermissionsService accesscontrol.DashboardPermissionsService
}
func (a *AccessControlDashboardGuardian) CanSave() (bool, error) {
@@ -169,9 +173,11 @@ func (a *AccessControlDashboardGuardian) GetAcl() ([]*models.DashboardAclInfoDTO
return nil, err
}
svc := a.permissionServices.GetDashboardService()
var svc accesscontrol.PermissionsService
if a.dashboard.IsFolder {
svc = a.permissionServices.GetFolderService()
svc = a.folderPermissionsService
} else {
svc = a.dashboardPermissionsService
}
permissions, err := svc.GetPermissions(a.ctx, a.user, strconv.FormatInt(a.dashboard.Id, 10))
@@ -559,10 +559,10 @@ func TestAccessControlDashboardGuardian_GetHiddenACL(t *testing.T) {
t.Run(tt.desc, func(t *testing.T) {
guardian, _ := setupAccessControlGuardianTest(t, "1", nil)
mocked := accesscontrolmock.NewPermissionsServicesMock()
guardian.permissionServices = mocked
mocked.Dashboards.On("MapActions", mock.Anything).Return("View")
mocked.Dashboards.On("GetPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tt.permissions, nil)
mocked := accesscontrolmock.NewMockedPermissionsService()
guardian.dashboardPermissionsService = mocked
mocked.On("MapActions", mock.Anything).Return("View")
mocked.On("GetPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tt.permissions, nil)
cfg := setting.NewCfg()
cfg.HiddenUsers = tt.hiddenUsers
permissions, err := guardian.GetHiddenACL(cfg)
@@ -595,8 +595,10 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []*acc
})
require.NoError(t, err)
ac := accesscontrolmock.New().WithPermissions(permissions)
services, err := ossaccesscontrol.ProvidePermissionsServices(setting.NewCfg(), routing.NewRouteRegister(), store, ac, database.ProvideService(store))
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(setting.NewCfg(), routing.NewRouteRegister(), store, ac, database.ProvideService(store))
require.NoError(t, err)
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(setting.NewCfg(), routing.NewRouteRegister(), store, ac, database.ProvideService(store))
require.NoError(t, err)
return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &models.SignedInUser{OrgId: 1}, store, ac, services), dash
return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &models.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions), dash
}
+10 -5
View File
@@ -5,16 +5,18 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
type Provider struct{}
func ProvideService(store *sqlstore.SQLStore, ac accesscontrol.AccessControl, permissionsServices accesscontrol.PermissionsServices, features featuremgmt.FeatureToggles) *Provider {
func ProvideService(
store *sqlstore.SQLStore, ac accesscontrol.AccessControl,
folderPermissionsService accesscontrol.FolderPermissionsService, dashboardPermissionsService accesscontrol.DashboardPermissionsService,
) *Provider {
if !ac.IsDisabled() {
// TODO: Fix this hack, see https://github.com/grafana/grafana-enterprise/issues/2935
InitAcessControlGuardian(store, ac, permissionsServices)
InitAccessControlGuardian(store, ac, folderPermissionsService, dashboardPermissionsService)
} else {
InitLegacyGuardian(store)
}
@@ -27,8 +29,11 @@ func InitLegacyGuardian(store sqlstore.Store) {
}
}
func InitAcessControlGuardian(store sqlstore.Store, ac accesscontrol.AccessControl, permissionsServices accesscontrol.PermissionsServices) {
func InitAccessControlGuardian(
store sqlstore.Store, ac accesscontrol.AccessControl, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService,
) {
New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
return NewAccessControlDashboardGuardian(ctx, dashId, user, store, ac, permissionsServices)
return NewAccessControlDashboardGuardian(ctx, dashId, user, store, ac, folderPermissionsService, dashboardPermissionsService)
}
}
@@ -205,9 +205,11 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.Sign
features := featuremgmt.WithFeatures()
cfg := setting.NewCfg()
cfg.IsFeatureToggleEnabled = features.IsEnabled
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
service := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, dashAlertExtractor,
features, acmock.NewPermissionsServicesMock(),
features, folderPermissions, dashboardPermissions,
)
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
require.NoError(t, err)
@@ -222,17 +224,18 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
cfg := setting.NewCfg()
features := featuremgmt.WithFeatures()
cfg.IsFeatureToggleEnabled = features.IsEnabled
permissionsServices := acmock.NewPermissionsServicesMock()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardStore := database.ProvideDashboardStore(sqlStore)
d := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
features, permissionsServices,
features, folderPermissions, dashboardPermissions,
)
ac := acmock.New()
s := dashboardservice.ProvideFolderService(
cfg, d, dashboardStore, nil,
features, permissionsServices, ac, nil,
features, folderPermissions, ac, nil,
)
t.Logf("Creating folder with title and UID %q", title)
folder, err := s.CreateFolder(context.Background(), &user, user.OrgId, title, title)
@@ -324,9 +327,12 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
features := featuremgmt.WithFeatures()
cfg := setting.NewCfg()
cfg.IsFeatureToggleEnabled = features.IsEnabled
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
features, acmock.NewPermissionsServicesMock(),
features, folderPermissions, dashboardPermissions,
)
ac := acmock.New()
service := LibraryElementService{
@@ -334,7 +340,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
SQLStore: sqlStore,
folderService: dashboardservice.ProvideFolderService(
cfg, dashboardService, dashboardStore, nil,
features, acmock.NewPermissionsServicesMock(), ac, nil,
features, folderPermissions, ac, nil,
),
}
@@ -1372,7 +1372,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.Sig
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
service := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, dashAlertService,
featuremgmt.WithFeatures(), acmock.NewPermissionsServicesMock(),
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), acmock.NewMockedPermissionsService(),
)
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
require.NoError(t, err)
@@ -1384,14 +1384,15 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
items []folderACLItem) *models.Folder {
t.Helper()
ac := acmock.New()
cfg := setting.NewCfg()
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
features := featuremgmt.WithFeatures()
permissionsServices := acmock.NewPermissionsServicesMock()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardStore := database.ProvideDashboardStore(sqlStore)
d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, permissionsServices)
ac := acmock.New()
s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, permissionsServices, ac, nil)
d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions)
s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, folderPermissions, ac, nil)
t.Logf("Creating folder with title and UID %q", title)
folder, err := s.CreateFolder(context.Background(), user, user.OrgId, title, title)
@@ -1484,17 +1485,18 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
dashboardStore := database.ProvideDashboardStore(sqlStore)
features := featuremgmt.WithFeatures()
permissionsServices := acmock.NewPermissionsServicesMock()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, &alerting.DashAlertExtractorService{},
features, permissionsServices,
features, folderPermissions, dashboardPermissions,
)
ac := acmock.New()
folderService := dashboardservice.ProvideFolderService(
cfg, dashboardService, dashboardStore, nil,
features, permissionsServices, ac, nil,
features, folderPermissions, ac, nil,
)
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService)
+4 -3
View File
@@ -51,15 +51,16 @@ func SetupTestEnv(t *testing.T, baseInterval time.Duration) (*ngalert.AlertNG, *
ac := acmock.New()
features := featuremgmt.WithFeatures()
permissionsServices := acmock.NewPermissionsServicesMock()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardService := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
features, permissionsServices,
features, folderPermissions, dashboardPermissions,
)
folderService := dashboardservice.ProvideFolderService(
cfg, dashboardService, dashboardStore, nil,
features, permissionsServices, ac, nil,
features, folderPermissions, ac, nil,
)
ng, err := ngalert.ProvideService(
+1 -1
View File
@@ -71,7 +71,7 @@ func setup(t *testing.T) *testContext {
ss := kvstore.SetupTestService(t)
ssvc := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
ds := datasources.ProvideService(nil, ssvc, ss, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
ds := datasources.ProvideService(nil, ssvc, ss, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
return &testContext{
pluginContext: pc,