Files
grafana/pkg/services/authz/zanzana/server/server_mutate_folder_test.go
T
Jo 318a0ebb36 IAM: Authorize writes to zanzana on token permissions (#115645)
* validate writes to zanzana, not reads

* lint ignore
2025-12-31 09:15:00 +00:00

165 lines
4.3 KiB
Go

package server
import (
"testing"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"github.com/stretchr/testify/require"
v1 "github.com/grafana/grafana/pkg/services/authz/proto/v1"
"github.com/grafana/grafana/pkg/services/authz/zanzana/common"
)
func setupMutateFolders(t *testing.T, srv *Server) *Server {
t.Helper()
// seed tuples
tuples := []*openfgav1.TupleKey{
common.NewFolderParentTuple("11", "1"),
common.NewFolderParentTuple("12", "1"),
common.NewFolderParentTuple("111", "11"),
common.NewFolderParentTuple("112", "11"),
common.NewFolderParentTuple("broken", "foo"),
common.NewFolderParentTuple("broken", "bar"),
}
return setupOpenFGADatabase(t, srv, tuples)
}
func testMutateFolders(t *testing.T, srv *Server) {
setupMutateFolders(t, srv)
t.Run("should create new folder parent relation", func(t *testing.T) {
_, err := srv.Mutate(newContextWithZanzanaUpdatePermission(), &v1.MutateRequest{
Namespace: "default",
Operations: []*v1.MutateOperation{
{
Operation: &v1.MutateOperation_SetFolderParent{
SetFolderParent: &v1.SetFolderParentOperation{
Folder: "new-folder",
Parent: "1",
DeleteExisting: false,
},
},
},
},
})
require.NoError(t, err)
res, err := srv.Read(newContextWithNamespace(), &v1.ReadRequest{
Namespace: "default",
TupleKey: &v1.ReadRequestTupleKey{
Object: "folder:new-folder",
Relation: "parent",
},
})
require.NoError(t, err)
require.Len(t, res.Tuples, 1)
require.Equal(t, "folder:new-folder", res.Tuples[0].Key.Object)
require.Equal(t, "parent", res.Tuples[0].Key.Relation)
require.Equal(t, "folder:1", res.Tuples[0].Key.User)
})
t.Run("should delete folder parent relation", func(t *testing.T) {
_, err := srv.Mutate(newContextWithZanzanaUpdatePermission(), &v1.MutateRequest{
Namespace: "default",
Operations: []*v1.MutateOperation{
{
Operation: &v1.MutateOperation_DeleteFolder{
DeleteFolder: &v1.DeleteFolderOperation{
Folder: "11",
Parent: "1",
},
},
},
},
})
require.NoError(t, err)
res, err := srv.Read(newContextWithNamespace(), &v1.ReadRequest{
Namespace: "default",
TupleKey: &v1.ReadRequestTupleKey{
Object: "folder:11",
Relation: "parent",
},
})
require.NoError(t, err)
require.Len(t, res.Tuples, 0)
})
t.Run("should clean up all parent relations", func(t *testing.T) {
_, err := srv.Mutate(newContextWithZanzanaUpdatePermission(), &v1.MutateRequest{
Namespace: "default",
Operations: []*v1.MutateOperation{
{
Operation: &v1.MutateOperation_DeleteFolder{
DeleteFolder: &v1.DeleteFolderOperation{
Folder: "broken",
DeleteExisting: true,
},
},
},
},
})
require.NoError(t, err)
res, err := srv.Read(newContextWithNamespace(), &v1.ReadRequest{
Namespace: "default",
TupleKey: &v1.ReadRequestTupleKey{
Object: "folder:broken",
Relation: "parent",
},
})
require.NoError(t, err)
require.Len(t, res.Tuples, 0)
})
t.Run("should perform batch mutate if multiple operations are provided", func(t *testing.T) {
_, err := srv.Mutate(newContextWithZanzanaUpdatePermission(), &v1.MutateRequest{
Namespace: "default",
Operations: []*v1.MutateOperation{
{
Operation: &v1.MutateOperation_SetFolderParent{
SetFolderParent: &v1.SetFolderParentOperation{
Folder: "new-folder-2",
Parent: "1",
},
},
},
{
Operation: &v1.MutateOperation_DeleteFolder{
DeleteFolder: &v1.DeleteFolderOperation{
Folder: "12",
Parent: "1",
},
},
},
},
})
require.NoError(t, err)
res, err := srv.Read(newContextWithNamespace(), &v1.ReadRequest{
Namespace: "default",
TupleKey: &v1.ReadRequestTupleKey{
Object: "folder:new-folder-2",
Relation: "parent",
},
})
require.NoError(t, err)
require.Len(t, res.Tuples, 1)
require.Equal(t, "folder:new-folder-2", res.Tuples[0].Key.Object)
require.Equal(t, "parent", res.Tuples[0].Key.Relation)
require.Equal(t, "folder:1", res.Tuples[0].Key.User)
res, err = srv.Read(newContextWithNamespace(), &v1.ReadRequest{
Namespace: "default",
TupleKey: &v1.ReadRequestTupleKey{
Object: "folder:12",
Relation: "parent",
},
})
require.NoError(t, err)
require.Len(t, res.Tuples, 0)
})
}