RBAC: Add and resolve action sets when searching user's permissions (#88694)
* include and resolve action sets when fetching user's permissions * expand both action and action prefix (returns an empty set for the one that isn't specified) Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> * if action is specified, check for exact match; also extend tests
This commit is contained in:
@@ -3,6 +3,7 @@ package acimpl
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -599,13 +600,15 @@ func TestService_SearchUsersPermissions(t *testing.T) {
|
||||
func TestService_SearchUserPermissions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
tests := []struct {
|
||||
name string
|
||||
searchOption accesscontrol.SearchOptions
|
||||
ramRoles map[string]*accesscontrol.RoleDTO // BasicRole => RBAC BasicRole
|
||||
storedPerms map[int64][]accesscontrol.Permission // UserID => Permissions
|
||||
storedRoles map[int64][]string // UserID => Roles
|
||||
want []accesscontrol.Permission
|
||||
wantErr bool
|
||||
name string
|
||||
searchOption accesscontrol.SearchOptions
|
||||
withActionSets bool
|
||||
actionSets map[string][]string
|
||||
ramRoles map[string]*accesscontrol.RoleDTO // BasicRole => RBAC BasicRole
|
||||
storedPerms map[int64][]accesscontrol.Permission // UserID => Permissions
|
||||
storedRoles map[int64][]string // UserID => Roles
|
||||
want []accesscontrol.Permission
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "ram only",
|
||||
@@ -726,10 +729,86 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:*"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "check action sets are correctly included if an action is specified",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
Action: "dashboards:read",
|
||||
NamespacedID: fmt.Sprintf("%s:1", identity.NamespaceUser),
|
||||
},
|
||||
withActionSets: true,
|
||||
actionSets: map[string][]string{
|
||||
"dashboards:view": {"dashboards:read"},
|
||||
"dashboards:edit": {"dashboards:read", "dashboards:write", "dashboards:read-advanced"},
|
||||
},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(roletype.RoleEditor): {Permissions: []accesscontrol.Permission{
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:ram"},
|
||||
}},
|
||||
},
|
||||
storedRoles: map[int64][]string{
|
||||
1: {string(roletype.RoleEditor)},
|
||||
},
|
||||
storedPerms: map[int64][]accesscontrol.Permission{
|
||||
1: {
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored"},
|
||||
{Action: "dashboards:edit", Scope: "dashboards:uid:stored2"},
|
||||
{Action: "dashboards:view", Scope: "dashboards:uid:stored3"},
|
||||
},
|
||||
},
|
||||
want: []accesscontrol.Permission{
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:ram"},
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored"},
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored2"},
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored3"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "check action sets are correctly included if an action prefix is specified",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "dashboards",
|
||||
NamespacedID: fmt.Sprintf("%s:1", identity.NamespaceUser),
|
||||
},
|
||||
withActionSets: true,
|
||||
actionSets: map[string][]string{
|
||||
"dashboards:view": {"dashboards:read"},
|
||||
"folders:view": {"dashboards:read", "folders:read"},
|
||||
"dashboards:edit": {"dashboards:read", "dashboards:write"},
|
||||
},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(roletype.RoleEditor): {Permissions: []accesscontrol.Permission{
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:ram"},
|
||||
}},
|
||||
},
|
||||
storedRoles: map[int64][]string{
|
||||
1: {string(roletype.RoleEditor)},
|
||||
},
|
||||
storedPerms: map[int64][]accesscontrol.Permission{
|
||||
1: {
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored"},
|
||||
{Action: "folders:view", Scope: "folders:uid:stored2"},
|
||||
{Action: "dashboards:edit", Scope: "dashboards:uid:stored3"},
|
||||
},
|
||||
},
|
||||
want: []accesscontrol.Permission{
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:ram"},
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored"},
|
||||
{Action: "dashboards:read", Scope: "folders:uid:stored2"},
|
||||
{Action: "dashboards:read", Scope: "dashboards:uid:stored3"},
|
||||
{Action: "dashboards:write", Scope: "dashboards:uid:stored3"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ac := setupTestEnv(t)
|
||||
if tt.withActionSets {
|
||||
ac.features = featuremgmt.WithFeatures(featuremgmt.FlagAccessActionSets)
|
||||
actionSetSvc := resourcepermissions.NewActionSetService()
|
||||
for set, actions := range tt.actionSets {
|
||||
actionSetSvc.StoreActionSet(strings.Split(set, ":")[0], strings.Split(set, ":")[1], actions)
|
||||
}
|
||||
ac.actionResolver = actionSetSvc
|
||||
}
|
||||
|
||||
ac.roles = tt.ramRoles
|
||||
ac.store = actest.FakeStore{
|
||||
|
||||
Reference in New Issue
Block a user