From 4c962f7343a295b7c04c4ad6655ea59ad5696741 Mon Sep 17 00:00:00 2001 From: Sujith H Date: Wed, 28 Jun 2017 14:56:23 +0530 Subject: [PATCH] Change to re-create masterkeys This change brings a new command to re-create masterkey A small modification to the decryptall, to standard output to console. Signed-off-by: Sujith H --- appinfo/info.xml | 1 + lib/Command/RecreateMasterKey.php | 263 ++++++++++++++++++++++++ lib/Crypto/DecryptAll.php | 2 +- lib/Crypto/EncryptAll.php | 1 + lib/KeyManager.php | 36 ++-- tests/Command/RecreateMasterKeyTest.php | 247 ++++++++++++++++++++++ tests/KeyManagerTest.php | 55 ++++- 7 files changed, 587 insertions(+), 18 deletions(-) create mode 100644 lib/Command/RecreateMasterKey.php create mode 100644 tests/Command/RecreateMasterKeyTest.php diff --git a/appinfo/info.xml b/appinfo/info.xml index 65001f23..d5875e98 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -31,6 +31,7 @@ OCA\Encryption\Command\SelectEncryptionType + OCA\Encryption\Command\RecreateMasterKey OCA\Encryption\Command\MigrateKeys diff --git a/lib/Command/RecreateMasterKey.php b/lib/Command/RecreateMasterKey.php new file mode 100644 index 00000000..1da833dc --- /dev/null +++ b/lib/Command/RecreateMasterKey.php @@ -0,0 +1,263 @@ + +* +* @copyright Copyright (c) 2017, ownCloud GmbH +* @license AGPL-3.0 +* +* This code is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License, version 3, +* along with this program. If not, see +* +*/ + + +namespace OCA\Encryption\Command; + +use OC\Encryption\DecryptAll; +use OC\Encryption\Exceptions\DecryptionFailedException; +use OC\Encryption\Manager; +use OC\Files\Filesystem; +use OC\Files\View; +use OC\Memcache\ArrayCache; +use OCA\Encryption\Crypto\EncryptAll; +use OCA\Encryption\KeyManager; +use OCA\Encryption\Users\Setup; +use OCA\Encryption\Util; +use OCP\App\IAppManager; +use OCP\IAppConfig; +use OCP\IConfig; +use OCP\IL10N; +use OCP\ILogger; +use OCP\ISession; +use OCP\IUserManager; +use OCP\Mail\IMailer; +use OCP\Security\ISecureRandom; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; + +class RecreateMasterKey extends Command { + + /** @var Manager */ + protected $encryptionManager; + + /** @var IUserManager */ + protected $userManager; + + /** @var View */ + protected $rootView; + + /** @var KeyManager */ + protected $keyManager; + + /** @var Util */ + protected $util; + + /** @var \OC\Encryption\Util */ + protected $encUtil; + + /** @var IAppManager */ + protected $appManager; + + /** @var IAppConfig */ + protected $appConfig; + + /** @var IConfig */ + protected $config; + + /** @var ISession */ + protected $session; + + /** @var QuestionHelper */ + protected $questionHelper; + + /** @var Setup */ + protected $userSetup; + + /** @var IMailer */ + protected $mailer; + + /** @var ISecureRandom */ + protected $secureRandom; + + /** @var IL10N */ + protected $l; + + /** @var ILogger */ + protected $logger; + + /** @var */ + protected $encryptAll; + + protected $decryptAll; + + /** @var array files which couldn't be decrypted */ + protected $failed; + + /** + * RecreateMasterKey constructor. + * + * @param IUserManager $userManager + * @param View $rootView + * @param KeyManager $keyManager + * @param Util $util + * @param IAppManager $appManager + * @param IAppConfig $appConfig + * @param IConfig $config + * @param ISession $session + * @param QuestionHelper $questionHelper + * @param Setup $userSetup + * @param IMailer $mailer + * @param ISecureRandom $secureRandom + * @param IL10N $l + * @param ILogger $logger + */ + public function __construct(IUserManager $userManager, View $rootView, KeyManager $keyManager, Util $util, \OC\Encryption\Util $encUtil, + IAppManager $appManager, IAppConfig $appConfig, IConfig $config, ISession $session, + Manager $encryptionManager, QuestionHelper $questionHelper, Setup $userSetup, IMailer $mailer, + ISecureRandom $secureRandom, IL10N $l, ILogger $logger) { + + parent::__construct(); + $this->userManager = $userManager; + $this->rootView = $rootView; + $this->keyManager = $keyManager; + $this->util = $util; + $this->encUtil = $encUtil; + $this->appManager = $appManager; + $this->appConfig = $appConfig; + $this->config = $config; + $this->session = $session; + $this->encryptionManager = $encryptionManager; + $this->questionHelper = $questionHelper; + $this->userSetup = $userSetup; + $this->mailer = $mailer; + $this->secureRandom = $secureRandom; + $this->l = $l; + $this->logger = $logger; + } + + protected function configure() { + parent::configure(); + + $this + ->setName('encryption:recreate-master-key') + ->setDescription('Replace existing master key with new one. Encrypt the file system with newly created master key') + ; + + $this->addOption( + 'yes', + 'y', + InputOption::VALUE_NONE, + 'Answer yes to all questions' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $yes = $input->getOption('yes'); + if ($this->util->isMasterKeyEnabled()) { + $question = new ConfirmationQuestion( + 'Warning: In order to re-create master key, the entire ownCloud filesystem will be decrypted and then encrypted using new master key.' + . ' Do you want to continue? (y/n)', false); + if ($yes || $this->questionHelper->ask($input, $output, $question)) { + + $output->writeln("Decryption started\n"); + $progress = new ProgressBar($output); + $progress->start(); + $progress->setMessage("Decryption in progress..."); + $progress->advance(); + + $this->decryptAllUsers($input, $output); + $progress->finish(); + + if (empty($this->failed)) { + + $this->appManager->disableApp('encryption'); + + //Delete the files_encryption dir + $filesEncryptionDir = $this->encUtil->getKeyStorageRoot(); + if ($filesEncryptionDir === '') { + $this->rootView->deleteAll('files_encryption'); + } else { + $this->rootView->deleteAll($filesEncryptionDir . '/files_encryption'); + } + + $this->appConfig->setValue('core', 'encryption_enabled', 'no'); + $this->appConfig->deleteKey('encryption', 'useMasterKey'); + $this->appConfig->deleteKey('encryption', 'masterKeyId'); + $this->appConfig->deleteKey('encryption', 'recoveryKeyId'); + $this->appConfig->deleteKey('encryption', 'publicShareKeyId'); + $this->appConfig->deleteKey('files_encryption', 'installed_version'); + + } + $output->writeln("\nDecryption completed\n"); + + //Reencrypt again + $this->appManager->enableApp('encryption'); + $this->appConfig->setValue('core', 'encryption_enabled', 'yes'); + $this->appConfig->setValue('encryption', 'enabled', 'yes'); + $output->writeln("Encryption started\n"); + + $output->writeln("Waiting for creating new masterkey\n"); + + $this->keyManager->setPublicShareKeyIDAndMasterKeyId(); + + $output->writeln("New masterkey created successfully\n"); + + $this->appConfig->setValue('encryption', 'enabled', 'yes'); + $this->appConfig->setValue('encryption', 'useMasterKey', '1'); + + /** + * Call validateShareKey method, to check if public share exists, + * else create one. + */ + $this->keyManager->validateShareKey(); + /** + * Same here, check if public masterkey exists else + * create one. + */ + $this->keyManager->validateMasterKey(); + $this->encryptAllUsers($input, $output); + $output->writeln("\nEncryption completed successfully\n"); + } else { + $output->writeln("The process is abandoned"); + } + } else { + $output->writeln("Master key is not enabled.\n"); + } + } + + protected function decryptAllUsers(InputInterface $input, OutputInterface $output) { + $this->decryptAll = new DecryptAll($this->encryptionManager, $this->userManager, $this->rootView); + $this->decryptAll->decryptAll($input,$output); + } + + protected function encryptAllUsers(InputInterface $input, OutputInterface $output) { + /* + * We are reusing the encryptAll code but not the decryptAll. The reason being + * decryptAll finishes by encrypting. Which is not what we want. This will make + * things out of scope for this command. We want first the entire oC FS to be + * decrypt. Then re-encrypt the entire oC FS with the new master key generated. + * + */ + $this->encryptAll = new EncryptAll( + $this->userSetup, $this->userManager, $this->rootView, + $this->keyManager, $this->util, $this->config, + $this->mailer, $this->l, $this->questionHelper, + $this->secureRandom); + $this->encryptAll->encryptAll($input, $output); + } +} + diff --git a/lib/Crypto/DecryptAll.php b/lib/Crypto/DecryptAll.php index c37e448f..52ab9e80 100644 --- a/lib/Crypto/DecryptAll.php +++ b/lib/Crypto/DecryptAll.php @@ -93,7 +93,7 @@ public function prepare(InputInterface $input, OutputInterface $output, $user) { $output->writeln('the users password or if he activated the recovery key.'); $output->writeln(''); $questionUseLoginPassword = new ConfirmationQuestion( - 'Do you want to use the users login password to decrypt all files? (y/n) ', + 'Do you want to use the user: ' . $user . ' login password to decrypt all files? (y/n) ', false ); $useLoginPassword = $this->questionHelper->ask($input, $output, $questionUseLoginPassword); diff --git a/lib/Crypto/EncryptAll.php b/lib/Crypto/EncryptAll.php index 081cd721..59942d50 100644 --- a/lib/Crypto/EncryptAll.php +++ b/lib/Crypto/EncryptAll.php @@ -293,6 +293,7 @@ protected function encryptFile($path) { $target = $path . '.encrypted.' . time(); try { + $this->keyManager->setVersion($source, 0, $this->rootView); $this->rootView->copy($source, $target); $this->rootView->rename($target, $source); } catch (DecryptionFailedException $e) { diff --git a/lib/KeyManager.php b/lib/KeyManager.php index e9f9eb6a..8c23a0a3 100644 --- a/lib/KeyManager.php +++ b/lib/KeyManager.php @@ -132,19 +132,7 @@ public function __construct( $this->recoveryKeyId); } - $this->publicShareKeyId = $this->config->getAppValue('encryption', - 'publicShareKeyId'); - if (empty($this->publicShareKeyId)) { - $this->publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); - $this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId); - } - - $this->masterKeyId = $this->config->getAppValue('encryption', - 'masterKeyId'); - if (empty($this->masterKeyId)) { - $this->masterKeyId = 'master_' . substr(md5(time()), 0, 8); - $this->config->setAppValue('encryption', 'masterKeyId', $this->masterKeyId); - } + $this->setPublicShareKeyIDAndMasterKeyId(); $this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false; $this->log = $log; @@ -701,6 +689,9 @@ public function getMasterKeyPassword() { * @return string */ public function getMasterKeyId() { + if($this->config->getAppValue('encryption', 'masterKeyId') !== $this->masterKeyId) { + $this->masterKeyId = $this->config->getAppValue('encryption', 'masterKeyId'); + } return $this->masterKeyId; } @@ -712,4 +703,23 @@ public function getMasterKeyId() { public function getPublicMasterKey() { return $this->keyStorage->getSystemUserKey($this->masterKeyId . '.publicKey', Encryption::ID); } + + /** + * set publicShareKeyId and masterKeyId if not set + */ + public function setPublicShareKeyIDAndMasterKeyId() { + $this->publicShareKeyId = $this->config->getAppValue('encryption', + 'publicShareKeyId'); + if (is_null($this->publicShareKeyId) || ($this->publicShareKeyId === '')) { + $this->publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); + $this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId); + } + + $this->masterKeyId = $this->config->getAppValue('encryption', + 'masterKeyId'); + if (is_null($this->masterKeyId) || ($this->masterKeyId === '')) { + $this->masterKeyId = 'master_' . substr(md5(time()), 0, 8); + $this->config->setAppValue('encryption', 'masterKeyId', $this->masterKeyId); + } + } } diff --git a/tests/Command/RecreateMasterKeyTest.php b/tests/Command/RecreateMasterKeyTest.php new file mode 100644 index 00000000..22531a54 --- /dev/null +++ b/tests/Command/RecreateMasterKeyTest.php @@ -0,0 +1,247 @@ + + * + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + + +namespace OCA\Encryption\Tests\Command; + +use OC\Files\FileInfo; +use OC\Files\View; +use OCA\Encryption\Command\RecreateMasterKey; +use OC\Encryption\Exceptions\DecryptionFailedException; +use OCA\Encryption\Users\Setup; +use OCP\IL10N; +use OCP\Mail\IMailer; +use OCP\Security\ISecureRandom; +use Symfony\Component\Console\Helper\QuestionHelper; +use Test\TestCase; + +class RecreateMasterKeyTest extends TestCase { + + /** @var Manager | \PHPUnit_Framework_MockObject_MockObject */ + protected $encryptionManager; + + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + + /** @var View | \PHPUnit_Framework_MockObject_MockObject */ + protected $rootView; + + /** @var KeyManager | \PHPUnit_Framework_MockObject_MockObject */ + protected $keyManager; + + /** @var Util | \PHPUnit_Framework_MockObject_MockObject */ + protected $util; + + protected $encUitl; + + /** @var IAppManager | \PHPUnit_Framework_MockObject_MockObject */ + protected $IAppManager; + + /** @var IAppConfig | \PHPUnit_Framework_MockObject_MockObject */ + protected $appConfig; + + /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ + protected $config; + + /** @var ISession | \PHPUnit_Framework_MockObject_MockObject */ + protected $session; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\UserInterface */ + protected $userInterface; + + /** @var \Symfony\Component\Console\Output\OutputInterface | \PHPUnit_Framework_MockObject_MockObject */ + protected $output; + + /** @var \Symfony\Component\Console\Input\InputInterface | \PHPUnit_Framework_MockObject_MockObject */ + protected $input; + + protected $questionHelper; + + protected $userSetup; + + protected $mailer; + + protected $secureRandom; + + protected $l; + + protected $logger; + + protected $progressbar; + + protected $setupfs; + + /** @var RecreateMasterKey */ + protected $recreateMasterKey; + + public function setUp() { + parent::setUp(); + + $this->encryptionManager = $this->getMockBuilder('OC\Encryption\Manager') + ->disableOriginalConstructor()->getMock(); + $this->userManager = $this->getMockBuilder('OCP\IUserManager') + ->disableOriginalConstructor()->getMock(); + $this->rootView = $this->getMockBuilder('OC\Files\View') + ->disableOriginalConstructor()->getMock(); + $this->keyManager = $this->getMockBuilder('OCA\Encryption\KeyManager') + ->disableOriginalConstructor()->getMock(); + $this->util = $this->getMockBuilder('OCA\Encryption\Util') + ->disableOriginalConstructor()->getMock(); + $this->encUitl = $this->getMockBuilder('OC\Encryption\Util') + ->disableOriginalConstructor()->getMock(); + $this->IAppManager = $this->getMockBuilder('OCP\App\IAppManager') + ->disableOriginalConstructor()->getMock(); + $this->appConfig = $this->getMockBuilder('OCP\IAppConfig') + ->disableOriginalConstructor()->getMock(); + $this->config = $this->getMockBuilder('OCP\IConfig') + ->disableOriginalConstructor()->getMock(); + $this->session = $this->getMockBuilder('OCP\ISession') + ->disableOriginalConstructor()->getMock(); + $this->questionHelper = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor()->getMock(); + $this->userSetup = $this->getMockBuilder(Setup::class) + ->disableOriginalConstructor()->getMock(); + $this->mailer = $this->getMockBuilder(IMailer::class) + ->disableOriginalConstructor()->getMock(); + $this->secureRandom = $this->getMockBuilder(ISecureRandom::class) + ->disableOriginalConstructor()->getMock(); + $this->l = $this->getMockBuilder(IL10N::class) + ->disableOriginalConstructor()->getMock(); + $this->logger = $this->getMockBuilder('OCP\ILogger') + ->disableOriginalConstructor()->getMock(); + $this->input = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface') + ->disableOriginalConstructor()->getMock(); + $this->output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface') + ->disableOriginalConstructor()->getMock(); + + $this->userInterface = $this->getMockBuilder('OCP\UserInterface') + ->disableOriginalConstructor()->getMock(); + + $this->output->expects($this->any())->method('getFormatter') + ->willReturn($this->createMock('\Symfony\Component\Console\Formatter\OutputFormatterInterface')); + + $this->recreateMasterKey = new RecreateMasterKey($this->userManager, + $this->rootView, $this->keyManager, $this->util, $this->encUitl, + $this->IAppManager, $this->appConfig, $this->config, $this->session, + $this->encryptionManager, $this->questionHelper, + $this->userSetup, $this->mailer, $this->secureRandom, $this->l, $this->logger); + + + $this->invokePrivate($this->recreateMasterKey, 'input', [$this->input]); + $this->invokePrivate($this->recreateMasterKey, 'output', [$this->output]); + } + + /** + * @dataProvider dataTestExecute + */ + public function testNewMasterKey($mastkerKeyEnabled) { + + if( $mastkerKeyEnabled === true) { + $this->recreateMasterKey = $this->getMockBuilder('OCA\Encryption\Command\RecreateMasterKey') + ->setConstructorArgs( + [ + $this->userManager, + $this->rootView, $this->keyManager, $this->util, $this->encUitl, + $this->IAppManager, $this->appConfig, $this->config, $this->session, + $this->encryptionManager, $this->questionHelper, + $this->userSetup, $this->mailer, $this->secureRandom, $this->l, + $this->logger + ] + )->setMethods(['setupUserFS', 'encryptAllUsers', 'decryptAllUsers'])->getMock(); + + $this->questionHelper->expects($this->once())->method('ask') + ->willReturn(true); + + $this->util->expects($this->any())->method('isMasterKeyEnabled') + ->willReturn(true); + + $this->userManager->expects($this->any()) + ->method('getBackends') + ->willReturn([$this->userInterface]); + + $this->userInterface->expects($this->any()) + ->method('getUsers') + ->willReturn(['user1']); + + $this->rootView->expects($this->any())->method('is_dir') + ->willReturnCallback( + function($path) { + if ($path === '/user1/files/foo') { + return true; + } + return false; + } + ); + + $this->encryptionManager->expects($this->any()) + ->method('isReadyForUser') + ->with('user1') + ->willReturn(true); + + global $outputText; + + $this->output->expects($this->at(16)) + ->method('writeln') + ->willReturnCallback(function ($value){ + global $outputText; + $outputText .= $value . "\n"; + }); + + $this->invokePrivate($this->recreateMasterKey, 'execute', [$this->input, $this->output]); + $this->assertSame("Encryption completed successfully", trim($outputText, "\n")); + $outputText=""; + } else { + $this->recreateMasterKey = $this->getMockBuilder('OCA\Encryption\Command\RecreateMasterKey') + ->setConstructorArgs( + [ + $this->userManager, + $this->rootView, $this->keyManager, $this->util, $this->encUitl, + $this->IAppManager, $this->appConfig, $this->config, + $this->session, $this->encryptionManager, $this->questionHelper, + $this->userSetup, $this->mailer, $this->secureRandom, $this->l, + $this->logger + ] + )->setMethods(['setupUserFS'])->getMock(); + + $this->util->expects($this->once())->method('isMasterKeyEnabled') + ->willReturn($mastkerKeyEnabled); + + global $outputText; + $this->output->expects($this->at(0)) + ->method('writeln') + ->willReturnCallback(function ($value){ + global $outputText; + $outputText .= $value . "\n"; + }); + + $this->invokePrivate($this->recreateMasterKey, 'execute', [$this->input, $this->output]); + $this->assertSame("Master key is not enabled.", trim($outputText, "\n")); + } + } + + public function dataTestExecute() { + return [ + [true], + [false] + ]; + } +} + diff --git a/tests/KeyManagerTest.php b/tests/KeyManagerTest.php index d812c035..d4475d5b 100644 --- a/tests/KeyManagerTest.php +++ b/tests/KeyManagerTest.php @@ -75,7 +75,7 @@ public function setUp() { $this->configMock = $this->createMock('OCP\IConfig'); $this->configMock->expects($this->any()) ->method('getAppValue') - ->willReturn($this->systemKeyId); + ->will($this->returnCallback(array($this, 'returnAppValue'))); $this->userMock = $this->createMock('OCP\IUserSession'); $this->sessionMock = $this->getMockBuilder('OCA\Encryption\Session') ->disableOriginalConstructor() @@ -95,6 +95,15 @@ public function setUp() { $this->utilMock); } + public function returnAppValue() { + $args = func_get_args(); + if($args[1] === 'masterKeyId') { + return 'masterKeyId'; + } else { + return 'systemKeyId'; + } + } + public function testDeleteShareKey() { $this->keyStorageMock->expects($this->any()) ->method('deleteFileKey') @@ -499,16 +508,48 @@ public function dataTestAddSystemKeys() { } public function testGetMasterKeyId() { - $this->assertSame('systemKeyId', $this->instance->getMasterKeyId()); + $localConfigMock = $this->createMock('OCP\IConfig'); + $localConfigMock->expects($this->any()) + ->method('getAppValue') + ->willReturn($this->systemKeyId); + $instance = $this->getMockBuilder('OCA\Encryption\KeyManager') + ->setConstructorArgs( + [ + $this->keyStorageMock, + $this->cryptMock, + $localConfigMock, + $this->userMock, + $this->sessionMock, + $this->logMock, + $this->utilMock + ] + )->setMethods()->getMock(); + $this->assertSame('systemKeyId', $instance->getMasterKeyId()); } public function testGetPublicMasterKey() { + $localConfigMock = $this->createMock('OCP\IConfig'); + $localConfigMock->expects($this->any()) + ->method('getAppValue') + ->willReturn($this->systemKeyId); + $instance = $this->getMockBuilder('OCA\Encryption\KeyManager') + ->setConstructorArgs( + [ + $this->keyStorageMock, + $this->cryptMock, + $localConfigMock, + $this->userMock, + $this->sessionMock, + $this->logMock, + $this->utilMock + ] + )->setMethods()->getMock(); $this->keyStorageMock->expects($this->once())->method('getSystemUserKey') ->with('systemKeyId.publicKey', \OCA\Encryption\Crypto\Encryption::ID) ->willReturn(true); $this->assertTrue( - $this->instance->getPublicMasterKey() + $instance->getPublicMasterKey() ); } @@ -538,13 +579,19 @@ public function testGetMasterKeyPasswordException() { */ public function testValidateMasterKey($masterKey) { + $localConfigMock = $this->createMock('OCP\IConfig'); + $returnVal = ($masterKey) ? 'masterKeyId' : $this->systemKeyId; + $localConfigMock->expects($this->any()) + ->method('getAppValue') + ->willReturn($returnVal); + /** @var \OCA\Encryption\KeyManager | \PHPUnit_Framework_MockObject_MockObject $instance */ $instance = $this->getMockBuilder('OCA\Encryption\KeyManager') ->setConstructorArgs( [ $this->keyStorageMock, $this->cryptMock, - $this->configMock, + $localConfigMock, $this->userMock, $this->sessionMock, $this->logMock,