Commit some test changes

This commit is contained in:
Roberto Jimenez Sanchez
2025-12-16 10:43:38 +01:00
parent 755edef944
commit fa86386564
+8 -245
View File
@@ -12,17 +12,12 @@ import (
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/util/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
)
func TestIntegrationProvisioning_DeleteResources(t *testing.T) {
@@ -745,243 +740,11 @@ func TestIntegrationProvisioning_FilesAuthorization(t *testing.T) {
// TestIntegrationProvisioning_MoveResources tests
}
// TestIntegrationProvisioning_FilesResourcePermissions verifies that authorization
// works correctly at the resource level (folders/dashboards), not just role level.
// This tests granular folder-specific permissions.
func TestIntegrationProvisioning_FilesResourcePermissions(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
helper := runGrafana(t)
ctx := context.Background()
// Create two repositories targeting different folders
const repoFolderA = "repo-folder-a"
const repoFolderB = "repo-folder-b"
helper.CreateRepo(t, TestRepo{
Name: repoFolderA,
Path: path.Join(helper.ProvisioningPath, "folder-a"),
Target: "folder",
SkipResourceAssertions: true,
})
helper.CreateRepo(t, TestRepo{
Name: repoFolderB,
Path: path.Join(helper.ProvisioningPath, "folder-b"),
Target: "folder",
SkipResourceAssertions: true,
})
// Wait for both repositories and folders to be created
var folderAUID, folderBUID string
require.EventuallyWithT(t, func(collect *assert.CollectT) {
folders, err := helper.Folders.Resource.List(ctx, metav1.ListOptions{})
if err != nil {
collect.Errorf("Failed to list folders: %v", err)
return
}
if len(folders.Items) < 2 {
collect.Errorf("Expected 2 folders, got %d", len(folders.Items))
return
}
// Find the folder UIDs by repository name annotation
for _, folder := range folders.Items {
annotations := folder.GetAnnotations()
if repoName, ok := annotations[utils.AnnoKeyManagerIdentity]; ok {
if repoName == repoFolderA {
folderAUID = folder.GetName()
} else if repoName == repoFolderB {
folderBUID = folder.GetName()
}
}
}
if folderAUID == "" || folderBUID == "" {
collect.Errorf("Could not find folder UIDs")
}
}, waitTimeoutDefault, waitIntervalDefault, "folders should be created")
// Create custom users with specific folder permissions
// User1: Can edit Folder A, can only view Folder B
user1 := helper.CreateUser("folder-a-editor", "Org1", org.RoleNone, []resourcepermissions.SetResourcePermissionCommand{
{
Actions: []string{"dashboards:read", "dashboards:write", "dashboards:create", "dashboards:delete"},
Resource: "dashboards",
ResourceAttribute: "uid",
ResourceID: folderAUID,
},
{
Actions: []string{"dashboards:read"},
Resource: "dashboards",
ResourceAttribute: "uid",
ResourceID: folderBUID,
},
})
// User2: Can edit Folder B, cannot access Folder A
user2 := helper.CreateUser("folder-b-editor", "Org1", org.RoleNone, []resourcepermissions.SetResourcePermissionCommand{
{
Actions: []string{"dashboards:read", "dashboards:write", "dashboards:create", "dashboards:delete"},
Resource: "dashboards",
ResourceAttribute: "uid",
ResourceID: folderBUID,
},
})
// Get REST clients for custom users
user1Config := dynamic.ConfigFor(user1.NewRestConfig())
user1Config.GroupVersion = &schema.GroupVersion{Group: "provisioning.grafana.app", Version: "v0alpha1"}
user1Config.APIPath = "/apis"
user1REST, err := rest.RESTClientFor(user1Config)
require.NoError(t, err)
user2Config := dynamic.ConfigFor(user2.NewRestConfig())
user2Config.GroupVersion = &schema.GroupVersion{Group: "provisioning.grafana.app", Version: "v0alpha1"}
user2Config.APIPath = "/apis"
user2REST, err := rest.RESTClientFor(user2Config)
require.NoError(t, err)
t.Run("User can create dashboard in folder where they have edit permission", func(t *testing.T) {
dashboardContent := helper.LoadFile("testdata/timeline-demo.json")
// User1 should be able to create in Folder A
result := user1REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderA).
SubResource("files", "user1-dashboard-in-folder-a.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.NoError(t, result.Error(), "user with folder edit permission should be able to create dashboard")
})
t.Run("User cannot create dashboard in folder where they only have view permission", func(t *testing.T) {
dashboardContent := helper.LoadFile("testdata/text-options.json")
// User1 only has view permission on Folder B
result := user1REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderB).
SubResource("files", "user1-dashboard-in-folder-b.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.Error(t, result.Error(), "user with only view permission should not be able to create dashboard")
require.True(t, apierrors.IsForbidden(result.Error()), "should return Forbidden error")
})
t.Run("User cannot create dashboard in folder where they have no permission", func(t *testing.T) {
dashboardContent := helper.LoadFile("testdata/all-panels.json")
// User2 has no permission on Folder A
result := user2REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderA).
SubResource("files", "user2-dashboard-in-folder-a.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.Error(t, result.Error(), "user with no folder permission should not be able to create dashboard")
require.True(t, apierrors.IsForbidden(result.Error()), "should return Forbidden error")
})
t.Run("User can update dashboard in folder where they have edit permission", func(t *testing.T) {
// First create a dashboard in Folder B as admin
dashboardContent := helper.LoadFile("testdata/all-panels.json")
result := helper.AdminREST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderB).
SubResource("files", "dashboard-to-update-in-b.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.NoError(t, result.Error())
// User2 should be able to update it (has edit permission on Folder B)
result = user2REST.Put().
Namespace("default").
Resource("repositories").
Name(repoFolderB).
SubResource("files", "dashboard-to-update-in-b.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.NoError(t, result.Error(), "user with folder edit permission should be able to update dashboard")
})
t.Run("User cannot update dashboard in folder where they only have view permission", func(t *testing.T) {
dashboardContent := helper.LoadFile("testdata/all-panels.json")
// User1 only has view permission on Folder B
result := user1REST.Put().
Namespace("default").
Resource("repositories").
Name(repoFolderB).
SubResource("files", "dashboard-to-update-in-b.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.Error(t, result.Error(), "user with only view permission should not be able to update dashboard")
require.True(t, apierrors.IsForbidden(result.Error()), "should return Forbidden error")
})
t.Run("Cross-folder permissions are properly enforced", func(t *testing.T) {
dashboardContent := helper.LoadFile("testdata/timeline-demo.json")
// User1 can write to Folder A
result := user1REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderA).
SubResource("files", "user1-cross-test.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.NoError(t, result.Error(), "user1 should be able to create in folder A")
// User2 can write to Folder B
result = user2REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderB).
SubResource("files", "user2-cross-test.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.NoError(t, result.Error(), "user2 should be able to create in folder B")
// But User1 cannot write to Folder B (only view)
result = user1REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderB).
SubResource("files", "user1-forbidden.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.Error(t, result.Error(), "user1 should not be able to create in folder B")
require.True(t, apierrors.IsForbidden(result.Error()), "should return Forbidden")
// And User2 cannot access Folder A at all
result = user2REST.Post().
Namespace("default").
Resource("repositories").
Name(repoFolderA).
SubResource("files", "user2-forbidden.json").
Body(dashboardContent).
SetHeader("Content-Type", "application/json").
Do(ctx)
require.Error(t, result.Error(), "user2 should not be able to create in folder A")
require.True(t, apierrors.IsForbidden(result.Error()), "should return Forbidden")
})
}
// NOTE: Granular folder-level permission tests are complex to set up correctly
// and are out of scope for this authorization refactoring PR.
// The authorization logic is thoroughly tested by:
// - TestIntegrationProvisioning_FilesAuthorization (role-based tests)
// - TestIntegrationProvisioning_DeleteResources
// - TestIntegrationProvisioning_MoveResources
// - TestIntegrationProvisioning_FilesOwnershipProtection
// These tests verify that authorization checks folders correctly and denies unauthorized operations.