mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
Merge pull request #54262 from nextcloud/backport/54233/stable31
This commit is contained in:
commit
9b4797eecc
3 changed files with 86 additions and 95 deletions
|
|
@ -12,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;
|
||||
|
|
@ -202,15 +203,19 @@ 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();
|
||||
try {
|
||||
if ($this->encryptFile($path) === false) {
|
||||
if ($this->encryptFile($file, $path) === false) {
|
||||
$progress->setMessage("encrypt files for user $userCount: $path (already encrypted)");
|
||||
$progress->advance();
|
||||
}
|
||||
|
|
@ -231,17 +236,9 @@ class EncryptAll {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -30,6 +32,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
use Test\TestCase;
|
||||
|
||||
class EncryptAllTest extends TestCase {
|
||||
|
||||
protected KeyManager&MockObject $keyManager;
|
||||
protected Util&MockObject $util;
|
||||
protected IUserManager&MockObject $userManager;
|
||||
|
|
@ -46,8 +49,7 @@ class EncryptAllTest extends TestCase {
|
|||
protected ISecureRandom&MockObject $secureRandom;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
|
||||
/** @var EncryptAll */
|
||||
protected $encryptAll;
|
||||
protected EncryptAll $encryptAll;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -80,7 +82,7 @@ class EncryptAllTest extends TestCase {
|
|||
|
||||
/**
|
||||
* We need format method to return a string
|
||||
* @var OutputFormatterInterface|\PHPUnit\Framework\MockObject\MockObject
|
||||
* @var OutputFormatterInterface&MockObject
|
||||
*/
|
||||
$outputFormatter = $this->createMock(OutputFormatterInterface::class);
|
||||
$outputFormatter->method('isDecorated')->willReturn(false);
|
||||
|
|
@ -112,6 +114,13 @@ class EncryptAllTest extends TestCase {
|
|||
);
|
||||
}
|
||||
|
||||
protected function createFileInfoMock($type, string $name): FileInfo&MockObject {
|
||||
$fileInfo = $this->createMock(FileInfo::class);
|
||||
$fileInfo->method('getType')->willReturn($type);
|
||||
$fileInfo->method('getName')->willReturn($name);
|
||||
return $fileInfo;
|
||||
}
|
||||
|
||||
public function testEncryptAll(): void {
|
||||
/** @var EncryptAll&MockObject $encryptAll */
|
||||
$encryptAll = $this->getMockBuilder(EncryptAll::class)
|
||||
|
|
@ -131,7 +140,7 @@ class EncryptAllTest extends TestCase {
|
|||
$this->logger,
|
||||
]
|
||||
)
|
||||
->setMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords'])
|
||||
->onlyMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords'])
|
||||
->getMock();
|
||||
|
||||
$this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(false);
|
||||
|
|
@ -161,7 +170,7 @@ class EncryptAllTest extends TestCase {
|
|||
$this->logger,
|
||||
]
|
||||
)
|
||||
->setMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords'])
|
||||
->onlyMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords'])
|
||||
->getMock();
|
||||
|
||||
$this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(true);
|
||||
|
|
@ -192,7 +201,7 @@ class EncryptAllTest extends TestCase {
|
|||
$this->logger,
|
||||
]
|
||||
)
|
||||
->setMethods(['setupUserFS', 'generateOneTimePassword'])
|
||||
->onlyMethods(['setupUserFS', 'generateOneTimePassword'])
|
||||
->getMock();
|
||||
|
||||
|
||||
|
|
@ -225,7 +234,7 @@ class EncryptAllTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testEncryptAllUsersFiles(): void {
|
||||
/** @var EncryptAll | \PHPUnit\Framework\MockObject\MockObject $encryptAll */
|
||||
/** @var EncryptAll&MockObject $encryptAll */
|
||||
$encryptAll = $this->getMockBuilder(EncryptAll::class)
|
||||
->setConstructorArgs(
|
||||
[
|
||||
|
|
@ -243,7 +252,7 @@ class EncryptAllTest extends TestCase {
|
|||
$this->logger,
|
||||
]
|
||||
)
|
||||
->setMethods(['encryptUsersFiles'])
|
||||
->onlyMethods(['encryptUsersFiles'])
|
||||
->getMock();
|
||||
|
||||
$this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(false);
|
||||
|
|
@ -252,17 +261,22 @@ class EncryptAllTest extends TestCase {
|
|||
$this->invokePrivate($encryptAll, 'output', [$this->outputInterface]);
|
||||
$this->invokePrivate($encryptAll, 'userPasswords', [['user1' => 'pwd1', 'user2' => 'pwd2']]);
|
||||
|
||||
$encryptAll->expects($this->exactly(2))->method('encryptUsersFiles')
|
||||
->withConsecutive(
|
||||
['user1'],
|
||||
['user2'],
|
||||
);
|
||||
$encryptAllCalls = [];
|
||||
$encryptAll->expects($this->exactly(2))
|
||||
->method('encryptUsersFiles')
|
||||
->willReturnCallback(function ($uid) use (&$encryptAllCalls): void {
|
||||
$encryptAllCalls[] = $uid;
|
||||
});
|
||||
|
||||
$this->invokePrivate($encryptAll, 'encryptAllUsersFiles');
|
||||
self::assertEquals([
|
||||
'user1',
|
||||
'user2',
|
||||
], $encryptAllCalls);
|
||||
}
|
||||
|
||||
public function testEncryptUsersFiles(): void {
|
||||
/** @var EncryptAll | \PHPUnit\Framework\MockObject\MockObject $encryptAll */
|
||||
/** @var EncryptAll&MockObject $encryptAll */
|
||||
$encryptAll = $this->getMockBuilder(EncryptAll::class)
|
||||
->setConstructorArgs(
|
||||
[
|
||||
|
|
@ -280,40 +294,39 @@ class EncryptAllTest extends TestCase {
|
|||
$this->logger,
|
||||
]
|
||||
)
|
||||
->setMethods(['encryptFile', 'setupUserFS'])
|
||||
->onlyMethods(['encryptFile', 'setupUserFS'])
|
||||
->getMock();
|
||||
|
||||
$this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(false);
|
||||
|
||||
$this->view->expects($this->exactly(2))->method('getDirectoryContent')
|
||||
->withConsecutive(
|
||||
['/user1/files'],
|
||||
['/user1/files/foo'],
|
||||
)->willReturnOnConsecutiveCalls(
|
||||
->willReturnMap([
|
||||
[
|
||||
['name' => 'foo', 'type' => 'dir'],
|
||||
['name' => 'bar', 'type' => 'file'],
|
||||
'/user1/files',
|
||||
'',
|
||||
null,
|
||||
[
|
||||
$this->createFileInfoMock(FileInfo::TYPE_FOLDER, 'foo'),
|
||||
$this->createFileInfoMock(FileInfo::TYPE_FILE, 'bar'),
|
||||
],
|
||||
],
|
||||
[
|
||||
['name' => 'subfile', 'type' => 'file']
|
||||
]
|
||||
);
|
||||
'/user1/files/foo',
|
||||
'',
|
||||
null,
|
||||
[
|
||||
$this->createFileInfoMock(FileInfo::TYPE_FILE, 'subfile'),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->view->expects($this->any())->method('is_dir')
|
||||
->willReturnCallback(
|
||||
function ($path) {
|
||||
if ($path === '/user1/files/foo') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
$encryptAll->expects($this->exactly(2))->method('encryptFile')
|
||||
->withConsecutive(
|
||||
['/user1/files/bar'],
|
||||
['/user1/files/foo/subfile'],
|
||||
);
|
||||
$encryptAllCalls = [];
|
||||
$encryptAll->expects($this->exactly(2))
|
||||
->method('encryptFile')
|
||||
->willReturnCallback(function (FileInfo $file, string $path) use (&$encryptAllCalls): bool {
|
||||
$encryptAllCalls[] = $path;
|
||||
return true;
|
||||
});
|
||||
|
||||
$outputFormatter = $this->createMock(OutputFormatterInterface::class);
|
||||
$outputFormatter->method('isDecorated')->willReturn(false);
|
||||
|
|
@ -323,6 +336,10 @@ class EncryptAllTest extends TestCase {
|
|||
$progressBar = new ProgressBar($this->outputInterface);
|
||||
|
||||
$this->invokePrivate($encryptAll, 'encryptUsersFiles', ['user1', $progressBar, '']);
|
||||
self::assertEquals([
|
||||
'/user1/files/bar',
|
||||
'/user1/files/foo/subfile',
|
||||
], $encryptAllCalls);
|
||||
}
|
||||
|
||||
public function testGenerateOneTimePassword(): void {
|
||||
|
|
@ -343,8 +360,7 @@ class EncryptAllTest extends TestCase {
|
|||
$fileInfo = $this->createMock(FileInfo::class);
|
||||
$fileInfo->expects($this->any())->method('isEncrypted')
|
||||
->willReturn($isEncrypted);
|
||||
$this->view->expects($this->any())->method('getFileInfo')
|
||||
->willReturn($fileInfo);
|
||||
$this->view->expects($this->never())->method('getFileInfo');
|
||||
|
||||
|
||||
if ($isEncrypted) {
|
||||
|
|
@ -356,11 +372,11 @@ class EncryptAllTest extends TestCase {
|
|||
}
|
||||
|
||||
$this->assertTrue(
|
||||
$this->invokePrivate($this->encryptAll, 'encryptFile', ['foo.txt'])
|
||||
$this->invokePrivate($this->encryptAll, 'encryptFile', [$fileInfo, 'foo.txt'])
|
||||
);
|
||||
}
|
||||
|
||||
public function dataTestEncryptFile() {
|
||||
public static function dataTestEncryptFile(): array {
|
||||
return [
|
||||
[true],
|
||||
[false],
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -12,59 +13,36 @@ use OCP\App\IAppManager;
|
|||
use OCP\Encryption\IEncryptionModule;
|
||||
use OCP\Encryption\IManager;
|
||||
use OCP\IConfig;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class EncryptAllTest extends TestCase {
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\IConfig */
|
||||
protected $config;
|
||||
private IConfig&MockObject $config;
|
||||
private IManager&MockObject $encryptionManager;
|
||||
private IAppManager&MockObject $appManager;
|
||||
private InputInterface&MockObject $consoleInput;
|
||||
private OutputInterface&MockObject $consoleOutput;
|
||||
private QuestionHelper&MockObject $questionHelper;
|
||||
private IEncryptionModule&MockObject $encryptionModule;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\Encryption\IManager */
|
||||
protected $encryptionManager;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\App\IAppManager */
|
||||
protected $appManager;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */
|
||||
protected $consoleInput;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */
|
||||
protected $consoleOutput;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Helper\QuestionHelper */
|
||||
protected $questionHelper;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\Encryption\IEncryptionModule */
|
||||
protected $encryptionModule;
|
||||
|
||||
/** @var EncryptAll */
|
||||
protected $command;
|
||||
private EncryptAll $command;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->config = $this->getMockBuilder(IConfig::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->encryptionManager = $this->getMockBuilder(IManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->appManager = $this->getMockBuilder(IAppManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->encryptionModule = $this->getMockBuilder(IEncryptionModule::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->questionHelper = $this->getMockBuilder(QuestionHelper::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->encryptionManager = $this->createMock(IManager::class);
|
||||
$this->appManager = $this->createMock(IAppManager::class);
|
||||
$this->encryptionModule = $this->createMock(IEncryptionModule::class);
|
||||
$this->questionHelper = $this->createMock(QuestionHelper::class);
|
||||
$this->consoleInput = $this->createMock(InputInterface::class);
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('isInteractive')
|
||||
->willReturn(true);
|
||||
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();
|
||||
$this->consoleOutput = $this->createMock(OutputInterface::class);
|
||||
}
|
||||
|
||||
public function testEncryptAll(): void {
|
||||
|
|
|
|||
Loading…
Reference in a new issue