RBAC: Search endpoint support wildcards (#80383)

* RBAC: Search endpoint support wildcards

* Allow wildcard filter with RAM permissions as well
This commit is contained in:
Gabriel MABILLE
2024-01-17 17:07:47 +01:00
committed by GitHub
parent c27bee567f
commit dce9d1e87c
5 changed files with 65 additions and 9 deletions
+11 -6
View File
@@ -3,6 +3,7 @@ package acimpl
import (
"context"
"fmt"
"slices"
"strconv"
"strings"
"time"
@@ -249,7 +250,7 @@ func (s *Service) SearchUsersPermissions(ctx context.Context, user identity.Requ
basicPermissions := map[string][]accesscontrol.Permission{}
for role, basicRole := range s.roles {
for i := range basicRole.Permissions {
if PermissionMatchesSearchOptions(basicRole.Permissions[i], options) {
if PermissionMatchesSearchOptions(basicRole.Permissions[i], &options) {
basicPermissions[role] = append(basicPermissions[role], basicRole.Permissions[i])
}
}
@@ -351,7 +352,7 @@ func (s *Service) searchUserPermissions(ctx context.Context, orgID int64, search
for _, builtin := range roles {
if basicRole, ok := s.roles[builtin]; ok {
for _, permission := range basicRole.Permissions {
if PermissionMatchesSearchOptions(permission, searchOptions) {
if PermissionMatchesSearchOptions(permission, &searchOptions) {
permissions = append(permissions, permission)
}
}
@@ -384,7 +385,7 @@ func (s *Service) searchUserPermissionsFromCache(orgID int64, searchOptions acce
s.log.Debug("Using cached permissions", "key", key)
filteredPermissions := make([]accesscontrol.Permission, 0)
for _, permission := range permissions.([]accesscontrol.Permission) {
if PermissionMatchesSearchOptions(permission, searchOptions) {
if PermissionMatchesSearchOptions(permission, &searchOptions) {
filteredPermissions = append(filteredPermissions, permission)
}
}
@@ -392,9 +393,13 @@ func (s *Service) searchUserPermissionsFromCache(orgID int64, searchOptions acce
return filteredPermissions, true
}
func PermissionMatchesSearchOptions(permission accesscontrol.Permission, searchOptions accesscontrol.SearchOptions) bool {
if searchOptions.Scope != "" && permission.Scope != searchOptions.Scope {
return false
func PermissionMatchesSearchOptions(permission accesscontrol.Permission, searchOptions *accesscontrol.SearchOptions) bool {
if searchOptions.Scope != "" {
// Permissions including the scope should also match
scopes := append(searchOptions.Wildcards(), searchOptions.Scope)
if !slices.Contains[[]string, string](scopes, permission.Scope) {
return false
}
}
if searchOptions.Action != "" {
return permission.Action == searchOptions.Action
@@ -448,6 +448,23 @@ func TestService_SearchUsersPermissions(t *testing.T) {
{Action: accesscontrol.ActionTeamsPermissionsRead, Scope: "teams:*"}},
},
},
{
name: "ram only search on scope",
siuPermissions: listAllPerms,
searchOption: accesscontrol.SearchOptions{Scope: "teams:id:2"},
ramRoles: map[string]*accesscontrol.RoleDTO{
string(roletype.RoleAdmin): {Permissions: []accesscontrol.Permission{
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:*"},
}},
},
storedRoles: map[int64][]string{
1: {string(roletype.RoleEditor)},
2: {string(roletype.RoleAdmin), accesscontrol.RoleGrafanaAdmin},
},
want: map[int64][]accesscontrol.Permission{
2: {{Action: accesscontrol.ActionTeamsRead, Scope: "teams:*"}},
},
},
{
name: "view permission on subset of users only",
siuPermissions: listSomePerms,