|
24 | 24 | use OCP\Files\InvalidCharacterInPathException; |
25 | 25 | use OCP\Files\InvalidDirectoryException; |
26 | 26 | use OCP\Files\InvalidPathException; |
| 27 | +use OCP\Files\Mount\IMountManager; |
27 | 28 | use OCP\Files\Mount\IMountPoint; |
28 | 29 | use OCP\Files\NotFoundException; |
29 | 30 | use OCP\Files\ReservedWordException; |
@@ -701,6 +702,9 @@ public function rename($source, $target) { |
701 | 702 | throw new ForbiddenException('Moving a folder into a child folder is forbidden', false); |
702 | 703 | } |
703 | 704 |
|
| 705 | + /** @var IMountManager $mountManager */ |
| 706 | + $mountManager = \OC::$server->get(IMountManager::class); |
| 707 | + |
704 | 708 | $targetParts = explode('/', $absolutePath2); |
705 | 709 | $targetUser = $targetParts[1] ?? null; |
706 | 710 | $result = false; |
@@ -758,31 +762,35 @@ public function rename($source, $target) { |
758 | 762 | try { |
759 | 763 | $this->changeLock($target, ILockingProvider::LOCK_EXCLUSIVE, true); |
760 | 764 |
|
| 765 | + $movedMounts = $mountManager->findIn($this->getAbsolutePath($source)); |
| 766 | + |
761 | 767 | 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 | | - } |
| 768 | + $sourceParentMount = $this->getMount(dirname($source)); |
| 769 | + $movedMounts[] = $mount1; |
| 770 | + $this->validateMountMove($movedMounts, $sourceParentMount, $mount2, !$this->targetIsNotShared($targetUser, $absolutePath2)); |
| 771 | + |
| 772 | + /** |
| 773 | + * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1 |
| 774 | + */ |
| 775 | + $sourceMountPoint = $mount1->getMountPoint(); |
| 776 | + $result = $mount1->moveMount($absolutePath2); |
| 777 | + $manager->moveMount($sourceMountPoint, $mount1->getMountPoint()); |
| 778 | + |
777 | 779 | // moving a file/folder within the same mount point |
778 | 780 | } elseif ($storage1 === $storage2) { |
| 781 | + if (count($movedMounts) > 0) { |
| 782 | + $this->validateMountMove($movedMounts, $mount1, $mount2, !$this->targetIsNotShared($targetUser, $absolutePath2)); |
| 783 | + } |
779 | 784 | if ($storage1) { |
780 | 785 | $result = $storage1->rename($internalPath1, $internalPath2); |
781 | 786 | } else { |
782 | 787 | $result = false; |
783 | 788 | } |
784 | 789 | // moving a file/folder between storages (from $storage1 to $storage2) |
785 | 790 | } else { |
| 791 | + if (count($movedMounts) > 0) { |
| 792 | + $this->validateMountMove($movedMounts, $mount1, $mount2, !$this->targetIsNotShared($targetUser, $absolutePath2)); |
| 793 | + } |
786 | 794 | $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); |
787 | 795 | } |
788 | 796 |
|
@@ -832,6 +840,34 @@ public function rename($source, $target) { |
832 | 840 | return $result; |
833 | 841 | } |
834 | 842 |
|
| 843 | + private function validateMountMove(array $mounts, IMountPoint $sourceMount, IMountPoint $targetMount, bool $targetIsShared): void { |
| 844 | + $targetType = 'storage'; |
| 845 | + if ($targetMount instanceof SharedMount) { |
| 846 | + $targetType = 'share'; |
| 847 | + } |
| 848 | + $targetPath = rtrim($targetMount->getMountPoint(), '/'); |
| 849 | + |
| 850 | + foreach ($mounts as $mount) { |
| 851 | + $sourcePath = rtrim($mount->getMountPoint(), '/'); |
| 852 | + $sourceType = 'storage'; |
| 853 | + if ($mount instanceof SharedMount) { |
| 854 | + $sourceType = 'share'; |
| 855 | + } |
| 856 | + |
| 857 | + if (!$mount instanceof MoveableMount) { |
| 858 | + throw new ForbiddenException("Storage {$sourcePath} cannot be moved", false); |
| 859 | + } |
| 860 | + |
| 861 | + if ($targetIsShared) { |
| 862 | + throw new ForbiddenException("Moving a $sourceType ($sourcePath) into shared folder is not allowed", false); |
| 863 | + } |
| 864 | + |
| 865 | + if ($sourceMount !== $targetMount) { |
| 866 | + throw new ForbiddenException("Moving a $sourceType ($sourcePath) into another $targetType ($targetPath) is not allowed", false); |
| 867 | + } |
| 868 | + } |
| 869 | + } |
| 870 | + |
835 | 871 | /** |
836 | 872 | * Copy a file/folder from the source path to target path |
837 | 873 | * |
|
0 commit comments