RBAC: Resolve action sets when GetPermissions is called (#89046)

* resolve action sets when GetPermissions is called

* a fix to ensure that dashboard permissions that override parent folder permissions are displayed on top of the inherited permission

* linting

* linting pt2
This commit is contained in:
Ieva 2024-06-13 20:06:37 +03:00 committed by GitHub
parent eb535e163d
commit bd35fa10f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6,6 +6,8 @@ import (
"fmt"
"sort"
"golang.org/x/exp/slices"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/db"
@ -83,16 +85,18 @@ func New(cfg *setting.Cfg,
}
s := &Service{
ac: ac,
store: NewStore(cfg, sqlStore, features),
options: options,
license: license,
permissions: permissions,
actions: actions,
sqlStore: sqlStore,
service: service,
teamService: teamService,
userService: userService,
ac: ac,
features: features,
store: NewStore(cfg, sqlStore, features),
options: options,
license: license,
permissions: permissions,
actions: actions,
sqlStore: sqlStore,
service: service,
teamService: teamService,
userService: userService,
actionSetSvc: actionSetService,
}
s.api = newApi(cfg, ac, router, s)
@ -108,18 +112,20 @@ func New(cfg *setting.Cfg,
// Service is used to create access control sub system including api / and service for managed resource permission
type Service struct {
ac accesscontrol.AccessControl
service accesscontrol.Service
store Store
api *api
license licensing.Licensing
ac accesscontrol.AccessControl
features featuremgmt.FeatureToggles
service accesscontrol.Service
store Store
api *api
license licensing.Licensing
options Options
permissions []string
actions []string
sqlStore db.DB
teamService team.Service
userService user.Service
options Options
permissions []string
actions []string
sqlStore db.DB
teamService team.Service
userService user.Service
actionSetSvc ActionSetService
}
func (s *Service) GetPermissions(ctx context.Context, user identity.Requester, resourceID string) ([]accesscontrol.ResourcePermission, error) {
@ -132,9 +138,21 @@ func (s *Service) GetPermissions(ctx context.Context, user identity.Requester, r
}
}
return s.store.GetResourcePermissions(ctx, user.GetOrgID(), GetResourcePermissionsQuery{
actions := s.actions
if s.features.IsEnabled(ctx, featuremgmt.FlagAccessActionSets) {
for _, action := range s.actions {
actionSets := s.actionSetSvc.ResolveAction(action)
for _, actionSet := range actionSets {
if !slices.Contains(actions, actionSet) {
actions = append(actions, actionSet)
}
}
}
}
resourcePermissions, err := s.store.GetResourcePermissions(ctx, user.GetOrgID(), GetResourcePermissionsQuery{
User: user,
Actions: s.actions,
Actions: actions,
Resource: s.options.Resource,
ResourceID: resourceID,
ResourceAttribute: s.options.ResourceAttribute,
@ -142,6 +160,35 @@ func (s *Service) GetPermissions(ctx context.Context, user identity.Requester, r
OnlyManaged: s.options.OnlyManaged,
EnforceAccessControl: s.license.FeatureEnabled("accesscontrol.enforcement"),
})
if err != nil {
return nil, err
}
if s.features.IsEnabled(ctx, featuremgmt.FlagAccessActionSets) {
for i := range resourcePermissions {
actions := resourcePermissions[i].Actions
var expandedActions []string
for _, action := range actions {
if isFolderOrDashboardAction(action) {
actionSetActions := s.actionSetSvc.ResolveActionSet(action)
if len(actionSetActions) > 0 {
for _, actionSetAction := range actionSetActions {
// This check is needed for resolving inherited permissions - we don't want to include
// actions that are not related to dashboards when expanding folder action sets
if slices.Contains(s.actions, actionSetAction) {
expandedActions = append(expandedActions, actionSetAction)
}
}
continue
}
}
expandedActions = append(expandedActions, action)
}
resourcePermissions[i].Actions = expandedActions
}
}
return resourcePermissions, nil
}
func (s *Service) SetUserPermission(ctx context.Context, orgID int64, user accesscontrol.User, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {