Skip to content

Commit 2b04b6b

Browse files
committed
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 <[email protected]>
1 parent 4c17229 commit 2b04b6b

File tree

2 files changed

+67
-77
lines changed

2 files changed

+67
-77
lines changed

core/Command/Encryption/DecryptAll.php

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
66
* SPDX-License-Identifier: AGPL-3.0-only
77
*/
8+
89
namespace OC\Core\Command\Encryption;
910

1011
use OCP\App\IAppManager;
11-
use OCP\Encryption\IManager;
12+
use OCP\IAppConfig;
1213
use OCP\IConfig;
1314
use Symfony\Component\Console\Command\Command;
1415
use Symfony\Component\Console\Helper\QuestionHelper;
@@ -22,9 +23,9 @@ class DecryptAll extends Command {
2223
protected bool $wasMaintenanceModeEnabled = false;
2324

2425
public function __construct(
25-
protected IManager $encryptionManager,
2626
protected IAppManager $appManager,
2727
protected IConfig $config,
28+
protected IAppConfig $appConfig,
2829
protected \OC\Encryption\DecryptAll $decryptAll,
2930
protected QuestionHelper $questionHelper,
3031
) {
@@ -88,14 +89,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8889
return 1;
8990
}
9091

92+
$originallyEnabled = $this->appConfig->getValueBool('core', 'encryption_enabled');
9193
try {
92-
if ($this->encryptionManager->isEnabled() === true) {
94+
if ($originallyEnabled) {
9395
$output->write('Disable server side encryption... ');
94-
$this->config->setAppValue('core', 'encryption_enabled', 'no');
96+
$this->appConfig->setValueBool('core', 'encryption_enabled', false);
9597
$output->writeln('done.');
9698
} else {
9799
$output->writeln('Server side encryption not enabled. Nothing to do.');
98-
return 0;
99100
}
100101

101102
$uid = $input->getArgument('user');
@@ -118,23 +119,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int
118119
$result = $this->decryptAll->decryptAll($input, $output, $user);
119120
if ($result === false) {
120121
$output->writeln(' aborted.');
122+
if ($originallyEnabled) {
123+
$output->writeln('Server side encryption remains enabled');
124+
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
125+
}
126+
} elseif (($uid !== '') && $originallyEnabled) {
121127
$output->writeln('Server side encryption remains enabled');
122-
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
123-
} elseif ($uid !== '') {
124-
$output->writeln('Server side encryption remains enabled');
125-
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
128+
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
126129
}
127130
$this->resetMaintenanceAndTrashbin();
128131
return 0;
129132
}
130-
$output->write('Enable server side encryption... ');
131-
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
132-
$output->writeln('done.');
133+
if ($originallyEnabled) {
134+
$output->write('Enable server side encryption... ');
135+
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
136+
$output->writeln('done.');
137+
}
133138
$output->writeln('aborted');
134139
return 1;
135140
} catch (\Exception $e) {
136141
// enable server side encryption again if something went wrong
137-
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
142+
if ($originallyEnabled) {
143+
$this->appConfig->setValueBool('core', 'encryption_enabled', true);
144+
}
138145
$this->resetMaintenanceAndTrashbin();
139146
throw $e;
140147
}

tests/Core/Command/Encryption/DecryptAllTest.php

Lines changed: 47 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,52 +10,32 @@
1010

1111
use OC\Core\Command\Encryption\DecryptAll;
1212
use OCP\App\IAppManager;
13-
use OCP\Encryption\IManager;
13+
use OCP\IAppConfig;
1414
use OCP\IConfig;
15+
use PHPUnit\Framework\MockObject\MockObject;
1516
use Symfony\Component\Console\Helper\QuestionHelper;
1617
use Symfony\Component\Console\Input\InputInterface;
1718
use Symfony\Component\Console\Output\OutputInterface;
1819
use Test\TestCase;
1920

2021
class DecryptAllTest extends TestCase {
21-
/** @var \PHPUnit\Framework\MockObject\MockObject|IConfig */
22-
protected $config;
23-
24-
/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\Encryption\IManager */
25-
protected $encryptionManager;
26-
27-
/** @var \PHPUnit\Framework\MockObject\MockObject|IAppManager */
28-
protected $appManager;
29-
30-
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */
31-
protected $consoleInput;
32-
33-
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */
34-
protected $consoleOutput;
35-
36-
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Helper\QuestionHelper */
37-
protected $questionHelper;
38-
39-
/** @var \PHPUnit\Framework\MockObject\MockObject | \OC\Encryption\DecryptAll */
40-
protected $decryptAll;
22+
private MockObject&IConfig $config;
23+
private MockObject&IAppConfig $appConfig;
24+
private MockObject&IAppManager $appManager;
25+
private MockObject&InputInterface $consoleInput;
26+
private MockObject&OutputInterface $consoleOutput;
27+
private MockObject&QuestionHelper $questionHelper;
28+
private MockObject&\OC\Encryption\DecryptAll $decryptAll;
4129

4230
protected function setUp(): void {
4331
parent::setUp();
4432

45-
$this->config = $this->getMockBuilder(IConfig::class)
46-
->disableOriginalConstructor()
47-
->getMock();
48-
$this->encryptionManager = $this->getMockBuilder(IManager::class)
49-
->disableOriginalConstructor()
50-
->getMock();
51-
$this->appManager = $this->getMockBuilder(IAppManager::class)
52-
->disableOriginalConstructor()
53-
->getMock();
54-
$this->questionHelper = $this->getMockBuilder(QuestionHelper::class)
55-
->disableOriginalConstructor()
56-
->getMock();
57-
$this->decryptAll = $this->getMockBuilder(\OC\Encryption\DecryptAll::class)
58-
->disableOriginalConstructor()->getMock();
33+
$this->config = $this->createMock(IConfig::class);
34+
$this->appConfig = $this->createMock(IAppConfig::class);
35+
$this->appManager = $this->createMock(IAppManager::class);
36+
$this->questionHelper = $this->createMock(QuestionHelper::class);
37+
$this->decryptAll = $this->createMock(\OC\Encryption\DecryptAll::class);
38+
5939
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
6040
$this->consoleInput->expects($this->any())
6141
->method('isInteractive')
@@ -92,9 +72,9 @@ public function testMaintenanceAndTrashbin(): void {
9272
->with('files_trashbin');
9373

9474
$instance = new DecryptAll(
95-
$this->encryptionManager,
9675
$this->appManager,
9776
$this->config,
77+
$this->appConfig,
9878
$this->decryptAll,
9979
$this->questionHelper
10080
);
@@ -113,15 +93,16 @@ public function testMaintenanceAndTrashbin(): void {
11393
#[\PHPUnit\Framework\Attributes\DataProvider('dataTestExecute')]
11494
public function testExecute($encryptionEnabled, $continue): void {
11595
$instance = new DecryptAll(
116-
$this->encryptionManager,
11796
$this->appManager,
11897
$this->config,
98+
$this->appConfig,
11999
$this->decryptAll,
120100
$this->questionHelper
121101
);
122102

123-
$this->encryptionManager->expects($this->once())
124-
->method('isEnabled')
103+
$this->appConfig->expects($this->once())
104+
->method('getValueBool')
105+
->with('core', 'encryption_enabled')
125106
->willReturn($encryptionEnabled);
126107

127108
$this->consoleInput->expects($this->any())
@@ -131,29 +112,29 @@ public function testExecute($encryptionEnabled, $continue): void {
131112

132113
if ($encryptionEnabled) {
133114
$calls = [
134-
['core', 'encryption_enabled', 'no'],
135-
['core', 'encryption_enabled', 'yes'],
115+
['core', 'encryption_enabled', false, false],
116+
['core', 'encryption_enabled', true, false],
136117
];
137-
$this->config->expects($this->exactly(2))
138-
->method('setAppValue')
139-
->willReturnCallback(function () use (&$calls): void {
118+
$this->appConfig->expects($this->exactly(count($calls)))
119+
->method('setValueBool')
120+
->willReturnCallback(function () use (&$calls): bool {
140121
$expected = array_shift($calls);
141122
$this->assertEquals($expected, func_get_args());
123+
return true;
142124
});
143-
$this->questionHelper->expects($this->once())
144-
->method('ask')
145-
->willReturn($continue);
146-
if ($continue) {
147-
$this->decryptAll->expects($this->once())
148-
->method('decryptAll')
149-
->with($this->consoleInput, $this->consoleOutput, 'user1');
150-
} else {
151-
$this->decryptAll->expects($this->never())->method('decryptAll');
152-
}
153125
} else {
154-
$this->config->expects($this->never())->method('setAppValue');
126+
$this->appConfig->expects($this->never())
127+
->method('setValueBool');
128+
}
129+
$this->questionHelper->expects($this->once())
130+
->method('ask')
131+
->willReturn($continue);
132+
if ($continue) {
133+
$this->decryptAll->expects($this->once())
134+
->method('decryptAll')
135+
->with($this->consoleInput, $this->consoleOutput, 'user1');
136+
} else {
155137
$this->decryptAll->expects($this->never())->method('decryptAll');
156-
$this->questionHelper->expects($this->never())->method('ask');
157138
}
158139

159140
$this->invokePrivate($instance, 'execute', [$this->consoleInput, $this->consoleOutput]);
@@ -173,26 +154,28 @@ public function testExecuteFailure(): void {
173154
$this->expectException(\Exception::class);
174155

175156
$instance = new DecryptAll(
176-
$this->encryptionManager,
177157
$this->appManager,
178158
$this->config,
159+
$this->appConfig,
179160
$this->decryptAll,
180161
$this->questionHelper
181162
);
182163

183164
// make sure that we enable encryption again after a exception was thrown
184165
$calls = [
185-
['core', 'encryption_enabled', 'no'],
186-
['core', 'encryption_enabled', 'yes'],
166+
['core', 'encryption_enabled', false, false],
167+
['core', 'encryption_enabled', true, false],
187168
];
188-
$this->config->expects($this->exactly(2))
189-
->method('setAppValue')
190-
->willReturnCallback(function () use (&$calls): void {
169+
$this->appConfig->expects($this->exactly(2))
170+
->method('setValuebool')
171+
->willReturnCallback(function () use (&$calls): bool {
191172
$expected = array_shift($calls);
192173
$this->assertEquals($expected, func_get_args());
174+
return true;
193175
});
194-
$this->encryptionManager->expects($this->once())
195-
->method('isEnabled')
176+
$this->appConfig->expects($this->once())
177+
->method('getValueBool')
178+
->with('core', 'encryption_enabled')
196179
->willReturn(true);
197180

198181
$this->consoleInput->expects($this->any())

0 commit comments

Comments
 (0)