Skip to content

Commit

Permalink
Update public link share in transfer ownership command
Browse files Browse the repository at this point in the history
The public link share wasn't updated in the command.
This resulted in failure, when the public links were
accessed after the files were transferred. This change
helps to update the share for public links. And hence
access to the links won't cause any failure.

Signed-off-by: Sujith H <[email protected]>
  • Loading branch information
sharidas committed May 30, 2018
1 parent c5bc39a commit 0d7f607
Show file tree
Hide file tree
Showing 5 changed files with 443 additions and 37 deletions.
30 changes: 1 addition & 29 deletions apps/files/lib/Command/TransferOwnership.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,35 +298,7 @@ private function restoreShares(OutputInterface $output) {

foreach ($this->shares as $share) {
try {
if ($share->getSharedWith() === $this->destinationUser) {
// Unmount the shares before deleting, so we don't try to get the storage later on.
$shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
if ($shareMountPoint) {
$this->mountManager->removeMount($shareMountPoint->getMountPoint());
}
$this->shareManager->deleteShare($share);
} else {
if ($share->getShareOwner() === $this->sourceUser) {
$share->setShareOwner($this->destinationUser);
}
if ($share->getSharedBy() === $this->sourceUser) {
$share->setSharedBy($this->destinationUser);
}
/*
* If the share is already moved then updateShare would cause exception
* This can happen if the folder is shared and file(s) inside the folder
* has shares, for example public link
*/
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
$sharePath = \ltrim($share->getNode()->getPath(), '/');
if (\strpos($sharePath, $this->finalTarget) !== false) {
//The share is already moved
continue;
}
}

$this->shareManager->updateShare($share);
}
$this->shareManager->transferShare($share, $this->sourceUser, $this->destinationUser, $this->finalTarget);
} catch (\OCP\Files\NotFoundException $e) {
$output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
} catch (\Exception $e) {
Expand Down
3 changes: 2 additions & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,8 @@ public function __construct($webRoot, \OC\Config $config) {
$factory,
$c->getUserManager(),
$c->getLazyRootFolder(),
$c->getEventDispatcher()
$c->getEventDispatcher(),
new View('/')
);

return $manager;
Expand Down
97 changes: 96 additions & 1 deletion lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

use OC\Cache\CappedMemoryCache;
use OC\Files\Mount\MoveableMount;
use OC\Files\View;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
Expand All @@ -42,8 +43,10 @@
use OCP\Security\ISecureRandom;
use OCP\Share\Exceptions\GenericShareException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\Exceptions\TransferSharesException;
use OCP\Share\IManager;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\GenericEvent;

Expand Down Expand Up @@ -77,6 +80,9 @@ class Manager implements IManager {
/** @var EventDispatcher */
private $eventDispatcher;

/** @var View */
private $view;

/**
* Manager constructor.
*
Expand All @@ -102,7 +108,8 @@ public function __construct(
IProviderFactory $factory,
IUserManager $userManager,
IRootFolder $rootFolder,
EventDispatcher $eventDispatcher
EventDispatcher $eventDispatcher,
View $view
) {
$this->logger = $logger;
$this->config = $config;
Expand All @@ -116,6 +123,7 @@ public function __construct(
$this->rootFolder = $rootFolder;
$this->sharingDisabledForUsersCache = new CappedMemoryCache();
$this->eventDispatcher = $eventDispatcher;
$this->view = $view;
}

/**
Expand Down Expand Up @@ -673,6 +681,93 @@ public function createShare(\OCP\Share\IShare $share) {
return $share;
}

/**
* Transfer shares from oldOwner to newOwner. Both old and new owners are uid
*
* finalTarget is of the form "user1/files/transferred from admin on 20180509"
*
* TransferShareException would be thrown when:
* - oldOwner, newOwner does not exist.
* - oldOwner and newOwner are same
* NotFoundException would be thrown when finalTarget does not exist in the file
* system
*
* @param IShare $share
* @param string $oldOwner
* @param string $newOwner
* @param string $finalTarget
* @throws TransferSharesException
* @throws NotFoundException
*/
public function transferShare(IShare $share, $oldOwner, $newOwner, $finalTarget) {
if ($this->userManager->get($oldOwner) === null) {
throw new TransferSharesException("The current owner of the share $oldOwner doesn't exist");
}
if ($this->userManager->get($newOwner) === null) {
throw new TransferSharesException("The future owner $newOwner, where the share has to be moved doesn't exist");
}

if ($oldOwner === $newOwner) {
throw new TransferSharesException("The current owner of the share and the future owner of the share are same");
}

//If the destination location, i.e finalTarget is not present, then
//throw an exception
if (!$this->view->file_exists($finalTarget)) {
throw new NotFoundException("The target location $finalTarget doesn't exist");
}

/**
* If the share was already shared with new owner, then we can delete it
*/
if ($share->getSharedWith() === $newOwner) {
// Unmount the shares before deleting, so we don't try to get the storage later on.
$shareMountPoint = $this->mountManager->find('/' . $newOwner . '/files' . $share->getTarget());
if ($shareMountPoint) {
$this->mountManager->removeMount($shareMountPoint->getMountPoint());
}
$this->deleteShare($share);
} else {
$sharedWith = $share->getSharedWith();

$targetFile = '/' . rtrim(basename($finalTarget), '/') . '/' . ltrim(basename($share->getTarget()), '/');
/**
* Scenario where share is made by old owner to a user different
* from new owner
*/
if (($sharedWith !== null) && ($sharedWith !== $oldOwner) && ($sharedWith !== $newOwner)) {
$sharedBy = $share->getSharedBy();
$sharedOwner = $share->getShareOwner();
//The origin of the share now has to be the destination user.
if ($sharedBy === $oldOwner) {
$share->setSharedBy($newOwner);
}
if ($sharedOwner === $oldOwner) {
$share->setShareOwner($newOwner);
}
if (($sharedBy === $oldOwner) || ($sharedOwner === $oldOwner)) {
$share->setTarget($targetFile);
}
} else {
if ($share->getShareOwner() === $oldOwner) {
$share->setShareOwner($newOwner);
}
if ($share->getSharedBy() === $oldOwner) {
$share->setSharedBy($newOwner);
}
}

/**
* Here we update the target when the share is link
*/
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
$share->setTarget($targetFile);
}

$this->updateShare($share);
}
}

/**
* Update a share
*
Expand Down
24 changes: 24 additions & 0 deletions lib/public/Share/IManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@

use OCP\Files\Node;

use OCP\Files\NotFoundException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\Exceptions\TransferSharesException;

/**
* Interface IManager
Expand Down Expand Up @@ -112,6 +114,28 @@ public function getAllSharesBy($userId, $shareTypes, $nodeIDs, $reshares = false
*/
public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0);

/**
* Transfer shares from oldOwner to newOwner. Both old and new owners are uid
*
* @param IShare $share
* @param string $oldOwner - is the previous owner of the share, the uid string
* @param string $newOwner - is the new owner of the share, the uid string
* @param string $finalTarget - is the target folder where share has to be moved
*
* finalTarget is of the form "user1/files/transferred from admin on 20180509"
*
* TransferShareException would be thrown when:
* - oldOwner, newOwner does not exist.
* - oldOwner and newOwner are same
* NotFoundException would be thrown when finalTarget does not exist in the file
* system
*
* @throws TransferSharesException
* @throws NotFoundException
* @since 10.0.9
*/
public function transferShare(IShare $share, $oldOwner, $newOwner, $finalTarget);

/**
* Get shares shared with $userId for specified share types.
* Filter by $node if provided
Expand Down
Loading

0 comments on commit 0d7f607

Please sign in to comment.