diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index c1ccb927df582224fe9fa92e94c75b68b7b3ca5f..6e375f99a8e4f31348b55ee52328be6550eeb13a 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -81,7 +81,7 @@ class Hooks { // Check if first-run file migration has already been performed $ready = false; $migrationStatus = $util->getMigrationStatus(); - if ($migrationStatus === Util::MIGRATION_OPEN) { + if ($migrationStatus === Util::MIGRATION_OPEN && $session !== false) { $ready = $util->beginMigration(); } elseif ($migrationStatus === Util::MIGRATION_IN_PROGRESS) { // refuse login as long as the initial encryption is running @@ -222,10 +222,14 @@ class Hooks { $util = new Util($view, $user); $recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null; + // we generate new keys if... + // ...we have a recovery password and the user enabled the recovery key + // ...encryption was activated for the first time (no keys exists) + // ...the user doesn't have any files if (($util->recoveryEnabledForUser() && $recoveryPassword) - || !$util->userKeysExists()) { + || !$util->userKeysExists() + || !$view->file_exists($user . '/files')) { - $recoveryPassword = $params['recoveryPassword']; $newUserPassword = $params['password']; // make sure that the users home is mounted diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index fcb369c7238eec877bfdc0d0ca996fcd97d1f1d2..437034726183fe3665e8a1d356323a5926987420 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -311,4 +311,46 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder); } + /** + * @brief replacing encryption keys during password change should be allowed + * until the user logged in for the first time + */ + public function testSetPassphrase() { + + $view = new \OC\Files\View(); + + // set user password for the first time + \OCA\Encryption\Hooks::postCreateUser(array('uid' => 'newUser', 'password' => 'newUserPassword')); + + $this->assertTrue($view->file_exists('public-keys/newUser.public.key')); + $this->assertTrue($view->file_exists('newUser/files_encryption/newUser.private.key')); + + // check if we are able to decrypt the private key + $encryptedKey = \OCA\Encryption\Keymanager::getPrivateKey($view, 'newUser'); + $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'newUserPassword'); + $this->assertTrue(is_string($privateKey)); + + // change the password before the user logged-in for the first time, + // we can replace the encryption keys + \OCA\Encryption\Hooks::setPassphrase(array('uid' => 'newUser', 'password' => 'passwordChanged')); + + $encryptedKey = \OCA\Encryption\Keymanager::getPrivateKey($view, 'newUser'); + $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged'); + $this->assertTrue(is_string($privateKey)); + + // now create a files folder to simulate a already used account + $view->mkdir('/newUser/files'); + + // change the password after the user logged in, now the password should not change + \OCA\Encryption\Hooks::setPassphrase(array('uid' => 'newUser', 'password' => 'passwordChanged2')); + + $encryptedKey = \OCA\Encryption\Keymanager::getPrivateKey($view, 'newUser'); + $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged2'); + $this->assertFalse($privateKey); + + $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged'); + $this->assertTrue(is_string($privateKey)); + + } + }