diff --git a/apps/files/lib/Command/TransferOwnership.php b/apps/files/lib/Command/TransferOwnership.php index 96281b5226..559cf02742 100644 --- a/apps/files/lib/Command/TransferOwnership.php +++ b/apps/files/lib/Command/TransferOwnership.php @@ -34,6 +34,7 @@ use OCP\IUserManager; use OCP\Share\IManager; use OCP\Share\IShare; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -65,6 +66,9 @@ class TransferOwnership extends Command { /** @var string */ private $destinationUser; + /** @var string */ + private $inputPath; + /** @var string */ private $finalTarget; @@ -88,6 +92,12 @@ class TransferOwnership extends Command { 'destination-user', InputArgument::REQUIRED, 'user who will be the new owner of the files' + ) + ->addOption( + 'path', + null, + InputOption::VALUE_REQUIRED, + 'selectively provide the path to transfer. For example --path="folder_name"' ); } @@ -107,6 +117,8 @@ class TransferOwnership extends Command { $this->sourceUser = $sourceUserObject->getUID(); $this->destinationUser = $destinationUserObject->getUID(); + $this->inputPath = $input->getOption('path'); + $this->inputPath = ltrim($this->inputPath, '/'); // target user has to be ready if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) { @@ -121,6 +133,16 @@ class TransferOwnership extends Command { Filesystem::initMountPoints($this->sourceUser); Filesystem::initMountPoints($this->destinationUser); + if (strlen($this->inputPath) >= 1) { + $view = new View(); + $unknownDir = $this->inputPath; + $this->inputPath = $this->sourceUser . "/files/" . $this->inputPath; + if (!$view->is_dir($this->inputPath)) { + $output->writeln("Unknown path provided: $unknownDir"); + return 1; + } + } + // analyse source folder $this->analyse($output); @@ -155,7 +177,14 @@ class TransferOwnership extends Command { $progress = new ProgressBar($output); $progress->start(); $self = $this; - $this->walkFiles($view, "$this->sourceUser/files", + $walkPath = "$this->sourceUser/files"; + if ( strlen($this->inputPath) > 0) { + if ($this->inputPath !== "$this->sourceUser/files") { + $walkPath = $this->inputPath; + } + } + + $this->walkFiles($view, $walkPath, function (FileInfo $fileInfo) use ($progress, $self) { if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) { // only analyze into folders from main storage, @@ -216,9 +245,20 @@ class TransferOwnership extends Command { protected function transfer(OutputInterface $output) { $view = new View(); $output->writeln("Transferring files to $this->finalTarget ..."); - $view->rename("$this->sourceUser/files", $this->finalTarget); - // because the files folder is moved away we need to recreate it - $view->mkdir("$this->sourceUser/files"); + $sourcePath = (strlen($this->inputPath) > 0) ? $this->inputPath : "$this->sourceUser/files"; + // This change will help user to transfer the folder specified using --path option. + // Else only the content inside folder is transferred which is not correct. + if (strlen($this->inputPath) > 0) { + if($this->inputPath !== ltrim("$this->sourceUser/files", '/')) { + $view->mkdir($this->finalTarget); + $this->finalTarget = $this->finalTarget . '/' . basename($sourcePath); + } + } + $view->rename($sourcePath, $this->finalTarget); + if (!is_dir("$this->sourceUser/files")) { + // because the files folder is moved away we need to recreate it + $view->mkdir("$this->sourceUser/files"); + } } /** diff --git a/build/integration/features/bootstrap/CommandLineContext.php b/build/integration/features/bootstrap/CommandLineContext.php index 95f492a62d..c8253966cd 100644 --- a/build/integration/features/bootstrap/CommandLineContext.php +++ b/build/integration/features/bootstrap/CommandLineContext.php @@ -88,6 +88,20 @@ class CommandLineContext implements \Behat\Behat\Context\Context { } } + /** + * @When /^transfering ownership of path "([^"]+)" from "([^"]+)" to "([^"]+)"/ + */ + public function transferingOwnershipPath($path, $user1, $user2) { + $path = '--path=' . $path; + if($this->runOcc(['files:transfer-ownership', $path, $user1, $user2]) === 0) { + $this->lastTransferPath = $this->findLastTransferFolderForUser($user1, $user2); + } else { + // failure + $this->lastTransferPath = null; + } + } + + /** * @When /^using received transfer folder of "([^"]+)" as dav path$/ */ diff --git a/build/integration/features/transfer-ownership.feature b/build/integration/features/transfer-ownership.feature index 92361f7090..7990eac328 100644 --- a/build/integration/features/transfer-ownership.feature +++ b/build/integration/features/transfer-ownership.feature @@ -117,3 +117,110 @@ Feature: transfer-ownership Then the command error output contains the text "Unknown target user" And the command failed with exit code 1 + Scenario: transfering ownership of a folder + Given user "user0" exists + And user "user1" exists + And User "user0" created a folder "/test" + And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" + When transfering ownership of path "test" from "user0" to "user1" + And the command was successful + And As an "user1" + And using received transfer folder of "user1" as dav path + Then Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" + + Scenario: transfering ownership of file shares + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And User "user0" created a folder "/test" + And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" + And file "/test/somefile.txt" of user "user0" is shared with user "user2" with permissions 19 + When transfering ownership of path "test" from "user0" to "user1" + And the command was successful + And As an "user2" + Then Downloaded content when downloading file "/somefile.txt" with range "bytes=0-6" should be "This is" + + Scenario: transfering ownership of folder shared with third user + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And User "user0" created a folder "/test" + And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" + And folder "/test" of user "user0" is shared with user "user2" with permissions 31 + When transfering ownership of path "test" from "user0" to "user1" + And the command was successful + And As an "user2" + Then Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" + + Scenario: transfering ownership of folder shared with transfer recipient + Given user "user0" exists + And user "user1" exists + And User "user0" created a folder "/test" + And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" + And folder "/test" of user "user0" is shared with user "user1" with permissions 31 + When transfering ownership of path "test" from "user0" to "user1" + And the command was successful + And As an "user1" + Then as "user1" the folder "/test" does not exist + And using received transfer folder of "user1" as dav path + And Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" + + Scenario: transfering ownership of folder doubly shared with third user + Given group "group1" exists + And user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user2" belongs to group "group1" + And User "user0" created a folder "/test" + And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" + And folder "/test" of user "user0" is shared with group "group1" with permissions 31 + And folder "/test" of user "user0" is shared with user "user2" with permissions 31 + When transfering ownership of path "test" from "user0" to "user1" + And the command was successful + And As an "user2" + Then Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" + + Scenario: transfering ownership does not transfer received shares + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And User "user2" created a folder "/test" + And User "user0" created a folder "/sub" + And folder "/test" of user "user2" is shared with user "user0" with permissions 31 + And User "user0" moved folder "/test" to "/sub/test" + When transfering ownership of path "sub" from "user0" to "user1" + And the command was successful + And As an "user1" + And using received transfer folder of "user1" as dav path + Then as "user1" the folder "/sub/test" does not exist + + Scenario: transfering ownership does not transfer external storage + Given user "user0" exists + And user "user1" exists + And User "user0" created a folder "/sub" + When transfering ownership of path "sub" from "user0" to "user1" + And the command was successful + And As an "user1" + And using received transfer folder of "user1" as dav path + Then as "user1" the folder "/local_storage" does not exist + + Scenario: transfering ownership fails with invalid source user + Given user "user0" exists + And User "user0" created a folder "/sub" + When transfering ownership of path "sub" from "invalid_user" to "user0" + Then the command error output contains the text "Unknown source user" + And the command failed with exit code 1 + + Scenario: transfering ownership fails with invalid target user + Given user "user0" exists + And User "user0" created a folder "/sub" + When transfering ownership of path "sub" from "user0" to "invalid_user" + Then the command error output contains the text "Unknown target user" + And the command failed with exit code 1 + + Scenario: transfering ownership fails with invalid path + Given user "user0" exists + And user "user1" exists + When transfering ownership of path "test" from "user0" to "user1" + Then the command error output contains the text "Unknown target user" + And the command failed with exit code 1