From 3000f0125fe9470012c362a13ecc33a31cceff18 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 17 Jul 2015 12:49:45 +0200 Subject: don't move keys if the key where already moved in a previous migration run --- apps/encryption/lib/migration.php | 74 +++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 14 deletions(-) (limited to 'apps/encryption/lib') diff --git a/apps/encryption/lib/migration.php b/apps/encryption/lib/migration.php index 26e2a143f69..0903587e879 100644 --- a/apps/encryption/lib/migration.php +++ b/apps/encryption/lib/migration.php @@ -26,6 +26,7 @@ namespace OCA\Encryption; use OC\DB\Connection; use OC\Files\View; use OCP\IConfig; +use OCP\ILogger; class Migration { @@ -37,17 +38,22 @@ class Migration { /** @var IConfig */ private $config; + /** @var ILogger */ + private $logger; + /** * @param IConfig $config * @param View $view * @param Connection $connection + * @param ILogger $logger */ - public function __construct(IConfig $config, View $view, Connection $connection) { + public function __construct(IConfig $config, View $view, Connection $connection, ILogger $logger) { $this->view = $view; $this->view->getUpdater()->disable(); $this->connection = $connection; $this->moduleId = \OCA\Encryption\Crypto\Encryption::ID; $this->config = $config; + $this->logger = $logger; } public function finalCleanUp() { @@ -234,9 +240,10 @@ class Migration { private function renameUsersPrivateKey($user) { $oldPrivateKey = $user . '/files_encryption/' . $user . '.privateKey'; $newPrivateKey = $user . '/files_encryption/' . $this->moduleId . '/' . $user . '.privateKey'; - $this->createPathForKeys(dirname($newPrivateKey)); - - $this->view->rename($oldPrivateKey, $newPrivateKey); + if ($this->view->file_exists($oldPrivateKey)) { + $this->createPathForKeys(dirname($newPrivateKey)); + $this->view->rename($oldPrivateKey, $newPrivateKey); + } } /** @@ -247,9 +254,10 @@ class Migration { private function renameUsersPublicKey($user) { $oldPublicKey = '/files_encryption/public_keys/' . $user . '.publicKey'; $newPublicKey = $user . '/files_encryption/' . $this->moduleId . '/' . $user . '.publicKey'; - $this->createPathForKeys(dirname($newPublicKey)); - - $this->view->rename($oldPublicKey, $newPublicKey); + if ($this->view->file_exists($oldPublicKey)) { + $this->createPathForKeys(dirname($newPublicKey)); + $this->view->rename($oldPublicKey, $newPublicKey); + } } /** @@ -261,6 +269,11 @@ class Migration { */ private function renameFileKeys($user, $path, $trash = false) { + if ($this->view->is_dir($user . '/' . $path) === false) { + $this->logger->info('Skip dir /' . $user . '/' . $path . ': does not exist'); + return; + } + $dh = $this->view->opendir($user . '/' . $path); if (is_resource($dh)) { @@ -270,8 +283,15 @@ class Migration { $this->renameFileKeys($user, $path . '/' . $file, $trash); } else { $target = $this->getTargetDir($user, $path, $file, $trash); - $this->createPathForKeys(dirname($target)); - $this->view->rename($user . '/' . $path . '/' . $file, $target); + if ($target) { + $this->createPathForKeys(dirname($target)); + $this->view->rename($user . '/' . $path . '/' . $file, $target); + } else { + $this->logger->warning( + 'did not move key "' . $file + . '" could not find the corresponding file in /data/' . $user . '/files.' + . 'Most likely the key was already moved in a previous migration run and is already on the right place.'); + } } } } @@ -279,23 +299,49 @@ class Migration { } } + /** + * get system mount points + * wrap static method so that it can be mocked for testing + * + * @return array + */ + protected function getSystemMountPoints() { + return \OC_Mount_Config::getSystemMountPoints(); + } + /** * generate target directory * * @param string $user - * @param string $filePath + * @param string $keyPath * @param string $filename * @param bool $trash * @return string */ - private function getTargetDir($user, $filePath, $filename, $trash) { + private function getTargetDir($user, $keyPath, $filename, $trash) { if ($trash) { - $targetDir = $user . '/files_encryption/keys/files_trashbin/' . substr($filePath, strlen('/files_trashbin/keys/')) . '/' . $this->moduleId . '/' . $filename; + $filePath = substr($keyPath, strlen('/files_trashbin/keys/')); + $targetDir = $user . '/files_encryption/keys/files_trashbin/' . $filePath . '/' . $this->moduleId . '/' . $filename; } else { - $targetDir = $user . '/files_encryption/keys/files/' . substr($filePath, strlen('/files_encryption/keys/')) . '/' . $this->moduleId . '/' . $filename; + $filePath = substr($keyPath, strlen('/files_encryption/keys/')); + $targetDir = $user . '/files_encryption/keys/files/' . $filePath . '/' . $this->moduleId . '/' . $filename; } - return $targetDir; + if ($user === '') { + // for system wide mounts we need to check if the mount point really exists + $normalized = trim($filePath, '/'); + $systemMountPoints = $this->getSystemMountPoints(); + foreach ($systemMountPoints as $mountPoint) { + if (strpos($normalized, $mountPoint['mountpoint']) === 0) + return $targetDir; + } + } else if ($trash === false && $this->view->file_exists('/' . $user. '/files/' . $filePath)) { + return $targetDir; + } else if ($trash === true && $this->view->file_exists('/' . $user. '/files_trashbin/' . $filePath)) { + return $targetDir; + } + + return false; } /** -- cgit v1.2.3