|
63 | 63 | use OCP\Files\InvalidCharacterInPathException; |
64 | 64 | use OCP\Files\InvalidDirectoryException; |
65 | 65 | use OCP\Files\InvalidPathException; |
| 66 | +use OCP\Files\Mount\IMountManager; |
66 | 67 | use OCP\Files\Mount\IMountPoint; |
67 | 68 | use OCP\Files\NotFoundException; |
68 | 69 | use OCP\Files\ReservedWordException; |
@@ -739,6 +740,9 @@ public function rename($source, $target) { |
739 | 740 | throw new ForbiddenException("Moving a folder into a child folder is forbidden", false); |
740 | 741 | } |
741 | 742 |
|
| 743 | + /** @var IMountManager $mountManager */ |
| 744 | + $mountManager = \OC::$server->get(IMountManager::class); |
| 745 | + |
742 | 746 | $targetParts = explode('/', $absolutePath2); |
743 | 747 | $targetUser = $targetParts[1] ?? null; |
744 | 748 | $result = false; |
@@ -792,31 +796,35 @@ public function rename($source, $target) { |
792 | 796 | try { |
793 | 797 | $this->changeLock($target, ILockingProvider::LOCK_EXCLUSIVE, true); |
794 | 798 |
|
| 799 | + $movedMounts = $mountManager->findIn($this->getAbsolutePath($source)); |
| 800 | + |
795 | 801 | if ($internalPath1 === '') { |
796 | | - if ($mount1 instanceof MoveableMount) { |
797 | | - $sourceParentMount = $this->getMount(dirname($source)); |
798 | | - if ($sourceParentMount === $mount2 && $this->targetIsNotShared($targetUser, $absolutePath2)) { |
799 | | - /** |
800 | | - * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1 |
801 | | - */ |
802 | | - $sourceMountPoint = $mount1->getMountPoint(); |
803 | | - $result = $mount1->moveMount($absolutePath2); |
804 | | - $manager->moveMount($sourceMountPoint, $mount1->getMountPoint()); |
805 | | - } else { |
806 | | - $result = false; |
807 | | - } |
808 | | - } else { |
809 | | - $result = false; |
810 | | - } |
| 802 | + $sourceParentMount = $this->getMount(dirname($source)); |
| 803 | + $movedMounts[] = $mount1; |
| 804 | + $this->validateMountMove($movedMounts, $sourceParentMount, $mount2, !$this->targetIsNotShared($targetUser, $absolutePath2)); |
| 805 | + |
| 806 | + /** |
| 807 | + * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1 |
| 808 | + */ |
| 809 | + $sourceMountPoint = $mount1->getMountPoint(); |
| 810 | + $result = $mount1->moveMount($absolutePath2); |
| 811 | + $manager->moveMount($sourceMountPoint, $mount1->getMountPoint()); |
| 812 | + |
811 | 813 | // moving a file/folder within the same mount point |
812 | 814 | } elseif ($storage1 === $storage2) { |
| 815 | + if (count($movedMounts) > 0) { |
| 816 | + $this->validateMountMove($movedMounts, $mount1, $mount2, !$this->targetIsNotShared($targetUser, $absolutePath2)); |
| 817 | + } |
813 | 818 | if ($storage1) { |
814 | 819 | $result = $storage1->rename($internalPath1, $internalPath2); |
815 | 820 | } else { |
816 | 821 | $result = false; |
817 | 822 | } |
818 | 823 | // moving a file/folder between storages (from $storage1 to $storage2) |
819 | 824 | } else { |
| 825 | + if (count($movedMounts) > 0) { |
| 826 | + $this->validateMountMove($movedMounts, $mount1, $mount2, !$this->targetIsNotShared($targetUser, $absolutePath2)); |
| 827 | + } |
820 | 828 | $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); |
821 | 829 | } |
822 | 830 |
|
@@ -866,6 +874,34 @@ public function rename($source, $target) { |
866 | 874 | return $result; |
867 | 875 | } |
868 | 876 |
|
| 877 | + private function validateMountMove(array $mounts, IMountPoint $sourceMount, IMountPoint $targetMount, bool $targetIsShared): void { |
| 878 | + $targetType = 'storage'; |
| 879 | + if ($targetMount instanceof SharedMount) { |
| 880 | + $targetType = 'share'; |
| 881 | + } |
| 882 | + $targetPath = rtrim($targetMount->getMountPoint(), '/'); |
| 883 | + |
| 884 | + foreach ($mounts as $mount) { |
| 885 | + $sourcePath = rtrim($mount->getMountPoint(), '/'); |
| 886 | + $sourceType = 'storage'; |
| 887 | + if ($mount instanceof SharedMount) { |
| 888 | + $sourceType = 'share'; |
| 889 | + } |
| 890 | + |
| 891 | + if (!$mount instanceof MoveableMount) { |
| 892 | + throw new ForbiddenException("Storage {$sourcePath} cannot be moved", false); |
| 893 | + } |
| 894 | + |
| 895 | + if ($targetIsShared) { |
| 896 | + throw new ForbiddenException("Moving a $sourceType ($sourcePath) into shared folder is not allowed", false); |
| 897 | + } |
| 898 | + |
| 899 | + if ($sourceMount !== $targetMount) { |
| 900 | + throw new ForbiddenException("Moving a $sourceType ($sourcePath) into another $targetType ($targetPath) is not allowed", false); |
| 901 | + } |
| 902 | + } |
| 903 | + } |
| 904 | + |
869 | 905 | /** |
870 | 906 | * Copy a file/folder from the source path to target path |
871 | 907 | * |
|
0 commit comments