add a copy to the owners trash bin if another user moves a file out of a shared folder

Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
This commit is contained in:
Bjoern Schiessle 2016-12-21 15:42:57 +01:00
parent d5036fd4af
commit 0e4eeab3c1
No known key found for this signature in database
GPG Key ID: 2378A753E2BF04F6
2 changed files with 67 additions and 10 deletions

View File

@ -28,6 +28,7 @@ namespace OCA\Files_Trashbin;
use OC\Files\Filesystem; use OC\Files\Filesystem;
use OC\Files\Storage\Wrapper\Wrapper; use OC\Files\Storage\Wrapper\Wrapper;
use OC\Files\View; use OC\Files\View;
use OCA\Files_Sharing\SharedStorage;
use OCP\IUserManager; use OCP\IUserManager;
class Storage extends Wrapper { class Storage extends Wrapper {
@ -44,10 +45,18 @@ class Storage extends Wrapper {
*/ */
private static $disableTrash = false; private static $disableTrash = false;
private static $moveOutOfSharedFolder = [];
/** @var IUserManager */ /** @var IUserManager */
private $userManager; private $userManager;
function __construct($parameters, IUserManager $userManager = null) { /**
* Storage constructor.
*
* @param array $parameters
* @param IUserManager|null $userManager
*/
public function __construct($parameters, IUserManager $userManager = null) {
$this->mountPoint = $parameters['mountPoint']; $this->mountPoint = $parameters['mountPoint'];
$this->userManager = $userManager; $this->userManager = $userManager;
parent::__construct($parameters); parent::__construct($parameters);
@ -58,8 +67,38 @@ class Storage extends Wrapper {
*/ */
public static function preRenameHook($params) { public static function preRenameHook($params) {
// in cross-storage cases, a rename is a copy + unlink, // in cross-storage cases, a rename is a copy + unlink,
// that last unlink must not go to trash // that last unlink must not go to trash, only exception:
self::$disableTrash = true; // if the file was moved from a shared storage to a local folder,
// in this case the owner should get a copy in his trash bin so that
// they can restore the files again
$oldPath = $params['oldpath'];
$newPath = dirname($params['newpath']);
$currentUser = \OC::$server->getUserSession()->getUser();
$fileMovedOutOfSharedFolder = false;
if ($currentUser) {
$currentUserId = $currentUser->getUID();
$view = new View($currentUserId . '/files');
$sourceStorage = $view->getFileInfo($oldPath)->getStorage();
$sourceOwner = $view->getOwner($oldPath);
$targetOwner = $view->getOwner($newPath);
if($sourceOwner !== $targetOwner
&& $sourceStorage->instanceOfStorage(SharedStorage::class)
) {
$fileMovedOutOfSharedFolder = true;
}
}
if($fileMovedOutOfSharedFolder) {
self::$moveOutOfSharedFolder['/' . $currentUserId . '/files' . $oldPath] = true;
} else {
self::$disableTrash = true;
}
} }
/** /**
@ -74,6 +113,7 @@ class Storage extends Wrapper {
* *
* @param string $path1 first path * @param string $path1 first path
* @param string $path2 second path * @param string $path2 second path
* @return bool
*/ */
public function rename($path1, $path2) { public function rename($path1, $path2) {
$result = $this->storage->rename($path1, $path2); $result = $this->storage->rename($path1, $path2);
@ -93,7 +133,14 @@ class Storage extends Wrapper {
* @return bool true if the operation succeeded, false otherwise * @return bool true if the operation succeeded, false otherwise
*/ */
public function unlink($path) { public function unlink($path) {
return $this->doDelete($path, 'unlink'); if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
$result = $this->doDelete($path, 'unlink', true);
unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
} else {
$result = $this->doDelete($path, 'unlink');
}
return $result;
} }
/** /**
@ -104,7 +151,14 @@ class Storage extends Wrapper {
* @return bool true if the operation succeeded, false otherwise * @return bool true if the operation succeeded, false otherwise
*/ */
public function rmdir($path) { public function rmdir($path) {
return $this->doDelete($path, 'rmdir'); if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
$result = $this->doDelete($path, 'rmdir', true);
unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
} else {
$result = $this->doDelete($path, 'rmdir');
}
return $result;
} }
/** /**
@ -133,10 +187,11 @@ class Storage extends Wrapper {
* *
* @param string $path path of file or folder to delete * @param string $path path of file or folder to delete
* @param string $method either "unlink" or "rmdir" * @param string $method either "unlink" or "rmdir"
* @param bool $ownerOnly delete for owner only (if file gets moved out of a shared folder)
* *
* @return bool true if the operation succeeded, false otherwise * @return bool true if the operation succeeded, false otherwise
*/ */
private function doDelete($path, $method) { private function doDelete($path, $method, $ownerOnly = false) {
if (self::$disableTrash if (self::$disableTrash
|| !\OC_App::isEnabled('files_trashbin') || !\OC_App::isEnabled('files_trashbin')
|| (pathinfo($path, PATHINFO_EXTENSION) === 'part') || (pathinfo($path, PATHINFO_EXTENSION) === 'part')
@ -158,7 +213,7 @@ class Storage extends Wrapper {
$this->deletedFiles[$normalized] = $normalized; $this->deletedFiles[$normalized] = $normalized;
if ($filesPath = $view->getRelativePath($normalized)) { if ($filesPath = $view->getRelativePath($normalized)) {
$filesPath = trim($filesPath, '/'); $filesPath = trim($filesPath, '/');
$result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath); $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath, $ownerOnly);
// in cross-storage cases the file will be copied // in cross-storage cases the file will be copied
// but not deleted, so we delete it here // but not deleted, so we delete it here
if ($result) { if ($result) {

View File

@ -196,9 +196,11 @@ class Trashbin {
* move file to the trash bin * move file to the trash bin
* *
* @param string $file_path path to the deleted file/directory relative to the files root directory * @param string $file_path path to the deleted file/directory relative to the files root directory
* @param bool $ownerOnly delete for owner only (if file gets moved out of a shared folder)
*
* @return bool * @return bool
*/ */
public static function move2trash($file_path) { public static function move2trash($file_path, $ownerOnly = false) {
// get the user for which the filesystem is setup // get the user for which the filesystem is setup
$root = Filesystem::getRoot(); $root = Filesystem::getRoot();
list(, $user) = explode('/', $root); list(, $user) = explode('/', $root);
@ -261,8 +263,8 @@ class Trashbin {
self::retainVersions($filename, $owner, $ownerPath, $timestamp); self::retainVersions($filename, $owner, $ownerPath, $timestamp);
// if owner !== user we need to also add a copy to the owners trash // if owner !== user we need to also add a copy to the users trash
if ($user !== $owner) { if ($user !== $owner && $ownerOnly === false) {
self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp); self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp);
} }
} }