Merge pull request #3668 from owncloud/encryption_migrate_only_once
make sure that only one process can enter the migration mode
This commit is contained in:
commit
2b179ccff0
|
@ -67,10 +67,13 @@ class Hooks {
|
||||||
$session->setPrivateKey($privateKey, $params['uid']);
|
$session->setPrivateKey($privateKey, $params['uid']);
|
||||||
|
|
||||||
// Check if first-run file migration has already been performed
|
// 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 migration not yet done
|
||||||
if (!$migrationCompleted) {
|
if ($ready) {
|
||||||
|
|
||||||
$userView = new \OC_FilesystemView('/' . $params['uid']);
|
$userView = new \OC_FilesystemView('/' . $params['uid']);
|
||||||
|
|
||||||
|
@ -102,7 +105,7 @@ class Hooks {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register successful migration in DB
|
// Register successful migration in DB
|
||||||
$util->setMigrationStatus(1);
|
$util->finishMigration();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,10 +96,13 @@ class Util {
|
||||||
//// DONE: test new encryption with sharing
|
//// DONE: test new encryption with sharing
|
||||||
//// TODO: test new encryption with proxies
|
//// 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 $view; // OC_FilesystemView object for filesystem operations
|
||||||
private $userId; // ID of the currently logged-in user
|
private $userId; // ID of the currently logged-in user
|
||||||
private $pwd; // User Password
|
|
||||||
private $client; // Client side encryption mode flag
|
private $client; // Client side encryption mode flag
|
||||||
private $publicKeyDir; // Dir containing all public user keys
|
private $publicKeyDir; // Dir containing all public user keys
|
||||||
private $encryptionDir; // Dir containing user's files_encryption
|
private $encryptionDir; // Dir containing user's files_encryption
|
||||||
|
@ -1054,36 +1057,56 @@ class Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set file migration status for user
|
* @brief start migration mode to initially encrypt users data
|
||||||
* @param $status
|
* @return boolean
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function setMigrationStatus($status) {
|
public function beginMigration() {
|
||||||
|
|
||||||
$sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?';
|
$return = false;
|
||||||
|
|
||||||
$args = array(
|
|
||||||
$status,
|
|
||||||
$this->userId
|
|
||||||
);
|
|
||||||
|
|
||||||
|
$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);
|
$query = \OCP\DB::prepare($sql);
|
||||||
|
$result = $query->execute($args);
|
||||||
|
$manipulatedRows = $result->numRows();
|
||||||
|
|
||||||
if ($query->execute($args)) {
|
if ($manipulatedRows === 1) {
|
||||||
|
$return = true;
|
||||||
return true;
|
\OCP\Util::writeLog('Encryption library', "Start migration to encryption mode for " . $this->userId, \OCP\Util::INFO);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
\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 false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check whether pwd recovery is enabled for a given user
|
* @brief close migration mode after users data has been encrypted successfully
|
||||||
* @return bool 1 = yes, 0 = no, false = no record
|
* @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
|
* @note If records are not being returned, check for a hidden space
|
||||||
* at the start of the uid in db
|
* at the start of the uid in db
|
||||||
*/
|
*/
|
||||||
|
@ -1112,14 +1135,11 @@ class Util {
|
||||||
|
|
||||||
// If no record is found
|
// If no record is found
|
||||||
if (empty($migrationStatus)) {
|
if (empty($migrationStatus)) {
|
||||||
|
\OCP\Util::writeLog('Encryption library', "Could not get migration status for " . $this->userId . ", no record found", \OCP\Util::ERROR);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If a record is found
|
// If a record is found
|
||||||
} else {
|
} else {
|
||||||
|
return (int)$migrationStatus[0];
|
||||||
return $migrationStatus[0];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,8 +182,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
|
||||||
$params['uid'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
|
$params['uid'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
|
||||||
$params['password'] = \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);
|
$this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
|
||||||
$util->setMigrationStatus(0);
|
|
||||||
|
|
||||||
$this->assertTrue(OCA\Encryption\Hooks::login($params));
|
$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;
|
$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 = 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));
|
$this->assertTrue(OCA\Encryption\Hooks::login($params));
|
||||||
|
|
||||||
|
@ -330,4 +329,28 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
|
||||||
$params['password'] = $password;
|
$params['password'] = $password;
|
||||||
OCA\Encryption\Hooks::login($params);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue