Skip to content

Commit ecabd2b

Browse files
committed
fix(encryption): handle legacy string-typed appconfig on upgrade boot
Manager::isEnabled() and EncryptionWrapper::wrap() are both called during OC::init() bootstrap, before occ upgrade has had a chance to run the RetypeEncryptionConfigKeys repair step. If encryption_enabled or encryptHomeStorage were previously stored as VALUE_STRING, the new getValueBool() calls throw AppConfigTypeConflictException and prevent the server from booting at all - making occ upgrade unrunnable. Add a catch(AppConfigTypeConflictException) fallback to both callers that reads the raw string value and interprets it the legacy way ('yes'/'1' → true). This fallback only fires in the upgrade window between extracting new code and running occ upgrade; once the repair step has re-typed the rows it is never reached again. Also strengthen RetypeEncryptionConfigKeysTest setUp() to delete both keys before each test, so real-DB residue from occ invocations in the same process cannot pollute the absence-check test. Signed-off-by: Stephen Cuppett <steve@cuppett.com>
1 parent ca59998 commit ecabd2b

3 files changed

Lines changed: 30 additions & 3 deletions

File tree

lib/private/Encryption/EncryptionWrapper.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OC\Memcache\ArrayCache;
1515
use OCP\Encryption\IFile;
1616
use OCP\Encryption\Keys\IStorage as EncryptionKeysStorage;
17+
use OCP\Exceptions\AppConfigTypeConflictException;
1718
use OCP\Files\Mount\IMountPoint;
1819
use OCP\Files\Storage\IDisableEncryptionStorage;
1920
use OCP\Files\Storage\IStorage;
@@ -72,8 +73,7 @@ public function wrapStorage(string $mountPoint, IStorage $storage, IMountPoint $
7273
}
7374

7475
// Skip encryption for home mounts if encryptHomeStorage is disabled
75-
if ($mount instanceof HomeMountPoint
76-
&& !Server::get(IAppConfig::class)->getValueBool('encryption', 'encryptHomeStorage', true)) {
76+
if ($mount instanceof HomeMountPoint && !$this->shouldEncryptHomeStorage()) {
7777
return $storage;
7878
}
7979
}
@@ -103,4 +103,18 @@ public function wrapStorage(string $mountPoint, IStorage $storage, IMountPoint $
103103
$this->arrayCache
104104
);
105105
}
106+
107+
private function shouldEncryptHomeStorage(): bool {
108+
$appConfig = Server::get(IAppConfig::class);
109+
try {
110+
return $appConfig->getValueBool('encryption', 'encryptHomeStorage', true);
111+
} catch (AppConfigTypeConflictException) {
112+
// Stored as VALUE_STRING from a pre-upgrade installation.
113+
// RetypeEncryptionConfigKeys repair step will fix the type on occ upgrade.
114+
return $appConfig->getValueString('encryption', 'encryptHomeStorage', '1') === '1';
115+
} catch (\Throwable) {
116+
// DB not ready (e.g. oc_appconfig does not yet exist during install).
117+
return true;
118+
}
119+
}
106120
}

lib/private/Encryption/Manager.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OC\ServiceUnavailableException;
1717
use OCP\Encryption\IEncryptionModule;
1818
use OCP\Encryption\IManager;
19+
use OCP\Exceptions\AppConfigTypeConflictException;
1920
use OCP\Files\Mount\IMountPoint;
2021
use OCP\Files\Storage\IStorage;
2122
use OCP\IAppConfig;
@@ -49,7 +50,16 @@ public function isEnabled() {
4950
return false;
5051
}
5152

52-
return $this->appConfig->getValueBool('core', 'encryption_enabled', false);
53+
try {
54+
return $this->appConfig->getValueBool('core', 'encryption_enabled', false);
55+
} catch (AppConfigTypeConflictException) {
56+
// Stored as VALUE_STRING from a pre-upgrade installation.
57+
// RetypeEncryptionConfigKeys repair step will fix the type on occ upgrade.
58+
return $this->appConfig->getValueString('core', 'encryption_enabled', 'no') === 'yes';
59+
} catch (\Throwable) {
60+
// DB not ready (e.g. oc_appconfig does not yet exist during install).
61+
return false;
62+
}
5363
}
5464

5565
/**

tests/lib/Repair/RetypeEncryptionConfigKeysTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ protected function setUp(): void {
2929
$this->appConfig = Server::get(IAppConfig::class);
3030
$this->output = $this->createMock(IOutput::class);
3131
$this->repair = new RetypeEncryptionConfigKeys($this->appConfig);
32+
// Clean slate in case previous test runs or occ invocations left residue
33+
$this->appConfig->deleteKey('core', 'encryption_enabled');
34+
$this->appConfig->deleteKey('encryption', 'encryptHomeStorage');
3235
}
3336

3437
protected function tearDown(): void {

0 commit comments

Comments
 (0)