mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Authz: For list collect all folder permisions into items (#99955)
* For list collect all folder permisions into items --------- Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
parent
4cd2ebe186
commit
d16374d339
@ -619,27 +619,28 @@ func (s *Service) listPermission(ctx context.Context, scopeMap map[string]bool,
|
||||
}
|
||||
}
|
||||
|
||||
folderSet := make(map[string]struct{}, len(scopeMap))
|
||||
var res *authzv1.ListResponse
|
||||
if strings.HasPrefix(req.Action, "folders:") {
|
||||
res = buildFolderList(scopeMap, folderMap)
|
||||
} else {
|
||||
res = buildItemList(scopeMap, folderMap, t.prefix())
|
||||
}
|
||||
|
||||
prefix := t.prefix()
|
||||
itemSet := make(map[string]struct{}, len(scopeMap))
|
||||
for scope := range scopeMap {
|
||||
if strings.HasPrefix(scope, "folders:uid:") {
|
||||
span.SetAttributes(attribute.Int("num_folders", len(res.Folders)), attribute.Int("num_items", len(res.Items)))
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func buildFolderList(scopes map[string]bool, tree map[string]FolderNode) *authzv1.ListResponse {
|
||||
itemSet := make(map[string]struct{}, len(scopes))
|
||||
|
||||
for scope := range scopes {
|
||||
identifier := strings.TrimPrefix(scope, "folders:uid:")
|
||||
if _, ok := folderSet[identifier]; ok {
|
||||
if _, ok := itemSet[identifier]; ok {
|
||||
continue
|
||||
}
|
||||
folderSet[identifier] = struct{}{}
|
||||
getChildren(folderMap, identifier, folderSet)
|
||||
} else {
|
||||
identifier := strings.TrimPrefix(scope, prefix)
|
||||
itemSet[identifier] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
folderList := make([]string, 0, len(folderSet))
|
||||
for folder := range folderSet {
|
||||
folderList = append(folderList, folder)
|
||||
itemSet[identifier] = struct{}{}
|
||||
getChildren(tree, identifier, itemSet)
|
||||
}
|
||||
|
||||
itemList := make([]string, 0, len(itemSet))
|
||||
@ -647,8 +648,35 @@ func (s *Service) listPermission(ctx context.Context, scopeMap map[string]bool,
|
||||
itemList = append(itemList, item)
|
||||
}
|
||||
|
||||
span.SetAttributes(attribute.Int("num_folders", len(folderList)), attribute.Int("num_items", len(itemList)))
|
||||
return &authzv1.ListResponse{Folders: folderList, Items: itemList}, nil
|
||||
return &authzv1.ListResponse{Items: itemList}
|
||||
}
|
||||
|
||||
func buildItemList(scopes map[string]bool, tree map[string]FolderNode, prefix string) *authzv1.ListResponse {
|
||||
folderSet := make(map[string]struct{}, len(scopes))
|
||||
itemSet := make(map[string]struct{}, len(scopes))
|
||||
|
||||
for scope := range scopes {
|
||||
if identifier, ok := strings.CutPrefix(scope, "folders:uid:"); ok {
|
||||
if _, ok := folderSet[identifier]; ok {
|
||||
continue
|
||||
}
|
||||
folderSet[identifier] = struct{}{}
|
||||
getChildren(tree, identifier, folderSet)
|
||||
} else {
|
||||
identifier := strings.TrimPrefix(scope, prefix)
|
||||
itemSet[identifier] = struct{}{}
|
||||
}
|
||||
}
|
||||
folderList := make([]string, 0, len(folderSet))
|
||||
for folder := range folderSet {
|
||||
folderList = append(folderList, folder)
|
||||
}
|
||||
itemList := make([]string, 0, len(itemSet))
|
||||
for item := range itemSet {
|
||||
itemList = append(itemList, item)
|
||||
}
|
||||
|
||||
return &authzv1.ListResponse{Folders: folderList, Items: itemList}
|
||||
}
|
||||
|
||||
func getChildren(folderMap map[string]FolderNode, folderUID string, folderSet map[string]struct{}) {
|
||||
|
@ -456,7 +456,7 @@ func TestService_listPermission(t *testing.T) {
|
||||
permissions []accesscontrol.Permission
|
||||
folderTree map[string]FolderNode
|
||||
list ListRequest
|
||||
expectedDashboards []string
|
||||
expectedItems []string
|
||||
expectedFolders []string
|
||||
expectedAll bool
|
||||
}
|
||||
@ -512,7 +512,7 @@ func TestService_listPermission(t *testing.T) {
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
},
|
||||
expectedDashboards: []string{"some_dashboard"},
|
||||
expectedItems: []string{"some_dashboard"},
|
||||
expectedFolders: []string{"some_folder_1", "some_folder_2"},
|
||||
},
|
||||
{
|
||||
@ -568,7 +568,7 @@ func TestService_listPermission(t *testing.T) {
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
},
|
||||
expectedDashboards: []string{"some_dashboard"},
|
||||
expectedItems: []string{"some_dashboard"},
|
||||
expectedFolders: []string{"some_folder_parent", "some_folder_child"},
|
||||
},
|
||||
{
|
||||
@ -613,6 +613,28 @@ func TestService_listPermission(t *testing.T) {
|
||||
Resource: "dashboards",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should collect folder permissions into items",
|
||||
permissions: []accesscontrol.Permission{
|
||||
{
|
||||
Action: "folders:read",
|
||||
Scope: "folders:uid:some_folder_parent",
|
||||
Kind: "folders",
|
||||
Attribute: "uid",
|
||||
Identifier: "some_folder_parent",
|
||||
},
|
||||
},
|
||||
folderTree: map[string]FolderNode{
|
||||
"some_folder_parent": {UID: "some_folder_parent", ChildrenUIDs: []string{"some_folder_child"}},
|
||||
"some_folder_child": {UID: "some_folder_child", ParentUID: strPtr("some_folder_parent")},
|
||||
},
|
||||
list: ListRequest{
|
||||
Action: "folders:read",
|
||||
Group: "folder.grafana.app",
|
||||
Resource: "folders",
|
||||
},
|
||||
expectedItems: []string{"some_folder_parent", "some_folder_child"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -626,7 +648,7 @@ func TestService_listPermission(t *testing.T) {
|
||||
got, err := s.listPermission(context.Background(), getScopeMap(tc.permissions), &tc.list)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedAll, got.All)
|
||||
assert.ElementsMatch(t, tc.expectedDashboards, got.Items)
|
||||
assert.ElementsMatch(t, tc.expectedItems, got.Items)
|
||||
assert.ElementsMatch(t, tc.expectedFolders, got.Folders)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user