Merge pull request #54233 from nextcloud/fix/ignore-shares-in-encrypt-all

pull/54264/head
John Molakvoæ 2025-08-05 15:31:35 +07:00 committed by GitHub
commit a4795a216c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 70 deletions

@ -12,6 +12,7 @@ use OC\Files\View;
use OCA\Encryption\KeyManager; use OCA\Encryption\KeyManager;
use OCA\Encryption\Users\Setup; use OCA\Encryption\Users\Setup;
use OCA\Encryption\Util; use OCA\Encryption\Util;
use OCP\Files\FileInfo;
use OCP\IConfig; use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\IUser; use OCP\IUser;
@ -202,15 +203,19 @@ class EncryptAll {
while ($root = array_pop($directories)) { while ($root = array_pop($directories)) {
$content = $this->rootView->getDirectoryContent($root); $content = $this->rootView->getDirectoryContent($root);
foreach ($content as $file) { foreach ($content as $file) {
$path = $root . '/' . $file['name']; $path = $root . '/' . $file->getName();
if ($this->rootView->is_dir($path)) { if ($file->isShared()) {
$progress->setMessage("Skip shared file/folder $path");
$progress->advance();
continue;
} elseif ($file->getType() === FileInfo::TYPE_FOLDER) {
$directories[] = $path; $directories[] = $path;
continue; continue;
} else { } else {
$progress->setMessage("encrypt files for user $userCount: $path"); $progress->setMessage("encrypt files for user $userCount: $path");
$progress->advance(); $progress->advance();
try { try {
if ($this->encryptFile($path) === false) { if ($this->encryptFile($file, $path) === false) {
$progress->setMessage("encrypt files for user $userCount: $path (already encrypted)"); $progress->setMessage("encrypt files for user $userCount: $path (already encrypted)");
$progress->advance(); $progress->advance();
} }
@ -231,17 +236,9 @@ class EncryptAll {
} }
} }
/** protected function encryptFile(FileInfo $fileInfo, string $path): bool {
* encrypt file
*
* @param string $path
* @return bool
*/
protected function encryptFile($path) {
// skip already encrypted files // skip already encrypted files
$fileInfo = $this->rootView->getFileInfo($path); if ($fileInfo->isEncrypted()) {
if ($fileInfo !== false && $fileInfo->isEncrypted()) {
return true; return true;
} }

@ -82,7 +82,7 @@ class EncryptAllTest extends TestCase {
/** /**
* We need format method to return a string * We need format method to return a string
* @var OutputFormatterInterface|\PHPUnit\Framework\MockObject\MockObject * @var OutputFormatterInterface&MockObject
*/ */
$outputFormatter = $this->createMock(OutputFormatterInterface::class); $outputFormatter = $this->createMock(OutputFormatterInterface::class);
$outputFormatter->method('isDecorated')->willReturn(false); $outputFormatter->method('isDecorated')->willReturn(false);
@ -114,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 { public function testEncryptAll(): void {
/** @var EncryptAll&MockObject $encryptAll */ /** @var EncryptAll&MockObject $encryptAll */
$encryptAll = $this->getMockBuilder(EncryptAll::class) $encryptAll = $this->getMockBuilder(EncryptAll::class)
@ -299,8 +306,8 @@ class EncryptAllTest extends TestCase {
'', '',
null, null,
[ [
['name' => 'foo', 'type' => 'dir'], $this->createFileInfoMock(FileInfo::TYPE_FOLDER, 'foo'),
['name' => 'bar', 'type' => 'file'], $this->createFileInfoMock(FileInfo::TYPE_FILE, 'bar'),
], ],
], ],
[ [
@ -308,26 +315,17 @@ class EncryptAllTest extends TestCase {
'', '',
null, null,
[ [
['name' => 'subfile', 'type' => 'file'] $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;
}
);
$encryptAllCalls = []; $encryptAllCalls = [];
$encryptAll->expects($this->exactly(2)) $encryptAll->expects($this->exactly(2))
->method('encryptFile') ->method('encryptFile')
->willReturnCallback(function (string $path) use (&$encryptAllCalls): void { ->willReturnCallback(function (FileInfo $file, string $path) use (&$encryptAllCalls): bool {
$encryptAllCalls[] = $path; $encryptAllCalls[] = $path;
return true;
}); });
$outputFormatter = $this->createMock(OutputFormatterInterface::class); $outputFormatter = $this->createMock(OutputFormatterInterface::class);
@ -362,8 +360,7 @@ class EncryptAllTest extends TestCase {
$fileInfo = $this->createMock(FileInfo::class); $fileInfo = $this->createMock(FileInfo::class);
$fileInfo->expects($this->any())->method('isEncrypted') $fileInfo->expects($this->any())->method('isEncrypted')
->willReturn($isEncrypted); ->willReturn($isEncrypted);
$this->view->expects($this->any())->method('getFileInfo') $this->view->expects($this->never())->method('getFileInfo');
->willReturn($fileInfo);
if ($isEncrypted) { if ($isEncrypted) {
@ -375,7 +372,7 @@ class EncryptAllTest extends TestCase {
} }
$this->assertTrue( $this->assertTrue(
$this->invokePrivate($this->encryptAll, 'encryptFile', ['foo.txt']) $this->invokePrivate($this->encryptAll, 'encryptFile', [$fileInfo, 'foo.txt'])
); );
} }

@ -13,59 +13,36 @@ use OCP\App\IAppManager;
use OCP\Encryption\IEncryptionModule; use OCP\Encryption\IEncryptionModule;
use OCP\Encryption\IManager; use OCP\Encryption\IManager;
use OCP\IConfig; use OCP\IConfig;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Test\TestCase; use Test\TestCase;
class EncryptAllTest extends TestCase { class EncryptAllTest extends TestCase {
/** @var \PHPUnit\Framework\MockObject\MockObject|IConfig */ private IConfig&MockObject $config;
protected $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 */ private EncryptAll $command;
protected $encryptionManager;
/** @var \PHPUnit\Framework\MockObject\MockObject|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|IEncryptionModule */
protected $encryptionModule;
/** @var EncryptAll */
protected $command;
protected function setUp(): void { protected function setUp(): void {
parent::setUp(); parent::setUp();
$this->config = $this->getMockBuilder(IConfig::class) $this->config = $this->createMock(IConfig::class);
->disableOriginalConstructor() $this->encryptionManager = $this->createMock(IManager::class);
->getMock(); $this->appManager = $this->createMock(IAppManager::class);
$this->encryptionManager = $this->getMockBuilder(IManager::class) $this->encryptionModule = $this->createMock(IEncryptionModule::class);
->disableOriginalConstructor() $this->questionHelper = $this->createMock(QuestionHelper::class);
->getMock(); $this->consoleInput = $this->createMock(InputInterface::class);
$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->consoleInput->expects($this->any()) $this->consoleInput->expects($this->any())
->method('isInteractive') ->method('isInteractive')
->willReturn(true); ->willReturn(true);
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock(); $this->consoleOutput = $this->createMock(OutputInterface::class);
} }
public function testEncryptAll(): void { public function testEncryptAll(): void {