Ported ObjectTree::move to IMoveTarget in new DAV endpoint
This commit is contained in:
parent
a761d4cce7
commit
0a9f7730d0
|
@ -34,12 +34,18 @@ use OCA\DAV\Connector\Sabre\Exception\Forbidden;
|
|||
use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
|
||||
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
|
||||
use OCP\Files\ForbiddenException;
|
||||
use OCP\Files\InvalidPathException;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\Lock\ILockingProvider;
|
||||
use OCP\Lock\LockedException;
|
||||
use Sabre\DAV\Exception\Locked;
|
||||
use Sabre\DAV\Exception\ServiceUnavailable;
|
||||
use Sabre\DAV\INode;
|
||||
use Sabre\DAV\Exception\BadRequest;
|
||||
use OC\Files\Mount\MoveableMount;
|
||||
|
||||
class Directory extends \OCA\DAV\Connector\Sabre\Node
|
||||
implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota {
|
||||
implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget {
|
||||
|
||||
/**
|
||||
* Cached directory content
|
||||
|
@ -137,7 +143,7 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node
|
|||
return $node->put($data);
|
||||
} catch (\OCP\Files\StorageNotAvailableException $e) {
|
||||
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
|
||||
} catch (\OCP\Files\InvalidPathException $ex) {
|
||||
} catch (InvalidPathException $ex) {
|
||||
throw new InvalidPath($ex->getMessage());
|
||||
} catch (ForbiddenException $ex) {
|
||||
throw new Forbidden($ex->getMessage(), $ex->getRetry());
|
||||
|
@ -168,7 +174,7 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node
|
|||
}
|
||||
} catch (\OCP\Files\StorageNotAvailableException $e) {
|
||||
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
|
||||
} catch (\OCP\Files\InvalidPathException $ex) {
|
||||
} catch (InvalidPathException $ex) {
|
||||
throw new InvalidPath($ex->getMessage());
|
||||
} catch (ForbiddenException $ex) {
|
||||
throw new Forbidden($ex->getMessage(), $ex->getRetry());
|
||||
|
@ -195,7 +201,7 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node
|
|||
$info = $this->fileView->getFileInfo($path);
|
||||
} catch (\OCP\Files\StorageNotAvailableException $e) {
|
||||
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
|
||||
} catch (\OCP\Files\InvalidPathException $ex) {
|
||||
} catch (InvalidPathException $ex) {
|
||||
throw new InvalidPath($ex->getMessage());
|
||||
} catch (ForbiddenException $e) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden();
|
||||
|
@ -311,4 +317,104 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a node into this collection.
|
||||
*
|
||||
* It is up to the implementors to:
|
||||
* 1. Create the new resource.
|
||||
* 2. Remove the old resource.
|
||||
* 3. Transfer any properties or other data.
|
||||
*
|
||||
* Generally you should make very sure that your collection can easily move
|
||||
* the move.
|
||||
*
|
||||
* If you don't, just return false, which will trigger sabre/dav to handle
|
||||
* the move itself. If you return true from this function, the assumption
|
||||
* is that the move was successful.
|
||||
*
|
||||
* @param string $targetName New local file/collection name.
|
||||
* @param string $fullSourcePath Full path to source node
|
||||
* @param INode $sourceNode Source node itself
|
||||
* @return bool
|
||||
* @throws BadRequest
|
||||
* @throws ServiceUnavailable
|
||||
* @throws Forbidden
|
||||
* @throws FileLocked
|
||||
* @throws \Sabre\DAV\Exception\Forbidden
|
||||
*/
|
||||
public function moveInto($targetName, $fullSourcePath, INode $sourceNode) {
|
||||
if (!$sourceNode instanceof Node) {
|
||||
throw new BadRequest('Incompatible node types');
|
||||
}
|
||||
|
||||
if (!$this->fileView) {
|
||||
throw new ServiceUnavailable('filesystem not setup');
|
||||
}
|
||||
|
||||
$destinationPath = $this->getPath() . '/' . $targetName;
|
||||
|
||||
|
||||
$targetNodeExists = $this->childExists($targetName);
|
||||
|
||||
// at getNodeForPath we also check the path for isForbiddenFileOrDir
|
||||
// with that we have covered both source and destination
|
||||
if ($sourceNode instanceof Directory && $targetNodeExists) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode->getName() . ', target exists');
|
||||
}
|
||||
|
||||
list($sourceDir,) = \Sabre\HTTP\URLUtil::splitPath($sourceNode->getPath());
|
||||
$destinationDir = $this->getPath();
|
||||
|
||||
$sourcePath = $sourceNode->getPath();
|
||||
|
||||
$isMovableMount = false;
|
||||
$sourceMount = \OC::$server->getMountManager()->find($this->fileView->getAbsolutePath($sourcePath));
|
||||
$internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
|
||||
if ($sourceMount instanceof MoveableMount && $internalPath === '') {
|
||||
$isMovableMount = true;
|
||||
}
|
||||
|
||||
try {
|
||||
$sameFolder = ($sourceDir === $destinationDir);
|
||||
// if we're overwriting or same folder
|
||||
if ($targetNodeExists || $sameFolder) {
|
||||
// note that renaming a share mount point is always allowed
|
||||
if (!$this->fileView->isUpdatable($destinationDir) && !$isMovableMount) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden();
|
||||
}
|
||||
} else {
|
||||
if (!$this->fileView->isCreatable($destinationDir)) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$sameFolder) {
|
||||
// moving to a different folder, source will be gone, like a deletion
|
||||
// note that moving a share mount point is always allowed
|
||||
if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
$fileName = basename($destinationPath);
|
||||
try {
|
||||
$this->fileView->verifyPath($destinationDir, $fileName);
|
||||
} catch (InvalidPathException $ex) {
|
||||
throw new InvalidPath($ex->getMessage());
|
||||
}
|
||||
|
||||
$renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
|
||||
if (!$renameOkay) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden('');
|
||||
}
|
||||
} catch (StorageNotAvailableException $e) {
|
||||
throw new ServiceUnavailable($e->getMessage());
|
||||
} catch (ForbiddenException $ex) {
|
||||
throw new Forbidden($ex->getMessage(), $ex->getRetry());
|
||||
} catch (LockedException $e) {
|
||||
throw new FileLocked($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue