diff --git a/csharp/App/Backend/DataTypes/Methods/Session.cs b/csharp/App/Backend/DataTypes/Methods/Session.cs index b9aee8351..5506baeee 100644 --- a/csharp/App/Backend/DataTypes/Methods/Session.cs +++ b/csharp/App/Backend/DataTypes/Methods/Session.cs @@ -41,9 +41,12 @@ public static class SessionMethods var user = session?.User; var folder = Db.GetFolderById(folderId); var parent = Db.GetFolderById(parentId); - + return user is not null && folder is not null + && parent is not null + && folderId != parentId // can't move into itself + && !IsFolderAncestorOf(folderId, parentId) // can't move into a descendant && user.UserType==2 && user.HasAccessTo(folder) && user.HasAccessTo(parent) @@ -51,6 +54,19 @@ public static class SessionMethods .Do(() => folder.ParentId = parentId) .Apply(Db.Update); } + + // Walks up the folder tree from candidateDescendantId to check if ancestorId is an ancestor. + // Prevents circular references when moving a folder into one of its own descendants. + private static Boolean IsFolderAncestorOf(Int64 ancestorId, Int64 candidateDescendantId) + { + var current = Db.GetFolderById(candidateDescendantId); + while (current is not null && current.ParentId != 0) + { + if (current.ParentId == ancestorId) return true; + current = Db.GetFolderById(current.ParentId); + } + return false; + } public static Boolean MoveInstallation(this Session? session, Int64 installationId, Int64 parentId) {