mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: Remove folder name scope resolver (#96484)
* remove folder name scope resolver * update test
This commit is contained in:
parent
7d10ffff1b
commit
0a85f15214
@ -42,37 +42,6 @@ var (
|
||||
tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/dashboards")
|
||||
)
|
||||
|
||||
// NewFolderNameScopeResolver provides an ScopeAttributeResolver that is able to convert a scope prefixed with "folders:name:" into an uid based scope.
|
||||
func NewFolderNameScopeResolver(folderDB folder.FolderStore, folderStore folder.Store) (string, ac.ScopeAttributeResolver) {
|
||||
prefix := ScopeFoldersProvider.GetResourceScopeName("")
|
||||
return prefix, ac.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, scope string) ([]string, error) {
|
||||
ctx, span := tracer.Start(ctx, "dashboards.NewFolderNameScopeResolver")
|
||||
span.End()
|
||||
|
||||
if !strings.HasPrefix(scope, prefix) {
|
||||
return nil, ac.ErrInvalidScope
|
||||
}
|
||||
nsName := scope[len(prefix):]
|
||||
if len(nsName) == 0 {
|
||||
return nil, ac.ErrInvalidScope
|
||||
}
|
||||
// this will fetch only root folders
|
||||
// this is legacy code so most probably it is not used
|
||||
folder, err := folderDB.GetFolderByTitle(ctx, orgID, nsName, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := GetInheritedScopes(ctx, folder.OrgID, folder.UID, folderStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append([]string{ScopeFoldersProvider.GetResourceScopeUID(folder.UID)}, result...)
|
||||
return result, nil
|
||||
})
|
||||
}
|
||||
|
||||
// NewFolderIDScopeResolver provides an ScopeAttributeResolver that is able to convert a scope prefixed with "folders:id:" into an uid based scope.
|
||||
func NewFolderIDScopeResolver(folderDB folder.FolderStore, folderStore folder.Store) (string, ac.ScopeAttributeResolver) {
|
||||
prefix := ScopeFoldersProvider.GetResourceScope("")
|
||||
|
@ -2,105 +2,17 @@ package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/folder/foldertest"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func TestNewFolderNameScopeResolver(t *testing.T) {
|
||||
t.Run("prefix should be expected", func(t *testing.T) {
|
||||
prefix, _ := NewFolderNameScopeResolver(foldertest.NewFakeFolderStore(t), folder.NewFakeStore())
|
||||
require.Equal(t, "folders:name:", prefix)
|
||||
})
|
||||
|
||||
t.Run("resolver should convert to uid scope", func(t *testing.T) {
|
||||
orgId := rand.Int63()
|
||||
title := "Very complex :title with: and /" + util.GenerateShortUID()
|
||||
db := &folder.Folder{Title: title, UID: util.GenerateShortUID()}
|
||||
folderStore := foldertest.NewFakeFolderStore(t)
|
||||
folderStore.On("GetFolderByTitle", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(db, nil).Once()
|
||||
|
||||
scope := "folders:name:" + title
|
||||
|
||||
_, resolver := NewFolderNameScopeResolver(folderStore, folder.NewFakeStore())
|
||||
resolvedScopes, err := resolver.Resolve(context.Background(), orgId, scope)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, resolvedScopes, 1)
|
||||
require.Equal(t, fmt.Sprintf("folders:uid:%v", db.UID), resolvedScopes[0])
|
||||
folderStore.AssertCalled(t, "GetFolderByTitle", mock.Anything, orgId, title, mock.Anything)
|
||||
})
|
||||
t.Run("resolver should include inherited scopes if any", func(t *testing.T) {
|
||||
orgId := rand.Int63()
|
||||
title := "Very complex :title with: and /" + util.GenerateShortUID()
|
||||
|
||||
db := &folder.Folder{Title: title, UID: util.GenerateShortUID()}
|
||||
|
||||
folderStore := foldertest.NewFakeFolderStore(t)
|
||||
folderStore.On("GetFolderByTitle", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(db, nil).Once()
|
||||
|
||||
scope := "folders:name:" + title
|
||||
|
||||
fStore := folder.NewFakeStore()
|
||||
fStore.ExpectedParentFolders = []*folder.Folder{
|
||||
{
|
||||
UID: "parent",
|
||||
},
|
||||
{
|
||||
UID: "grandparent",
|
||||
},
|
||||
}
|
||||
_, resolver := NewFolderNameScopeResolver(folderStore, fStore)
|
||||
|
||||
resolvedScopes, err := resolver.Resolve(context.Background(), orgId, scope)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, resolvedScopes, 3)
|
||||
|
||||
if diff := cmp.Diff([]string{
|
||||
fmt.Sprintf("folders:uid:%v", db.UID),
|
||||
"folders:uid:parent",
|
||||
"folders:uid:grandparent",
|
||||
}, resolvedScopes); diff != "" {
|
||||
t.Errorf("Result mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
|
||||
folderStore.AssertCalled(t, "GetFolderByTitle", mock.Anything, orgId, title, mock.Anything)
|
||||
})
|
||||
t.Run("resolver should fail if input scope is not expected", func(t *testing.T) {
|
||||
_, resolver := NewFolderNameScopeResolver(foldertest.NewFakeFolderStore(t), folder.NewFakeStore())
|
||||
|
||||
_, err := resolver.Resolve(context.Background(), rand.Int63(), "folders:id:123")
|
||||
require.ErrorIs(t, err, ac.ErrInvalidScope)
|
||||
})
|
||||
t.Run("resolver should fail if resource of input scope is empty", func(t *testing.T) {
|
||||
_, resolver := NewFolderNameScopeResolver(foldertest.NewFakeFolderStore(t), folder.NewFakeStore())
|
||||
|
||||
_, err := resolver.Resolve(context.Background(), rand.Int63(), "folders:name:")
|
||||
require.ErrorIs(t, err, ac.ErrInvalidScope)
|
||||
})
|
||||
t.Run("returns 'not found' if folder does not exist", func(t *testing.T) {
|
||||
folderStore := foldertest.NewFakeFolderStore(t)
|
||||
_, resolver := NewFolderNameScopeResolver(folderStore, folder.NewFakeStore())
|
||||
|
||||
orgId := rand.Int63()
|
||||
folderStore.On("GetFolderByTitle", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, ErrDashboardNotFound).Once()
|
||||
|
||||
scope := "folders:name:" + util.GenerateShortUID()
|
||||
|
||||
resolvedScopes, err := resolver.Resolve(context.Background(), orgId, scope)
|
||||
require.ErrorIs(t, err, ErrDashboardNotFound)
|
||||
require.Nil(t, resolvedScopes)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewFolderIDScopeResolver(t *testing.T) {
|
||||
t.Run("prefix should be expected", func(t *testing.T) {
|
||||
prefix, _ := NewFolderIDScopeResolver(foldertest.NewFakeFolderStore(t), folder.NewFakeStore())
|
||||
|
@ -95,7 +95,6 @@ func ProvideService(
|
||||
|
||||
supportBundles.RegisterSupportItemCollector(srv.supportBundleCollector())
|
||||
|
||||
ac.RegisterScopeAttributeResolver(dashboards.NewFolderNameScopeResolver(folderStore, store))
|
||||
ac.RegisterScopeAttributeResolver(dashboards.NewFolderIDScopeResolver(folderStore, store))
|
||||
ac.RegisterScopeAttributeResolver(dashboards.NewFolderUIDScopeResolver(store))
|
||||
return srv
|
||||
|
@ -68,7 +68,7 @@ func TestIntegrationProvideFolderService(t *testing.T) {
|
||||
ProvideService(store, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), nil, nil, db,
|
||||
featuremgmt.WithFeatures(), cfg, folderPermissions, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
|
||||
|
||||
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 3)
|
||||
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user