@@ -412,18 +412,44 @@ class Hooks { | |||
'uid' => $ownerOld, | |||
'path' => $pathOld, | |||
'type' => $type, | |||
'operation' => 'rename', | |||
); | |||
} | |||
} | |||
/** | |||
* after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing | |||
* @param array $params array with oldpath and newpath | |||
* mark file as renamed so that we know the original source after the file was renamed | |||
* @param array $params with the old path and the new path | |||
*/ | |||
public static function preCopy($params) { | |||
$user = \OCP\User::getUser(); | |||
$view = new \OC\Files\View('/'); | |||
$util = new Util($view, $user); | |||
list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']); | |||
// we only need to rename the keys if the rename happens on the same mountpoint | |||
// otherwise we perform a stream copy, so we get a new set of keys | |||
$mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']); | |||
$mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']); | |||
$type = $view->is_dir('/' . $user . '/files/' . $params['oldpath']) ? 'folder' : 'file'; | |||
if ($mp1 === $mp2) { | |||
self::$renamedFiles[$params['oldpath']] = array( | |||
'uid' => $ownerOld, | |||
'path' => $pathOld, | |||
'type' => $type, | |||
'operation' => 'copy'); | |||
} | |||
} | |||
/** | |||
* after a file is renamed/copied, rename/copy its keyfile and share-keys also fix the file size and fix also the sharing | |||
* | |||
* This function is connected to the rename signal of OC_Filesystem and adjust the name and location | |||
* of the stored versions along the actual file | |||
* @param array $params array with oldpath and newpath | |||
*/ | |||
public static function postRename($params) { | |||
public static function postRenameOrCopy($params) { | |||
if (\OCP\App::isEnabled('files_encryption') === false) { | |||
return true; | |||
@@ -442,6 +468,7 @@ class Hooks { | |||
$ownerOld = self::$renamedFiles[$params['oldpath']]['uid']; | |||
$pathOld = self::$renamedFiles[$params['oldpath']]['path']; | |||
$type = self::$renamedFiles[$params['oldpath']]['type']; | |||
$operation = self::$renamedFiles[$params['oldpath']]['operation']; | |||
unset(self::$renamedFiles[$params['oldpath']]); | |||
} else { | |||
\OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG); | |||
@@ -484,17 +511,17 @@ class Hooks { | |||
$matches = Helper::findShareKeys($oldShareKeyPath, $view); | |||
foreach ($matches as $src) { | |||
$dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src)); | |||
$view->rename($src, $dst); | |||
$view->$operation($src, $dst); | |||
} | |||
} else { | |||
// handle share-keys folders | |||
$view->rename($oldShareKeyPath, $newShareKeyPath); | |||
$view->$operation($oldShareKeyPath, $newShareKeyPath); | |||
} | |||
// Rename keyfile so it isn't orphaned | |||
if ($view->file_exists($oldKeyfilePath)) { | |||
$view->rename($oldKeyfilePath, $newKeyfilePath); | |||
$view->$operation($oldKeyfilePath, $newKeyfilePath); | |||
} | |||
@@ -62,7 +62,9 @@ class Helper { | |||
public static function registerFilesystemHooks() { | |||
\OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRenameOrCopy'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'copy', 'OCA\Encryption\Hooks', 'preCopy'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Encryption\Hooks', 'postRenameOrCopy'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete'); | |||
\OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount'); |
@@ -14,3 +14,4 @@ OCP\Util::connectHook('OC_Filesystem', 'write', "OCA\Files_Versions\Hooks", "wri | |||
OCP\Util::connectHook('OC_Filesystem', 'post_delete', "OCA\Files_Versions\Hooks", "remove_hook"); | |||
OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Versions\Hooks", "pre_remove_hook"); | |||
OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA\Files_Versions\Hooks", "rename_hook"); | |||
OCP\Util::connectHook('OC_Filesystem', 'copy', "OCA\Files_Versions\Hooks", "copy_hook"); |
@@ -69,7 +69,25 @@ class Hooks { | |||
$oldpath = $params['oldpath']; | |||
$newpath = $params['newpath']; | |||
if($oldpath<>'' && $newpath<>'') { | |||
Storage::rename( $oldpath, $newpath ); | |||
Storage::renameOrCopy($oldpath, $newpath, 'rename'); | |||
} | |||
} | |||
} | |||
/** | |||
* copy versions of copied files | |||
* @param array $params array with oldpath and newpath | |||
* | |||
* This function is connected to the copy signal of OC_Filesystem and copies the | |||
* the stored versions to the new location | |||
*/ | |||
public static function copy_hook($params) { | |||
if (\OCP\App::isEnabled('files_versions')) { | |||
$oldpath = $params['oldpath']; | |||
$newpath = $params['newpath']; | |||
if($oldpath<>'' && $newpath<>'') { | |||
Storage::renameOrCopy($oldpath, $newpath, 'copy'); | |||
} | |||
} | |||
} |
@@ -174,9 +174,12 @@ class Storage { | |||
} | |||
/** | |||
* rename versions of a file | |||
* rename or copy versions of a file | |||
* @param string $old_path | |||
* @param string $new_path | |||
* @param string $operation can be 'copy' or 'rename' | |||
*/ | |||
public static function rename($old_path, $new_path) { | |||
public static function renameOrCopy($old_path, $new_path, $operation) { | |||
list($uid, $oldpath) = self::getUidAndFilename($old_path); | |||
list($uidn, $newpath) = self::getUidAndFilename($new_path); | |||
$versions_view = new \OC\Files\View('/'.$uid .'/files_versions'); | |||
@@ -191,13 +194,13 @@ class Storage { | |||
self::expire($newpath); | |||
if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) { | |||
$versions_view->rename($oldpath, $newpath); | |||
$versions_view->$operation($oldpath, $newpath); | |||
} else if ( ($versions = Storage::getVersions($uid, $oldpath)) ) { | |||
// create missing dirs if necessary | |||
self::createMissingDirectories($newpath, new \OC\Files\View('/'. $uidn)); | |||
foreach ($versions as $v) { | |||
$versions_view->rename($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']); | |||
$versions_view->$operation($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']); | |||
} | |||
} | |||
} |