mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: extend IsInherited
method to work for nested folders (#62498)
* extend IsInherited function to work for nested folders * add tests * update tests and logic * process inherited permissions seprately to correctly grey them out in the frontend
This commit is contained in:
parent
62c30dea4d
commit
6ae0ea80f6
@ -39,11 +39,13 @@ type flatResourcePermission struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *flatResourcePermission) IsManaged(scope string) bool {
|
func (p *flatResourcePermission) IsManaged(scope string) bool {
|
||||||
return strings.HasPrefix(p.RoleName, accesscontrol.ManagedRolePrefix) && !p.IsInherited(scope)
|
return strings.HasPrefix(p.RoleName, accesscontrol.ManagedRolePrefix) && p.Scope == scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInherited returns true for scopes from managed permissions that don't directly match the required scope
|
||||||
|
// (ie, managed permissions on a parent resource)
|
||||||
func (p *flatResourcePermission) IsInherited(scope string) bool {
|
func (p *flatResourcePermission) IsInherited(scope string) bool {
|
||||||
return !strings.HasPrefix(p.Scope, strings.Split(strings.ReplaceAll(scope, "*", ""), ":")[0])
|
return strings.HasPrefix(p.RoleName, accesscontrol.ManagedRolePrefix) && p.Scope != scope
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) SetUserResourcePermission(
|
func (s *store) SetUserResourcePermission(
|
||||||
@ -412,10 +414,12 @@ func groupPermissionsByAssignment(permissions []flatResourcePermission) (map[int
|
|||||||
}
|
}
|
||||||
|
|
||||||
func flatPermissionsToResourcePermissions(scope string, permissions []flatResourcePermission) []accesscontrol.ResourcePermission {
|
func flatPermissionsToResourcePermissions(scope string, permissions []flatResourcePermission) []accesscontrol.ResourcePermission {
|
||||||
var managed, provisioned []flatResourcePermission
|
var managed, inherited, provisioned []flatResourcePermission
|
||||||
for _, p := range permissions {
|
for _, p := range permissions {
|
||||||
if p.IsManaged(scope) {
|
if p.IsManaged(scope) {
|
||||||
managed = append(managed, p)
|
managed = append(managed, p)
|
||||||
|
} else if p.IsInherited(scope) {
|
||||||
|
inherited = append(inherited, p)
|
||||||
} else {
|
} else {
|
||||||
provisioned = append(provisioned, p)
|
provisioned = append(provisioned, p)
|
||||||
}
|
}
|
||||||
@ -425,6 +429,9 @@ func flatPermissionsToResourcePermissions(scope string, permissions []flatResour
|
|||||||
if g := flatPermissionsToResourcePermission(scope, managed); g != nil {
|
if g := flatPermissionsToResourcePermission(scope, managed); g != nil {
|
||||||
result = append(result, *g)
|
result = append(result, *g)
|
||||||
}
|
}
|
||||||
|
if g := flatPermissionsToResourcePermission(scope, inherited); g != nil {
|
||||||
|
result = append(result, *g)
|
||||||
|
}
|
||||||
if g := flatPermissionsToResourcePermission(scope, provisioned); g != nil {
|
if g := flatPermissionsToResourcePermission(scope, provisioned); g != nil {
|
||||||
result = append(result, *g)
|
result = append(result, *g)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||||
@ -520,3 +521,58 @@ func setupTestEnv(t testing.TB) (*store, *sqlstore.SQLStore) {
|
|||||||
sql := db.InitTestDB(t)
|
sql := db.InitTestDB(t)
|
||||||
return NewStore(sql), sql
|
return NewStore(sql), sql
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStore_IsInherited(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
description string
|
||||||
|
permission *flatResourcePermission
|
||||||
|
requiredScope string
|
||||||
|
expected bool
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []testCase{
|
||||||
|
{
|
||||||
|
description: "same scope is not inherited",
|
||||||
|
permission: &flatResourcePermission{
|
||||||
|
Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID("some_uid"),
|
||||||
|
RoleName: fmt.Sprintf("%stest_role", accesscontrol.ManagedRolePrefix),
|
||||||
|
},
|
||||||
|
requiredScope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID("some_uid"),
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "specific folder scope for dashboards is inherited",
|
||||||
|
permission: &flatResourcePermission{
|
||||||
|
Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("parent"),
|
||||||
|
RoleName: fmt.Sprintf("%stest_role", accesscontrol.ManagedRolePrefix),
|
||||||
|
},
|
||||||
|
requiredScope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID("some_uid"),
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "wildcard scope from a fixed role is not inherited",
|
||||||
|
permission: &flatResourcePermission{
|
||||||
|
Scope: dashboards.ScopeDashboardsAll,
|
||||||
|
RoleName: fmt.Sprintf("%sfixed_role", accesscontrol.FixedRolePrefix),
|
||||||
|
},
|
||||||
|
requiredScope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID("some_uid"),
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "parent folder scope for nested folders is inherited",
|
||||||
|
permission: &flatResourcePermission{
|
||||||
|
Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("parent"),
|
||||||
|
RoleName: fmt.Sprintf("%stest_role", accesscontrol.ManagedRolePrefix),
|
||||||
|
},
|
||||||
|
requiredScope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("some_folder"),
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
isInherited := tc.permission.IsInherited(tc.requiredScope)
|
||||||
|
assert.Equal(t, tc.expected, isInherited)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user