mirror of
https://github.com/nextcloud/server.git
synced 2026-03-27 04:43:20 -04:00
feat(encryption): Support running decrypt-all when encryption is already disabled
This was an arbitrary limitation since the first thing the command does is disabling encryption anyway, it makes little sence to force the admin to enable encryption first. Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
parent
1829269f9d
commit
a6184661bd
2 changed files with 67 additions and 77 deletions
|
|
@ -5,10 +5,11 @@
|
|||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace OC\Core\Command\Encryption;
|
||||
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Encryption\IManager;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
|
|
@ -22,9 +23,9 @@ class DecryptAll extends Command {
|
|||
protected bool $wasMaintenanceModeEnabled = false;
|
||||
|
||||
public function __construct(
|
||||
protected IManager $encryptionManager,
|
||||
protected IAppManager $appManager,
|
||||
protected IConfig $config,
|
||||
protected IAppConfig $appConfig,
|
||||
protected \OC\Encryption\DecryptAll $decryptAll,
|
||||
protected QuestionHelper $questionHelper,
|
||||
) {
|
||||
|
|
@ -88,14 +89,14 @@ class DecryptAll extends Command {
|
|||
return 1;
|
||||
}
|
||||
|
||||
$originallyEnabled = $this->appConfig->getValueBool('core', 'encryption_enabled');
|
||||
try {
|
||||
if ($this->encryptionManager->isEnabled() === true) {
|
||||
if ($originallyEnabled) {
|
||||
$output->write('Disable server side encryption... ');
|
||||
$this->config->setAppValue('core', 'encryption_enabled', 'no');
|
||||
$this->appConfig->setValueBool('core', 'encryption_enabled', false);
|
||||
$output->writeln('done.');
|
||||
} else {
|
||||
$output->writeln('Server side encryption not enabled. Nothing to do.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$uid = $input->getArgument('user');
|
||||
|
|
@ -118,23 +119,29 @@ class DecryptAll extends Command {
|
|||
$result = $this->decryptAll->decryptAll($input, $output, $user);
|
||||
if ($result === false) {
|
||||
$output->writeln(' aborted.');
|
||||
if ($originallyEnabled) {
|
||||
$output->writeln('Server side encryption remains enabled');
|
||||
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
|
||||
}
|
||||
} elseif (($uid !== '') && $originallyEnabled) {
|
||||
$output->writeln('Server side encryption remains enabled');
|
||||
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
|
||||
} elseif ($uid !== '') {
|
||||
$output->writeln('Server side encryption remains enabled');
|
||||
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
|
||||
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
|
||||
}
|
||||
$this->resetMaintenanceAndTrashbin();
|
||||
return 0;
|
||||
}
|
||||
$output->write('Enable server side encryption... ');
|
||||
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
|
||||
$output->writeln('done.');
|
||||
if ($originallyEnabled) {
|
||||
$output->write('Enable server side encryption... ');
|
||||
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
|
||||
$output->writeln('done.');
|
||||
}
|
||||
$output->writeln('aborted');
|
||||
return 1;
|
||||
} catch (\Exception $e) {
|
||||
// enable server side encryption again if something went wrong
|
||||
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
|
||||
if ($originallyEnabled) {
|
||||
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
|
||||
}
|
||||
$this->resetMaintenanceAndTrashbin();
|
||||
throw $e;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,52 +10,32 @@ namespace Tests\Core\Command\Encryption;
|
|||
|
||||
use OC\Core\Command\Encryption\DecryptAll;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Encryption\IManager;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class DecryptAllTest extends TestCase {
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject|IConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\Encryption\IManager */
|
||||
protected $encryptionManager;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject|IAppManager */
|
||||
protected $appManager;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */
|
||||
protected $consoleInput;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */
|
||||
protected $consoleOutput;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Helper\QuestionHelper */
|
||||
protected $questionHelper;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \OC\Encryption\DecryptAll */
|
||||
protected $decryptAll;
|
||||
private MockObject&IConfig $config;
|
||||
private MockObject&IAppConfig $appConfig;
|
||||
private MockObject&IAppManager $appManager;
|
||||
private MockObject&InputInterface $consoleInput;
|
||||
private MockObject&OutputInterface $consoleOutput;
|
||||
private MockObject&QuestionHelper $questionHelper;
|
||||
private MockObject&\OC\Encryption\DecryptAll $decryptAll;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->config = $this->getMockBuilder(IConfig::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->encryptionManager = $this->getMockBuilder(IManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->appManager = $this->getMockBuilder(IAppManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->questionHelper = $this->getMockBuilder(QuestionHelper::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->decryptAll = $this->getMockBuilder(\OC\Encryption\DecryptAll::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->appManager = $this->createMock(IAppManager::class);
|
||||
$this->questionHelper = $this->createMock(QuestionHelper::class);
|
||||
$this->decryptAll = $this->createMock(\OC\Encryption\DecryptAll::class);
|
||||
|
||||
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('isInteractive')
|
||||
|
|
@ -92,9 +72,9 @@ class DecryptAllTest extends TestCase {
|
|||
->with('files_trashbin');
|
||||
|
||||
$instance = new DecryptAll(
|
||||
$this->encryptionManager,
|
||||
$this->appManager,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->decryptAll,
|
||||
$this->questionHelper
|
||||
);
|
||||
|
|
@ -113,15 +93,16 @@ class DecryptAllTest extends TestCase {
|
|||
#[\PHPUnit\Framework\Attributes\DataProvider('dataTestExecute')]
|
||||
public function testExecute($encryptionEnabled, $continue): void {
|
||||
$instance = new DecryptAll(
|
||||
$this->encryptionManager,
|
||||
$this->appManager,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->decryptAll,
|
||||
$this->questionHelper
|
||||
);
|
||||
|
||||
$this->encryptionManager->expects($this->once())
|
||||
->method('isEnabled')
|
||||
$this->appConfig->expects($this->once())
|
||||
->method('getValueBool')
|
||||
->with('core', 'encryption_enabled')
|
||||
->willReturn($encryptionEnabled);
|
||||
|
||||
$this->consoleInput->expects($this->any())
|
||||
|
|
@ -131,29 +112,29 @@ class DecryptAllTest extends TestCase {
|
|||
|
||||
if ($encryptionEnabled) {
|
||||
$calls = [
|
||||
['core', 'encryption_enabled', 'no'],
|
||||
['core', 'encryption_enabled', 'yes'],
|
||||
['core', 'encryption_enabled', false, false],
|
||||
['core', 'encryption_enabled', true, false],
|
||||
];
|
||||
$this->config->expects($this->exactly(2))
|
||||
->method('setAppValue')
|
||||
->willReturnCallback(function () use (&$calls): void {
|
||||
$this->appConfig->expects($this->exactly(count($calls)))
|
||||
->method('setValueBool')
|
||||
->willReturnCallback(function () use (&$calls): bool {
|
||||
$expected = array_shift($calls);
|
||||
$this->assertEquals($expected, func_get_args());
|
||||
return true;
|
||||
});
|
||||
$this->questionHelper->expects($this->once())
|
||||
->method('ask')
|
||||
->willReturn($continue);
|
||||
if ($continue) {
|
||||
$this->decryptAll->expects($this->once())
|
||||
->method('decryptAll')
|
||||
->with($this->consoleInput, $this->consoleOutput, 'user1');
|
||||
} else {
|
||||
$this->decryptAll->expects($this->never())->method('decryptAll');
|
||||
}
|
||||
} else {
|
||||
$this->config->expects($this->never())->method('setAppValue');
|
||||
$this->appConfig->expects($this->never())
|
||||
->method('setValueBool');
|
||||
}
|
||||
$this->questionHelper->expects($this->once())
|
||||
->method('ask')
|
||||
->willReturn($continue);
|
||||
if ($continue) {
|
||||
$this->decryptAll->expects($this->once())
|
||||
->method('decryptAll')
|
||||
->with($this->consoleInput, $this->consoleOutput, 'user1');
|
||||
} else {
|
||||
$this->decryptAll->expects($this->never())->method('decryptAll');
|
||||
$this->questionHelper->expects($this->never())->method('ask');
|
||||
}
|
||||
|
||||
$this->invokePrivate($instance, 'execute', [$this->consoleInput, $this->consoleOutput]);
|
||||
|
|
@ -173,26 +154,28 @@ class DecryptAllTest extends TestCase {
|
|||
$this->expectException(\Exception::class);
|
||||
|
||||
$instance = new DecryptAll(
|
||||
$this->encryptionManager,
|
||||
$this->appManager,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->decryptAll,
|
||||
$this->questionHelper
|
||||
);
|
||||
|
||||
// make sure that we enable encryption again after a exception was thrown
|
||||
$calls = [
|
||||
['core', 'encryption_enabled', 'no'],
|
||||
['core', 'encryption_enabled', 'yes'],
|
||||
['core', 'encryption_enabled', false, false],
|
||||
['core', 'encryption_enabled', true, false],
|
||||
];
|
||||
$this->config->expects($this->exactly(2))
|
||||
->method('setAppValue')
|
||||
->willReturnCallback(function () use (&$calls): void {
|
||||
$this->appConfig->expects($this->exactly(2))
|
||||
->method('setValuebool')
|
||||
->willReturnCallback(function () use (&$calls): bool {
|
||||
$expected = array_shift($calls);
|
||||
$this->assertEquals($expected, func_get_args());
|
||||
return true;
|
||||
});
|
||||
$this->encryptionManager->expects($this->once())
|
||||
->method('isEnabled')
|
||||
$this->appConfig->expects($this->once())
|
||||
->method('getValueBool')
|
||||
->with('core', 'encryption_enabled')
|
||||
->willReturn(true);
|
||||
|
||||
$this->consoleInput->expects($this->any())
|
||||
|
|
|
|||
Loading…
Reference in a new issue