chore(encryption): Cleanup typing in EncryptAll/DecryptAll

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
pull/54316/head
Côme Chilliet 8 months ago
parent 7ac0856f9f
commit 94254db001
No known key found for this signature in database
GPG Key ID: A3E2F658B28C760A
  1. 27
      apps/encryption/lib/Crypto/DecryptAll.php
  2. 37
      apps/encryption/lib/Crypto/EncryptAll.php
  3. 40
      apps/encryption/lib/Session.php
  4. 93
      lib/private/Encryption/DecryptAll.php

@ -1,10 +1,13 @@
<?php
declare(strict_types=1);
/**
* 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;
@ -18,14 +21,6 @@ use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
class DecryptAll {
/**
* @param Util $util
* @param KeyManager $keyManager
* @param Crypt $crypt
* @param Session $session
* @param QuestionHelper $questionHelper
*/
public function __construct(
protected Util $util,
protected KeyManager $keyManager,
@ -37,13 +32,8 @@ class DecryptAll {
/**
* prepare encryption module to decrypt all files
*
* @param InputInterface $input
* @param OutputInterface $output
* @param $user
* @return bool
*/
public function prepare(InputInterface $input, OutputInterface $output, $user) {
public function prepare(InputInterface $input, OutputInterface $output, ?string $user): bool {
$question = new Question('Please enter the recovery key password: ');
if ($this->util->isMasterKeyEnabled()) {
@ -52,7 +42,7 @@ class DecryptAll {
$password = $this->keyManager->getMasterKeyPassword();
} else {
$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
if (!empty($user)) {
if ($user !== null && $user !== '') {
$output->writeln('You can only decrypt the users files if you know');
$output->writeln('the users password or if they activated the recovery key.');
$output->writeln('');
@ -96,12 +86,9 @@ class DecryptAll {
/**
* get the private key which will be used to decrypt all files
*
* @param string $user
* @param string $password
* @return bool|string
* @throws PrivateKeyMissingException
*/
protected function getPrivateKey($user, $password) {
protected function getPrivateKey(string $user, string $password): string|false {
$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
$masterKeyId = $this->keyManager->getMasterKeyId();
if ($user === $recoveryKeyId) {
@ -118,7 +105,7 @@ class DecryptAll {
return $privateKey;
}
protected function updateSession($user, $privateKey) {
protected function updateSession(string $user, string $privateKey): void {
$this->session->prepareDecryptAll($user, $privateKey);
}
}

@ -1,10 +1,13 @@
<?php
declare(strict_types=1);
/**
* 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;
use OC\Encryption\Exceptions\DecryptionFailedException;
@ -60,11 +63,8 @@ class EncryptAll {
/**
* start to encrypt all files
*
* @param InputInterface $input
* @param OutputInterface $output
*/
public function encryptAll(InputInterface $input, OutputInterface $output) {
public function encryptAll(InputInterface $input, OutputInterface $output): void {
$this->input = $input;
$this->output = $output;
@ -111,7 +111,7 @@ class EncryptAll {
/**
* create key-pair for every user
*/
protected function createKeyPairs() {
protected function createKeyPairs(): void {
$this->output->writeln("\n");
$progress = new ProgressBar($this->output);
$progress->setFormat(" %message% \n [%bar%]");
@ -146,7 +146,7 @@ class EncryptAll {
/**
* iterate over all user and encrypt their files
*/
protected function encryptAllUsersFiles() {
protected function encryptAllUsersFiles(): void {
$this->output->writeln("\n");
$progress = new ProgressBar($this->output);
$progress->setFormat(" %message% \n [%bar%]");
@ -168,10 +168,8 @@ class EncryptAll {
/**
* encrypt all user files with the master key
*
* @param ProgressBar $progress
*/
protected function encryptAllUserFilesWithMasterKey(ProgressBar $progress) {
protected function encryptAllUserFilesWithMasterKey(ProgressBar $progress): void {
$userNo = 1;
foreach ($this->userManager->getBackends() as $backend) {
$limit = 500;
@ -190,12 +188,8 @@ class EncryptAll {
/**
* encrypt files from the given user
*
* @param string $uid
* @param ProgressBar $progress
* @param string $userCount
*/
protected function encryptUsersFiles($uid, ProgressBar $progress, $userCount) {
protected function encryptUsersFiles(string $uid, ProgressBar $progress, string $userCount): void {
$this->setupUserFS($uid);
$directories = [];
$directories[] = '/' . $uid . '/files';
@ -268,7 +262,7 @@ class EncryptAll {
/**
* output one-time encryption passwords
*/
protected function outputPasswords() {
protected function outputPasswords(): void {
$table = new Table($this->output);
$table->setHeaders(['Username', 'Private key password']);
@ -309,10 +303,8 @@ class EncryptAll {
/**
* write one-time encryption passwords to a csv file
*
* @param array $passwords
*/
protected function writePasswordsToFile(array $passwords) {
protected function writePasswordsToFile(array $passwords): void {
$fp = $this->rootView->fopen('oneTimeEncryptionPasswords.csv', 'w');
foreach ($passwords as $pwd) {
fputcsv($fp, $pwd);
@ -330,10 +322,8 @@ class EncryptAll {
/**
* setup user file system
*
* @param string $uid
*/
protected function setupUserFS($uid) {
protected function setupUserFS(string $uid): void {
\OC_Util::tearDownFS();
\OC_Util::setupFS($uid);
}
@ -341,10 +331,9 @@ class EncryptAll {
/**
* generate one time password for the user and store it in a array
*
* @param string $uid
* @return string password
*/
protected function generateOneTimePassword($uid) {
protected function generateOneTimePassword(string $uid): string {
$password = $this->secureRandom->generate(16, ISecureRandom::CHAR_HUMAN_READABLE);
$this->userPasswords[$uid] = $password;
return $password;
@ -353,7 +342,7 @@ class EncryptAll {
/**
* send encryption key passwords to the users by mail
*/
protected function sendPasswordsByMail() {
protected function sendPasswordsByMail(): void {
$noMail = [];
$this->output->writeln('');

@ -1,24 +1,23 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Encryption;
use OCA\Encryption\Exceptions\PrivateKeyMissingException;
use OCP\ISession;
class Session {
public const NOT_INITIALIZED = '0';
public const INIT_EXECUTED = '1';
public const INIT_SUCCESSFUL = '2';
/**
* @param ISession $session
*/
public function __construct(
protected ISession $session,
) {
@ -29,7 +28,7 @@ class Session {
*
* @param string $status INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INITIALIZED
*/
public function setStatus($status) {
public function setStatus(string $status): void {
$this->session->set('encryptionInitialized', $status);
}
@ -38,7 +37,7 @@ class Session {
*
* @return string init status INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INITIALIZED
*/
public function getStatus() {
public function getStatus(): string {
$status = $this->session->get('encryptionInitialized');
if (is_null($status)) {
$status = self::NOT_INITIALIZED;
@ -49,10 +48,8 @@ class Session {
/**
* check if encryption was initialized successfully
*
* @return bool
*/
public function isReady() {
public function isReady(): bool {
$status = $this->getStatus();
return $status === self::INIT_SUCCESSFUL;
}
@ -63,7 +60,7 @@ class Session {
* @return string $privateKey The user's plaintext private key
* @throws Exceptions\PrivateKeyMissingException
*/
public function getPrivateKey() {
public function getPrivateKey(): string {
$key = $this->session->get('privateKey');
if (is_null($key)) {
throw new PrivateKeyMissingException('please try to log-out and log-in again');
@ -73,10 +70,8 @@ class Session {
/**
* check if private key is set
*
* @return boolean
*/
public function isPrivateKeySet() {
public function isPrivateKeySet(): bool {
$key = $this->session->get('privateKey');
if (is_null($key)) {
return false;
@ -92,17 +87,14 @@ class Session {
*
* @note this should only be set on login
*/
public function setPrivateKey($key) {
public function setPrivateKey(string $key): void {
$this->session->set('privateKey', $key);
}
/**
* store data needed for the decrypt all operation in the session
*
* @param string $user
* @param string $key
*/
public function prepareDecryptAll($user, $key) {
public function prepareDecryptAll(string $user, string $key): void {
$this->session->set('decryptAll', true);
$this->session->set('decryptAllKey', $key);
$this->session->set('decryptAllUid', $user);
@ -110,10 +102,8 @@ class Session {
/**
* check if we are in decrypt all mode
*
* @return bool
*/
public function decryptAllModeActivated() {
public function decryptAllModeActivated(): bool {
$decryptAll = $this->session->get('decryptAll');
return ($decryptAll === true);
}
@ -121,10 +111,9 @@ class Session {
/**
* get uid used for decrypt all operation
*
* @return string
* @throws \Exception
*/
public function getDecryptAllUid() {
public function getDecryptAllUid(): string {
$uid = $this->session->get('decryptAllUid');
if (is_null($uid) && $this->decryptAllModeActivated()) {
throw new \Exception('No uid found while in decrypt all mode');
@ -138,10 +127,9 @@ class Session {
/**
* get private key for decrypt all operation
*
* @return string
* @throws PrivateKeyMissingException
*/
public function getDecryptAllKey() {
public function getDecryptAllKey(): string {
$privateKey = $this->session->get('decryptAllKey');
if (is_null($privateKey) && $this->decryptAllModeActivated()) {
throw new PrivateKeyMissingException('No private key found while in decrypt all mode');
@ -155,7 +143,7 @@ class Session {
/**
* remove keys from session
*/
public function clear() {
public function clear(): void {
$this->session->remove('publicSharePrivateKey');
$this->session->remove('privateKey');
$this->session->remove('encryptionInitialized');

@ -1,10 +1,13 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Encryption;
use OC\Encryption\Exceptions\DecryptionFailedException;
@ -17,61 +20,50 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class DecryptAll {
/** @var OutputInterface */
protected $output;
/** @var InputInterface */
protected $input;
/** @var array files which couldn't be decrypted */
protected $failed;
/** @var array<string,list<string>> files which couldn't be decrypted */
protected array $failed = [];
public function __construct(
protected IManager $encryptionManager,
protected IUserManager $userManager,
protected View $rootView,
) {
$this->failed = [];
}
/**
* start to decrypt all files
*
* @param InputInterface $input
* @param OutputInterface $output
* @param string $user which users data folder should be decrypted, default = all users
* @return bool
* @throws \Exception
*/
public function decryptAll(InputInterface $input, OutputInterface $output, $user = '') {
$this->input = $input;
$this->output = $output;
public function decryptAll(InputInterface $input, OutputInterface $output, string $user = ''): bool {
if ($user !== '' && $this->userManager->userExists($user) === false) {
$this->output->writeln('User "' . $user . '" does not exist. Please check the username and try again');
$output->writeln('User "' . $user . '" does not exist. Please check the username and try again');
return false;
}
$this->output->writeln('prepare encryption modules...');
if ($this->prepareEncryptionModules($user) === false) {
$output->writeln('prepare encryption modules...');
if ($this->prepareEncryptionModules($input, $output, $user) === false) {
return false;
}
$this->output->writeln(' done.');
$output->writeln(' done.');
$this->decryptAllUsersFiles($user);
$this->failed = [];
$this->decryptAllUsersFiles($output, $user);
/** @psalm-suppress RedundantCondition $this->failed is modified by decryptAllUsersFiles, not clear why psalm fails to see it */
if (empty($this->failed)) {
$this->output->writeln('all files could be decrypted successfully!');
$output->writeln('all files could be decrypted successfully!');
} else {
$this->output->writeln('Files for following users couldn\'t be decrypted, ');
$this->output->writeln('maybe the user is not set up in a way that supports this operation: ');
$output->writeln('Files for following users couldn\'t be decrypted, ');
$output->writeln('maybe the user is not set up in a way that supports this operation: ');
foreach ($this->failed as $uid => $paths) {
$this->output->writeln(' ' . $uid);
$output->writeln(' ' . $uid);
foreach ($paths as $path) {
$this->output->writeln(' ' . $path);
$output->writeln(' ' . $path);
}
}
$this->output->writeln('');
$output->writeln('');
}
return true;
@ -79,21 +71,18 @@ class DecryptAll {
/**
* prepare encryption modules to perform the decrypt all function
*
* @param $user
* @return bool
*/
protected function prepareEncryptionModules($user) {
protected function prepareEncryptionModules(InputInterface $input, OutputInterface $output, string $user): bool {
// prepare all encryption modules for decrypt all
$encryptionModules = $this->encryptionManager->getEncryptionModules();
foreach ($encryptionModules as $moduleDesc) {
/** @var IEncryptionModule $module */
$module = call_user_func($moduleDesc['callback']);
$this->output->writeln('');
$this->output->writeln('Prepare "' . $module->getDisplayName() . '"');
$this->output->writeln('');
if ($module->prepareDecryptAll($this->input, $this->output, $user) === false) {
$this->output->writeln('Module "' . $moduleDesc['displayName'] . '" does not support the functionality to decrypt all files again or the initialization of the module failed!');
$output->writeln('');
$output->writeln('Prepare "' . $module->getDisplayName() . '"');
$output->writeln('');
if ($module->prepareDecryptAll($input, $output, $user) === false) {
$output->writeln('Module "' . $moduleDesc['displayName'] . '" does not support the functionality to decrypt all files again or the initialization of the module failed!');
return false;
}
}
@ -106,12 +95,12 @@ class DecryptAll {
*
* @param string $user which users files should be decrypted, default = all users
*/
protected function decryptAllUsersFiles($user = '') {
$this->output->writeln("\n");
protected function decryptAllUsersFiles(OutputInterface $output, string $user = ''): void {
$output->writeln("\n");
$userList = [];
if ($user === '') {
$fetchUsersProgress = new ProgressBar($this->output);
$fetchUsersProgress = new ProgressBar($output);
$fetchUsersProgress->setFormat(" %message% \n [%bar%]");
$fetchUsersProgress->start();
$fetchUsersProgress->setMessage('Fetch list of users...');
@ -135,9 +124,9 @@ class DecryptAll {
$userList[] = $user;
}
$this->output->writeln("\n\n");
$output->writeln("\n\n");
$progress = new ProgressBar($this->output);
$progress = new ProgressBar($output);
$progress->setFormat(" %message% \n [%bar%]");
$progress->start();
$progress->setMessage('starting to decrypt files...');
@ -154,17 +143,13 @@ class DecryptAll {
$progress->setMessage('starting to decrypt files... finished');
$progress->finish();
$this->output->writeln("\n\n");
$output->writeln("\n\n");
}
/**
* encrypt files from the given user
*
* @param string $uid
* @param ProgressBar $progress
* @param string $userCount
*/
protected function decryptUsersFiles($uid, ProgressBar $progress, $userCount) {
protected function decryptUsersFiles(string $uid, ProgressBar $progress, string $userCount): void {
$this->setupUserFS($uid);
$directories = [];
$directories[] = '/' . $uid . '/files';
@ -207,11 +192,8 @@ class DecryptAll {
/**
* encrypt file
*
* @param string $path
* @return bool
*/
protected function decryptFile($path) {
protected function decryptFile(string $path): bool {
// skip already decrypted files
$fileInfo = $this->rootView->getFileInfo($path);
if ($fileInfo !== false && !$fileInfo->isEncrypted()) {
@ -237,20 +219,15 @@ class DecryptAll {
/**
* get current timestamp
*
* @return int
*/
protected function getTimestamp() {
protected function getTimestamp(): int {
return time();
}
/**
* setup user file system
*
* @param string $uid
*/
protected function setupUserFS($uid) {
protected function setupUserFS(string $uid): void {
\OC_Util::tearDownFS();
\OC_Util::setupFS($uid);
}

Loading…
Cancel
Save