2424use OCP \Files \InvalidCharacterInPathException ;
2525use OCP \Files \InvalidDirectoryException ;
2626use OCP \Files \InvalidPathException ;
27+ use OCP \Files \Mount \IMountManager ;
2728use OCP \Files \Mount \IMountPoint ;
2829use OCP \Files \NotFoundException ;
2930use OCP \Files \ReservedWordException ;
3233use OCP \Lock \ILockingProvider ;
3334use OCP \Lock \LockedException ;
3435use OCP \Server ;
35- use OCP \Share \IManager ;
36- use OCP \Share \IShare ;
3736use Psr \Log \LoggerInterface ;
3837
3938/**
@@ -701,6 +700,9 @@ public function rename($source, $target) {
701700 throw new ForbiddenException ('Moving a folder into a child folder is forbidden ' , false );
702701 }
703702
703+ /** @var IMountManager $mountManager */
704+ $ mountManager = \OC ::$ server ->get (IMountManager::class);
705+
704706 $ targetParts = explode ('/ ' , $ absolutePath2 );
705707 $ targetUser = $ targetParts [1 ] ?? null ;
706708 $ result = false ;
@@ -758,22 +760,20 @@ public function rename($source, $target) {
758760 try {
759761 $ this ->changeLock ($ target , ILockingProvider::LOCK_EXCLUSIVE , true );
760762
763+ $ movedMounts = $ mountManager ->findIn ($ this ->getAbsolutePath ($ source ));
764+
761765 if ($ internalPath1 === '' ) {
762- if ($ mount1 instanceof MoveableMount) {
763- $ sourceParentMount = $ this ->getMount (dirname ($ source ));
764- if ($ sourceParentMount === $ mount2 && $ this ->targetIsNotShared ($ targetUser , $ absolutePath2 )) {
765- /**
766- * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
767- */
768- $ sourceMountPoint = $ mount1 ->getMountPoint ();
769- $ result = $ mount1 ->moveMount ($ absolutePath2 );
770- $ manager ->moveMount ($ sourceMountPoint , $ mount1 ->getMountPoint ());
771- } else {
772- $ result = false ;
773- }
774- } else {
775- $ result = false ;
776- }
766+ $ sourceParentMount = $ this ->getMount (dirname ($ source ));
767+ $ movedMounts [] = $ mount1 ;
768+ $ this ->validateMountMove ($ movedMounts , $ sourceParentMount , $ mount2 );
769+
770+ /**
771+ * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
772+ */
773+ $ sourceMountPoint = $ mount1 ->getMountPoint ();
774+ $ result = $ mount1 ->moveMount ($ absolutePath2 );
775+ $ manager ->moveMount ($ sourceMountPoint , $ mount1 ->getMountPoint ());
776+
777777 // moving a file/folder within the same mount point
778778 } elseif ($ storage1 === $ storage2 ) {
779779 if ($ storage1 ) {
@@ -783,6 +783,7 @@ public function rename($source, $target) {
783783 }
784784 // moving a file/folder between storages (from $storage1 to $storage2)
785785 } else {
786+ $ this ->validateMountMove ($ movedMounts , $ mount1 , $ mount2 );
786787 $ result = $ storage2 ->moveFromStorage ($ storage1 , $ internalPath1 , $ internalPath2 );
787788 }
788789
@@ -832,6 +833,28 @@ public function rename($source, $target) {
832833 return $ result ;
833834 }
834835
836+ private function validateMountMove (array $ mounts , IMountPoint $ sourceMount , IMountPoint $ targetMount ): void {
837+ $ targetType = 'storage ' ;
838+ if ($ targetMount instanceof SharedMount) {
839+ $ targetType = 'share ' ;
840+ }
841+ $ targetPath = rtrim ($ targetMount ->getMountPoint (), '/ ' );
842+
843+ if ($ sourceMount !== $ targetMount ) {
844+ foreach ($ mounts as $ mount ) {
845+ $ sourcePath = rtrim ($ mount ->getMountPoint (), '/ ' );
846+ if (!$ mount instanceof MoveableMount) {
847+ throw new ForbiddenException ("Storage {$ sourcePath } cannot be moved " , false );
848+ }
849+ $ sourceType = 'storage ' ;
850+ if ($ mount instanceof SharedMount) {
851+ $ sourceType = 'share ' ;
852+ }
853+ throw new ForbiddenException ("Moving a $ sourceType ( $ sourcePath) into another $ targetType ( $ targetPath) is not allowed " , false );
854+ }
855+ }
856+ }
857+
835858 /**
836859 * Copy a file/folder from the source path to target path
837860 *
@@ -1791,40 +1814,6 @@ private function assertPathLength($path): void {
17911814 }
17921815 }
17931816
1794- /**
1795- * check if it is allowed to move a mount point to a given target.
1796- * It is not allowed to move a mount point into a different mount point or
1797- * into an already shared folder
1798- */
1799- private function targetIsNotShared (string $ user , string $ targetPath ): bool {
1800- $ providers = [
1801- IShare::TYPE_USER ,
1802- IShare::TYPE_GROUP ,
1803- IShare::TYPE_EMAIL ,
1804- IShare::TYPE_CIRCLE ,
1805- IShare::TYPE_ROOM ,
1806- IShare::TYPE_DECK ,
1807- IShare::TYPE_SCIENCEMESH
1808- ];
1809- $ shareManager = Server::get (IManager::class);
1810- /** @var IShare[] $shares */
1811- $ shares = array_merge (...array_map (function (int $ type ) use ($ shareManager , $ user ) {
1812- return $ shareManager ->getSharesBy ($ user , $ type );
1813- }, $ providers ));
1814-
1815- foreach ($ shares as $ share ) {
1816- $ sharedPath = $ share ->getNode ()->getPath ();
1817- if ($ targetPath === $ sharedPath || str_starts_with ($ targetPath , $ sharedPath . '/ ' )) {
1818- $ this ->logger ->debug (
1819- 'It is not allowed to move one mount point into a shared folder ' ,
1820- ['app ' => 'files ' ]);
1821- return false ;
1822- }
1823- }
1824-
1825- return true ;
1826- }
1827-
18281817 /**
18291818 * Get a fileinfo object for files that are ignored in the cache (part files)
18301819 */
0 commit comments