aboutsummaryrefslogtreecommitdiffstats
path: root/apps/encryption/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/encryption/lib')
-rw-r--r--apps/encryption/lib/AppInfo/Application.php151
-rw-r--r--apps/encryption/lib/Command/DisableMasterKey.php84
-rw-r--r--apps/encryption/lib/Command/DropLegacyFileKey.php29
-rw-r--r--apps/encryption/lib/Command/EnableMasterKey.php76
-rw-r--r--apps/encryption/lib/Command/FixEncryptedVersion.php79
-rw-r--r--apps/encryption/lib/Command/FixKeyLocation.php111
-rw-r--r--apps/encryption/lib/Command/RecoverUser.php61
-rw-r--r--apps/encryption/lib/Command/ScanLegacyFormat.php68
-rw-r--r--apps/encryption/lib/Controller/RecoveryController.php59
-rw-r--r--apps/encryption/lib/Controller/SettingsController.php87
-rw-r--r--apps/encryption/lib/Controller/StatusController.php53
-rw-r--r--apps/encryption/lib/Crypto/Crypt.php47
-rw-r--r--apps/encryption/lib/Crypto/DecryptAll.php58
-rw-r--r--apps/encryption/lib/Crypto/EncryptAll.php151
-rw-r--r--apps/encryption/lib/Crypto/Encryption.php67
-rw-r--r--apps/encryption/lib/Exceptions/MultiKeyDecryptException.php22
-rw-r--r--apps/encryption/lib/Exceptions/MultiKeyEncryptException.php22
-rw-r--r--apps/encryption/lib/Exceptions/PrivateKeyMissingException.php27
-rw-r--r--apps/encryption/lib/Exceptions/PublicKeyMissingException.php25
-rw-r--r--apps/encryption/lib/HookManager.php59
-rw-r--r--apps/encryption/lib/Hooks/Contracts/IHook.php31
-rw-r--r--apps/encryption/lib/Hooks/UserHooks.php286
-rw-r--r--apps/encryption/lib/KeyManager.php59
-rw-r--r--apps/encryption/lib/Listeners/UserEventsListener.php144
-rw-r--r--apps/encryption/lib/Migration/SetMasterKeyStatus.php31
-rw-r--r--apps/encryption/lib/Recovery.php66
-rw-r--r--apps/encryption/lib/Services/PassphraseService.php148
-rw-r--r--apps/encryption/lib/Session.php37
-rw-r--r--apps/encryption/lib/Settings/Admin.php31
-rw-r--r--apps/encryption/lib/Settings/Personal.php47
-rw-r--r--apps/encryption/lib/Users/Setup.php40
-rw-r--r--apps/encryption/lib/Util.php46
32 files changed, 757 insertions, 1545 deletions
diff --git a/apps/encryption/lib/AppInfo/Application.php b/apps/encryption/lib/AppInfo/Application.php
index 7d794ab15a6..b1bf93b9dea 100644
--- a/apps/encryption/lib/AppInfo/Application.php
+++ b/apps/encryption/lib/AppInfo/Application.php
@@ -1,92 +1,111 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\AppInfo;
+use OC\Core\Events\BeforePasswordResetEvent;
+use OC\Core\Events\PasswordResetEvent;
use OCA\Encryption\Crypto\Crypt;
use OCA\Encryption\Crypto\DecryptAll;
use OCA\Encryption\Crypto\EncryptAll;
use OCA\Encryption\Crypto\Encryption;
-use OCA\Encryption\HookManager;
-use OCA\Encryption\Hooks\UserHooks;
use OCA\Encryption\KeyManager;
-use OCA\Encryption\Recovery;
+use OCA\Encryption\Listeners\UserEventsListener;
use OCA\Encryption\Session;
use OCA\Encryption\Users\Setup;
use OCA\Encryption\Util;
+use OCP\AppFramework\App;
+use OCP\AppFramework\Bootstrap\IBootContext;
+use OCP\AppFramework\Bootstrap\IBootstrap;
+use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Encryption\IManager;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
+use OCP\IL10N;
+use OCP\IUserSession;
+use OCP\User\Events\BeforePasswordUpdatedEvent;
+use OCP\User\Events\PasswordUpdatedEvent;
+use OCP\User\Events\UserCreatedEvent;
+use OCP\User\Events\UserDeletedEvent;
+use OCP\User\Events\UserLoggedInEvent;
+use OCP\User\Events\UserLoggedInWithCookieEvent;
+use OCP\User\Events\UserLoggedOutEvent;
use Psr\Log\LoggerInterface;
-class Application extends \OCP\AppFramework\App {
- /**
- * @param array $urlParams
- */
- public function __construct($urlParams = []) {
- parent::__construct('encryption', $urlParams);
+class Application extends App implements IBootstrap {
+ public const APP_ID = 'encryption';
+
+ public function __construct(array $urlParams = []) {
+ parent::__construct(self::APP_ID, $urlParams);
+ }
+
+ public function register(IRegistrationContext $context): void {
+ }
+
+ public function boot(IBootContext $context): void {
+ \OCP\Util::addScript(self::APP_ID, 'encryption');
+
+ $context->injectFn(function (IManager $encryptionManager) use ($context): void {
+ if (!($encryptionManager instanceof \OC\Encryption\Manager)) {
+ return;
+ }
+
+ if (!$encryptionManager->isReady()) {
+ return;
+ }
+
+ $context->injectFn($this->registerEncryptionModule(...));
+ $context->injectFn($this->registerEventListeners(...));
+ $context->injectFn($this->setUp(...));
+ });
}
public function setUp(IManager $encryptionManager) {
if ($encryptionManager->isEnabled()) {
/** @var Setup $setup */
- $setup = $this->getContainer()->query(Setup::class);
+ $setup = $this->getContainer()->get(Setup::class);
$setup->setupSystem();
}
}
- /**
- * register hooks
- */
- public function registerHooks(IConfig $config) {
- if (!$config->getSystemValueBool('maintenance')) {
- $container = $this->getContainer();
- $server = $container->getServer();
- // Register our hooks and fire them.
- $hookManager = new HookManager();
-
- $hookManager->registerHook([
- new UserHooks($container->query(KeyManager::class),
- $server->getUserManager(),
- $server->get(LoggerInterface::class),
- $container->query(Setup::class),
- $server->getUserSession(),
- $container->query(Util::class),
- $container->query(Session::class),
- $container->query(Crypt::class),
- $container->query(Recovery::class))
- ]);
+ public function registerEventListeners(
+ IConfig $config,
+ IEventDispatcher $eventDispatcher,
+ IManager $encryptionManager,
+ Util $util,
+ ): void {
+ if (!$encryptionManager->isEnabled()) {
+ return;
+ }
- $hookManager->fireHooks();
- } else {
+ if ($config->getSystemValueBool('maintenance')) {
// Logout user if we are in maintenance to force re-login
- $this->getContainer()->getServer()->getUserSession()->logout();
+ $this->getContainer()->get(IUserSession::class)->logout();
+ return;
+ }
+
+ // No maintenance so register all events
+ $eventDispatcher->addServiceListener(UserLoggedInEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(UserLoggedInWithCookieEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(UserLoggedOutEvent::class, UserEventsListener::class);
+ if (!$util->isMasterKeyEnabled()) {
+ // Only make sense if no master key is used
+ $eventDispatcher->addServiceListener(UserCreatedEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(UserDeletedEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(BeforePasswordUpdatedEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(PasswordUpdatedEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(BeforePasswordResetEvent::class, UserEventsListener::class);
+ $eventDispatcher->addServiceListener(PasswordResetEvent::class, UserEventsListener::class);
}
}
- public function registerEncryptionModule(IManager $encryptionManager) {
+ public function registerEncryptionModule(
+ IManager $encryptionManager,
+ ) {
$container = $this->getContainer();
$encryptionManager->registerEncryptionModule(
@@ -94,14 +113,14 @@ class Application extends \OCP\AppFramework\App {
Encryption::DISPLAY_NAME,
function () use ($container) {
return new Encryption(
- $container->query(Crypt::class),
- $container->query(KeyManager::class),
- $container->query(Util::class),
- $container->query(Session::class),
- $container->query(EncryptAll::class),
- $container->query(DecryptAll::class),
- $container->getServer()->get(LoggerInterface::class),
- $container->getServer()->getL10N($container->getAppName())
+ $container->get(Crypt::class),
+ $container->get(KeyManager::class),
+ $container->get(Util::class),
+ $container->get(Session::class),
+ $container->get(EncryptAll::class),
+ $container->get(DecryptAll::class),
+ $container->get(LoggerInterface::class),
+ $container->get(IL10N::class),
);
});
}
diff --git a/apps/encryption/lib/Command/DisableMasterKey.php b/apps/encryption/lib/Command/DisableMasterKey.php
index 5a07e294248..0b8b8e39e78 100644
--- a/apps/encryption/lib/Command/DisableMasterKey.php
+++ b/apps/encryption/lib/Command/DisableMasterKey.php
@@ -1,26 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Command;
@@ -33,31 +15,15 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
class DisableMasterKey extends Command {
-
- /** @var Util */
- protected $util;
-
- /** @var IConfig */
- protected $config;
-
- /** @var QuestionHelper */
- protected $questionHelper;
-
- /**
- * @param Util $util
- * @param IConfig $config
- * @param QuestionHelper $questionHelper
- */
- public function __construct(Util $util,
- IConfig $config,
- QuestionHelper $questionHelper) {
- $this->util = $util;
- $this->config = $config;
- $this->questionHelper = $questionHelper;
+ public function __construct(
+ protected Util $util,
+ protected IConfig $config,
+ protected QuestionHelper $questionHelper,
+ ) {
parent::__construct();
}
- protected function configure() {
+ protected function configure(): void {
$this
->setName('encryption:disable-master-key')
->setDescription('Disable the master key and use per-user keys instead. Only available for fresh installations with no existing encrypted data! There is no way to enable it again.');
@@ -68,21 +34,23 @@ class DisableMasterKey extends Command {
if (!$isMasterKeyEnabled) {
$output->writeln('Master key already disabled');
- } else {
- $question = new ConfirmationQuestion(
- 'Warning: Only perform this operation for a fresh installations with no existing encrypted data! '
- . 'There is no way to enable the master key again. '
- . 'We strongly recommend to keep the master key, it provides significant performance improvements '
- . 'and is easier to handle for both, users and administrators. '
- . 'Do you really want to switch to per-user keys? (y/n) ', false);
- if ($this->questionHelper->ask($input, $output, $question)) {
- $this->config->setAppValue('encryption', 'useMasterKey', '0');
- $output->writeln('Master key successfully disabled.');
- } else {
- $output->writeln('aborted.');
- return 1;
- }
+ return self::SUCCESS;
+ }
+
+ $question = new ConfirmationQuestion(
+ 'Warning: Only perform this operation for a fresh installations with no existing encrypted data! '
+ . 'There is no way to enable the master key again. '
+ . 'We strongly recommend to keep the master key, it provides significant performance improvements '
+ . 'and is easier to handle for both, users and administrators. '
+ . 'Do you really want to switch to per-user keys? (y/n) ', false);
+
+ if ($this->questionHelper->ask($input, $output, $question)) {
+ $this->config->setAppValue('encryption', 'useMasterKey', '0');
+ $output->writeln('Master key successfully disabled.');
+ return self::SUCCESS;
}
- return 0;
+
+ $output->writeln('aborted.');
+ return self::FAILURE;
}
}
diff --git a/apps/encryption/lib/Command/DropLegacyFileKey.php b/apps/encryption/lib/Command/DropLegacyFileKey.php
index f0a5f36f30f..a9add1ad93b 100644
--- a/apps/encryption/lib/Command/DropLegacyFileKey.php
+++ b/apps/encryption/lib/Command/DropLegacyFileKey.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023, Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Command;
@@ -75,10 +58,10 @@ class DropLegacyFileKey extends Command {
if ($result) {
$output->writeln('All scanned files are properly encrypted.');
- return 0;
+ return self::SUCCESS;
}
- return 1;
+ return self::FAILURE;
}
private function scanFolder(OutputInterface $output, string $folder): bool {
@@ -131,10 +114,10 @@ class DropLegacyFileKey extends Command {
$copyResource = $this->rootView->fopen($target, 'r');
$sourceResource = $this->rootView->fopen($source, 'w');
if ($copyResource === false || $sourceResource === false) {
- throw new DecryptionFailedException('Failed to open '.$source.' or '.$target);
+ throw new DecryptionFailedException('Failed to open ' . $source . ' or ' . $target);
}
if (stream_copy_to_stream($copyResource, $sourceResource) === false) {
- $output->writeln('<error>Failed to copy '.$target.' data into '.$source.'</error>');
+ $output->writeln('<error>Failed to copy ' . $target . ' data into ' . $source . '</error>');
$output->writeln('<error>Leaving both files in there to avoid data loss</error>');
return;
}
diff --git a/apps/encryption/lib/Command/EnableMasterKey.php b/apps/encryption/lib/Command/EnableMasterKey.php
index 7c49988c7fb..0d8b893e0e2 100644
--- a/apps/encryption/lib/Command/EnableMasterKey.php
+++ b/apps/encryption/lib/Command/EnableMasterKey.php
@@ -1,25 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Command;
@@ -32,31 +16,15 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
class EnableMasterKey extends Command {
-
- /** @var Util */
- protected $util;
-
- /** @var IConfig */
- protected $config;
-
- /** @var QuestionHelper */
- protected $questionHelper;
-
- /**
- * @param Util $util
- * @param IConfig $config
- * @param QuestionHelper $questionHelper
- */
- public function __construct(Util $util,
- IConfig $config,
- QuestionHelper $questionHelper) {
- $this->util = $util;
- $this->config = $config;
- $this->questionHelper = $questionHelper;
+ public function __construct(
+ protected Util $util,
+ protected IConfig $config,
+ protected QuestionHelper $questionHelper,
+ ) {
parent::__construct();
}
- protected function configure() {
+ protected function configure(): void {
$this
->setName('encryption:enable-master-key')
->setDescription('Enable the master key. Only available for fresh installations with no existing encrypted data! There is also no way to disable it again.');
@@ -67,18 +35,20 @@ class EnableMasterKey extends Command {
if ($isAlreadyEnabled) {
$output->writeln('Master key already enabled');
- } else {
- $question = new ConfirmationQuestion(
- 'Warning: Only available for fresh installations with no existing encrypted data! '
+ return self::SUCCESS;
+ }
+
+ $question = new ConfirmationQuestion(
+ 'Warning: Only available for fresh installations with no existing encrypted data! '
. 'There is also no way to disable it again. Do you want to continue? (y/n) ', false);
- if ($this->questionHelper->ask($input, $output, $question)) {
- $this->config->setAppValue('encryption', 'useMasterKey', '1');
- $output->writeln('Master key successfully enabled.');
- } else {
- $output->writeln('aborted.');
- return 1;
- }
+
+ if ($this->questionHelper->ask($input, $output, $question)) {
+ $this->config->setAppValue('encryption', 'useMasterKey', '1');
+ $output->writeln('Master key successfully enabled.');
+ return self::SUCCESS;
}
- return 0;
+
+ $output->writeln('aborted.');
+ return self::FAILURE;
}
}
diff --git a/apps/encryption/lib/Command/FixEncryptedVersion.php b/apps/encryption/lib/Command/FixEncryptedVersion.php
index d0fbf1adb31..462e3a5cc2a 100644
--- a/apps/encryption/lib/Command/FixEncryptedVersion.php
+++ b/apps/encryption/lib/Command/FixEncryptedVersion.php
@@ -1,23 +1,9 @@
<?php
+
/**
- * @author Sujith Haridasan <sharidasan@owncloud.com>
- * @author Ilja Neumann <ineumann@owncloud.com>
- *
- * @copyright Copyright (c) 2019, 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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2019 ownCloud GmbH
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Command;
@@ -26,6 +12,7 @@ use OC\Files\Storage\Wrapper\Encryption;
use OC\Files\View;
use OC\ServerNotAvailableException;
use OCA\Encryption\Util;
+use OCP\Encryption\Exceptions\InvalidHeaderException;
use OCP\Files\IRootFolder;
use OCP\HintException;
use OCP\IConfig;
@@ -39,7 +26,7 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class FixEncryptedVersion extends Command {
- private bool $supportLegacy;
+ private bool $supportLegacy = false;
public function __construct(
private IConfig $config,
@@ -49,8 +36,6 @@ class FixEncryptedVersion extends Command {
private Util $util,
private View $view,
) {
- $this->supportLegacy = false;
-
parent::__construct();
}
@@ -83,47 +68,49 @@ class FixEncryptedVersion extends Command {
if ($skipSignatureCheck) {
$output->writeln("<error>Repairing is not possible when \"encryption_skip_signature_check\" is set. Please disable this flag in the configuration.</error>\n");
- return 1;
+ return self::FAILURE;
}
if (!$this->util->isMasterKeyEnabled()) {
$output->writeln("<error>Repairing only works with master key encryption.</error>\n");
- return 1;
+ return self::FAILURE;
}
$user = $input->getArgument('user');
$all = $input->getOption('all');
$pathOption = \trim(($input->getOption('path') ?? ''), '/');
+ if (!$user && !$all) {
+ $output->writeln('Either a user id or --all needs to be provided');
+ return self::FAILURE;
+ }
+
if ($user) {
if ($all) {
- $output->writeln("Specifying a user id and --all are mutually exclusive");
- return 1;
+ $output->writeln('Specifying a user id and --all are mutually exclusive');
+ return self::FAILURE;
}
if ($this->userManager->get($user) === null) {
$output->writeln("<error>User id $user does not exist. Please provide a valid user id</error>");
- return 1;
+ return self::FAILURE;
}
return $this->runForUser($user, $pathOption, $output);
- } elseif ($all) {
- $result = 0;
- $this->userManager->callForSeenUsers(function (IUser $user) use ($pathOption, $output, &$result) {
- $output->writeln("Processing files for " . $user->getUID());
- $result = $this->runForUser($user->getUID(), $pathOption, $output);
- return $result === 0;
- });
- return $result;
- } else {
- $output->writeln("Either a user id or --all needs to be provided");
- return 1;
}
+
+ $result = 0;
+ $this->userManager->callForSeenUsers(function (IUser $user) use ($pathOption, $output, &$result) {
+ $output->writeln('Processing files for ' . $user->getUID());
+ $result = $this->runForUser($user->getUID(), $pathOption, $output);
+ return $result === 0;
+ });
+ return $result;
}
private function runForUser(string $user, string $pathOption, OutputInterface $output): int {
$pathToWalk = "/$user/files";
- if ($pathOption !== "") {
+ if ($pathOption !== '') {
$pathToWalk = "$pathToWalk/$pathOption";
}
return $this->walkPathOfUser($user, $pathToWalk, $output);
@@ -136,13 +123,13 @@ class FixEncryptedVersion extends Command {
$this->setupUserFs($user);
if (!$this->view->file_exists($path)) {
$output->writeln("<error>Path \"$path\" does not exist. Please provide a valid path.</error>");
- return 1;
+ return self::FAILURE;
}
if ($this->view->is_file($path)) {
$output->writeln("Verifying the content of file \"$path\"");
$this->verifyFileContent($path, $output);
- return 0;
+ return self::SUCCESS;
}
$directories = [];
$directories[] = $path;
@@ -158,7 +145,7 @@ class FixEncryptedVersion extends Command {
}
}
}
- return 0;
+ return self::SUCCESS;
}
/**
@@ -210,7 +197,7 @@ class FixEncryptedVersion extends Command {
\fclose($handle);
return true;
- } catch (ServerNotAvailableException $e) {
+ } catch (ServerNotAvailableException|InvalidHeaderException $e) {
// not a "bad signature" error and likely "legacy cipher" exception
// this could mean that the file is maybe not encrypted but the encrypted version is set
if (!$this->supportLegacy && $ignoreCorrectEncVersionCall === true) {
@@ -219,7 +206,7 @@ class FixEncryptedVersion extends Command {
}
return false;
} catch (HintException $e) {
- $this->logger->warning("Issue: " . $e->getMessage());
+ $this->logger->warning('Issue: ' . $e->getMessage());
// If allowOnce is set to false, this becomes recursive.
if ($ignoreCorrectEncVersionCall === true) {
// Lets rectify the file by correcting encrypted version
@@ -268,7 +255,7 @@ class FixEncryptedVersion extends Command {
// try with zero first
$cacheInfo = ['encryptedVersion' => 0, 'encrypted' => 0];
$cache->put($fileCache->getPath(), $cacheInfo);
- $output->writeln("<info>Set the encrypted version to 0 (unencrypted)</info>");
+ $output->writeln('<info>Set the encrypted version to 0 (unencrypted)</info>');
if ($this->verifyFileContent($path, $output, false) === true) {
$output->writeln("<info>Fixed the file: \"$path\" with version 0 (unencrypted)</info>");
return true;
@@ -282,7 +269,7 @@ class FixEncryptedVersion extends Command {
$cache->put($fileCache->getPath(), $cacheInfo);
$output->writeln("<info>Decrement the encrypted version to $encryptedVersion</info>");
if ($this->verifyFileContent($path, $output, false) === true) {
- $output->writeln("<info>Fixed the file: \"$path\" with version " . $encryptedVersion . "</info>");
+ $output->writeln("<info>Fixed the file: \"$path\" with version " . $encryptedVersion . '</info>');
return true;
}
$encryptedVersion--;
@@ -305,7 +292,7 @@ class FixEncryptedVersion extends Command {
$cache->put($fileCache->getPath(), $cacheInfo);
$output->writeln("<info>Increment the encrypted version to $newEncryptedVersion</info>");
if ($this->verifyFileContent($path, $output, false) === true) {
- $output->writeln("<info>Fixed the file: \"$path\" with version " . $newEncryptedVersion . "</info>");
+ $output->writeln("<info>Fixed the file: \"$path\" with version " . $newEncryptedVersion . '</info>');
return true;
}
$increment++;
diff --git a/apps/encryption/lib/Command/FixKeyLocation.php b/apps/encryption/lib/Command/FixKeyLocation.php
index 5001da4bb92..da529a4be2f 100644
--- a/apps/encryption/lib/Command/FixKeyLocation.php
+++ b/apps/encryption/lib/Command/FixKeyLocation.php
@@ -2,23 +2,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Command;
@@ -43,29 +28,21 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class FixKeyLocation extends Command {
- private IUserManager $userManager;
- private IUserMountCache $userMountCache;
- private Util $encryptionUtil;
- private IRootFolder $rootFolder;
private string $keyRootDirectory;
private View $rootView;
private Manager $encryptionManager;
public function __construct(
- IUserManager $userManager,
- IUserMountCache $userMountCache,
- Util $encryptionUtil,
- IRootFolder $rootFolder,
- IManager $encryptionManager
+ private IUserManager $userManager,
+ private IUserMountCache $userMountCache,
+ private Util $encryptionUtil,
+ private IRootFolder $rootFolder,
+ IManager $encryptionManager,
) {
- $this->userManager = $userManager;
- $this->userMountCache = $userMountCache;
- $this->encryptionUtil = $encryptionUtil;
- $this->rootFolder = $rootFolder;
$this->keyRootDirectory = rtrim($this->encryptionUtil->getKeyStorageRoot(), '/');
$this->rootView = new View();
if (!$encryptionManager instanceof Manager) {
- throw new \Exception("Wrong encryption manager");
+ throw new \Exception('Wrong encryption manager');
}
$this->encryptionManager = $encryptionManager;
@@ -80,7 +57,7 @@ class FixKeyLocation extends Command {
->setName('encryption:fix-key-location')
->setDescription('Fix the location of encryption keys for external storage')
->addOption('dry-run', null, InputOption::VALUE_NONE, "Only list files that require key migration, don't try to perform any migration")
- ->addArgument('user', InputArgument::REQUIRED, "User id to fix the key locations for");
+ ->addArgument('user', InputArgument::REQUIRED, 'User id to fix the key locations for');
}
protected function execute(InputInterface $input, OutputInterface $output): int {
@@ -89,7 +66,7 @@ class FixKeyLocation extends Command {
$user = $this->userManager->get($userId);
if (!$user) {
$output->writeln("<error>User $userId not found</error>");
- return 1;
+ return self::FAILURE;
}
\OC_Util::setupFS($user->getUID());
@@ -98,7 +75,7 @@ class FixKeyLocation extends Command {
foreach ($mounts as $mount) {
$mountRootFolder = $this->rootFolder->get($mount->getMountPoint());
if (!$mountRootFolder instanceof Folder) {
- $output->writeln("<error>System wide mount point is not a directory, skipping: " . $mount->getMountPoint() . "</error>");
+ $output->writeln('<error>System wide mount point is not a directory, skipping: ' . $mount->getMountPoint() . '</error>');
continue;
}
@@ -112,14 +89,14 @@ class FixKeyLocation extends Command {
// key was stored incorrectly as user key, migrate
if ($dryRun) {
- $output->writeln("<info>" . $file->getPath() . "</info> needs migration");
+ $output->writeln('<info>' . $file->getPath() . '</info> needs migration');
} else {
- $output->write("Migrating key for <info>" . $file->getPath() . "</info> ");
+ $output->write('Migrating key for <info>' . $file->getPath() . '</info> ');
if ($this->copyUserKeyToSystemAndValidate($user, $file)) {
- $output->writeln("<info>✓</info>");
+ $output->writeln('<info>✓</info>');
} else {
- $output->writeln("<fg=red>❌</>");
- $output->writeln(" Failed to validate key for <error>" . $file->getPath() . "</error>, key will not be migrated");
+ $output->writeln('<fg=red>❌</>');
+ $output->writeln(' Failed to validate key for <error>' . $file->getPath() . '</error>, key will not be migrated');
}
}
} else {
@@ -130,42 +107,42 @@ class FixKeyLocation extends Command {
if ($isActuallyEncrypted) {
if ($dryRun) {
if ($shouldBeEncrypted) {
- $output->write("<info>" . $file->getPath() . "</info> needs migration");
+ $output->write('<info>' . $file->getPath() . '</info> needs migration');
} else {
- $output->write("<info>" . $file->getPath() . "</info> needs decryption");
+ $output->write('<info>' . $file->getPath() . '</info> needs decryption');
}
$foundKey = $this->findUserKeyForSystemFile($user, $file);
if ($foundKey) {
- $output->writeln(", valid key found at <info>" . $foundKey . "</info>");
+ $output->writeln(', valid key found at <info>' . $foundKey . '</info>');
} else {
- $output->writeln(" <error>❌ No key found</error>");
+ $output->writeln(' <error>❌ No key found</error>');
}
} else {
if ($shouldBeEncrypted) {
- $output->write("<info>Migrating key for " . $file->getPath() . "</info>");
+ $output->write('<info>Migrating key for ' . $file->getPath() . '</info>');
} else {
- $output->write("<info>Decrypting " . $file->getPath() . "</info>");
+ $output->write('<info>Decrypting ' . $file->getPath() . '</info>');
}
$foundKey = $this->findUserKeyForSystemFile($user, $file);
if ($foundKey) {
if ($shouldBeEncrypted) {
$systemKeyPath = $this->getSystemKeyPath($file);
$this->rootView->copy($foundKey, $systemKeyPath);
- $output->writeln(" Migrated key from <info>" . $foundKey . "</info>");
+ $output->writeln(' Migrated key from <info>' . $foundKey . '</info>');
} else {
$this->decryptWithSystemKey($file, $foundKey);
- $output->writeln(" Decrypted with key from <info>" . $foundKey . "</info>");
+ $output->writeln(' Decrypted with key from <info>' . $foundKey . '</info>');
}
} else {
- $output->writeln(" <error>❌ No key found</error>");
+ $output->writeln(' <error>❌ No key found</error>');
}
}
} else {
if ($dryRun) {
- $output->writeln("<info>" . $file->getPath() . " needs to be marked as not encrypted</info>");
+ $output->writeln('<info>' . $file->getPath() . ' needs to be marked as not encrypted</info>');
} else {
$this->markAsUnEncrypted($file);
- $output->writeln("<info>" . $file->getPath() . " marked as not encrypted</info>");
+ $output->writeln('<info>' . $file->getPath() . ' marked as not encrypted</info>');
}
}
}
@@ -173,7 +150,7 @@ class FixKeyLocation extends Command {
}
}
- return 0;
+ return self::SUCCESS;
}
private function getUserRelativePath(string $path): string {
@@ -186,7 +163,6 @@ class FixKeyLocation extends Command {
}
/**
- * @param IUser $user
* @return ICachedMountInfo[]
*/
private function getSystemMountsForUser(IUser $user): array {
@@ -201,7 +177,6 @@ class FixKeyLocation extends Command {
/**
* Get all files in a folder which are marked as encrypted
*
- * @param Folder $folder
* @return \Generator<File>
*/
private function getAllEncryptedFiles(Folder $folder) {
@@ -242,10 +217,6 @@ class FixKeyLocation extends Command {
/**
* Check that the user key stored for a file can decrypt the file
- *
- * @param IUser $user
- * @param File $node
- * @return bool
*/
private function copyUserKeyToSystemAndValidate(IUser $user, File $node): bool {
$path = trim(substr($node->getPath(), strlen($user->getUID()) + 1), '/');
@@ -282,7 +253,6 @@ class FixKeyLocation extends Command {
/**
* Get the contents of a file without decrypting it
*
- * @param File $node
* @return resource
*/
private function openWithoutDecryption(File $node, string $mode) {
@@ -303,16 +273,13 @@ class FixKeyLocation extends Command {
}
/** @var resource|false $handle */
if ($handle === false) {
- throw new \Exception("Failed to open " . $node->getPath());
+ throw new \Exception('Failed to open ' . $node->getPath());
}
return $handle;
}
/**
* Check if the data stored for a file is encrypted, regardless of it's metadata
- *
- * @param File $node
- * @return bool
*/
private function isDataEncrypted(File $node): bool {
$handle = $this->openWithoutDecryption($node, 'r');
@@ -325,9 +292,6 @@ class FixKeyLocation extends Command {
/**
* Attempt to find a key (stored for user) for a file (that needs a system key) even when it's not stored in the expected location
- *
- * @param File $node
- * @return string
*/
private function findUserKeyForSystemFile(IUser $user, File $node): ?string {
$userKeyPath = $this->getUserBaseKeyPath($user);
@@ -343,8 +307,6 @@ class FixKeyLocation extends Command {
/**
* Attempt to find a key for a file even when it's not stored in the expected location
*
- * @param string $basePath
- * @param string $name
* @return \Generator<string>
*/
private function findKeysByFileName(string $basePath, string $name) {
@@ -354,7 +316,7 @@ class FixKeyLocation extends Command {
/** @var false|resource $dh */
$dh = $this->rootView->opendir($basePath);
if (!$dh) {
- throw new \Exception("Invalid base path " . $basePath);
+ throw new \Exception('Invalid base path ' . $basePath);
}
while ($child = readdir($dh)) {
if ($child != '..' && $child != '.') {
@@ -371,11 +333,6 @@ class FixKeyLocation extends Command {
/**
* Test if the provided key is valid as a system key for the file
- *
- * @param IUser $user
- * @param string $key
- * @param File $node
- * @return bool
*/
private function testSystemKey(IUser $user, string $key, File $node): bool {
$systemKeyPath = $this->getSystemKeyPath($node);
@@ -393,10 +350,6 @@ class FixKeyLocation extends Command {
/**
* Decrypt a file with the specified system key and mark the key as not-encrypted
- *
- * @param File $node
- * @param string $key
- * @return void
*/
private function decryptWithSystemKey(File $node, string $key): void {
$storage = $node->getStorage();
@@ -413,7 +366,7 @@ class FixKeyLocation extends Command {
/** @var false|resource $source */
$source = $storage->fopen($node->getInternalPath(), 'r');
if (!$source) {
- throw new \Exception("Failed to open " . $node->getPath() . " with " . $key);
+ throw new \Exception('Failed to open ' . $node->getPath() . ' with ' . $key);
}
$decryptedNode = $node->getParent()->newFile($name);
@@ -433,7 +386,7 @@ class FixKeyLocation extends Command {
}
if ($this->isDataEncrypted($decryptedNode)) {
- throw new \Exception($node->getPath() . " still encrypted after attempting to decrypt with " . $key);
+ throw new \Exception($node->getPath() . ' still encrypted after attempting to decrypt with ' . $key);
}
$this->markAsUnEncrypted($decryptedNode);
diff --git a/apps/encryption/lib/Command/RecoverUser.php b/apps/encryption/lib/Command/RecoverUser.php
index 97a26b1d404..8da962ac8b1 100644
--- a/apps/encryption/lib/Command/RecoverUser.php
+++ b/apps/encryption/lib/Command/RecoverUser.php
@@ -1,26 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2018 Bjoern Schiessle <bjoern@schiessle.org>
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Command;
@@ -35,33 +17,16 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
class RecoverUser extends Command {
-
- /** @var Util */
- protected $util;
-
- /** @var IUserManager */
- protected $userManager;
-
- /** @var QuestionHelper */
- protected $questionHelper;
-
- /**
- * @param Util $util
- * @param IConfig $config
- * @param IUserManager $userManager
- * @param QuestionHelper $questionHelper
- */
- public function __construct(Util $util,
+ public function __construct(
+ protected Util $util,
IConfig $config,
- IUserManager $userManager,
- QuestionHelper $questionHelper) {
- $this->util = $util;
- $this->questionHelper = $questionHelper;
- $this->userManager = $userManager;
+ protected IUserManager $userManager,
+ protected QuestionHelper $questionHelper,
+ ) {
parent::__construct();
}
- protected function configure() {
+ protected function configure(): void {
$this
->setName('encryption:recover-user')
->setDescription('Recover user data in case of password lost. This only works if the user enabled the recovery key.');
@@ -78,20 +43,20 @@ class RecoverUser extends Command {
if ($isMasterKeyEnabled) {
$output->writeln('You use the master key, no individual user recovery needed.');
- return 0;
+ return self::SUCCESS;
}
$uid = $input->getArgument('user');
$userExists = $this->userManager->userExists($uid);
if ($userExists === false) {
$output->writeln('User "' . $uid . '" unknown.');
- return 1;
+ return self::FAILURE;
}
$recoveryKeyEnabled = $this->util->isRecoveryEnabledForUser($uid);
if ($recoveryKeyEnabled === false) {
$output->writeln('Recovery key is not enabled for: ' . $uid);
- return 1;
+ return self::FAILURE;
}
$question = new Question('Please enter the recovery key password: ');
@@ -107,6 +72,6 @@ class RecoverUser extends Command {
$output->write('Start to recover users files... This can take some time...');
$this->userManager->get($uid)->setPassword($newLoginPassword, $recoveryPassword);
$output->writeln('Done.');
- return 0;
+ return self::SUCCESS;
}
}
diff --git a/apps/encryption/lib/Command/ScanLegacyFormat.php b/apps/encryption/lib/Command/ScanLegacyFormat.php
index 8e0178af486..1e46a3d7545 100644
--- a/apps/encryption/lib/Command/ScanLegacyFormat.php
+++ b/apps/encryption/lib/Command/ScanLegacyFormat.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @author essys <essys@users.noreply.github.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Command;
@@ -36,40 +18,20 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ScanLegacyFormat extends Command {
- /** @var Util */
- protected $util;
-
- /** @var IConfig */
- protected $config;
-
- /** @var QuestionHelper */
- protected $questionHelper;
-
- /** @var IUserManager */
- private $userManager;
-
- /** @var View */
- private $rootView;
-
- /**
- * @param Util $util
- * @param IConfig $config
- * @param QuestionHelper $questionHelper
- */
- public function __construct(Util $util,
- IConfig $config,
- QuestionHelper $questionHelper,
- IUserManager $userManager) {
+ private View $rootView;
+
+ public function __construct(
+ protected Util $util,
+ protected IConfig $config,
+ protected QuestionHelper $questionHelper,
+ private IUserManager $userManager,
+ ) {
parent::__construct();
- $this->util = $util;
- $this->config = $config;
- $this->questionHelper = $questionHelper;
- $this->userManager = $userManager;
$this->rootView = new View();
}
- protected function configure() {
+ protected function configure(): void {
$this
->setName('encryption:scan:legacy-format')
->setDescription('Scan the files for the legacy format');
@@ -96,10 +58,10 @@ class ScanLegacyFormat extends Command {
if ($result) {
$output->writeln('All scanned files are properly encrypted. You can disable the legacy compatibility mode.');
- return 0;
+ return self::SUCCESS;
}
- return 1;
+ return self::FAILURE;
}
private function scanFolder(OutputInterface $output, string $folder): bool {
@@ -130,10 +92,8 @@ class ScanLegacyFormat extends Command {
/**
* setup user file system
- *
- * @param string $uid
*/
- protected function setupUserFS($uid) {
+ protected function setupUserFS(string $uid): void {
\OC_Util::tearDownFS();
\OC_Util::setupFS($uid);
}
diff --git a/apps/encryption/lib/Controller/RecoveryController.php b/apps/encryption/lib/Controller/RecoveryController.php
index 743e17e5eff..d75406e6319 100644
--- a/apps/encryption/lib/Controller/RecoveryController.php
+++ b/apps/encryption/lib/Controller/RecoveryController.php
@@ -1,34 +1,16 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Controller;
use OCA\Encryption\Recovery;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\IConfig;
use OCP\IL10N;
@@ -36,34 +18,20 @@ use OCP\IRequest;
class RecoveryController extends Controller {
/**
- * @var IConfig
- */
- private $config;
- /**
- * @var IL10N
- */
- private $l;
- /**
- * @var Recovery
- */
- private $recovery;
-
- /**
* @param string $AppName
* @param IRequest $request
* @param IConfig $config
- * @param IL10N $l10n
+ * @param IL10N $l
* @param Recovery $recovery
*/
- public function __construct($AppName,
+ public function __construct(
+ $AppName,
IRequest $request,
- IConfig $config,
- IL10N $l10n,
- Recovery $recovery) {
+ private IConfig $config,
+ private IL10N $l,
+ private Recovery $recovery,
+ ) {
parent::__construct($AppName, $request);
- $this->config = $config;
- $this->l = $l10n;
- $this->recovery = $recovery;
}
/**
@@ -155,11 +123,10 @@ class RecoveryController extends Controller {
}
/**
- * @NoAdminRequired
- *
* @param string $userEnableRecovery
* @return DataResponse
*/
+ #[NoAdminRequired]
public function userSetRecovery($userEnableRecovery) {
if ($userEnableRecovery === '0' || $userEnableRecovery === '1') {
$result = $this->recovery->setRecoveryForUser($userEnableRecovery);
diff --git a/apps/encryption/lib/Controller/SettingsController.php b/apps/encryption/lib/Controller/SettingsController.php
index fa4c3d2ae2b..8548ea51c04 100644
--- a/apps/encryption/lib/Controller/SettingsController.php
+++ b/apps/encryption/lib/Controller/SettingsController.php
@@ -1,25 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Controller;
@@ -29,6 +13,8 @@ use OCA\Encryption\Session;
use OCA\Encryption\Util;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\Attribute\UseSession;
use OCP\AppFramework\Http\DataResponse;
use OCP\IL10N;
use OCP\IRequest;
@@ -38,34 +24,10 @@ use OCP\IUserSession;
class SettingsController extends Controller {
- /** @var IL10N */
- private $l;
-
- /** @var IUserManager */
- private $userManager;
-
- /** @var IUserSession */
- private $userSession;
-
- /** @var KeyManager */
- private $keyManager;
-
- /** @var Crypt */
- private $crypt;
-
- /** @var Session */
- private $session;
-
- /** @var ISession */
- private $ocSession;
-
- /** @var Util */
- private $util;
-
/**
* @param string $AppName
* @param IRequest $request
- * @param IL10N $l10n
+ * @param IL10N $l
* @param IUserManager $userManager
* @param IUserSession $userSession
* @param KeyManager $keyManager
@@ -74,37 +36,29 @@ class SettingsController extends Controller {
* @param ISession $ocSession
* @param Util $util
*/
- public function __construct($AppName,
+ public function __construct(
+ $AppName,
IRequest $request,
- IL10N $l10n,
- IUserManager $userManager,
- IUserSession $userSession,
- KeyManager $keyManager,
- Crypt $crypt,
- Session $session,
- ISession $ocSession,
- Util $util
+ private IL10N $l,
+ private IUserManager $userManager,
+ private IUserSession $userSession,
+ private KeyManager $keyManager,
+ private Crypt $crypt,
+ private Session $session,
+ private ISession $ocSession,
+ private Util $util,
) {
parent::__construct($AppName, $request);
- $this->l = $l10n;
- $this->userSession = $userSession;
- $this->userManager = $userManager;
- $this->keyManager = $keyManager;
- $this->crypt = $crypt;
- $this->session = $session;
- $this->ocSession = $ocSession;
- $this->util = $util;
}
/**
- * @NoAdminRequired
- * @UseSession
- *
* @param string $oldPassword
* @param string $newPassword
* @return DataResponse
*/
+ #[NoAdminRequired]
+ #[UseSession]
public function updatePrivateKeyPassword($oldPassword, $newPassword) {
$result = false;
$uid = $this->userSession->getUser()->getUID();
@@ -153,11 +107,10 @@ class SettingsController extends Controller {
}
/**
- * @UseSession
- *
* @param bool $encryptHomeStorage
* @return DataResponse
*/
+ #[UseSession]
public function setEncryptHomeStorage($encryptHomeStorage) {
$this->util->setEncryptHomeStorage($encryptHomeStorage);
return new DataResponse();
diff --git a/apps/encryption/lib/Controller/StatusController.php b/apps/encryption/lib/Controller/StatusController.php
index 29582a66ad3..341ad6bc49f 100644
--- a/apps/encryption/lib/Controller/StatusController.php
+++ b/apps/encryption/lib/Controller/StatusController.php
@@ -1,33 +1,15 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Controller;
use OCA\Encryption\Session;
use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\Encryption\IManager;
use OCP\IL10N;
@@ -35,38 +17,27 @@ use OCP\IRequest;
class StatusController extends Controller {
- /** @var IL10N */
- private $l;
-
- /** @var Session */
- private $session;
-
- /** @var IManager */
- private $encryptionManager;
-
/**
* @param string $AppName
* @param IRequest $request
- * @param IL10N $l10n
+ * @param IL10N $l
* @param Session $session
* @param IManager $encryptionManager
*/
- public function __construct($AppName,
+ public function __construct(
+ $AppName,
IRequest $request,
- IL10N $l10n,
- Session $session,
- IManager $encryptionManager
+ private IL10N $l,
+ private Session $session,
+ private IManager $encryptionManager,
) {
parent::__construct($AppName, $request);
- $this->l = $l10n;
- $this->session = $session;
- $this->encryptionManager = $encryptionManager;
}
/**
- * @NoAdminRequired
* @return DataResponse
*/
+ #[NoAdminRequired]
public function getStatus() {
$status = 'error';
$message = 'no valid init status';
diff --git a/apps/encryption/lib/Crypto/Crypt.php b/apps/encryption/lib/Crypto/Crypt.php
index 2d212c1f055..463ca4e22bb 100644
--- a/apps/encryption/lib/Crypto/Crypt.php
+++ b/apps/encryption/lib/Crypto/Crypt.php
@@ -1,34 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Kevin Niehage <kevin@niehage.name>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Stefan Weiberg <sweiberg@suse.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Crypto;
@@ -108,7 +83,7 @@ class Crypt {
/**
* create new private/public key-pair for user
*
- * @return array|bool
+ * @return array{publicKey: string, privateKey: string}|false
*/
public function createKeyPair() {
$res = $this->getOpenSSLPKey();
@@ -180,7 +155,7 @@ class Crypt {
$this->getCipher());
// Create a signature based on the key as well as the current version
- $sig = $this->createSignature($encryptedContent, $passPhrase.'_'.$version.'_'.$position);
+ $sig = $this->createSignature($encryptedContent, $passPhrase . '_' . $version . '_' . $position);
// combine content to encrypt the IV identifier and actual IV
$catFile = $this->concatIV($encryptedContent, $iv);
@@ -482,7 +457,7 @@ class Crypt {
if ($enforceSignature) {
throw new GenericEncryptionException('Bad Signature', $this->l->t('Bad Signature'));
} else {
- $this->logger->info("Signature check skipped", ['app' => 'encryption']);
+ $this->logger->info('Signature check skipped', ['app' => 'encryption']);
}
}
}
@@ -776,7 +751,7 @@ class Crypt {
$result = false;
// check if RC4 is used
- if (strcasecmp($cipher_algo, "rc4") === 0) {
+ if (strcasecmp($cipher_algo, 'rc4') === 0) {
// decrypt the intermediate key with RSA
if (openssl_private_decrypt($encrypted_key, $intermediate, $private_key, OPENSSL_PKCS1_PADDING)) {
// decrypt the file key with the intermediate key
@@ -785,7 +760,7 @@ class Crypt {
$result = (strlen($output) === strlen($data));
}
} else {
- throw new DecryptionFailedException('Unsupported cipher '.$cipher_algo);
+ throw new DecryptionFailedException('Unsupported cipher ' . $cipher_algo);
}
return $result;
@@ -801,7 +776,7 @@ class Crypt {
$result = false;
// check if RC4 is used
- if (strcasecmp($cipher_algo, "rc4") === 0) {
+ if (strcasecmp($cipher_algo, 'rc4') === 0) {
// make sure that there is at least one public key to use
if (count($public_key) >= 1) {
// generate the intermediate key
@@ -832,7 +807,7 @@ class Crypt {
}
}
} else {
- throw new EncryptionFailedException('Unsupported cipher '.$cipher_algo);
+ throw new EncryptionFailedException('Unsupported cipher ' . $cipher_algo);
}
return $result;
diff --git a/apps/encryption/lib/Crypto/DecryptAll.php b/apps/encryption/lib/Crypto/DecryptAll.php
index e982da72086..362f43b8672 100644
--- a/apps/encryption/lib/Crypto/DecryptAll.php
+++ b/apps/encryption/lib/Crypto/DecryptAll.php
@@ -1,27 +1,13 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Crypto;
+use OCA\Encryption\Exceptions\PrivateKeyMissingException;
use OCA\Encryption\KeyManager;
use OCA\Encryption\Session;
use OCA\Encryption\Util;
@@ -33,21 +19,6 @@ use Symfony\Component\Console\Question\Question;
class DecryptAll {
- /** @var Util */
- protected $util;
-
- /** @var QuestionHelper */
- protected $questionHelper;
-
- /** @var Crypt */
- protected $crypt;
-
- /** @var KeyManager */
- protected $keyManager;
-
- /** @var Session */
- protected $session;
-
/**
* @param Util $util
* @param KeyManager $keyManager
@@ -56,17 +27,12 @@ class DecryptAll {
* @param QuestionHelper $questionHelper
*/
public function __construct(
- Util $util,
- KeyManager $keyManager,
- Crypt $crypt,
- Session $session,
- QuestionHelper $questionHelper
+ protected Util $util,
+ protected KeyManager $keyManager,
+ protected Crypt $crypt,
+ protected Session $session,
+ protected QuestionHelper $questionHelper,
) {
- $this->util = $util;
- $this->keyManager = $keyManager;
- $this->crypt = $crypt;
- $this->session = $session;
- $this->questionHelper = $questionHelper;
}
/**
@@ -88,7 +54,7 @@ class DecryptAll {
$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
if (!empty($user)) {
$output->writeln('You can only decrypt the users files if you know');
- $output->writeln('the users password or if he activated the recovery key.');
+ $output->writeln('the users password or if they activated the recovery key.');
$output->writeln('');
$questionUseLoginPassword = new ConfirmationQuestion(
'Do you want to use the users login password to decrypt all files? (y/n) ',
@@ -133,7 +99,7 @@ class DecryptAll {
* @param string $user
* @param string $password
* @return bool|string
- * @throws \OCA\Encryption\Exceptions\PrivateKeyMissingException
+ * @throws PrivateKeyMissingException
*/
protected function getPrivateKey($user, $password) {
$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
diff --git a/apps/encryption/lib/Crypto/EncryptAll.php b/apps/encryption/lib/Crypto/EncryptAll.php
index 5420e729898..4ed75b85a93 100644
--- a/apps/encryption/lib/Crypto/EncryptAll.php
+++ b/apps/encryption/lib/Crypto/EncryptAll.php
@@ -1,29 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Kenneth Newwood <kenneth@newwood.name>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Crypto;
@@ -32,6 +12,7 @@ use OC\Files\View;
use OCA\Encryption\KeyManager;
use OCA\Encryption\Users\Setup;
use OCA\Encryption\Util;
+use OCP\Files\FileInfo;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IUser;
@@ -40,6 +21,7 @@ use OCP\L10N\IFactory;
use OCP\Mail\Headers\AutoSubmitted;
use OCP\Mail\IMailer;
use OCP\Security\ISecureRandom;
+use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\Table;
@@ -49,72 +31,29 @@ use Symfony\Component\Console\Question\ConfirmationQuestion;
class EncryptAll {
- /** @var Setup */
- protected $userSetup;
-
- /** @var IUserManager */
- protected $userManager;
-
- /** @var View */
- protected $rootView;
-
- /** @var KeyManager */
- protected $keyManager;
-
- /** @var Util */
- protected $util;
-
- /** @var array */
+ /** @var array */
protected $userPasswords;
- /** @var IConfig */
- protected $config;
-
- /** @var IMailer */
- protected $mailer;
-
- /** @var IL10N */
- protected $l;
-
- /** @var IFactory */
- protected $l10nFactory;
-
- /** @var QuestionHelper */
- protected $questionHelper;
-
- /** @var OutputInterface */
+ /** @var OutputInterface */
protected $output;
- /** @var InputInterface */
+ /** @var InputInterface */
protected $input;
- /** @var ISecureRandom */
- protected $secureRandom;
-
public function __construct(
- Setup $userSetup,
- IUserManager $userManager,
- View $rootView,
- KeyManager $keyManager,
- Util $util,
- IConfig $config,
- IMailer $mailer,
- IL10N $l,
- IFactory $l10nFactory,
- QuestionHelper $questionHelper,
- ISecureRandom $secureRandom
+ protected Setup $userSetup,
+ protected IUserManager $userManager,
+ protected View $rootView,
+ protected KeyManager $keyManager,
+ protected Util $util,
+ protected IConfig $config,
+ protected IMailer $mailer,
+ protected IL10N $l,
+ protected IFactory $l10nFactory,
+ protected QuestionHelper $questionHelper,
+ protected ISecureRandom $secureRandom,
+ protected LoggerInterface $logger,
) {
- $this->userSetup = $userSetup;
- $this->userManager = $userManager;
- $this->rootView = $rootView;
- $this->keyManager = $keyManager;
- $this->util = $util;
- $this->config = $config;
- $this->mailer = $mailer;
- $this->l = $l;
- $this->l10nFactory = $l10nFactory;
- $this->questionHelper = $questionHelper;
- $this->secureRandom = $secureRandom;
// store one time passwords for the users
$this->userPasswords = [];
}
@@ -223,7 +162,7 @@ class EncryptAll {
$userNo++;
}
}
- $progress->setMessage("all files encrypted");
+ $progress->setMessage('all files encrypted');
$progress->finish();
}
@@ -264,33 +203,42 @@ class EncryptAll {
while ($root = array_pop($directories)) {
$content = $this->rootView->getDirectoryContent($root);
foreach ($content as $file) {
- $path = $root . '/' . $file['name'];
- if ($this->rootView->is_dir($path)) {
+ $path = $root . '/' . $file->getName();
+ if ($file->isShared()) {
+ $progress->setMessage("Skip shared file/folder $path");
+ $progress->advance();
+ continue;
+ } elseif ($file->getType() === FileInfo::TYPE_FOLDER) {
$directories[] = $path;
continue;
} else {
$progress->setMessage("encrypt files for user $userCount: $path");
$progress->advance();
- if ($this->encryptFile($path) === false) {
- $progress->setMessage("encrypt files for user $userCount: $path (already encrypted)");
+ try {
+ if ($this->encryptFile($file, $path) === false) {
+ $progress->setMessage("encrypt files for user $userCount: $path (already encrypted)");
+ $progress->advance();
+ }
+ } catch (\Exception $e) {
+ $progress->setMessage("Failed to encrypt path $path: " . $e->getMessage());
$progress->advance();
+ $this->logger->error(
+ 'Failed to encrypt path {path}',
+ [
+ 'user' => $uid,
+ 'path' => $path,
+ 'exception' => $e,
+ ]
+ );
}
}
}
}
}
- /**
- * encrypt file
- *
- * @param string $path
- * @return bool
- */
- protected function encryptFile($path) {
-
+ protected function encryptFile(FileInfo $fileInfo, string $path): bool {
// skip already encrypted files
- $fileInfo = $this->rootView->getFileInfo($path);
- if ($fileInfo !== false && $fileInfo->isEncrypted()) {
+ if ($fileInfo->isEncrypted()) {
return true;
}
@@ -298,7 +246,14 @@ class EncryptAll {
$target = $path . '.encrypted.' . time();
try {
- $this->rootView->copy($source, $target);
+ $copySuccess = $this->rootView->copy($source, $target);
+ if ($copySuccess === false) {
+ /* Copy failed, abort */
+ if ($this->rootView->file_exists($target)) {
+ $this->rootView->unlink($target);
+ }
+ throw new \Exception('Copy failed for ' . $source);
+ }
$this->rootView->rename($target, $source);
} catch (DecryptionFailedException $e) {
if ($this->rootView->file_exists($target)) {
diff --git a/apps/encryption/lib/Crypto/Encryption.php b/apps/encryption/lib/Crypto/Encryption.php
index 1481d3a9a23..6d388624e48 100644
--- a/apps/encryption/lib/Crypto/Encryption.php
+++ b/apps/encryption/lib/Crypto/Encryption.php
@@ -1,41 +1,16 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Jan-Christoph Borchardt <hey@jancborchardt.net>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Valdnet <47037905+Valdnet@users.noreply.github.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Crypto;
use OC\Encryption\Exceptions\DecryptionFailedException;
use OC\Files\Cache\Scanner;
use OC\Files\View;
+use OCA\Encryption\Exceptions\MultiKeyEncryptException;
use OCA\Encryption\Exceptions\PublicKeyMissingException;
use OCA\Encryption\KeyManager;
use OCA\Encryption\Session;
@@ -80,8 +55,6 @@ class Encryption implements IEncryptionModule {
/** @var int Current version of the file */
private int $version = 0;
- private bool $useLegacyFileKey = true;
-
/** @var array remember encryption signature version */
private static $rememberVersion = [];
@@ -127,8 +100,8 @@ class Encryption implements IEncryptionModule {
* @param array $accessList who has access to the file contains the key 'users' and 'public'
*
* @return array $header contain data as key-value pairs which should be
- * written to the header, in case of a write operation
- * or if no additional data is needed return a empty array
+ * written to the header, in case of a write operation
+ * or if no additional data is needed return a empty array
*/
public function begin($path, $user, $mode, array $header, array $accessList) {
$this->path = $this->getPathToRealFile($path);
@@ -138,7 +111,6 @@ class Encryption implements IEncryptionModule {
$this->writeCache = '';
$this->useLegacyBase64Encoding = true;
- $this->useLegacyFileKey = ($header['useLegacyFileKey'] ?? 'true') !== 'false';
if (isset($header['encoding'])) {
$this->useLegacyBase64Encoding = $header['encoding'] !== Crypt::BINARY_ENCODING_FORMAT;
@@ -152,19 +124,10 @@ class Encryption implements IEncryptionModule {
}
}
- if ($this->session->decryptAllModeActivated()) {
- $shareKey = $this->keyManager->getShareKey($this->path, $this->session->getDecryptAllUid());
- if ($this->useLegacyFileKey) {
- $encryptedFileKey = $this->keyManager->getEncryptedFileKey($this->path);
- $this->fileKey = $this->crypt->multiKeyDecryptLegacy($encryptedFileKey,
- $shareKey,
- $this->session->getDecryptAllKey());
- } else {
- $this->fileKey = $this->crypt->multiKeyDecrypt($shareKey, $this->session->getDecryptAllKey());
- }
- } else {
- $this->fileKey = $this->keyManager->getFileKey($this->path, $this->user, $this->useLegacyFileKey);
- }
+ /* 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());
// 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
@@ -225,7 +188,7 @@ class Encryption implements IEncryptionModule {
* of a write operation
* @throws PublicKeyMissingException
* @throws \Exception
- * @throws \OCA\Encryption\Exceptions\MultiKeyEncryptException
+ * @throws MultiKeyEncryptException
*/
public function end($path, $position = '0') {
$result = '';
@@ -470,7 +433,7 @@ class Encryption implements IEncryptionModule {
* e.g. if all encryption keys exists
*
* @param string $path
- * @param string $uid user for whom we want to check if he can read the file
+ * @param string $uid user for whom we want to check if they can read the file
* @return bool
* @throws DecryptionFailedException
*/
@@ -483,8 +446,8 @@ class Encryption implements IEncryptionModule {
// error message because in this case it means that the file was
// shared with the user at a point where the user didn't had a
// valid private/public key
- $msg = 'Encryption module "' . $this->getDisplayName() .
- '" is not able to read ' . $path;
+ $msg = 'Encryption module "' . $this->getDisplayName()
+ . '" is not able to read ' . $path;
$hint = $this->l->t('Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
$this->logger->warning($msg);
throw new DecryptionFailedException($msg, $hint);
diff --git a/apps/encryption/lib/Exceptions/MultiKeyDecryptException.php b/apps/encryption/lib/Exceptions/MultiKeyDecryptException.php
index 562f6955ae4..1246d51190b 100644
--- a/apps/encryption/lib/Exceptions/MultiKeyDecryptException.php
+++ b/apps/encryption/lib/Exceptions/MultiKeyDecryptException.php
@@ -1,23 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Exceptions;
diff --git a/apps/encryption/lib/Exceptions/MultiKeyEncryptException.php b/apps/encryption/lib/Exceptions/MultiKeyEncryptException.php
index 3771e7e36ba..60394af45c2 100644
--- a/apps/encryption/lib/Exceptions/MultiKeyEncryptException.php
+++ b/apps/encryption/lib/Exceptions/MultiKeyEncryptException.php
@@ -1,23 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Exceptions;
diff --git a/apps/encryption/lib/Exceptions/PrivateKeyMissingException.php b/apps/encryption/lib/Exceptions/PrivateKeyMissingException.php
index b8fd4fb9234..15fe8f4e72f 100644
--- a/apps/encryption/lib/Exceptions/PrivateKeyMissingException.php
+++ b/apps/encryption/lib/Exceptions/PrivateKeyMissingException.php
@@ -1,26 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Exceptions;
@@ -33,7 +16,7 @@ class PrivateKeyMissingException extends GenericEncryptionException {
*/
public function __construct($userId) {
if (empty($userId)) {
- $userId = "<no-user-id-given>";
+ $userId = '<no-user-id-given>';
}
parent::__construct("Private Key missing for user: $userId");
}
diff --git a/apps/encryption/lib/Exceptions/PublicKeyMissingException.php b/apps/encryption/lib/Exceptions/PublicKeyMissingException.php
index 73edc5c710d..78eeeccf47d 100644
--- a/apps/encryption/lib/Exceptions/PublicKeyMissingException.php
+++ b/apps/encryption/lib/Exceptions/PublicKeyMissingException.php
@@ -1,24 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Exceptions;
@@ -31,7 +16,7 @@ class PublicKeyMissingException extends GenericEncryptionException {
*/
public function __construct($userId) {
if (empty($userId)) {
- $userId = "<no-user-id-given>";
+ $userId = '<no-user-id-given>';
}
parent::__construct("Public Key missing for user: $userId");
}
diff --git a/apps/encryption/lib/HookManager.php b/apps/encryption/lib/HookManager.php
deleted file mode 100644
index 0e7ec5cfd56..00000000000
--- a/apps/encryption/lib/HookManager.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Encryption;
-
-use OCA\Encryption\Hooks\Contracts\IHook;
-
-class HookManager {
- /** @var IHook[] */
- private $hookInstances = [];
-
- /**
- * @param array|IHook $instances
- * - This accepts either a single instance of IHook or an array of instances of IHook
- * @return bool
- */
- public function registerHook($instances) {
- if (is_array($instances)) {
- foreach ($instances as $instance) {
- if (!$instance instanceof IHook) {
- return false;
- }
- $this->hookInstances[] = $instance;
- }
- } elseif ($instances instanceof IHook) {
- $this->hookInstances[] = $instances;
- }
- return true;
- }
-
- public function fireHooks() {
- foreach ($this->hookInstances as $instance) {
- /**
- * Fire off the add hooks method of each instance stored in cache
- */
- $instance->addHooks();
- }
- }
-}
diff --git a/apps/encryption/lib/Hooks/Contracts/IHook.php b/apps/encryption/lib/Hooks/Contracts/IHook.php
deleted file mode 100644
index 54128d10327..00000000000
--- a/apps/encryption/lib/Hooks/Contracts/IHook.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Clark Tomlinson <fallen013@gmail.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Encryption\Hooks\Contracts;
-
-interface IHook {
- /**
- * Connects Hooks
- *
- * @return null
- */
- public function addHooks();
-}
diff --git a/apps/encryption/lib/Hooks/UserHooks.php b/apps/encryption/lib/Hooks/UserHooks.php
deleted file mode 100644
index 487e1089495..00000000000
--- a/apps/encryption/lib/Hooks/UserHooks.php
+++ /dev/null
@@ -1,286 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Encryption\Hooks;
-
-use OC\Files\Filesystem;
-use OCA\Encryption\Crypto\Crypt;
-use OCA\Encryption\Hooks\Contracts\IHook;
-use OCA\Encryption\KeyManager;
-use OCA\Encryption\Recovery;
-use OCA\Encryption\Session;
-use OCA\Encryption\Users\Setup;
-use OCA\Encryption\Util;
-use OCP\Encryption\Exceptions\GenericEncryptionException;
-use OCP\IUserManager;
-use OCP\IUserSession;
-use OCP\Util as OCUtil;
-use Psr\Log\LoggerInterface;
-
-class UserHooks implements IHook {
- /**
- * list of user for which we perform a password reset
- * @var array<string, true>
- */
- protected static array $passwordResetUsers = [];
-
- public function __construct(
- private KeyManager $keyManager,
- private IUserManager $userManager,
- private LoggerInterface $logger,
- private Setup $userSetup,
- private IUserSession $userSession,
- private Util $util,
- private Session $session,
- private Crypt $crypt,
- private Recovery $recovery,
- ) {
- }
-
- /**
- * Connects Hooks
- *
- * @return null
- */
- public function addHooks() {
- OCUtil::connectHook('OC_User', 'post_login', $this, 'login');
- OCUtil::connectHook('OC_User', 'logout', $this, 'logout');
-
- // this hooks only make sense if no master key is used
- if ($this->util->isMasterKeyEnabled() === false) {
- OCUtil::connectHook('OC_User',
- 'post_setPassword',
- $this,
- 'setPassphrase');
-
- OCUtil::connectHook('OC_User',
- 'pre_setPassword',
- $this,
- 'preSetPassphrase');
-
- OCUtil::connectHook('\OC\Core\LostPassword\Controller\LostController',
- 'post_passwordReset',
- $this,
- 'postPasswordReset');
-
- OCUtil::connectHook('\OC\Core\LostPassword\Controller\LostController',
- 'pre_passwordReset',
- $this,
- 'prePasswordReset');
-
- OCUtil::connectHook('OC_User',
- 'post_createUser',
- $this,
- 'postCreateUser');
-
- OCUtil::connectHook('OC_User',
- 'post_deleteUser',
- $this,
- 'postDeleteUser');
- }
- }
-
-
- /**
- * Startup encryption backend upon user login
- *
- * @note This method should never be called for users using client side encryption
- * @param array $params
- * @return boolean|null
- */
- public function login($params) {
- // ensure filesystem is loaded
- if (!\OC\Files\Filesystem::$loaded) {
- $this->setupFS($params['uid']);
- }
- if ($this->util->isMasterKeyEnabled() === false) {
- $this->userSetup->setupUser($params['uid'], $params['password']);
- }
-
- $this->keyManager->init($params['uid'], $params['password']);
- }
-
- /**
- * remove keys from session during logout
- */
- public function logout() {
- $this->session->clear();
- }
-
- /**
- * setup encryption backend upon user created
- *
- * @note This method should never be called for users using client side encryption
- * @param array $params
- */
- public function postCreateUser($params) {
- $this->userSetup->setupUser($params['uid'], $params['password']);
- }
-
- /**
- * cleanup encryption backend upon user deleted
- *
- * @param array $params : uid, password
- * @note This method should never be called for users using client side encryption
- */
- public function postDeleteUser($params) {
- $this->keyManager->deletePublicKey($params['uid']);
- }
-
- public function prePasswordReset($params) {
- $user = $params['uid'];
- self::$passwordResetUsers[$user] = true;
- }
-
- public function postPasswordReset($params) {
- $uid = $params['uid'];
- $password = $params['password'];
- $this->keyManager->backupUserKeys('passwordReset', $uid);
- $this->keyManager->deleteUserKeys($uid);
- $this->userSetup->setupUser($uid, $password);
- unset(self::$passwordResetUsers[$uid]);
- }
-
- /**
- * If the password can't be changed within Nextcloud, than update the key password in advance.
- *
- * @param array $params : uid, password
- * @return boolean|null
- */
- public function preSetPassphrase($params) {
- $user = $this->userManager->get($params['uid']);
-
- if ($user && !$user->canChangePassword()) {
- $this->setPassphrase($params);
- }
- }
-
- /**
- * Change a user's encryption passphrase
- *
- * @param array $params keys: uid, password
- * @return boolean|null
- */
- public function setPassphrase($params) {
- // if we are in the process to resetting a user password, we have nothing
- // to do here
- if (isset(self::$passwordResetUsers[$params['uid']])) {
- return true;
- }
-
- // Get existing decrypted private key
- $user = $this->userSession->getUser();
-
- // current logged in user changes his own password
- if ($user && $params['uid'] === $user->getUID()) {
- $privateKey = $this->session->getPrivateKey();
-
- // Encrypt private key with new user pwd as passphrase
- $encryptedPrivateKey = $this->crypt->encryptPrivateKey($privateKey, $params['password'], $params['uid']);
-
- // Save private key
- if ($encryptedPrivateKey) {
- $this->keyManager->setPrivateKey($user->getUID(),
- $this->crypt->generateHeader() . $encryptedPrivateKey);
- } else {
- $this->logger->error('Encryption could not update users encryption password');
- }
-
- // NOTE: Session does not need to be updated as the
- // private key has not changed, only the passphrase
- // used to decrypt it has changed
- } else { // admin changed the password for a different user, create new keys and re-encrypt file keys
- $userId = $params['uid'];
- $this->initMountPoints($userId);
- $recoveryPassword = $params['recoveryPassword'] ?? null;
-
- $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
- $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
- try {
- $decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $recoveryPassword);
- } catch (\Exception $e) {
- $decryptedRecoveryKey = false;
- }
- if ($decryptedRecoveryKey === false) {
- $message = 'Can not decrypt the recovery key. Maybe you provided the wrong password. Try again.';
- throw new GenericEncryptionException($message, $message);
- }
-
- // we generate new keys if...
- // ...we have a recovery password and the user enabled the recovery key
- // ...encryption was activated for the first time (no keys exists)
- // ...the user doesn't have any files
- if (
- ($this->recovery->isRecoveryEnabledForUser($userId) && $recoveryPassword)
- || !$this->keyManager->userHasKeys($userId)
- || !$this->util->userHasFiles($userId)
- ) {
- // backup old keys
- //$this->backupAllKeys('recovery');
-
- $newUserPassword = $params['password'];
-
- $keyPair = $this->crypt->createKeyPair();
-
- // Save public key
- $this->keyManager->setPublicKey($userId, $keyPair['publicKey']);
-
- // Encrypt private key with new password
- $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $newUserPassword, $userId);
-
- if ($encryptedKey) {
- $this->keyManager->setPrivateKey($userId, $this->crypt->generateHeader() . $encryptedKey);
-
- if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
- $this->recovery->recoverUsersFiles($recoveryPassword, $userId);
- }
- } else {
- $this->logger->error('Encryption Could not update users encryption password');
- }
- }
- }
- }
-
- /**
- * init mount points for given user
- *
- * @param string $user
- * @throws \OC\User\NoUserException
- */
- protected function initMountPoints($user) {
- Filesystem::initMountPoints($user);
- }
-
- /**
- * setup file system for user
- *
- * @param string $uid user id
- */
- protected function setupFS($uid) {
- \OC_Util::setupFS($uid);
- }
-}
diff --git a/apps/encryption/lib/KeyManager.php b/apps/encryption/lib/KeyManager.php
index 7d6380f3b83..f9c1ef94634 100644
--- a/apps/encryption/lib/KeyManager.php
+++ b/apps/encryption/lib/KeyManager.php
@@ -1,33 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption;
@@ -235,8 +211,8 @@ class KeyManager {
*/
public function setRecoveryKey($password, $keyPair) {
// Save Public Key
- $this->keyStorage->setSystemUserKey($this->getRecoveryKeyId().
- '.' . $this->publicKeyId,
+ $this->keyStorage->setSystemUserKey($this->getRecoveryKeyId()
+ . '.' . $this->publicKeyId,
$keyPair['publicKey'],
Encryption::ID);
@@ -311,11 +287,9 @@ class KeyManager {
/**
* Decrypt private key and store it
*
- * @param string $uid user id
- * @param string $passPhrase users password
* @return boolean
*/
- public function init($uid, $passPhrase) {
+ public function init(string $uid, ?string $passPhrase) {
$this->session->setStatus(Session::INIT_EXECUTED);
try {
@@ -324,6 +298,10 @@ class KeyManager {
$passPhrase = $this->getMasterKeyPassword();
$privateKey = $this->getSystemPrivateKey($uid);
} else {
+ if ($passPhrase === null) {
+ $this->logger->warning('Master key is disabled but not passphrase provided.');
+ return false;
+ }
$privateKey = $this->getPrivateKey($uid);
}
$privateKey = $this->crypt->decryptPrivateKey($privateKey, $passPhrase, $uid);
@@ -367,12 +345,9 @@ class KeyManager {
}
/**
- * @param string $path
- * @param $uid
* @param ?bool $useLegacyFileKey null means try both
- * @return string
*/
- public function getFileKey(string $path, ?string $uid, ?bool $useLegacyFileKey): string {
+ public function getFileKey(string $path, ?string $uid, ?bool $useLegacyFileKey, bool $useDecryptAll = false): string {
if ($uid === '') {
$uid = null;
}
@@ -385,8 +360,10 @@ class KeyManager {
return '';
}
}
-
- if ($this->util->isMasterKeyEnabled()) {
+ if ($useDecryptAll) {
+ $shareKey = $this->getShareKey($path, $this->session->getDecryptAllUid());
+ $privateKey = $this->session->getDecryptAllKey();
+ } elseif ($this->util->isMasterKeyEnabled()) {
$uid = $this->getMasterKeyId();
$shareKey = $this->getShareKey($path, $uid);
if ($publicAccess) {
@@ -656,8 +633,8 @@ class KeyManager {
$publicKeys[$this->getPublicShareKeyId()] = $publicShareKey;
}
- if ($this->recoveryKeyExists() &&
- $this->util->isRecoveryEnabledForUser($uid)) {
+ if ($this->recoveryKeyExists()
+ && $this->util->isRecoveryEnabledForUser($uid)) {
$publicKeys[$this->getRecoveryKeyId()] = $this->getRecoveryKey();
}
diff --git a/apps/encryption/lib/Listeners/UserEventsListener.php b/apps/encryption/lib/Listeners/UserEventsListener.php
new file mode 100644
index 00000000000..3f61fde599b
--- /dev/null
+++ b/apps/encryption/lib/Listeners/UserEventsListener.php
@@ -0,0 +1,144 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\Encryption\Listeners;
+
+use OC\Core\Events\BeforePasswordResetEvent;
+use OC\Core\Events\PasswordResetEvent;
+use OC\Files\SetupManager;
+use OCA\Encryption\KeyManager;
+use OCA\Encryption\Services\PassphraseService;
+use OCA\Encryption\Session;
+use OCA\Encryption\Users\Setup;
+use OCA\Encryption\Util;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\User\Events\BeforePasswordUpdatedEvent;
+use OCP\User\Events\PasswordUpdatedEvent;
+use OCP\User\Events\UserCreatedEvent;
+use OCP\User\Events\UserDeletedEvent;
+use OCP\User\Events\UserLoggedInEvent;
+use OCP\User\Events\UserLoggedInWithCookieEvent;
+use OCP\User\Events\UserLoggedOutEvent;
+
+/**
+ * @template-implements IEventListener<UserCreatedEvent|UserDeletedEvent|UserLoggedInEvent|UserLoggedInWithCookieEvent|UserLoggedOutEvent|BeforePasswordUpdatedEvent|PasswordUpdatedEvent|BeforePasswordResetEvent|PasswordResetEvent>
+ */
+class UserEventsListener implements IEventListener {
+
+ public function __construct(
+ private Util $util,
+ private Setup $userSetup,
+ private Session $session,
+ private KeyManager $keyManager,
+ private IUserManager $userManager,
+ private IUserSession $userSession,
+ private SetupManager $setupManager,
+ private PassphraseService $passphraseService,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if ($event instanceof UserCreatedEvent) {
+ $this->onUserCreated($event->getUid(), $event->getPassword());
+ } elseif ($event instanceof UserDeletedEvent) {
+ $this->onUserDeleted($event->getUid());
+ } elseif ($event instanceof UserLoggedInEvent || $event instanceof UserLoggedInWithCookieEvent) {
+ $this->onUserLogin($event->getUser(), $event->getPassword());
+ } elseif ($event instanceof UserLoggedOutEvent) {
+ $this->onUserLogout();
+ } elseif ($event instanceof BeforePasswordUpdatedEvent) {
+ $this->onBeforePasswordUpdated($event->getUser(), $event->getPassword(), $event->getRecoveryPassword());
+ } elseif ($event instanceof PasswordUpdatedEvent) {
+ $this->onPasswordUpdated($event->getUid(), $event->getPassword(), $event->getRecoveryPassword());
+ } elseif ($event instanceof BeforePasswordResetEvent) {
+ $this->onBeforePasswordReset($event->getUid());
+ } elseif ($event instanceof PasswordResetEvent) {
+ $this->onPasswordReset($event->getUid(), $event->getPassword());
+ }
+ }
+
+ /**
+ * Startup encryption backend upon user login
+ */
+ private function onUserLogin(IUser $user, ?string $password): void {
+ // ensure filesystem is loaded
+ $this->setupManager->setupForUser($user);
+ if ($this->util->isMasterKeyEnabled() === false) {
+ // Skip if no master key and the password is not provided
+ if ($password === null) {
+ return;
+ }
+
+ $this->userSetup->setupUser($user->getUID(), $password);
+ }
+
+ $this->keyManager->init($user->getUID(), $password);
+ }
+
+ /**
+ * Remove keys from session during logout
+ */
+ private function onUserLogout(): void {
+ $this->session->clear();
+ }
+
+ /**
+ * Setup encryption backend upon user created
+ *
+ * This method should never be called for users using client side encryption
+ */
+ protected function onUserCreated(string $userId, string $password): void {
+ $this->userSetup->setupUser($userId, $password);
+ }
+
+ /**
+ * Cleanup encryption backend upon user deleted
+ *
+ * This method should never be called for users using client side encryption
+ */
+ protected function onUserDeleted(string $userId): void {
+ $this->keyManager->deletePublicKey($userId);
+ }
+
+ /**
+ * If the password can't be changed within Nextcloud, than update the key password in advance.
+ */
+ public function onBeforePasswordUpdated(IUser $user, string $password, ?string $recoveryPassword = null): void {
+ if (!$user->canChangePassword()) {
+ $this->passphraseService->setPassphraseForUser($user->getUID(), $password, $recoveryPassword);
+ }
+ }
+
+ /**
+ * Change a user's encryption passphrase
+ */
+ public function onPasswordUpdated(string $userId, string $password, ?string $recoveryPassword): void {
+ $this->passphraseService->setPassphraseForUser($userId, $password, $recoveryPassword);
+ }
+
+ /**
+ * Set user password resetting state to allow ignoring "reset"-requests on password update
+ */
+ public function onBeforePasswordReset(string $userId): void {
+ $this->passphraseService->setProcessingReset($userId);
+ }
+
+ /**
+ * Create new encryption keys on password reset and backup the old one
+ */
+ public function onPasswordReset(string $userId, string $password): void {
+ $this->keyManager->backupUserKeys('passwordReset', $userId);
+ $this->keyManager->deleteUserKeys($userId);
+ $this->userSetup->setupUser($userId, $password);
+ $this->passphraseService->setProcessingReset($userId, false);
+ }
+}
diff --git a/apps/encryption/lib/Migration/SetMasterKeyStatus.php b/apps/encryption/lib/Migration/SetMasterKeyStatus.php
index a80d7144cc4..5f98308de89 100644
--- a/apps/encryption/lib/Migration/SetMasterKeyStatus.php
+++ b/apps/encryption/lib/Migration/SetMasterKeyStatus.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Migration;
@@ -34,12 +18,9 @@ use OCP\Migration\IRepairStep;
class SetMasterKeyStatus implements IRepairStep {
- /** @var IConfig */
- private $config;
-
-
- public function __construct(IConfig $config) {
- $this->config = $config;
+ public function __construct(
+ private IConfig $config,
+ ) {
}
/**
diff --git a/apps/encryption/lib/Recovery.php b/apps/encryption/lib/Recovery.php
index 66ad59266a5..38e78f5e822 100644
--- a/apps/encryption/lib/Recovery.php
+++ b/apps/encryption/lib/Recovery.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption;
@@ -39,26 +20,6 @@ class Recovery {
* @var null|IUser
*/
protected $user;
- /**
- * @var Crypt
- */
- protected $crypt;
- /**
- * @var KeyManager
- */
- private $keyManager;
- /**
- * @var IConfig
- */
- private $config;
- /**
- * @var View
- */
- private $view;
- /**
- * @var IFile
- */
- private $file;
/**
* @param IUserSession $userSession
@@ -68,18 +29,15 @@ class Recovery {
* @param IFile $file
* @param View $view
*/
- public function __construct(IUserSession $userSession,
- Crypt $crypt,
- KeyManager $keyManager,
- IConfig $config,
- IFile $file,
- View $view) {
+ public function __construct(
+ IUserSession $userSession,
+ protected Crypt $crypt,
+ private KeyManager $keyManager,
+ private IConfig $config,
+ private IFile $file,
+ private View $view,
+ ) {
$this->user = ($userSession->isLoggedIn()) ? $userSession->getUser() : null;
- $this->crypt = $crypt;
- $this->keyManager = $keyManager;
- $this->config = $config;
- $this->view = $view;
- $this->file = $file;
}
/**
diff --git a/apps/encryption/lib/Services/PassphraseService.php b/apps/encryption/lib/Services/PassphraseService.php
new file mode 100644
index 00000000000..bdcc3f1108a
--- /dev/null
+++ b/apps/encryption/lib/Services/PassphraseService.php
@@ -0,0 +1,148 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\Encryption\Services;
+
+use OC\Files\Filesystem;
+use OCA\Encryption\Crypto\Crypt;
+use OCA\Encryption\KeyManager;
+use OCA\Encryption\Recovery;
+use OCA\Encryption\Session;
+use OCA\Encryption\Util;
+use OCP\Encryption\Exceptions\GenericEncryptionException;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use Psr\Log\LoggerInterface;
+
+class PassphraseService {
+
+ /** @var array<string, bool> */
+ private static array $passwordResetUsers = [];
+
+ public function __construct(
+ private Util $util,
+ private Crypt $crypt,
+ private Session $session,
+ private Recovery $recovery,
+ private KeyManager $keyManager,
+ private LoggerInterface $logger,
+ private IUserManager $userManager,
+ private IUserSession $userSession,
+ ) {
+ }
+
+ public function setProcessingReset(string $uid, bool $processing = true): void {
+ if ($processing) {
+ self::$passwordResetUsers[$uid] = true;
+ } else {
+ unset(self::$passwordResetUsers[$uid]);
+ }
+ }
+
+ /**
+ * Change a user's encryption passphrase
+ */
+ public function setPassphraseForUser(string $userId, string $password, ?string $recoveryPassword = null): bool {
+ // if we are in the process to resetting a user password, we have nothing
+ // to do here
+ if (isset(self::$passwordResetUsers[$userId])) {
+ return true;
+ }
+
+ if ($this->util->isMasterKeyEnabled()) {
+ $this->logger->error('setPassphraseForUser should never be called when master key is enabled');
+ return true;
+ }
+
+ // Check user exists on backend
+ $user = $this->userManager->get($userId);
+ if ($user === null) {
+ return false;
+ }
+
+ // Get existing decrypted private key
+ $currentUser = $this->userSession->getUser();
+
+ // current logged in user changes his own password
+ if ($currentUser !== null && $userId === $currentUser->getUID()) {
+ $privateKey = $this->session->getPrivateKey();
+
+ // Encrypt private key with new user pwd as passphrase
+ $encryptedPrivateKey = $this->crypt->encryptPrivateKey($privateKey, $password, $userId);
+
+ // Save private key
+ if ($encryptedPrivateKey !== false) {
+ $key = $this->crypt->generateHeader() . $encryptedPrivateKey;
+ $this->keyManager->setPrivateKey($userId, $key);
+ return true;
+ }
+
+ $this->logger->error('Encryption could not update users encryption password');
+
+ // NOTE: Session does not need to be updated as the
+ // private key has not changed, only the passphrase
+ // used to decrypt it has changed
+ } else {
+ // admin changed the password for a different user, create new keys and re-encrypt file keys
+ $recoveryPassword = $recoveryPassword ?? '';
+ $this->initMountPoints($user);
+
+ $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
+ $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
+ try {
+ $this->crypt->decryptPrivateKey($recoveryKey, $recoveryPassword);
+ } catch (\Exception) {
+ $message = 'Can not decrypt the recovery key. Maybe you provided the wrong password. Try again.';
+ throw new GenericEncryptionException($message, $message);
+ }
+
+ // we generate new keys if...
+ // ...we have a recovery password and the user enabled the recovery key
+ // ...encryption was activated for the first time (no keys exists)
+ // ...the user doesn't have any files
+ if (
+ ($this->recovery->isRecoveryEnabledForUser($userId) && $recoveryPassword !== '')
+ || !$this->keyManager->userHasKeys($userId)
+ || !$this->util->userHasFiles($userId)
+ ) {
+ $keyPair = $this->crypt->createKeyPair();
+ if ($keyPair === false) {
+ $this->logger->error('Could not create new private key-pair for user.');
+ return false;
+ }
+
+ // Save public key
+ $this->keyManager->setPublicKey($userId, $keyPair['publicKey']);
+
+ // Encrypt private key with new password
+ $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password, $userId);
+ if ($encryptedKey === false) {
+ $this->logger->error('Encryption could not update users encryption password');
+ return false;
+ }
+
+ $this->keyManager->setPrivateKey($userId, $this->crypt->generateHeader() . $encryptedKey);
+
+ if ($recoveryPassword !== '') {
+ // if recovery key is set we can re-encrypt the key files
+ $this->recovery->recoverUsersFiles($recoveryPassword, $userId);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Init mount points for given user
+ */
+ private function initMountPoints(IUser $user): void {
+ Filesystem::initMountPoints($user);
+ }
+}
diff --git a/apps/encryption/lib/Session.php b/apps/encryption/lib/Session.php
index ad07008d480..df1e5d664ad 100644
--- a/apps/encryption/lib/Session.php
+++ b/apps/encryption/lib/Session.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption;
@@ -31,9 +12,6 @@ use OCP\ISession;
class Session {
- /** @var ISession */
- protected $session;
-
public const NOT_INITIALIZED = '0';
public const INIT_EXECUTED = '1';
public const INIT_SUCCESSFUL = '2';
@@ -41,8 +19,9 @@ class Session {
/**
* @param ISession $session
*/
- public function __construct(ISession $session) {
- $this->session = $session;
+ public function __construct(
+ protected ISession $session,
+ ) {
}
/**
@@ -87,7 +66,7 @@ class Session {
public function getPrivateKey() {
$key = $this->session->get('privateKey');
if (is_null($key)) {
- throw new Exceptions\PrivateKeyMissingException('please try to log-out and log-in again', 0);
+ throw new PrivateKeyMissingException('please try to log-out and log-in again');
}
return $key;
}
diff --git a/apps/encryption/lib/Settings/Admin.php b/apps/encryption/lib/Settings/Admin.php
index 9ce765723d8..a5de4ba68ff 100644
--- a/apps/encryption/lib/Settings/Admin.php
+++ b/apps/encryption/lib/Settings/Admin.php
@@ -1,27 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Settings;
@@ -45,7 +26,7 @@ class Admin implements ISettings {
private IUserSession $userSession,
private IConfig $config,
private IUserManager $userManager,
- private ISession $session
+ private ISession $session,
) {
}
@@ -91,8 +72,8 @@ class Admin implements ISettings {
/**
* @return int whether the form should be rather on the top or bottom of
- * the admin section. The forms are arranged in ascending order of the
- * priority values. It is required to return a value between 0 and 100.
+ * the admin section. The forms are arranged in ascending order of the
+ * priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
*/
diff --git a/apps/encryption/lib/Settings/Personal.php b/apps/encryption/lib/Settings/Personal.php
index 70b85a667a9..8814d3afb58 100644
--- a/apps/encryption/lib/Settings/Personal.php
+++ b/apps/encryption/lib/Settings/Personal.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Encryption\Settings;
@@ -32,20 +15,12 @@ use OCP\Settings\ISettings;
class Personal implements ISettings {
- /** @var IConfig */
- private $config;
- /** @var Session */
- private $session;
- /** @var Util */
- private $util;
- /** @var IUserSession */
- private $userSession;
-
- public function __construct(IConfig $config, Session $session, Util $util, IUserSession $userSession) {
- $this->config = $config;
- $this->session = $session;
- $this->util = $util;
- $this->userSession = $userSession;
+ public function __construct(
+ private IConfig $config,
+ private Session $session,
+ private Util $util,
+ private IUserSession $userSession,
+ ) {
}
/**
@@ -82,8 +57,8 @@ class Personal implements ISettings {
/**
* @return int whether the form should be rather on the top or bottom of
- * the admin section. The forms are arranged in ascending order of the
- * priority values. It is required to return a value between 0 and 100.
+ * the admin section. The forms are arranged in ascending order of the
+ * priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
* @since 9.1
diff --git a/apps/encryption/lib/Users/Setup.php b/apps/encryption/lib/Users/Setup.php
index 8b0ddaa8cd0..f2189d6dab2 100644
--- a/apps/encryption/lib/Users/Setup.php
+++ b/apps/encryption/lib/Users/Setup.php
@@ -1,29 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption\Users;
@@ -31,15 +11,11 @@ use OCA\Encryption\Crypto\Crypt;
use OCA\Encryption\KeyManager;
class Setup {
- /** @var Crypt */
- private $crypt;
- /** @var KeyManager */
- private $keyManager;
- public function __construct(Crypt $crypt,
- KeyManager $keyManager) {
- $this->crypt = $crypt;
- $this->keyManager = $keyManager;
+ public function __construct(
+ private Crypt $crypt,
+ private KeyManager $keyManager,
+ ) {
}
/**
diff --git a/apps/encryption/lib/Util.php b/apps/encryption/lib/Util.php
index f1b43413be3..ccbdcdcb242 100644
--- a/apps/encryption/lib/Util.php
+++ b/apps/encryption/lib/Util.php
@@ -1,33 +1,16 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Phil Davis <phil.davis@inf.org>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption;
+use OC\Files\Storage\Storage;
use OC\Files\View;
use OCA\Encryption\Crypto\Crypt;
+use OCP\Files\Storage\IStorage;
use OCP\IConfig;
use OCP\IUser;
use OCP\IUserManager;
@@ -44,11 +27,7 @@ class Util {
private IConfig $config,
private IUserManager $userManager,
) {
- $this->files = $files;
- $this->crypt = $crypt;
$this->user = $userSession->isLoggedIn() ? $userSession->getUser() : false;
- $this->config = $config;
- $this->userManager = $userManager;
}
/**
@@ -142,21 +121,16 @@ class Util {
if (count($parts) > 1) {
$owner = $parts[1];
if ($this->userManager->userExists($owner) === false) {
- throw new \BadMethodCallException('Unknown user: ' .
- 'method expects path to a user folder relative to the data folder');
+ throw new \BadMethodCallException('Unknown user: '
+ . 'method expects path to a user folder relative to the data folder');
}
}
return $owner;
}
- /**
- * get storage of path
- *
- * @param string $path
- * @return \OC\Files\Storage\Storage|null
- */
- public function getStorage($path) {
+ public function getStorage(string $path): ?IStorage {
return $this->files->getMount($path)->getStorage();
}
+
}