Signed-off-by: Luka Trovic <luka@nextcloud.com>pull/43025/head
parent
8995272f60
commit
2ca51919db
@ -0,0 +1,65 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
/** |
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
namespace OCA\Files_Sharing\Command; |
||||
|
||||
use OC\Core\Command\Base; |
||||
use OCA\Files_Sharing\OrphanHelper; |
||||
use Symfony\Component\Console\Input\InputInterface; |
||||
use Symfony\Component\Console\Input\InputOption; |
||||
use Symfony\Component\Console\Output\OutputInterface; |
||||
|
||||
class FixShareOwners extends Base { |
||||
public function __construct( |
||||
private readonly OrphanHelper $orphanHelper, |
||||
) { |
||||
parent::__construct(); |
||||
} |
||||
|
||||
protected function configure(): void { |
||||
$this |
||||
->setName('sharing:fix-share-owners') |
||||
->setDescription('Fix owner of broken shares after transfer ownership on old versions') |
||||
->addOption( |
||||
'dry-run', |
||||
null, |
||||
InputOption::VALUE_NONE, |
||||
'only show which shares would be updated' |
||||
); |
||||
} |
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output): int { |
||||
$shares = $this->orphanHelper->getAllShares(); |
||||
$dryRun = $input->getOption('dry-run'); |
||||
$count = 0; |
||||
|
||||
foreach ($shares as $share) { |
||||
if ($this->orphanHelper->isShareValid($share['owner'], $share['fileid']) || !$this->orphanHelper->fileExists($share['fileid'])) { |
||||
continue; |
||||
} |
||||
|
||||
$owner = $this->orphanHelper->findOwner($share['fileid']); |
||||
|
||||
if ($owner !== null) { |
||||
if ($dryRun) { |
||||
$output->writeln("Share with id <info>{$share['id']}</info> (target: <info>{$share['target']}</info>) can be updated to owner <info>$owner</info>"); |
||||
} else { |
||||
$this->orphanHelper->updateShareOwner($share['id'], $owner); |
||||
$output->writeln("Share with id <info>{$share['id']}</info> (target: <info>{$share['target']}</info>) updated to owner <info>$owner</info>"); |
||||
} |
||||
$count++; |
||||
} |
||||
} |
||||
|
||||
if ($count === 0) { |
||||
$output->writeln('No broken shares detected'); |
||||
} |
||||
|
||||
return static::SUCCESS; |
||||
} |
||||
} |
@ -0,0 +1,116 @@ |
||||
<?php |
||||
/** |
||||
* SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-only |
||||
*/ |
||||
namespace OCA\Files_Sharing\Tests\Command; |
||||
|
||||
use OCA\Files_Sharing\Command\FixShareOwners; |
||||
use OCA\Files_Sharing\OrphanHelper; |
||||
use Symfony\Component\Console\Input\InputInterface; |
||||
use Symfony\Component\Console\Output\OutputInterface; |
||||
use Test\TestCase; |
||||
|
||||
/** |
||||
* Class FixShareOwnersTest |
||||
* |
||||
* @package OCA\Files_Sharing\Tests\Command |
||||
*/ |
||||
class FixShareOwnersTest extends TestCase { |
||||
/** |
||||
* @var FixShareOwners |
||||
*/ |
||||
private $command; |
||||
|
||||
/** |
||||
* @var OrphanHelper|\PHPUnit\Framework\MockObject\MockObject |
||||
*/ |
||||
private $orphanHelper; |
||||
|
||||
protected function setUp(): void { |
||||
parent::setUp(); |
||||
|
||||
$this->orphanHelper = $this->createMock(OrphanHelper::class); |
||||
$this->command = new FixShareOwners($this->orphanHelper); |
||||
} |
||||
|
||||
public function testExecuteNoSharesDetected() { |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('getAllShares') |
||||
->willReturn([ |
||||
['id' => 1, 'owner' => 'user1', 'fileid' => 1, 'target' => 'target1'], |
||||
['id' => 2, 'owner' => 'user2', 'fileid' => 2, 'target' => 'target2'], |
||||
]); |
||||
$this->orphanHelper->expects($this->exactly(2)) |
||||
->method('isShareValid') |
||||
->willReturn(true); |
||||
|
||||
$input = $this->createMock(InputInterface::class); |
||||
$output = $this->createMock(OutputInterface::class); |
||||
|
||||
$output->expects($this->once()) |
||||
->method('writeln') |
||||
->with('No broken shares detected'); |
||||
$this->command->execute($input, $output); |
||||
} |
||||
|
||||
public function testExecuteSharesDetected() { |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('getAllShares') |
||||
->willReturn([ |
||||
['id' => 1, 'owner' => 'user1', 'fileid' => 1, 'target' => 'target1'], |
||||
['id' => 2, 'owner' => 'user2', 'fileid' => 2, 'target' => 'target2'], |
||||
]); |
||||
$this->orphanHelper->expects($this->exactly(2)) |
||||
->method('isShareValid') |
||||
->willReturnOnConsecutiveCalls(true, false); |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('fileExists') |
||||
->willReturn(true); |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('findOwner') |
||||
->willReturn('newOwner'); |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('updateShareOwner'); |
||||
|
||||
$input = $this->createMock(InputInterface::class); |
||||
$output = $this->createMock(OutputInterface::class); |
||||
|
||||
$output->expects($this->once()) |
||||
->method('writeln') |
||||
->with('Share with id <info>2</info> (target: <info>target2</info>) updated to owner <info>newOwner</info>'); |
||||
$this->command->execute($input, $output); |
||||
} |
||||
|
||||
public function testExecuteSharesDetectedDryRun() { |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('getAllShares') |
||||
->willReturn([ |
||||
['id' => 1, 'owner' => 'user1', 'fileid' => 1, 'target' => 'target1'], |
||||
['id' => 2, 'owner' => 'user2', 'fileid' => 2, 'target' => 'target2'], |
||||
]); |
||||
$this->orphanHelper->expects($this->exactly(2)) |
||||
->method('isShareValid') |
||||
->willReturnOnConsecutiveCalls(true, false); |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('fileExists') |
||||
->willReturn(true); |
||||
$this->orphanHelper->expects($this->once()) |
||||
->method('findOwner') |
||||
->willReturn('newOwner'); |
||||
$this->orphanHelper->expects($this->never()) |
||||
->method('updateShareOwner'); |
||||
|
||||
$input = $this->createMock(InputInterface::class); |
||||
$output = $this->createMock(OutputInterface::class); |
||||
|
||||
$output->expects($this->once()) |
||||
->method('writeln') |
||||
->with('Share with id <info>2</info> (target: <info>target2</info>) can be updated to owner <info>newOwner</info>'); |
||||
$input->expects($this->once()) |
||||
->method('getOption') |
||||
->with('dry-run') |
||||
->willReturn(true); |
||||
$this->command->execute($input, $output); |
||||
} |
||||
} |
Loading…
Reference in new issue