fix(encryption): Do not depend upon user in session unless really necessary

Should fix a bunch of stuff when encryption listener is triggered by events from occ commands or background jobs

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
Côme Chilliet 2025-08-07 18:08:42 +02:00
parent 55ad42ad95
commit b74c7538ac
No known key found for this signature in database
GPG key ID: A3E2F658B28C760A
4 changed files with 17 additions and 25 deletions

View file

@ -127,7 +127,7 @@ class Encryption implements IEncryptionModule {
/* If useLegacyFileKey is not specified in header, auto-detect, to be safe */
$useLegacyFileKey = (($header['useLegacyFileKey'] ?? '') == 'false' ? false : null);
$this->fileKey = $this->keyManager->getFileKey($this->path, $this->user, $useLegacyFileKey, $this->session->decryptAllModeActivated());
$this->fileKey = $this->keyManager->getFileKey($this->path, null, $useLegacyFileKey, $this->session->decryptAllModeActivated());
// always use the version from the original file, also part files
// need to have a correct version number if they get moved over to the
@ -322,7 +322,7 @@ class Encryption implements IEncryptionModule {
* update encrypted file, e.g. give additional users access to the file
*
* @param string $path path to the file which should be updated
* @param string $uid of the user who performs the operation
* @param string $uid ignored
* @param array $accessList who has access to the file contains the key 'users' and 'public'
* @return bool
*/
@ -335,7 +335,7 @@ class Encryption implements IEncryptionModule {
return false;
}
$fileKey = $this->keyManager->getFileKey($path, $uid, null);
$fileKey = $this->keyManager->getFileKey($path, null, null);
if (!empty($fileKey)) {
$publicKeys = [];

View file

@ -23,7 +23,7 @@ class KeyManager {
private string $recoveryKeyId;
private string $publicShareKeyId;
private string $masterKeyId;
private string $keyId;
private ?string $keyUid;
private string $publicKeyId = 'publicKey';
private string $privateKeyId = 'privateKey';
private string $shareKeyId = 'shareKey';
@ -62,7 +62,7 @@ class KeyManager {
$this->config->setAppValue('encryption', 'masterKeyId', $this->masterKeyId);
}
$this->keyId = $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false;
$this->keyUid = $userSession->isLoggedIn() ? $userSession->getUser()?->getUID() : null;
}
/**
@ -345,13 +345,11 @@ class KeyManager {
}
/**
* @param ?string $uid deprecated
* @param ?bool $useLegacyFileKey null means try both
*/
public function getFileKey(string $path, ?string $uid, ?bool $useLegacyFileKey, bool $useDecryptAll = false): string {
if ($uid === '') {
$uid = null;
}
$publicAccess = is_null($uid);
$publicAccess = ($this->keyUid === null);
$encryptedFileKey = '';
if ($useLegacyFileKey ?? true) {
$encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID);
@ -380,6 +378,7 @@ class KeyManager {
$privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.' . $this->privateKeyId, Encryption::ID);
$privateKey = $this->crypt->decryptPrivateKey($privateKey);
} else {
$uid = $this->keyUid;
$shareKey = $this->getShareKey($path, $uid);
$privateKey = $this->session->getPrivateKey();
}

View file

@ -67,21 +67,16 @@ class EncryptionEventListener implements IEventListener {
}
private function getUpdate(?IUser $owner = null): Update {
if (is_null($this->updater)) {
$user = $this->userSession->getUser();
if (!$user && ($owner !== null)) {
$user = $owner;
}
if (!$user) {
throw new \Exception('Inconsistent data, File unshared, but owner not found. Should not happen');
}
$uid = $user->getUID();
$user = $this->userSession->getUser();
if (!$user && ($owner !== null)) {
$user = $owner;
}
if ($user) {
if (!$this->setupManager->isSetupComplete($user)) {
$this->setupManager->setupForUser($user);
}
}
if (is_null($this->updater)) {
$this->updater = new Update(
new Util(
new View(),
@ -91,7 +86,6 @@ class EncryptionEventListener implements IEventListener {
\OC::$server->getEncryptionManager(),
\OC::$server->get(IFile::class),
\OC::$server->get(LoggerInterface::class),
$uid
);
}

View file

@ -27,7 +27,6 @@ class Update {
protected Manager $encryptionManager,
protected File $file,
protected LoggerInterface $logger,
protected string $uid,
) {
}
@ -108,10 +107,10 @@ class Update {
foreach ($allFiles as $file) {
$usersSharing = $this->file->getAccessList($file);
try {
$encryptionModule->update($file, $this->uid, $usersSharing);
$encryptionModule->update($file, '', $usersSharing);
} catch (GenericEncryptionException $e) {
// If the update of an individual file fails e.g. due to a corrupt key we should continue the operation and just log the failure
$this->logger->error('Failed to update encryption module for ' . $this->uid . ' ' . $file, [ 'exception' => $e ]);
$this->logger->error('Failed to update encryption module for ' . $file, [ 'exception' => $e ]);
}
}
}