Actionsets: Add cfg option for only writing actionsets (#88367)

* test

* test

* missed test

* fix review comments
This commit is contained in:
Eric Leijonmarck
2024-05-28 16:32:23 +01:00
committed by GitHub
parent 5f326e98c1
commit 910553df20
12 changed files with 48 additions and 34 deletions

View File

@@ -476,7 +476,7 @@ func setupTestEnv(t testing.TB) (*database.AccessControlStore, rs.Store, user.Se
cfg.AutoAssignOrgRole = "Viewer"
cfg.AutoAssignOrgId = 1
acstore := database.ProvideService(sql)
permissionStore := rs.NewStore(sql, featuremgmt.WithFeatures())
permissionStore := rs.NewStore(cfg, sql, featuremgmt.WithFeatures())
teamService, err := teamimpl.ProvideService(sql, cfg, tracing.InitializeTracerForTest())
require.NoError(t, err)
orgService, err := orgimpl.ProvideService(sql, cfg, quotatest.New(false, nil))

View File

@@ -288,9 +288,9 @@ var DatasourceQueryActions = []string{
datasources.ActionQuery,
}
func ProvideDatasourcePermissionsService(features featuremgmt.FeatureToggles, db db.DB) *DatasourcePermissionsService {
func ProvideDatasourcePermissionsService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, db db.DB) *DatasourcePermissionsService {
return &DatasourcePermissionsService{
store: resourcepermissions.NewStore(db, features),
store: resourcepermissions.NewStore(cfg, db, features),
}
}

View File

@@ -84,7 +84,7 @@ func New(cfg *setting.Cfg,
s := &Service{
ac: ac,
store: NewStore(sqlStore, features),
store: NewStore(cfg, sqlStore, features),
options: options,
license: license,
permissions: permissions,

View File

@@ -14,15 +14,17 @@ import (
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
func NewStore(sql db.DB, features featuremgmt.FeatureToggles) *store {
store := &store{sql: sql, features: features}
func NewStore(cfg *setting.Cfg, sql db.DB, features featuremgmt.FeatureToggles) *store {
store := &store{cfg: cfg, sql: sql, features: features}
return store
}
type store struct {
cfg *setting.Cfg
sql db.DB
features featuremgmt.FeatureToggles
}
@@ -268,7 +270,7 @@ func (s *store) setResourcePermission(
return nil, err
}
if err := s.createPermissions(sess, role.ID, cmd.Resource, cmd.ResourceID, cmd.ResourceAttribute, missing, cmd.Permission); err != nil {
if err := s.createPermissions(sess, role.ID, cmd, missing); err != nil {
return nil, err
}
@@ -659,12 +661,17 @@ 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, missingActions map[string]struct{}, permission string) error {
func (s *store) createPermissions(sess *db.Session, roleID int64, cmd SetResourcePermissionCommand, missingActions map[string]struct{}) error {
permissions := make([]accesscontrol.Permission, 0, len(missingActions))
resource := cmd.Resource
resourceID := cmd.ResourceID
resourceAttribute := cmd.ResourceAttribute
permission := cmd.Permission
/*
Add ACTION SET of managed permissions to in-memory store
*/
if s.features.IsEnabled(context.TODO(), featuremgmt.FlagAccessActionSets) && permission != "" {
if s.shouldStoreActionSet(permission) {
actionSetName := GetActionSetName(resource, permission)
p := managedPermission(actionSetName, resource, resourceID, resourceAttribute)
p.RoleID = roleID
@@ -674,24 +681,23 @@ func (s *store) createPermissions(sess *db.Session, roleID int64, resource, reso
permissions = append(permissions, p)
}
// If there are no missing actions for the resource (in case of access level downgrade or resource removal), we don't need to insert any prior actions
// we still want to add the action set in case of access level downgrade, but not in case of resource removal (when permission == "")
if len(missingActions) == 0 {
if s.features.IsEnabled(context.TODO(), featuremgmt.FlagAccessActionSets) && permission != "" {
if _, err := sess.InsertMulti(&permissions); err != nil {
return err
}
}
// If there are no missing actions for the resource (in case of access level downgrade or resource removal), we don't need to insert any actions
// we still want to add the action set (when permission != "")
if len(missingActions) == 0 && !s.shouldStoreActionSet(permission) {
return nil
}
for action := range missingActions {
p := managedPermission(action, 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 we have actionset feature enabled and are only working with action sets
// skip adding the missing actions to the permissions table
if !(s.shouldStoreActionSet(permission) && s.cfg.OnlyStoreAccessActionSets) {
for action := range missingActions {
p := managedPermission(action, 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 {
@@ -700,6 +706,10 @@ func (s *store) createPermissions(sess *db.Session, roleID int64, resource, reso
return nil
}
func (s *store) shouldStoreActionSet(permission string) bool {
return (s.features.IsEnabled(context.TODO(), featuremgmt.FlagAccessActionSets) && permission != "")
}
func deletePermissions(sess *db.Session, ids []int64) error {
if len(ids) == 0 {
return nil

View File

@@ -563,7 +563,7 @@ func seedResourcePermissions(
func setupTestEnv(t testing.TB) (*store, db.DB, *setting.Cfg) {
sql, cfg := db.InitTestDBWithCfg(t)
return NewStore(sql, featuremgmt.WithFeatures()), sql, cfg
return NewStore(cfg, sql, featuremgmt.WithFeatures()), sql, cfg
}
func TestStore_IsInherited(t *testing.T) {

View File

@@ -322,6 +322,9 @@ type Cfg struct {
// GrafanaJavascriptAgent config
GrafanaJavascriptAgent GrafanaJavascriptAgent
// accessactionsets
OnlyStoreAccessActionSets bool
// Data sources
DataSourceLimit int
// Number of queries to be executed concurrently. Only for the datasource supports concurrency.
@@ -1633,6 +1636,7 @@ func readAccessControlSettings(iniFile *ini.File, cfg *Cfg) {
cfg.RBACPermissionValidationEnabled = rbac.Key("permission_validation_enabled").MustBool(false)
cfg.RBACResetBasicRoles = rbac.Key("reset_basic_roles").MustBool(false)
cfg.RBACSingleOrganization = rbac.Key("single_organization").MustBool(false)
cfg.OnlyStoreAccessActionSets = rbac.Key("only_store_access_action_sets").MustBool(false)
}
func readOAuth2ServerSettings(cfg *Cfg) {

View File

@@ -306,7 +306,7 @@ func TestIntegrationSilenceAuth(t *testing.T) {
apiClient := newAlertingApiClient(grafanaListedAddr, randomLogin, randomLogin)
// Set permissions.
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
for _, cmd := range tt.permissions {
_, err := permissionsStore.SetUserResourcePermission(
context.Background(),

View File

@@ -108,7 +108,7 @@ func TestBacktesting(t *testing.T) {
})
// access control permissions store
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
_, err := permissionsStore.SetUserResourcePermission(context.Background(),
accesscontrol.GlobalOrgID,
accesscontrol.User{ID: testUserId},

View File

@@ -675,7 +675,7 @@ func TestIntegrationPrometheusRulesPermissions(t *testing.T) {
apiClient := newAlertingApiClient(grafanaListedAddr, "grafana", "password")
// access control permissions store
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
// Create the namespace we'll save our alerts to.
apiClient.CreateFolder(t, "folder1", "folder1")

View File

@@ -52,7 +52,7 @@ func TestIntegrationAlertRulePermissions(t *testing.T) {
})
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
// Create a user to make authenticated requests
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
@@ -336,7 +336,7 @@ func TestIntegrationAlertRuleNestedPermissions(t *testing.T) {
})
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
// Create a user to make authenticated requests
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
@@ -732,7 +732,7 @@ func TestAlertRulePostExport(t *testing.T) {
})
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
// Create a user to make authenticated requests
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{
@@ -1412,7 +1412,7 @@ func TestIntegrationRuleUpdate(t *testing.T) {
AppModeProduction: true,
})
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
// Create a user to make authenticated requests
userID := createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{

View File

@@ -275,7 +275,7 @@ func TestGrafanaRuleConfig(t *testing.T) {
})
// access control permissions store
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(env.Cfg, env.SQLStore, featuremgmt.WithFeatures())
_, err := permissionsStore.SetUserResourcePermission(context.Background(),
accesscontrol.GlobalOrgID,
accesscontrol.User{ID: testUserId},

View File

@@ -65,7 +65,7 @@ func TestGetFolders(t *testing.T) {
viewerClient := tests.GetClient(grafanaListedAddr, "viewer", "viewer")
// access control permissions store
permissionsStore := resourcepermissions.NewStore(store, featuremgmt.WithFeatures())
permissionsStore := resourcepermissions.NewStore(cfg, store, featuremgmt.WithFeatures())
numberOfFolders := 5
indexWithoutPermission := 3