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:
Ieva 2023-01-31 17:38:03 +00:00 committed by GitHub
parent 62c30dea4d
commit 6ae0ea80f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 3 deletions

View File

@ -39,11 +39,13 @@ type flatResourcePermission struct {
}
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 {
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(
@ -412,10 +414,12 @@ func groupPermissionsByAssignment(permissions []flatResourcePermission) (map[int
}
func flatPermissionsToResourcePermissions(scope string, permissions []flatResourcePermission) []accesscontrol.ResourcePermission {
var managed, provisioned []flatResourcePermission
var managed, inherited, provisioned []flatResourcePermission
for _, p := range permissions {
if p.IsManaged(scope) {
managed = append(managed, p)
} else if p.IsInherited(scope) {
inherited = append(inherited, p)
} else {
provisioned = append(provisioned, p)
}
@ -425,6 +429,9 @@ func flatPermissionsToResourcePermissions(scope string, permissions []flatResour
if g := flatPermissionsToResourcePermission(scope, managed); g != nil {
result = append(result, *g)
}
if g := flatPermissionsToResourcePermission(scope, inherited); g != nil {
result = append(result, *g)
}
if g := flatPermissionsToResourcePermission(scope, provisioned); g != nil {
result = append(result, *g)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"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/orgimpl"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
@ -520,3 +521,58 @@ func setupTestEnv(t testing.TB) (*store, *sqlstore.SQLStore) {
sql := db.InitTestDB(t)
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)
})
}
}