Skip to content

Commit

Permalink
Merge pull request #3030 from nextcloud/filesapi-renamefailcase
Browse files Browse the repository at this point in the history
Fix files node API failed rename/copy
  • Loading branch information
MorrisJobke authored Jan 25, 2017
2 parents c3e57d2 + 269b652 commit 95ab46e
Show file tree
Hide file tree
Showing 6 changed files with 565 additions and 641 deletions.
56 changes: 10 additions & 46 deletions lib/private/Files/Node/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
use OCP\Files\NotPermittedException;

class File extends Node implements \OCP\Files\File {
/**
* Creates a Folder that represents a non-existing path
*
* @param string $path path
* @return string non-existing node class
*/
protected function createNonExistingNode($path) {
return new NonExistingFile($this->root, $this->view, $path);
}

/**
* @return string
* @throws \OCP\Files\NotPermittedException
Expand Down Expand Up @@ -113,52 +123,6 @@ public function delete() {
}
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->copy($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
return $targetNode;
} else {
throw new NotPermittedException();
}
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->rename($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
$this->path = $targetPath;
$this->fileInfo = null;
return $targetNode;
} else {
throw new NotPermittedException();
}
}

/**
* @param string $type
* @param bool $raw
Expand Down
55 changes: 10 additions & 45 deletions lib/private/Files/Node/Folder.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@
use OCP\Files\NotPermittedException;

class Folder extends Node implements \OCP\Files\Folder {
/**
* Creates a Folder that represents a non-existing path
*
* @param string $path path
* @return string non-existing node class
*/
protected function createNonExistingNode($path) {
return new NonExistingFolder($this->root, $this->view, $path);
}

/**
* @param string $path path relative to the folder
* @return string
Expand Down Expand Up @@ -325,51 +335,6 @@ public function delete() {
}
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->copy($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
return $targetNode;
} else {
throw new NotPermittedException('No permission to copy to path');
}
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
$this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
$this->view->rename($this->path, $targetPath);
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
$this->root->emit('\OC\Files', 'postWrite', array($targetNode));
$this->path = $targetPath;
return $targetNode;
} else {
throw new NotPermittedException('No permission to move to path');
}
}

/**
* Add a suffix to the name in case the file exists
*
Expand Down
80 changes: 62 additions & 18 deletions lib/private/Files/Node/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;

// FIXME: this class really should be abstract
class Node implements \OCP\Files\Node {
/**
* @var \OC\Files\View $view
Expand All @@ -56,7 +57,7 @@ class Node implements \OCP\Files\Node {

/**
* @param \OC\Files\View $view
* @param \OC\Files\Node\Root $root
* @param \OCP\Files\IRootFolder $root
* @param string $path
* @param FileInfo $fileInfo
*/
Expand All @@ -67,6 +68,16 @@ public function __construct($root, $view, $path, $fileInfo = null) {
$this->fileInfo = $fileInfo;
}

/**
* Creates a Node of the same type that represents a non-existing path
*
* @param string $path path
* @return string non-existing node class
*/
protected function createNonExistingNode($path) {
throw new \Exception('Must be implemented by subclasses');
}

/**
* Returns the matching file info
*
Expand Down Expand Up @@ -106,27 +117,10 @@ protected function checkPermissions($permissions) {
return ($this->getPermissions() & $permissions) === $permissions;
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
return;
}

public function delete() {
return;
}

/**
* @param string $targetPath
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
return;
}

/**
* @param int $mtime
* @throws \OCP\Files\NotPermittedException
Expand Down Expand Up @@ -381,4 +375,54 @@ public function changeLock($type) {
public function unlock($type) {
$this->view->unlockFile($this->path, $type);
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException if copy not allowed or failed
* @return \OC\Files\Node\Node
*/
public function copy($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = $this->createNonExistingNode($targetPath);
$this->root->emit('\OC\Files', 'preCopy', [$this, $nonExisting]);
$this->root->emit('\OC\Files', 'preWrite', [$nonExisting]);
if (!$this->view->copy($this->path, $targetPath)) {
throw new NotPermittedException('Could not copy ' . $this->path . ' to ' . $targetPath);
}
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postCopy', [$this, $targetNode]);
$this->root->emit('\OC\Files', 'postWrite', [$targetNode]);
return $targetNode;
} else {
throw new NotPermittedException('No permission to copy to path ' . $targetPath);
}
}

/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException if move not allowed or failed
* @return \OC\Files\Node\Node
*/
public function move($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = $this->createNonExistingNode($targetPath);
$this->root->emit('\OC\Files', 'preRename', [$this, $nonExisting]);
$this->root->emit('\OC\Files', 'preWrite', [$nonExisting]);
if (!$this->view->rename($this->path, $targetPath)) {
throw new NotPermittedException('Could not move ' . $this->path . ' to ' . $targetPath);
}
$targetNode = $this->root->get($targetPath);
$this->root->emit('\OC\Files', 'postRename', [$this, $targetNode]);
$this->root->emit('\OC\Files', 'postWrite', [$targetNode]);
$this->path = $targetPath;
return $targetNode;
} else {
throw new NotPermittedException('No permission to move to path ' . $targetPath);
}
}

}
Loading

0 comments on commit 95ab46e

Please sign in to comment.