Merge pull request #17739 from nextcloud/enh/share/filter
Get all shares iterable
This commit is contained in:
commit
fd475d4212
|
@ -1100,4 +1100,31 @@ class FederatedShareProvider implements IShareProvider {
|
|||
|
||||
return ['remote' => $remote];
|
||||
}
|
||||
|
||||
public function getAllShares(): iterable {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_REMOTE)),
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_REMOTE_GROUP))
|
||||
)
|
||||
);
|
||||
|
||||
$cursor = $qb->execute();
|
||||
while($data = $cursor->fetch()) {
|
||||
try {
|
||||
$share = $this->createShareObject($data);
|
||||
} catch (InvalidShare $e) {
|
||||
continue;
|
||||
} catch (ShareNotFound $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $share;
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1166,4 +1166,29 @@ class ShareByMailProvider implements IShareProvider {
|
|||
return ['public' => $mail];
|
||||
}
|
||||
|
||||
public function getAllShares(): iterable {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_EMAIL))
|
||||
)
|
||||
);
|
||||
|
||||
$cursor = $qb->execute();
|
||||
while($data = $cursor->fetch()) {
|
||||
try {
|
||||
$share = $this->createShareObject($data);
|
||||
} catch (InvalidShare $e) {
|
||||
continue;
|
||||
} catch (ShareNotFound $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $share;
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1382,4 +1382,30 @@ class DefaultShareProvider implements IShareProvider {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public function getAllShares(): iterable {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_USER)),
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_GROUP)),
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_LINK))
|
||||
)
|
||||
);
|
||||
|
||||
$cursor = $qb->execute();
|
||||
while($data = $cursor->fetch()) {
|
||||
try {
|
||||
$share = $this->createShare($data);
|
||||
} catch (InvalidShare $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $share;
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1671,4 +1671,11 @@ class Manager implements IManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getAllShares(): iterable {
|
||||
$providers = $this->factory->getAllProviders();
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
yield from $provider->getAllShares();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,4 +385,16 @@ interface IManager {
|
|||
*/
|
||||
public function shareProviderExists($shareType);
|
||||
|
||||
/**
|
||||
* @Internal
|
||||
*
|
||||
* Get all the shares as iterable to reduce memory overhead
|
||||
* Note, since this opens up database cursors the iterable should
|
||||
* be fully itterated.
|
||||
*
|
||||
* @return iterable
|
||||
* @since 18.0.0
|
||||
*/
|
||||
public function getAllShares(): iterable;
|
||||
|
||||
}
|
||||
|
|
|
@ -217,4 +217,13 @@ interface IShareProvider {
|
|||
* @since 12
|
||||
*/
|
||||
public function getAccessList($nodes, $currentAccess);
|
||||
|
||||
/**
|
||||
* Get all the shares in this provider returned as iterable to reduce memory
|
||||
* overhead
|
||||
*
|
||||
* @return iterable
|
||||
* @since 18.0.0
|
||||
*/
|
||||
public function getAllShares(): iterable;
|
||||
}
|
||||
|
|
|
@ -2742,4 +2742,169 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
$u5->delete();
|
||||
$g1->delete();
|
||||
}
|
||||
|
||||
public function testGetAllShares() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
|
||||
$qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
|
||||
'share_with' => $qb->expr()->literal('sharedWith1'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner1'),
|
||||
'uid_initiator' => $qb->expr()->literal('sharedBy1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(42),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(13),
|
||||
]);
|
||||
$qb->execute();
|
||||
|
||||
$id1 = $qb->getLastInsertId();
|
||||
|
||||
$qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP),
|
||||
'share_with' => $qb->expr()->literal('sharedWith2'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner2'),
|
||||
'uid_initiator' => $qb->expr()->literal('sharedBy2'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(43),
|
||||
'file_target' => $qb->expr()->literal('myTarget2'),
|
||||
'permissions' => $qb->expr()->literal(14),
|
||||
]);
|
||||
$qb->execute();
|
||||
|
||||
$id2 = $qb->getLastInsertId();
|
||||
|
||||
$qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK),
|
||||
'token' => $qb->expr()->literal('token3'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner3'),
|
||||
'uid_initiator' => $qb->expr()->literal('sharedBy3'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(44),
|
||||
'file_target' => $qb->expr()->literal('myTarget3'),
|
||||
'permissions' => $qb->expr()->literal(15),
|
||||
]);
|
||||
$qb->execute();
|
||||
|
||||
$id3 = $qb->getLastInsertId();
|
||||
|
||||
$qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_EMAIL),
|
||||
'share_with' => $qb->expr()->literal('shareOwner4'),
|
||||
'token' => $qb->expr()->literal('token4'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner4'),
|
||||
'uid_initiator' => $qb->expr()->literal('sharedBy4'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(45),
|
||||
'file_target' => $qb->expr()->literal('myTarget4'),
|
||||
'permissions' => $qb->expr()->literal(16),
|
||||
]);
|
||||
$qb->execute();
|
||||
|
||||
$id4 = $qb->getLastInsertId();
|
||||
|
||||
$qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK),
|
||||
'token' => $qb->expr()->literal('token5'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner5'),
|
||||
'uid_initiator' => $qb->expr()->literal('sharedBy5'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(46),
|
||||
'file_target' => $qb->expr()->literal('myTarget5'),
|
||||
'permissions' => $qb->expr()->literal(17),
|
||||
]);
|
||||
$qb->execute();
|
||||
|
||||
$id5 = $qb->getLastInsertId();
|
||||
|
||||
$ownerPath1 = $this->createMock(File::class);
|
||||
$shareOwner1Folder = $this->createMock(Folder::class);
|
||||
$shareOwner1Folder->method('getById')->willReturn([$ownerPath1]);
|
||||
|
||||
$ownerPath2 = $this->createMock(File::class);
|
||||
$shareOwner2Folder = $this->createMock(Folder::class);
|
||||
$shareOwner2Folder->method('getById')->willReturn([$ownerPath2]);
|
||||
|
||||
$ownerPath3 = $this->createMock(File::class);
|
||||
$shareOwner3Folder = $this->createMock(Folder::class);
|
||||
$shareOwner3Folder->method('getById')->willReturn([$ownerPath3]);
|
||||
|
||||
$ownerPath4 = $this->createMock(File::class);
|
||||
$shareOwner4Folder = $this->createMock(Folder::class);
|
||||
$shareOwner4Folder->method('getById')->willReturn([$ownerPath4]);
|
||||
|
||||
$ownerPath5 = $this->createMock(File::class);
|
||||
$shareOwner5Folder = $this->createMock(Folder::class);
|
||||
$shareOwner5Folder->method('getById')->willReturn([$ownerPath5]);
|
||||
|
||||
$this->rootFolder
|
||||
->method('getUserFolder')
|
||||
->will($this->returnValueMap(
|
||||
[
|
||||
['shareOwner1', $shareOwner1Folder],
|
||||
['shareOwner2', $shareOwner2Folder],
|
||||
['shareOwner3', $shareOwner3Folder],
|
||||
['shareOwner4', $shareOwner4Folder],
|
||||
['shareOwner5', $shareOwner5Folder],
|
||||
]
|
||||
));
|
||||
|
||||
$shares = iterator_to_array($this->provider->getAllShares());
|
||||
$this->assertEquals(4, count($shares));
|
||||
|
||||
$share = $shares[0];
|
||||
|
||||
// We fetch the node so the root folder is eventually called
|
||||
|
||||
$this->assertEquals($id1, $share->getId());
|
||||
$this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType());
|
||||
$this->assertEquals('sharedWith1', $share->getSharedWith());
|
||||
$this->assertEquals('sharedBy1', $share->getSharedBy());
|
||||
$this->assertEquals('shareOwner1', $share->getShareOwner());
|
||||
$this->assertEquals($ownerPath1, $share->getNode());
|
||||
$this->assertEquals(13, $share->getPermissions());
|
||||
$this->assertEquals(null, $share->getToken());
|
||||
$this->assertEquals('myTarget1', $share->getTarget());
|
||||
|
||||
$share = $shares[1];
|
||||
|
||||
$this->assertEquals($id2, $share->getId());
|
||||
$this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType());
|
||||
$this->assertEquals('sharedWith2', $share->getSharedWith());
|
||||
$this->assertEquals('sharedBy2', $share->getSharedBy());
|
||||
$this->assertEquals('shareOwner2', $share->getShareOwner());
|
||||
$this->assertEquals($ownerPath2, $share->getNode());
|
||||
$this->assertEquals(14, $share->getPermissions());
|
||||
$this->assertEquals(null, $share->getToken());
|
||||
$this->assertEquals('myTarget2', $share->getTarget());
|
||||
|
||||
$share = $shares[2];
|
||||
|
||||
$this->assertEquals($id3, $share->getId());
|
||||
$this->assertEquals(\OCP\Share::SHARE_TYPE_LINK, $share->getShareType());
|
||||
$this->assertEquals(null, $share->getSharedWith());
|
||||
$this->assertEquals('sharedBy3', $share->getSharedBy());
|
||||
$this->assertEquals('shareOwner3', $share->getShareOwner());
|
||||
$this->assertEquals($ownerPath3, $share->getNode());
|
||||
$this->assertEquals(15, $share->getPermissions());
|
||||
$this->assertEquals('token3', $share->getToken());
|
||||
$this->assertEquals('myTarget3', $share->getTarget());
|
||||
|
||||
$share = $shares[3];
|
||||
|
||||
$this->assertEquals($id5, $share->getId());
|
||||
$this->assertEquals(\OCP\Share::SHARE_TYPE_LINK, $share->getShareType());
|
||||
$this->assertEquals(null, $share->getSharedWith());
|
||||
$this->assertEquals('sharedBy5', $share->getSharedBy());
|
||||
$this->assertEquals('shareOwner5', $share->getShareOwner());
|
||||
$this->assertEquals($ownerPath5, $share->getNode());
|
||||
$this->assertEquals(17, $share->getPermissions());
|
||||
$this->assertEquals('token5', $share->getToken());
|
||||
$this->assertEquals('myTarget5', $share->getTarget());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3685,6 +3685,57 @@ class ManagerTest extends \Test\TestCase {
|
|||
$this->assertSame($expected['users'], $result['users']);
|
||||
|
||||
}
|
||||
|
||||
public function testGetAllShares() {
|
||||
$factory = new DummyFactory2($this->createMock(IServerContainer::class));
|
||||
|
||||
$manager = new Manager(
|
||||
$this->logger,
|
||||
$this->config,
|
||||
$this->secureRandom,
|
||||
$this->hasher,
|
||||
$this->mountManager,
|
||||
$this->groupManager,
|
||||
$this->l,
|
||||
$this->l10nFactory,
|
||||
$factory,
|
||||
$this->userManager,
|
||||
$this->rootFolder,
|
||||
$this->eventDispatcher,
|
||||
$this->mailer,
|
||||
$this->urlGenerator,
|
||||
$this->defaults
|
||||
);
|
||||
|
||||
$factory->setProvider($this->defaultProvider);
|
||||
$extraProvider = $this->createMock(IShareProvider::class);
|
||||
$factory->setSecondProvider($extraProvider);
|
||||
|
||||
$share1 = $this->createMock(IShare::class);
|
||||
$share2 = $this->createMock(IShare::class);
|
||||
$share3 = $this->createMock(IShare::class);
|
||||
$share4 = $this->createMock(IShare::class);
|
||||
|
||||
$this->defaultProvider->method('getAllShares')
|
||||
->willReturnCallback(function() use ($share1, $share2) {
|
||||
yield $share1;
|
||||
yield $share2;
|
||||
});
|
||||
$extraProvider->method('getAllShares')
|
||||
->willReturnCallback(function() use ($share3, $share4) {
|
||||
yield $share3;
|
||||
yield $share4;
|
||||
});
|
||||
|
||||
// "yield from", used in "getAllShares()", does not reset the keys, so
|
||||
// "use_keys" has to be disabled to collect all the values while
|
||||
// ignoring the keys returned by the generator.
|
||||
$result = iterator_to_array($manager->getAllShares(), $use_keys = false);
|
||||
|
||||
$expects = [$share1, $share2, $share3, $share4];
|
||||
|
||||
$this->assertSame($expects, $result);
|
||||
}
|
||||
}
|
||||
|
||||
class DummyFactory implements IProviderFactory {
|
||||
|
|
Loading…
Reference in New Issue