diff options
Diffstat (limited to 'apps/encryption/lib/Hooks/UserHooks.php')
-rw-r--r-- | apps/encryption/lib/Hooks/UserHooks.php | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/apps/encryption/lib/Hooks/UserHooks.php b/apps/encryption/lib/Hooks/UserHooks.php deleted file mode 100644 index 2424370e47f..00000000000 --- a/apps/encryption/lib/Hooks/UserHooks.php +++ /dev/null @@ -1,266 +0,0 @@ -<?php - -/** - * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. - * SPDX-License-Identifier: AGPL-3.0-only - */ -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); - } -} |