fix(folders): prevent circular dependencies (#113595)

This commit is contained in:
Jean-Philippe Quéméner
2025-11-07 14:19:55 +00:00
committed by GitHub
parent e5ed003fb2
commit 1ca95cda4a
2 changed files with 73 additions and 0 deletions
+8
View File
@@ -120,6 +120,14 @@ func validateOnUpdate(ctx context.Context,
return err
}
// Check that the folder being moved is not an ancestor of the target parent.
// This prevents circular references (e.g., moving A under B when B is already under A).
for _, ancestor := range info.Items {
if ancestor.Name == obj.Name {
return fmt.Errorf("cannot move folder under its own descendant, this would create a circular reference")
}
}
// if by moving a folder we exceed the max depth, return an error
if len(info.Items) > maxDepth+1 {
return folder.ErrMaximumDepthReached.Errorf("maximum folder depth reached")
@@ -264,6 +264,71 @@ func TestValidateUpdate(t *testing.T) {
maxDepth: folder.MaxNestedFolderDepth,
expectedErr: "[folder.maximum-depth-reached]",
},
{
name: "error when moving folder under its own descendant (direct child)",
folder: &folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "parent",
Annotations: map[string]string{
utils.AnnoKeyFolder: "child",
},
},
Spec: folders.FolderSpec{
Title: "parent folder",
},
},
old: &folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "parent",
},
Spec: folders.FolderSpec{
Title: "parent folder",
},
},
// When querying parents of "child", we get the chain: child -> parent -> root
// This means "parent" is an ancestor of "child", so we can't move "parent" under "child"
parents: &folders.FolderInfoList{
Items: []folders.FolderInfo{
{Name: "child", Parent: "parent"},
{Name: "parent", Parent: folder.GeneralFolderUID},
{Name: folder.GeneralFolderUID},
},
},
expectedErr: "cannot move folder under its own descendant",
},
{
name: "error when moving folder under its grandchild",
folder: &folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "grandparent",
Annotations: map[string]string{
utils.AnnoKeyFolder: "grandchild",
},
},
Spec: folders.FolderSpec{
Title: "grandparent folder",
},
},
old: &folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "grandparent",
},
Spec: folders.FolderSpec{
Title: "grandparent folder",
},
},
// When querying parents of "grandchild", we get: grandchild -> child -> grandparent -> root
// This means "grandparent" is in the ancestry, so we can't move it under "grandchild"
parents: &folders.FolderInfoList{
Items: []folders.FolderInfo{
{Name: "grandchild", Parent: "child"},
{Name: "child", Parent: "grandparent"},
{Name: "grandparent", Parent: folder.GeneralFolderUID},
{Name: folder.GeneralFolderUID},
},
},
expectedErr: "cannot move folder under its own descendant",
},
}
for _, tt := range tests {