From aeb041a9af3470335571eac1152e9667570a9dde Mon Sep 17 00:00:00 2001 From: Ieva Date: Tue, 14 Oct 2025 14:54:19 +0100 Subject: [PATCH] Folder permissions: Remove default creator can Admin permissions for folders (#111984) * Remove default creator can Admin permissions for folders * Actually, we only need to set permissions for root level folders * Put back creator permission * linting * use FT for assessing what permissions to set * fix tests --- pkg/registry/apis/folders/folder_storage.go | 13 +++++++++-- .../apis/folders/folder_storage_test.go | 2 ++ pkg/registry/apis/folders/register.go | 1 + .../dashboards/service/dashboard_service.go | 22 +++++++------------ 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/pkg/registry/apis/folders/folder_storage.go b/pkg/registry/apis/folders/folder_storage.go index 8d96a494859..4b55a55390d 100644 --- a/pkg/registry/apis/folders/folder_storage.go +++ b/pkg/registry/apis/folders/folder_storage.go @@ -19,6 +19,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" "github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/org" ) @@ -39,6 +40,7 @@ type folderStorage struct { tableConverter rest.TableConvertor permissionsOnCreate bool // cfg.RBAC.PermissionsOnCreation("folder") + features featuremgmt.FeatureToggles folderPermissionsSvc accesscontrol.FolderPermissionsService acService accesscontrol.Service } @@ -152,23 +154,30 @@ func (s *folderStorage) DeleteCollection(ctx context.Context, deleteValidation r func (s *folderStorage) setDefaultFolderPermissions(ctx context.Context, orgID int64, user identity.Requester, uid, parentUID string) error { var permissions []accesscontrol.SetResourcePermissionCommand + isNested := parentUID != "" + if s.features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboards) && isNested { + // No permissions on nested folders when kubernetesDashboards is enabled + return nil + } + + // Creator permissions always set with the legacy behaviour and set on root level folders for new behaviour if user.IsIdentityType(claims.TypeUser, claims.TypeServiceAccount) { userID, err := user.GetInternalID() if err != nil { return err } - permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{ UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(), }) } - isNested := parentUID != "" + if !isNested { permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ {BuiltinRole: string(org.RoleEditor), Permission: dashboardaccess.PERMISSION_EDIT.String()}, {BuiltinRole: string(org.RoleViewer), Permission: dashboardaccess.PERMISSION_VIEW.String()}, }...) } + _, err := s.folderPermissionsSvc.SetPermissions(ctx, orgID, uid, permissions...) if err != nil { return err diff --git a/pkg/registry/apis/folders/folder_storage_test.go b/pkg/registry/apis/folders/folder_storage_test.go index a37bd38ed6a..d03b0947f5d 100644 --- a/pkg/registry/apis/folders/folder_storage_test.go +++ b/pkg/registry/apis/folders/folder_storage_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -54,6 +55,7 @@ func TestSetDefaultPermissionsWhenCreatingFolder(t *testing.T) { acService: actest.FakeService{}, store: store, permissionsOnCreate: cfg.RBAC.PermissionsOnCreation("folder"), + features: featuremgmt.WithFeatures(), } obj := &folders.Folder{} diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index 4f818f40ea8..6bfdced4089 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -168,6 +168,7 @@ func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.API b.storage = &folderStorage{ tableConverter: resourceInfo.TableConverter(), folderPermissionsSvc: b.folderPermissionsSvc, + features: b.features, acService: b.acService, permissionsOnCreate: b.permissionsOnCreate, store: dw, diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index b9962afd285..170c924b6cd 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -1179,30 +1179,24 @@ func (dr *DashboardServiceImpl) SetDefaultPermissionsAfterCreate(ctx context.Con return err } permissions := []accesscontrol.SetResourcePermissionCommand{} + + isNested := obj.GetFolder() != "" + if dr.features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboards) && isNested { + // Don't set any permissions for nested dashboards + return nil + } if user.IsIdentityType(claims.TypeUser, claims.TypeServiceAccount) { permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{ UserID: uid, Permission: dashboardaccess.PERMISSION_ADMIN.String(), }) } - isNested := obj.GetFolder() != "" - if !dr.features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboards) { - // legacy behavior - if !isNested { - permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ - {BuiltinRole: string(org.RoleEditor), Permission: dashboardaccess.PERMISSION_EDIT.String()}, - {BuiltinRole: string(org.RoleViewer), Permission: dashboardaccess.PERMISSION_VIEW.String()}, - }...) - } - } else { - // Don't set any permissions for nested dashboards - if isNested { - return nil - } + if !isNested { permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ {BuiltinRole: string(org.RoleEditor), Permission: dashboardaccess.PERMISSION_EDIT.String()}, {BuiltinRole: string(org.RoleViewer), Permission: dashboardaccess.PERMISSION_VIEW.String()}, }...) } + svc := dr.getPermissionsService(key.Resource == "folders") if _, err := svc.SetPermissions(ctx, ns.OrgID, obj.GetName(), permissions...); err != nil { logger.Error("Could not set default permissions", "error", err)