RBAC: Clean up action set code (#88147)

* remove unused action set code, refactor the existing code

* fix import ordering

* use a separate interface for permission expansion after all, to avoid circular dependencies

* add comments, fix a test
This commit is contained in:
Ieva
2024-05-23 12:14:01 +01:00
committed by GitHub
parent 84ef99c1dc
commit bd2b248f0e
15 changed files with 82 additions and 249 deletions
@@ -2,15 +2,12 @@ package acimpl_test
import (
"context"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/user"
)
@@ -24,7 +21,6 @@ func TestAccessControl_Evaluate(t *testing.T) {
expected bool
expectedErr error
scopeResolver accesscontrol.ScopeAttributeResolver
actionSets map[string][]string
}
tests := []testCase{
@@ -65,101 +61,6 @@ func TestAccessControl_Evaluate(t *testing.T) {
}),
expected: true,
},
{
desc: "expect user to have access when resolver translates actions to action sets",
user: user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
1: {"folders:edit": {"folders:uid:test_folder"}},
},
},
evaluator: accesscontrol.EvalPermission(dashboards.ActionFoldersWrite, "folders:uid:test_folder"),
actionSets: map[string][]string{
"folders:edit": {dashboards.ActionFoldersWrite, dashboards.ActionFoldersRead, dashboards.ActionDashboardsWrite, dashboards.ActionDashboardsRead},
},
expected: true,
},
{
desc: "expect user to have access when resolver translates scopes, as well as expands actions to action sets",
user: user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
1: {"folders:edit": {"folders:uid:test_folder"}},
},
},
evaluator: accesscontrol.EvalPermission(dashboards.ActionDashboardsRead, "dashboards:uid:test_dashboard"),
actionSets: map[string][]string{
"folders:edit": {dashboards.ActionFoldersWrite, dashboards.ActionFoldersRead, dashboards.ActionDashboardsWrite, dashboards.ActionDashboardsRead},
},
resolverPrefix: "dashboards:uid:",
scopeResolver: accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
return []string{"folders:uid:test_folder"}, nil
}),
expected: true,
},
{
desc: "expect user to have access with eval all evaluator when resolver translates scopes, as well as expands actions to action sets",
user: user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
1: {"folders:edit": {"folders:uid:test_folder"}},
},
},
evaluator: accesscontrol.EvalAll(
accesscontrol.EvalPermission(dashboards.ActionFoldersRead, "folders:uid:test_folder"),
accesscontrol.EvalPermission(dashboards.ActionDashboardsWrite, "dashboards:uid:test_dashboard"),
),
actionSets: map[string][]string{
"folders:edit": {dashboards.ActionFoldersWrite, dashboards.ActionFoldersRead, dashboards.ActionDashboardsWrite, dashboards.ActionDashboardsRead},
},
resolverPrefix: "dashboards:uid:",
scopeResolver: accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
return []string{"folders:uid:test_folder"}, nil
}),
expected: true,
},
{
desc: "expect user to not have access with eval all evaluator with resolvers when not all permissions resolve to permissions that the user has",
user: user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
1: {"folders:edit": {"folders:uid:test_folder"}},
},
},
evaluator: accesscontrol.EvalAll(
accesscontrol.EvalPermission(dashboards.ActionDashboardsWrite, "datasources:uid:test_ds"),
accesscontrol.EvalPermission(dashboards.ActionDashboardsWrite, "dashboards:uid:test_dashboard"),
),
actionSets: map[string][]string{
"folders:edit": {dashboards.ActionFoldersWrite, dashboards.ActionFoldersRead, dashboards.ActionDashboardsWrite, dashboards.ActionDashboardsRead},
},
resolverPrefix: "dashboards:uid:",
scopeResolver: accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
return []string{"folders:uid:test_folder"}, nil
}),
expected: false,
},
{
desc: "expect user to have access with eval any evaluator when resolver translates scopes, as well as expands actions to action sets",
user: user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
1: {"folders:edit": {"folders:uid:test_folder"}},
},
},
evaluator: accesscontrol.EvalAny(
accesscontrol.EvalPermission(dashboards.ActionDashboardsDelete, "dashboards:uid:test_dashboard"),
accesscontrol.EvalPermission(dashboards.ActionDashboardsWrite, "dashboards:uid:test_dashboard"),
),
actionSets: map[string][]string{
"folders:edit": {dashboards.ActionFoldersWrite, dashboards.ActionFoldersRead, dashboards.ActionDashboardsWrite, dashboards.ActionDashboardsRead},
},
resolverPrefix: "dashboards:uid:",
scopeResolver: accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
return []string{"folders:uid:test_folder"}, nil
}),
expected: true,
},
}
for _, tt := range tests {
@@ -170,15 +71,6 @@ func TestAccessControl_Evaluate(t *testing.T) {
ac.RegisterScopeAttributeResolver(tt.resolverPrefix, tt.scopeResolver)
}
if tt.actionSets != nil {
actionSetResolver := resourcepermissions.NewActionSetService(ac)
for actionSet, actions := range tt.actionSets {
splitActionSet := strings.Split(actionSet, ":")
actionSetResolver.StoreActionSet(splitActionSet[0], splitActionSet[1], actions)
}
ac.RegisterActionResolver(actionSetResolver)
}
hasAccess, err := ac.Evaluate(context.Background(), &tt.user, tt.evaluator)
assert.Equal(t, tt.expected, hasAccess)
if tt.expectedErr != nil {