diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index c4b247da1e..7e68f476a7 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -67,10 +67,13 @@ class Hooks { $session->setPrivateKey($privateKey, $params['uid']); // Check if first-run file migration has already been performed - $migrationCompleted = $util->getMigrationStatus(); + $ready = false; + if ($util->getMigrationStatus() === Util::MIGRATION_OPEN) { + $ready = $util->beginMigration(); + } // If migration not yet done - if (!$migrationCompleted) { + if ($ready) { $userView = new \OC_FilesystemView('/' . $params['uid']); @@ -102,7 +105,7 @@ class Hooks { } // Register successful migration in DB - $util->setMigrationStatus(1); + $util->finishMigration(); } diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index a6711880c2..b6e3543bca 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -96,10 +96,13 @@ class Util { //// DONE: test new encryption with sharing //// TODO: test new encryption with proxies + const MIGRATION_COMPLETED = 1; // migration to new encryption completed + const MIGRATION_IN_PROGRESS = -1; // migration is running + const MIGRATION_OPEN = 0; // user still needs to be migrated + private $view; // OC_FilesystemView object for filesystem operations private $userId; // ID of the currently logged-in user - private $pwd; // User Password private $client; // Client side encryption mode flag private $publicKeyDir; // Dir containing all public user keys private $encryptionDir; // Dir containing user's files_encryption @@ -1054,36 +1057,56 @@ class Util { } /** - * @brief Set file migration status for user - * @param $status - * @return bool + * @brief start migration mode to initially encrypt users data + * @return boolean */ - public function setMigrationStatus($status) { + public function beginMigration() { - $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?'; - - $args = array( - $status, - $this->userId - ); + $return = false; + $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?'; + $args = array(self::MIGRATION_IN_PROGRESS, $this->userId, self::MIGRATION_OPEN); $query = \OCP\DB::prepare($sql); + $result = $query->execute($args); + $manipulatedRows = $result->numRows(); - if ($query->execute($args)) { - - return true; - + if ($manipulatedRows === 1) { + $return = true; + \OCP\Util::writeLog('Encryption library', "Start migration to encryption mode for " . $this->userId, \OCP\Util::INFO); } else { - - return false; - + \OCP\Util::writeLog('Encryption library', "Could not activate migration mode for " . $this->userId . ". Probably another process already started the initial encryption", \OCP\Util::WARN); } + return $return; } /** - * @brief Check whether pwd recovery is enabled for a given user - * @return bool 1 = yes, 0 = no, false = no record + * @brief close migration mode after users data has been encrypted successfully + * @return boolean + */ + public function finishMigration() { + + $return = false; + + $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?'; + $args = array(self::MIGRATION_COMPLETED, $this->userId, self::MIGRATION_IN_PROGRESS); + $query = \OCP\DB::prepare($sql); + $result = $query->execute($args); + $manipulatedRows = $result->numRows(); + + if ($manipulatedRows === 1) { + $return = true; + \OCP\Util::writeLog('Encryption library', "Finish migration successfully for " . $this->userId, \OCP\Util::INFO); + } else { + \OCP\Util::writeLog('Encryption library', "Could not deactivate migration mode for " . $this->userId, \OCP\Util::WARN); + } + + return $return; + } + + /** + * @brief check if files are already migrated to the encryption system + * @return migration status, false = in case of no record * @note If records are not being returned, check for a hidden space * at the start of the uid in db */ @@ -1112,14 +1135,11 @@ class Util { // If no record is found if (empty($migrationStatus)) { - + \OCP\Util::writeLog('Encryption library', "Could not get migration status for " . $this->userId . ", no record found", \OCP\Util::ERROR); return false; - // If a record is found } else { - - return $migrationStatus[0]; - + return (int)$migrationStatus[0]; } } diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index 6d6c8bca3d..14caf1105d 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -182,8 +182,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $params['uid'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER; $params['password'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER; - $util = new Encryption\Util($this->view, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); - $util->setMigrationStatus(0); + $this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); $this->assertTrue(OCA\Encryption\Hooks::login($params)); @@ -285,7 +284,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $params['password'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER; $util = new Encryption\Util($this->view, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); - $util->setMigrationStatus(0); + $this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); $this->assertTrue(OCA\Encryption\Hooks::login($params)); @@ -330,4 +329,28 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $params['password'] = $password; OCA\Encryption\Hooks::login($params); } + + /** + * helper function to set migration status to the right value + * to be able to test the migration path + * + * @param $status needed migration status for test + * @param $user for which user the status should be set + * @return boolean + */ + private function setMigrationStatus($status, $user) { + $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?'; + $args = array( + $status, + $user + ); + + $query = \OCP\DB::prepare($sql); + if ($query->execute($args)) { + return true; + } else { + return false; + } + } + }