Merge pull request #26192 from nextcloud/backport/25331/stable21
[stable21] Fix valid storages removed when cleaning remote storages
This commit is contained in:
commit
15cb3f0624
|
@ -794,7 +794,7 @@ steps:
|
||||||
- bash tests/drone-run-integration-tests.sh || exit 0
|
- bash tests/drone-run-integration-tests.sh || exit 0
|
||||||
- ./occ maintenance:install --admin-pass=admin
|
- ./occ maintenance:install --admin-pass=admin
|
||||||
- cd build/integration
|
- cd build/integration
|
||||||
- ./run.sh federation_features/federated.feature
|
- ./run.sh federation_features/
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
namespace OCA\Files_Sharing\Command;
|
namespace OCA\Files_Sharing\Command;
|
||||||
|
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
|
use OCP\Federation\ICloudIdManager;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -42,8 +43,14 @@ class CleanupRemoteStorages extends Command {
|
||||||
*/
|
*/
|
||||||
protected $connection;
|
protected $connection;
|
||||||
|
|
||||||
public function __construct(IDBConnection $connection) {
|
/**
|
||||||
|
* @var ICloudIdManager
|
||||||
|
*/
|
||||||
|
private $cloudIdManager;
|
||||||
|
|
||||||
|
public function __construct(IDBConnection $connection, ICloudIdManager $cloudIdManager) {
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
|
$this->cloudIdManager = $cloudIdManager;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,14 +173,17 @@ class CleanupRemoteStorages extends Command {
|
||||||
|
|
||||||
public function getRemoteShareIds() {
|
public function getRemoteShareIds() {
|
||||||
$queryBuilder = $this->connection->getQueryBuilder();
|
$queryBuilder = $this->connection->getQueryBuilder();
|
||||||
$queryBuilder->select(['id', 'share_token', 'remote'])
|
$queryBuilder->select(['id', 'share_token', 'owner', 'remote'])
|
||||||
->from('share_external');
|
->from('share_external');
|
||||||
$query = $queryBuilder->execute();
|
$query = $queryBuilder->execute();
|
||||||
|
|
||||||
$remoteShareIds = [];
|
$remoteShareIds = [];
|
||||||
|
|
||||||
while ($row = $query->fetch()) {
|
while ($row = $query->fetch()) {
|
||||||
$remoteShareIds[$row['id']] = 'shared::' . md5($row['share_token'] . '@' . $row['remote']);
|
$cloudId = $this->cloudIdManager->getCloudId($row['owner'], $row['remote']);
|
||||||
|
$remote = $cloudId->getRemote();
|
||||||
|
|
||||||
|
$remoteShareIds[$row['id']] = 'shared::' . md5($row['share_token'] . '@' . $remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $remoteShareIds;
|
return $remoteShareIds;
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
namespace OCA\Files_Sharing\Tests\Command;
|
namespace OCA\Files_Sharing\Tests\Command;
|
||||||
|
|
||||||
use OCA\Files_Sharing\Command\CleanupRemoteStorages;
|
use OCA\Files_Sharing\Command\CleanupRemoteStorages;
|
||||||
|
use OCP\Federation\ICloudId;
|
||||||
|
use OCP\Federation\ICloudIdManager;
|
||||||
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;
|
||||||
|
@ -49,6 +51,11 @@ class CleanupRemoteStoragesTest extends TestCase {
|
||||||
*/
|
*/
|
||||||
private $connection;
|
private $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject
|
||||||
|
*/
|
||||||
|
private $cloudIdManager;
|
||||||
|
|
||||||
private $storages = [
|
private $storages = [
|
||||||
['id' => 'shared::7b4a322b22f9d0047c38d77d471ce3cf', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e1', 'remote' => 'https://hostname.tld/owncloud1', 'user' => 'user1'],
|
['id' => 'shared::7b4a322b22f9d0047c38d77d471ce3cf', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e1', 'remote' => 'https://hostname.tld/owncloud1', 'user' => 'user1'],
|
||||||
['id' => 'shared::efe3b456112c3780da6155d3a9b9141c', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e2', 'remote' => 'https://hostname.tld/owncloud2', 'user' => 'user2'],
|
['id' => 'shared::efe3b456112c3780da6155d3a9b9141c', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e2', 'remote' => 'https://hostname.tld/owncloud2', 'user' => 'user2'],
|
||||||
|
@ -109,7 +116,9 @@ class CleanupRemoteStoragesTest extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->command = new CleanupRemoteStorages($this->connection);
|
$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
|
||||||
|
|
||||||
|
$this->command = new CleanupRemoteStorages($this->connection, $this->cloudIdManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void {
|
protected function tearDown(): void {
|
||||||
|
@ -191,6 +200,22 @@ class CleanupRemoteStoragesTest extends TestCase {
|
||||||
->method('writeln')
|
->method('writeln')
|
||||||
->with('5 remote share(s) exist');
|
->with('5 remote share(s) exist');
|
||||||
|
|
||||||
|
$this->cloudIdManager
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getCloudId')
|
||||||
|
->will($this->returnCallback(function (string $user, string $remote) {
|
||||||
|
$cloudIdMock = $this->createMock(ICloudId::class);
|
||||||
|
|
||||||
|
// The remotes are already sanitized in the original data, so
|
||||||
|
// they can be directly returned.
|
||||||
|
$cloudIdMock
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getRemote')
|
||||||
|
->willReturn($remote);
|
||||||
|
|
||||||
|
return $cloudIdMock;
|
||||||
|
}));
|
||||||
|
|
||||||
$this->command->execute($input, $output);
|
$this->command->execute($input, $output);
|
||||||
|
|
||||||
$this->assertTrue($this->doesStorageExist($this->storages[0]['numeric_id']));
|
$this->assertTrue($this->doesStorageExist($this->storages[0]['numeric_id']));
|
||||||
|
|
|
@ -37,6 +37,20 @@ require __DIR__ . '/../../vendor/autoload.php';
|
||||||
class FederationContext implements Context, SnippetAcceptingContext {
|
class FederationContext implements Context, SnippetAcceptingContext {
|
||||||
use WebDav;
|
use WebDav;
|
||||||
use AppConfiguration;
|
use AppConfiguration;
|
||||||
|
use CommandLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BeforeScenario
|
||||||
|
*/
|
||||||
|
public function cleanupRemoteStorages() {
|
||||||
|
// Ensure that dangling remote storages from previous tests will not
|
||||||
|
// interfere with the current scenario.
|
||||||
|
// The storages must be cleaned before each scenario; they can not be
|
||||||
|
// cleaned after each scenario, as this hook is executed before the hook
|
||||||
|
// that removes the users, so the shares would be still valid and thus
|
||||||
|
// the storages would not be dangling yet.
|
||||||
|
$this->runOcc(['sharing:cleanup-remote-storages']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given /^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with user "([^"]*)" from server "(LOCAL|REMOTE)"$/
|
* @Given /^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with user "([^"]*)" from server "(LOCAL|REMOTE)"$/
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
Feature: cleanup-remote-storage
|
||||||
|
Background:
|
||||||
|
Given using api version "1"
|
||||||
|
|
||||||
|
Scenario: cleanup remote storage with active storages
|
||||||
|
Given Using server "LOCAL"
|
||||||
|
And user "user0" exists
|
||||||
|
Given Using server "REMOTE"
|
||||||
|
And user "user1" exists
|
||||||
|
# Rename file so it has a unique name in the target server (as the target
|
||||||
|
# server may have its own /textfile0.txt" file)
|
||||||
|
And User "user1" copies file "/textfile0.txt" to "/remote-share.txt"
|
||||||
|
And User "user1" from server "REMOTE" shares "/remote-share.txt" with user "user0" from server "LOCAL"
|
||||||
|
And Using server "LOCAL"
|
||||||
|
# Accept and download the file to ensure that a storage is created for the
|
||||||
|
# federated share
|
||||||
|
And User "user0" from server "LOCAL" accepts last pending share
|
||||||
|
And As an "user0"
|
||||||
|
And Downloading file "/remote-share.txt"
|
||||||
|
And the HTTP status code should be "200"
|
||||||
|
When invoking occ with "sharing:cleanup-remote-storage"
|
||||||
|
Then the command was successful
|
||||||
|
And the command output contains the text "1 remote storage(s) need(s) to be checked"
|
||||||
|
And the command output contains the text "1 remote share(s) exist"
|
||||||
|
And the command output contains the text "no storages deleted"
|
||||||
|
|
||||||
|
Scenario: cleanup remote storage with inactive storages
|
||||||
|
Given Using server "LOCAL"
|
||||||
|
And user "user0" exists
|
||||||
|
Given Using server "REMOTE"
|
||||||
|
And user "user1" exists
|
||||||
|
# Rename file so it has a unique name in the target server (as the target
|
||||||
|
# server may have its own /textfile0.txt" file)
|
||||||
|
And User "user1" copies file "/textfile0.txt" to "/remote-share.txt"
|
||||||
|
And User "user1" from server "REMOTE" shares "/remote-share.txt" with user "user0" from server "LOCAL"
|
||||||
|
And Using server "LOCAL"
|
||||||
|
# Accept and download the file to ensure that a storage is created for the
|
||||||
|
# federated share
|
||||||
|
And User "user0" from server "LOCAL" accepts last pending share
|
||||||
|
And As an "user0"
|
||||||
|
And Downloading file "/remote-share.txt"
|
||||||
|
And the HTTP status code should be "200"
|
||||||
|
And Using server "REMOTE"
|
||||||
|
And As an "user1"
|
||||||
|
And Deleting last share
|
||||||
|
And the OCS status code should be "100"
|
||||||
|
And the HTTP status code should be "200"
|
||||||
|
When Using server "LOCAL"
|
||||||
|
And invoking occ with "sharing:cleanup-remote-storage"
|
||||||
|
Then the command was successful
|
||||||
|
And the command output contains the text "1 remote storage(s) need(s) to be checked"
|
||||||
|
And the command output contains the text "0 remote share(s) exist"
|
||||||
|
And the command output contains the text "deleted 1 storage"
|
Loading…
Reference in New Issue