RBAC: Allow to list users for dashboard / folder admins (#57080)

* RBAC: Use query struct in tests

* RBAC: If access control enforcement is disabled don't filter out users
when fetching permissions
This commit is contained in:
Karl Persson
2022-10-19 11:53:59 +02:00
committed by GitHub
parent 0b72c36527
commit 9adaf1565c
4 changed files with 90 additions and 58 deletions

View File

@@ -22,11 +22,12 @@ type SetResourcePermissionsCommand struct {
}
type GetResourcePermissionsQuery struct {
Actions []string
Resource string
ResourceID string
ResourceAttribute string
OnlyManaged bool
InheritedScopes []string
User *user.SignedInUser
Actions []string
Resource string
ResourceID string
ResourceAttribute string
OnlyManaged bool
InheritedScopes []string
EnforceAccessControl bool
User *user.SignedInUser
}

View File

@@ -125,13 +125,14 @@ func (s *Service) GetPermissions(ctx context.Context, user *user.SignedInUser, r
}
return s.store.GetResourcePermissions(ctx, user.OrgID, GetResourcePermissionsQuery{
User: user,
Actions: s.actions,
Resource: s.options.Resource,
ResourceID: resourceID,
ResourceAttribute: s.options.ResourceAttribute,
InheritedScopes: inheritedScopes,
OnlyManaged: s.options.OnlyManaged,
User: user,
Actions: s.actions,
Resource: s.options.Resource,
ResourceID: resourceID,
ResourceAttribute: s.options.ResourceAttribute,
InheritedScopes: inheritedScopes,
OnlyManaged: s.options.OnlyManaged,
EnforceAccessControl: s.license.FeatureEnabled("accesscontrol.enforcement"),
})
}

View File

@@ -351,13 +351,15 @@ func (s *store) getResourcePermissions(sess *sqlstore.DBSession, orgID int64, qu
}
initialLength := len(args)
userFilter, err := accesscontrol.Filter(query.User, "u.id", "users:id:", accesscontrol.ActionOrgUsersRead)
if err != nil {
return nil, err
userQuery := userSelect + userFrom + where
if query.EnforceAccessControl {
userFilter, err := accesscontrol.Filter(query.User, "u.id", "users:id:", accesscontrol.ActionOrgUsersRead)
if err != nil {
return nil, err
}
userQuery += " AND " + userFilter.Where
args = append(args, userFilter.Args...)
}
user := userSelect + userFrom + where + " AND " + userFilter.Where
args = append(args, userFilter.Args...)
teamFilter, err := accesscontrol.Filter(query.User, "t.id", "teams:id:", accesscontrol.ActionTeamsRead)
if err != nil {
@@ -371,7 +373,7 @@ func (s *store) getResourcePermissions(sess *sqlstore.DBSession, orgID int64, qu
builtin := builtinSelect + builtinFrom + where
args = append(args, args[:initialLength]...)
sql := user + " UNION " + team + " UNION " + builtin
sql := userQuery + " UNION " + team + " UNION " + builtin
queryResults := make([]flatResourcePermission, 0)
if err := sess.SQL(sql, args...).Find(&queryResults); err != nil {
return nil, err

View File

@@ -336,14 +336,11 @@ func TestIntegrationStore_SetResourcePermissions(t *testing.T) {
}
type getResourcePermissionsTest struct {
desc string
user *user.SignedInUser
numUsers int
actions []string
resource string
resourceID string
resourceAttribute string
onlyManaged bool
desc string
user *user.SignedInUser
numUsers int
query GetResourcePermissionsQuery
expectedLen int
}
func TestIntegrationStore_GetResourcePermissions(t *testing.T) {
@@ -355,11 +352,15 @@ func TestIntegrationStore_GetResourcePermissions(t *testing.T) {
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}},
}},
numUsers: 3,
actions: []string{"datasources:query"},
resource: "datasources",
resourceID: "1",
resourceAttribute: "uid",
numUsers: 3,
query: GetResourcePermissionsQuery{
Actions: []string{"datasources:query"},
Resource: "datasources",
ResourceID: "1",
ResourceAttribute: "uid",
EnforceAccessControl: true,
},
expectedLen: 4,
},
{
desc: "should return manage permissions for all resource ids",
@@ -368,22 +369,60 @@ func TestIntegrationStore_GetResourcePermissions(t *testing.T) {
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}},
}},
numUsers: 3,
actions: []string{"datasources:query"},
resource: "datasources",
resourceID: "1",
resourceAttribute: "uid",
onlyManaged: true,
numUsers: 3,
query: GetResourcePermissionsQuery{
Actions: []string{"datasources:query"},
Resource: "datasources",
ResourceID: "1",
ResourceAttribute: "uid",
OnlyManaged: true,
EnforceAccessControl: true,
},
expectedLen: 3,
},
{
desc: "should return users caller can read",
user: &user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {"users:id:1", "users:id:3"}},
}},
numUsers: 3,
query: GetResourcePermissionsQuery{
Actions: []string{"datasources:query"},
Resource: "datasources",
ResourceID: "1",
ResourceAttribute: "uid",
OnlyManaged: true,
EnforceAccessControl: true,
},
expectedLen: 2,
},
{
desc: "should return permissions for all users when access control is not enforces",
user: &user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{1: {}}},
numUsers: 3,
query: GetResourcePermissionsQuery{
Actions: []string{"datasources:query"},
Resource: "datasources",
ResourceID: "1",
ResourceAttribute: "uid",
OnlyManaged: true,
EnforceAccessControl: false,
},
expectedLen: 3,
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
store, sql := setupTestEnv(t)
err := sql.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
role := &accesscontrol.Role{
OrgID: test.user.OrgID,
OrgID: tt.user.OrgID,
UID: "seeded",
Name: "seeded",
Updated: time.Now(),
@@ -416,23 +455,12 @@ func TestIntegrationStore_GetResourcePermissions(t *testing.T) {
})
require.NoError(t, err)
seedResourcePermissions(t, store, sql, test.actions, test.resource, test.resourceID, test.resourceAttribute, test.numUsers)
seedResourcePermissions(t, store, sql, tt.query.Actions, tt.query.Resource, tt.query.ResourceID, tt.query.ResourceAttribute, tt.numUsers)
permissions, err := store.GetResourcePermissions(context.Background(), test.user.OrgID, GetResourcePermissionsQuery{
User: test.user,
Actions: test.actions,
Resource: test.resource,
ResourceID: test.resourceID,
ResourceAttribute: test.resourceAttribute,
OnlyManaged: test.onlyManaged,
})
tt.query.User = tt.user
permissions, err := store.GetResourcePermissions(context.Background(), tt.user.OrgID, tt.query)
require.NoError(t, err)
expectedLen := test.numUsers
if !test.onlyManaged {
expectedLen += 1
}
assert.Len(t, permissions, expectedLen)
assert.Len(t, permissions, tt.expectedLen)
})
}
}