mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: Add actionsets struct and write path (#86108)
* Add actionsets struct and failing test
* update from review
* review comments
* review comments update
* refactor: create interface
* actionset service
* fix tests
* move from wireoss to wire
* Apply suggestions from code review
remove unnecessary comments
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
* nil for the actionsetservice
* Revert "nil for the actionsetservice"
This reverts commit e3d3cc8171
.
---------
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
parent
a057e8be06
commit
ddabef9895
@ -25,6 +25,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
@ -459,10 +460,10 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(
|
||||
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc)
|
||||
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, resourcepermissions.NewActionSetService())
|
||||
require.NoError(b, err)
|
||||
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
|
||||
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc)
|
||||
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, resourcepermissions.NewActionSetService())
|
||||
require.NoError(b, err)
|
||||
|
||||
dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl(
|
||||
|
@ -37,6 +37,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
||||
"github.com/grafana/grafana/pkg/services/annotations"
|
||||
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
||||
"github.com/grafana/grafana/pkg/services/anonymous/anonimpl/anonstore"
|
||||
@ -379,6 +380,7 @@ var wireBasicSet = wire.NewSet(
|
||||
// Kubernetes API server
|
||||
grafanaapiserver.WireSet,
|
||||
apiregistry.WireSet,
|
||||
resourcepermissions.NewActionSetService,
|
||||
)
|
||||
|
||||
var wireSet = wire.NewSet(
|
||||
|
@ -393,7 +393,8 @@ func setupTestEnv(t testing.TB) (*AccessControlStore, rs.Store, user.Service, te
|
||||
cfg.AutoAssignOrgRole = "Viewer"
|
||||
cfg.AutoAssignOrgId = 1
|
||||
acstore := ProvideService(sql)
|
||||
permissionStore := rs.NewStore(sql, featuremgmt.WithFeatures())
|
||||
asService := rs.NewActionSetService()
|
||||
permissionStore := rs.NewStore(sql, featuremgmt.WithFeatures(), &asService)
|
||||
teamService, err := teamimpl.ProvideService(sql, cfg)
|
||||
require.NoError(t, err)
|
||||
orgService, err := orgimpl.ProvideService(sql, cfg, quotatest.New(false, nil))
|
||||
|
@ -47,7 +47,7 @@ var (
|
||||
func ProvideTeamPermissions(
|
||||
cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB,
|
||||
ac accesscontrol.AccessControl, license licensing.Licensing, service accesscontrol.Service,
|
||||
teamService team.Service, userService user.Service,
|
||||
teamService team.Service, userService user.Service, actionSetService resourcepermissions.ActionSetService,
|
||||
) (*TeamPermissionsService, error) {
|
||||
options := resourcepermissions.Options{
|
||||
Resource: "teams",
|
||||
@ -103,7 +103,7 @@ func ProvideTeamPermissions(
|
||||
},
|
||||
}
|
||||
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService)
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService, actionSetService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -142,7 +142,7 @@ func getDashboardAdminActions(features featuremgmt.FeatureToggles) []string {
|
||||
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,
|
||||
teamService team.Service, userService user.Service,
|
||||
teamService team.Service, userService user.Service, actionSetService resourcepermissions.ActionSetService,
|
||||
) (*DashboardPermissionsService, error) {
|
||||
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*dashboards.Dashboard, error) {
|
||||
query := &dashboards.GetDashboardQuery{UID: resourceID, OrgID: orgID}
|
||||
@ -207,7 +207,7 @@ func ProvideDashboardPermissions(
|
||||
RoleGroup: "Dashboards",
|
||||
}
|
||||
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService)
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService, actionSetService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -237,7 +237,7 @@ var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFol
|
||||
func ProvideFolderPermissions(
|
||||
cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, accesscontrol accesscontrol.AccessControl,
|
||||
license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service,
|
||||
teamService team.Service, userService user.Service,
|
||||
teamService team.Service, userService user.Service, actionSetService resourcepermissions.ActionSetService,
|
||||
) (*FolderPermissionsService, error) {
|
||||
options := resourcepermissions.Options{
|
||||
Resource: "folders",
|
||||
@ -273,7 +273,7 @@ func ProvideFolderPermissions(
|
||||
WriterRoleName: "Folder permission writer",
|
||||
RoleGroup: "Folders",
|
||||
}
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, accesscontrol, service, sql, teamService, userService)
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, accesscontrol, service, sql, teamService, userService, actionSetService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -337,7 +337,7 @@ type ServiceAccountPermissionsService struct {
|
||||
func ProvideServiceAccountPermissions(
|
||||
cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl,
|
||||
license licensing.Licensing, serviceAccountRetrieverService *retriever.Service, service accesscontrol.Service,
|
||||
teamService team.Service, userService user.Service,
|
||||
teamService team.Service, userService user.Service, actionSetService resourcepermissions.ActionSetService,
|
||||
) (*ServiceAccountPermissionsService, error) {
|
||||
options := resourcepermissions.Options{
|
||||
Resource: "serviceaccounts",
|
||||
@ -364,7 +364,7 @@ func ProvideServiceAccountPermissions(
|
||||
RoleGroup: "Service accounts",
|
||||
}
|
||||
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService)
|
||||
srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService, actionSetService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ type Store interface {
|
||||
func New(cfg *setting.Cfg,
|
||||
options Options, features featuremgmt.FeatureToggles, router routing.RouteRegister, license licensing.Licensing,
|
||||
ac accesscontrol.AccessControl, service accesscontrol.Service, sqlStore db.DB,
|
||||
teamService team.Service, userService user.Service,
|
||||
teamService team.Service, userService user.Service, actionSetService ActionSetService,
|
||||
) (*Service, error) {
|
||||
permissions := make([]string, 0, len(options.PermissionsToActions))
|
||||
actionSet := make(map[string]struct{})
|
||||
@ -66,6 +66,7 @@ func New(cfg *setting.Cfg,
|
||||
for _, a := range actions {
|
||||
actionSet[a] = struct{}{}
|
||||
}
|
||||
actionSetService.StoreActionSet(options.Resource, permission, actions)
|
||||
}
|
||||
|
||||
// Sort all permissions based on action length. Will be used when mapping between actions to permissions
|
||||
@ -80,7 +81,7 @@ func New(cfg *setting.Cfg,
|
||||
|
||||
s := &Service{
|
||||
ac: ac,
|
||||
store: NewStore(sqlStore, features),
|
||||
store: NewStore(sqlStore, features, &actionSetService),
|
||||
options: options,
|
||||
license: license,
|
||||
permissions: permissions,
|
||||
|
@ -246,7 +246,7 @@ func setupTestEnvironment(t *testing.T, ops Options) (*Service, db.DB, *setting.
|
||||
acService := &actest.FakeService{}
|
||||
service, err := New(
|
||||
cfg, ops, featuremgmt.WithFeatures(), routing.NewRouteRegister(), license,
|
||||
ac, acService, sql, teamSvc, userSvc,
|
||||
ac, acService, sql, teamSvc, userSvc, NewActionSetService(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"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/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@ -16,13 +17,14 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func NewStore(sql db.DB, features featuremgmt.FeatureToggles) *store {
|
||||
return &store{sql, features}
|
||||
func NewStore(sql db.DB, features featuremgmt.FeatureToggles, actionsetService *ActionSetService) *store {
|
||||
return &store{sql, features, *actionsetService}
|
||||
}
|
||||
|
||||
type store struct {
|
||||
sql db.DB
|
||||
features featuremgmt.FeatureToggles
|
||||
sql db.DB
|
||||
features featuremgmt.FeatureToggles
|
||||
actionSetService ActionSetService
|
||||
}
|
||||
|
||||
type flatResourcePermission struct {
|
||||
@ -266,7 +268,7 @@ func (s *store) setResourcePermission(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.createPermissions(sess, role.ID, cmd.Resource, cmd.ResourceID, cmd.ResourceAttribute, missing); err != nil {
|
||||
if err := s.createPermissions(sess, role.ID, cmd.Resource, cmd.ResourceID, cmd.ResourceAttribute, missing, cmd.Permission); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -657,11 +659,12 @@ func (s *store) getPermissions(sess *db.Session, resource, resourceID, resourceA
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *store) createPermissions(sess *db.Session, roleID int64, resource, resourceID, resourceAttribute string, actions map[string]struct{}) error {
|
||||
func (s *store) createPermissions(sess *db.Session, roleID int64, resource, resourceID, resourceAttribute string, actions map[string]struct{}, permission string) error {
|
||||
if len(actions) == 0 {
|
||||
return nil
|
||||
}
|
||||
permissions := make([]accesscontrol.Permission, 0, len(actions))
|
||||
|
||||
for action := range actions {
|
||||
p := managedPermission(action, resource, resourceID, resourceAttribute)
|
||||
p.RoleID = roleID
|
||||
@ -670,6 +673,18 @@ func (s *store) createPermissions(sess *db.Session, roleID int64, resource, reso
|
||||
p.Kind, p.Attribute, p.Identifier = p.SplitScope()
|
||||
permissions = append(permissions, p)
|
||||
}
|
||||
/*
|
||||
Add ACTION SET of managed permissions to in-memory store
|
||||
*/
|
||||
if s.features.IsEnabled(context.TODO(), featuremgmt.FlagAccessActionSets) {
|
||||
actionSetName := s.actionSetService.GetActionSetName(resource, permission)
|
||||
p := managedPermission(actionSetName, resource, resourceID, resourceAttribute)
|
||||
p.RoleID = roleID
|
||||
p.Created = time.Now()
|
||||
p.Updated = time.Now()
|
||||
p.Kind, p.Attribute, p.Identifier = p.SplitScope()
|
||||
permissions = append(permissions, p)
|
||||
}
|
||||
|
||||
if _, err := sess.InsertMulti(&permissions); err != nil {
|
||||
return err
|
||||
@ -703,3 +718,63 @@ func managedPermission(action, resource string, resourceID, resourceAttribute st
|
||||
Scope: accesscontrol.Scope(resource, resourceAttribute, resourceID),
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ACTION SETS
|
||||
Stores actionsets IN MEMORY
|
||||
*/
|
||||
// ActionSet is a struct that represents a set of actions that can be performed on a resource.
|
||||
// An example of an action set is "folders:edit" which represents the set of RBAC actions that are granted by edit access to a folder.
|
||||
|
||||
type ActionSetService interface {
|
||||
GetActionSet(actionName string) []string
|
||||
GetActionSetName(resource, permission string) string
|
||||
StoreActionSet(resource, permission string, actions []string)
|
||||
}
|
||||
|
||||
type ActionSet struct {
|
||||
Action string `json:"action"`
|
||||
Actions []string `json:"actions"`
|
||||
}
|
||||
|
||||
// InMemoryActionSets is an in-memory implementation of the ActionSetService.
|
||||
type InMemoryActionSets struct {
|
||||
log log.Logger
|
||||
actionSets map[string][]string
|
||||
}
|
||||
|
||||
// NewActionSetService returns a new instance of InMemoryActionSetService.
|
||||
func NewActionSetService() ActionSetService {
|
||||
return &InMemoryActionSets{
|
||||
actionSets: make(map[string][]string),
|
||||
log: log.New("resourcepermissions.actionsets"),
|
||||
}
|
||||
}
|
||||
|
||||
// GetActionSet returns the action set for the given action.
|
||||
func (s *InMemoryActionSets) GetActionSet(actionName string) []string {
|
||||
actionSet, ok := s.actionSets[actionName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return actionSet
|
||||
}
|
||||
|
||||
func (s *InMemoryActionSets) StoreActionSet(resource, permission string, actions []string) {
|
||||
s.log.Debug("storing action set\n")
|
||||
name := s.GetActionSetName(resource, permission)
|
||||
actionSet := &ActionSet{
|
||||
Action: name,
|
||||
Actions: actions,
|
||||
}
|
||||
s.actionSets[actionSet.Action] = actions
|
||||
s.log.Debug("stored action set actionname \n", actionSet.Action)
|
||||
}
|
||||
|
||||
// GetActionSetName function creates an action set from a list of actions and stores it inmemory.
|
||||
func (s *InMemoryActionSets) GetActionSetName(resource, permission string) string {
|
||||
// lower cased
|
||||
resource = strings.ToLower(resource)
|
||||
permission = strings.ToLower(permission)
|
||||
return fmt.Sprintf("%s:%s", resource, permission)
|
||||
}
|
||||
|
@ -559,7 +559,8 @@ func seedResourcePermissions(
|
||||
|
||||
func setupTestEnv(t testing.TB) (*store, db.DB, *setting.Cfg) {
|
||||
sql := db.InitTestDB(t)
|
||||
return NewStore(sql, featuremgmt.WithFeatures()), sql, sql.Cfg
|
||||
asService := NewActionSetService()
|
||||
return NewStore(sql, featuremgmt.WithFeatures(), &asService), sql, sql.Cfg
|
||||
}
|
||||
|
||||
func TestStore_IsInherited(t *testing.T) {
|
||||
@ -753,3 +754,50 @@ func retrievePermissionsHelper(store *store, t *testing.T) []orgPermission {
|
||||
require.NoError(t, err)
|
||||
return permissions
|
||||
}
|
||||
|
||||
func TestStore_ResourcePermissionsActionSets(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
type actionSetTest struct {
|
||||
desc string
|
||||
orgID int64
|
||||
actionSet ActionSet
|
||||
}
|
||||
|
||||
tests := []actionSetTest{
|
||||
{
|
||||
desc: "should be able to store actionset",
|
||||
orgID: 1,
|
||||
actionSet: ActionSet{
|
||||
Actions: []string{"folders:read", "folders:write"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
store, _, _ := setupTestEnv(t)
|
||||
store.features = featuremgmt.WithFeatures([]any{featuremgmt.FlagAccessActionSets})
|
||||
|
||||
_, err := store.SetResourcePermissions(context.Background(), 1, []SetResourcePermissionsCommand{
|
||||
{
|
||||
User: accesscontrol.User{ID: 1},
|
||||
SetResourcePermissionCommand: SetResourcePermissionCommand{
|
||||
Actions: tt.actionSet.Actions,
|
||||
Resource: "folders",
|
||||
Permission: "edit",
|
||||
ResourceID: "1",
|
||||
ResourceAttribute: "uid",
|
||||
},
|
||||
},
|
||||
}, ResourceHooks{})
|
||||
require.NoError(t, err)
|
||||
|
||||
actionname := fmt.Sprintf("%s:%s", "folders", "edit")
|
||||
actionSet := store.actionSetService.GetActionSet(actionname)
|
||||
require.Equal(t, tt.actionSet.Actions, actionSet)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -107,8 +107,9 @@ func TestBacktesting(t *testing.T) {
|
||||
require.Equalf(t, http.StatusForbidden, status, "Response: %s", body)
|
||||
})
|
||||
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
// access control permissions store
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
_, err := permissionsStore.SetUserResourcePermission(context.Background(),
|
||||
accesscontrol.GlobalOrgID,
|
||||
accesscontrol.User{ID: testUserId},
|
||||
|
@ -668,8 +668,9 @@ func TestIntegrationPrometheusRulesPermissions(t *testing.T) {
|
||||
|
||||
apiClient := newAlertingApiClient(grafanaListedAddr, "grafana", "password")
|
||||
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
// access control permissions store
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
|
||||
// Create the namespace we'll save our alerts to.
|
||||
apiClient.CreateFolder(t, "folder1", "folder1")
|
||||
|
@ -52,7 +52,8 @@ func TestIntegrationAlertRulePermissions(t *testing.T) {
|
||||
})
|
||||
|
||||
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
|
||||
// Create a user to make authenticated requests
|
||||
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
|
||||
@ -336,7 +337,8 @@ func TestIntegrationAlertRuleNestedPermissions(t *testing.T) {
|
||||
})
|
||||
|
||||
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
|
||||
// Create a user to make authenticated requests
|
||||
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
|
||||
@ -732,7 +734,8 @@ func TestAlertRulePostExport(t *testing.T) {
|
||||
})
|
||||
|
||||
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
|
||||
// Create a user to make authenticated requests
|
||||
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
|
||||
@ -1412,7 +1415,8 @@ func TestIntegrationRuleUpdate(t *testing.T) {
|
||||
AppModeProduction: true,
|
||||
})
|
||||
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
|
||||
// Create a user to make authenticated requests
|
||||
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
|
||||
|
@ -275,7 +275,8 @@ func TestGrafanaRuleConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
// access control permissions store
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
||||
asService := resourcepermissions.NewActionSetService()
|
||||
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures(), &asService)
|
||||
_, err := permissionsStore.SetUserResourcePermission(context.Background(),
|
||||
accesscontrol.GlobalOrgID,
|
||||
accesscontrol.User{ID: testUserId},
|
||||
|
@ -65,7 +65,8 @@ func TestGetFolders(t *testing.T) {
|
||||
viewerClient := tests.GetClient(grafanaListedAddr, "viewer", "viewer")
|
||||
|
||||
// access control permissions store
|
||||
permissionsStore := resourcepermissions.NewStore(store, featuremgmt.WithFeatures())
|
||||
actionSetService := resourcepermissions.NewActionSetService()
|
||||
permissionsStore := resourcepermissions.NewStore(store, featuremgmt.WithFeatures(), &actionSetService)
|
||||
|
||||
numberOfFolders := 5
|
||||
indexWithoutPermission := 3
|
||||
|
Loading…
Reference in New Issue
Block a user