mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge pull request #57292 from nextcloud/feature/54562/files-sharing-authoritative
feat(files_sharing): implement partial mount providers
This commit is contained in:
commit
2716b0f6a6
11 changed files with 268 additions and 44 deletions
|
|
@ -14,7 +14,7 @@
|
|||
Turning the feature off removes shared files and folders on the server for all share recipients, and also on the sync clients and mobile apps. More information is available in the Nextcloud Documentation.
|
||||
|
||||
</description>
|
||||
<version>1.25.1</version>
|
||||
<version>1.25.2</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Michael Gapczynski</author>
|
||||
<author>Bjoern Schiessle</author>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use OCA\Files_Sharing\External\Storage as ExternalShareStorage;
|
|||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\Files\Config\IMountProvider;
|
||||
use OCP\Files\Config\IPartialMountProvider;
|
||||
use OCP\Files\Storage\IStorageFactory;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\ICertificateManager;
|
||||
|
|
@ -21,7 +22,7 @@ use OCP\IUser;
|
|||
use OCP\Server;
|
||||
use OCP\Share\IShare;
|
||||
|
||||
class MountProvider implements IMountProvider {
|
||||
class MountProvider implements IMountProvider, IPartialMountProvider {
|
||||
public const STORAGE = ExternalShareStorage::class;
|
||||
|
||||
/**
|
||||
|
|
@ -69,4 +70,54 @@ class MountProvider implements IMountProvider {
|
|||
$result->closeCursor();
|
||||
return $mounts;
|
||||
}
|
||||
|
||||
public function getMountsForPath(
|
||||
string $setupPathHint,
|
||||
bool $forChildren,
|
||||
array $mountProviderArgs,
|
||||
IStorageFactory $loader,
|
||||
): array {
|
||||
$user = $mountProviderArgs[0]->mountInfo->getUser();
|
||||
$userId = $user->getUID();
|
||||
|
||||
if (!$forChildren) {
|
||||
// override path with mount point when fetching without children
|
||||
$setupPathHint = $mountProviderArgs[0]->mountInfo->getMountPoint();
|
||||
}
|
||||
|
||||
// remove /uid/files as the target is stored without
|
||||
$setupPathHint = \substr($setupPathHint, \strlen('/' . $userId . '/files'));
|
||||
// remove trailing slash
|
||||
$setupPathHint = \rtrim($setupPathHint, '/');
|
||||
|
||||
// make sure trailing slash is present when loading children
|
||||
if ($forChildren || $setupPathHint === '') {
|
||||
$setupPathHint .= '/';
|
||||
}
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->select('id', 'remote', 'share_token', 'password', 'mountpoint', 'owner')
|
||||
->from('share_external')
|
||||
->where($qb->expr()->eq('user', $qb->createNamedParameter($user->getUID())))
|
||||
->andWhere($qb->expr()->eq('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED, IQueryBuilder::PARAM_INT)));
|
||||
|
||||
if ($forChildren) {
|
||||
$qb->andWhere($qb->expr()->like('mountpoint', $qb->createNamedParameter($this->connection->escapeLikeParameter($setupPathHint) . '_%')));
|
||||
} else {
|
||||
$qb->andWhere($qb->expr()->eq('mountpoint', $qb->createNamedParameter($setupPathHint)));
|
||||
}
|
||||
|
||||
$result = $qb->executeQuery();
|
||||
|
||||
$mounts = [];
|
||||
while ($row = $result->fetchAssociative()) {
|
||||
$row['manager'] = $this;
|
||||
$row['token'] = $row['share_token'];
|
||||
$mount = $this->getMount($user, $row, $loader);
|
||||
$mounts[$mount->getMountPoint()] = $mount;
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return $mounts;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ class Version11300Date20201120141438 extends SimpleMigrationStep {
|
|||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
$table->addUniqueIndex(['user', 'mountpoint_hash'], 'sh_external_mp');
|
||||
$table->addIndex(['user', 'mountpoint'], 'user_mountpoint_index', [], ['lengths' => [null, 128]]);
|
||||
} else {
|
||||
$table = $schema->getTable('share_external');
|
||||
$remoteIdColumn = $table->getColumn('remote_id');
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use OCA\Files_Sharing\Event\ShareMountedEvent;
|
|||
use OCP\Cache\CappedMemoryCache;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Config\IMountProvider;
|
||||
use OCP\Files\Config\IPartialMountProvider;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorageFactory;
|
||||
|
|
@ -24,9 +25,10 @@ use OCP\Share\IAttributes;
|
|||
use OCP\Share\IManager;
|
||||
use OCP\Share\IShare;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
use function count;
|
||||
|
||||
class MountProvider implements IMountProvider {
|
||||
class MountProvider implements IMountProvider, IPartialMountProvider {
|
||||
/**
|
||||
* @param IConfig $config
|
||||
* @param IManager $shareManager
|
||||
|
|
@ -51,7 +53,7 @@ class MountProvider implements IMountProvider {
|
|||
*/
|
||||
public function getMountsForUser(IUser $user, IStorageFactory $loader) {
|
||||
$userId = $user->getUID();
|
||||
$shares = array_merge(
|
||||
$shares = $this->mergeIterables(
|
||||
$this->shareManager->getSharedWith($userId, IShare::TYPE_USER, null, -1),
|
||||
$this->shareManager->getSharedWith($userId, IShare::TYPE_GROUP, null, -1),
|
||||
$this->shareManager->getSharedWith($userId, IShare::TYPE_CIRCLE, null, -1),
|
||||
|
|
@ -62,17 +64,24 @@ class MountProvider implements IMountProvider {
|
|||
$shares = $this->filterShares($shares, $userId);
|
||||
$superShares = $this->buildSuperShares($shares, $user);
|
||||
|
||||
return $this->getMountsFromSuperShares($userId, $superShares, $loader, $user);
|
||||
return array_values(
|
||||
$this->getMountsFromSuperShares(
|
||||
$userId,
|
||||
$superShares,
|
||||
$loader,
|
||||
$user,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups shares by path (nodeId) and target path
|
||||
*
|
||||
* @param IShare[] $shares
|
||||
* @param iterable<IShare> $shares
|
||||
* @return IShare[][] array of grouped shares, each element in the
|
||||
* array is a group which itself is an array of shares
|
||||
*/
|
||||
private function groupShares(array $shares) {
|
||||
private function groupShares(iterable $shares): array {
|
||||
$tmp = [];
|
||||
|
||||
foreach ($shares as $share) {
|
||||
|
|
@ -108,11 +117,11 @@ class MountProvider implements IMountProvider {
|
|||
* the shares in the group, forming the most permissive combination
|
||||
* possible.
|
||||
*
|
||||
* @param IShare[] $allShares
|
||||
* @param iterable<IShare> $allShares
|
||||
* @param IUser $user user
|
||||
* @return list<array{IShare, array<IShare>}> Tuple of [superShare, groupedShares]
|
||||
*/
|
||||
private function buildSuperShares(array $allShares, IUser $user) {
|
||||
private function buildSuperShares(iterable $allShares, IUser $user): array {
|
||||
$result = [];
|
||||
|
||||
$groupedShares = $this->groupShares($allShares);
|
||||
|
|
@ -237,8 +246,7 @@ class MountProvider implements IMountProvider {
|
|||
// null groups which usually appear with group backend
|
||||
// caching inconsistencies
|
||||
$this->logger->debug(
|
||||
'Could not adjust share target for share ' . $share->getId(
|
||||
) . ' to make it consistent: ' . $e->getMessage(),
|
||||
'Could not adjust share target for share ' . $share->getId() . ' to make it consistent: ' . $e->getMessage(),
|
||||
['app' => 'files_sharing']
|
||||
);
|
||||
}
|
||||
|
|
@ -248,7 +256,7 @@ class MountProvider implements IMountProvider {
|
|||
* @param array $superShares
|
||||
* @param IStorageFactory $loader
|
||||
* @param IUser $user
|
||||
* @return array
|
||||
* @return array IMountPoint indexed by mount point
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getMountsFromSuperShares(
|
||||
|
|
@ -261,13 +269,11 @@ class MountProvider implements IMountProvider {
|
|||
$mounts = [];
|
||||
$view = new View('/' . $userId . '/files');
|
||||
$ownerViews = [];
|
||||
$sharingDisabledForUser
|
||||
= $this->shareManager->sharingDisabledForUser($userId);
|
||||
$sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($userId);
|
||||
/** @var CappedMemoryCache<bool> $folderExistCache */
|
||||
$foldersExistCache = new CappedMemoryCache();
|
||||
|
||||
$validShareCache
|
||||
= $this->cacheFactory->createLocal('share-valid-mountpoint-max');
|
||||
$validShareCache = $this->cacheFactory->createLocal('share-valid-mountpoint-max');
|
||||
$maxValidatedShare = $validShareCache->get($userId) ?? 0;
|
||||
$newMaxValidatedShare = $maxValidatedShare;
|
||||
|
||||
|
|
@ -312,12 +318,10 @@ class MountProvider implements IMountProvider {
|
|||
$event = new ShareMountedEvent($mount);
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
|
||||
$mounts[$mount->getMountPoint()]
|
||||
= $allMounts[$mount->getMountPoint()] = $mount;
|
||||
$mounts[$mount->getMountPoint()] = $allMounts[$mount->getMountPoint()] = $mount;
|
||||
foreach ($event->getAdditionalMounts() as $additionalMount) {
|
||||
$allMounts[$additionalMount->getMountPoint()]
|
||||
= $mounts[$additionalMount->getMountPoint()]
|
||||
= $additionalMount;
|
||||
$mounts[$additionalMount->getMountPoint()] = $additionalMount;
|
||||
$allMounts[$additionalMount->getMountPoint()] = $additionalMount;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error(
|
||||
|
|
@ -333,24 +337,74 @@ class MountProvider implements IMountProvider {
|
|||
$validShareCache->set($userId, $newMaxValidatedShare, 24 * 60 * 60);
|
||||
|
||||
// array_filter removes the null values from the array
|
||||
return array_values(array_filter($mounts));
|
||||
return array_filter($mounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out shares owned or shared by the user and ones for which the
|
||||
* user has no permissions.
|
||||
*
|
||||
* @param IShare[] $shares
|
||||
* @return IShare[]
|
||||
* @param iterable<IShare> $shares
|
||||
* @return iterable<IShare>
|
||||
*/
|
||||
private function filterShares(array $shares, string $userId): array {
|
||||
return array_filter(
|
||||
$shares,
|
||||
static function (IShare $share) use ($userId) {
|
||||
return $share->getPermissions() > 0
|
||||
&& $share->getShareOwner() !== $userId
|
||||
&& $share->getSharedBy() !== $userId;
|
||||
private function filterShares(iterable $shares, string $userId): iterable {
|
||||
foreach ($shares as $share) {
|
||||
if (
|
||||
$share->getPermissions() > 0
|
||||
&& $share->getShareOwner() !== $userId
|
||||
&& $share->getSharedBy() !== $userId
|
||||
) {
|
||||
yield $share;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getMountsForPath(
|
||||
string $setupPathHint,
|
||||
bool $forChildren,
|
||||
array $mountProviderArgs,
|
||||
IStorageFactory $loader,
|
||||
): array {
|
||||
$limit = -1;
|
||||
$user = $mountProviderArgs[0]->mountInfo->getUser();
|
||||
$userId = $user->getUID();
|
||||
|
||||
if (!$forChildren) {
|
||||
// override path with mount point when fetching without children
|
||||
$setupPathHint = $mountProviderArgs[0]->mountInfo->getMountPoint();
|
||||
}
|
||||
|
||||
// remove /uid/files as the target is stored without
|
||||
$setupPathHint = \substr($setupPathHint, \strlen('/' . $userId . '/files'));
|
||||
// remove trailing slash
|
||||
$setupPathHint = \rtrim($setupPathHint, '/');
|
||||
|
||||
// make sure trailing slash is present when loading children
|
||||
if ($forChildren || $setupPathHint === '') {
|
||||
$setupPathHint .= '/';
|
||||
}
|
||||
|
||||
$shares = $this->mergeIterables(
|
||||
$this->shareManager->getSharedWithByPath($userId, IShare::TYPE_USER, $setupPathHint, $forChildren, $limit),
|
||||
$this->shareManager->getSharedWithByPath($userId, IShare::TYPE_GROUP, $setupPathHint, $forChildren, $limit),
|
||||
$this->shareManager->getSharedWithByPath($userId, IShare::TYPE_CIRCLE, $setupPathHint, $forChildren, $limit),
|
||||
$this->shareManager->getSharedWithByPath($userId, IShare::TYPE_ROOM, $setupPathHint, $forChildren, $limit),
|
||||
$this->shareManager->getSharedWithByPath($userId, IShare::TYPE_DECK, $setupPathHint, $forChildren, $limit),
|
||||
);
|
||||
|
||||
$shares = $this->filterShares($shares, $userId);
|
||||
$superShares = $this->buildSuperShares($shares, $user);
|
||||
|
||||
return $this->getMountsFromSuperShares($userId, $superShares, $loader, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iterable ...$iterables
|
||||
* @return iterable
|
||||
*/
|
||||
private function mergeIterables(...$iterables): iterable {
|
||||
foreach ($iterables as $iterable) {
|
||||
yield from $iterable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,17 @@
|
|||
*/
|
||||
namespace OCA\Files_Sharing\Tests;
|
||||
|
||||
use OC\Memcache\NullCache;
|
||||
use OC\Share20\Share;
|
||||
use OCA\Files_Sharing\MountProvider;
|
||||
use OCA\Files_Sharing\SharedMount;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Cache\ICacheEntry;
|
||||
use OCP\Files\Config\ICachedMountInfo;
|
||||
use OCP\Files\Config\MountProviderArgs;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use OCP\Files\Storage\IStorageFactory;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUser;
|
||||
|
|
@ -35,6 +38,7 @@ class MountProviderTest extends \Test\TestCase {
|
|||
protected IManager&MockObject $shareManager;
|
||||
protected IStorageFactory&MockObject $loader;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
private ICache&MockObject $cache;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -45,9 +49,10 @@ class MountProviderTest extends \Test\TestCase {
|
|||
$this->shareManager = $this->getMockBuilder(IManager::class)->getMock();
|
||||
$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
|
||||
$eventDispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$this->cache = $this->createMock(ICache::class);
|
||||
$this->cache->method('get')->willReturn(true);
|
||||
$cacheFactory = $this->createMock(ICacheFactory::class);
|
||||
$cacheFactory->method('createLocal')
|
||||
->willReturn(new NullCache());
|
||||
$cacheFactory->method('createLocal')->willReturn($this->cache);
|
||||
$mountManager = $this->createMock(IMountManager::class);
|
||||
|
||||
$this->provider = new MountProvider($this->config, $this->shareManager, $this->logger, $eventDispatcher, $cacheFactory, $mountManager);
|
||||
|
|
@ -355,7 +360,6 @@ class MountProviderTest extends \Test\TestCase {
|
|||
$circleShares = [];
|
||||
$roomShares = [];
|
||||
$deckShares = [];
|
||||
$scienceMeshShares = [];
|
||||
$this->shareManager->expects($this->exactly(5))
|
||||
->method('getSharedWith')
|
||||
->willReturnMap([
|
||||
|
|
@ -402,4 +406,90 @@ class MountProviderTest extends \Test\TestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'mergeSharesDataProvider')]
|
||||
public function testMergeSharesInGetMountsForPath(array $userShares, array $groupShares, array $expectedShares, bool $moveFails = false): void {
|
||||
$rootFolder = $this->createMock(IRootFolder::class);
|
||||
$userManager = $this->createMock(IUserManager::class);
|
||||
|
||||
$userShares = array_map(function ($shareSpec) {
|
||||
return $this->makeMockShare($shareSpec[0], $shareSpec[1], $shareSpec[2], $shareSpec[3], $shareSpec[4], $shareSpec[5]);
|
||||
}, $userShares);
|
||||
$groupShares = array_map(function ($shareSpec) {
|
||||
return $this->makeMockShare($shareSpec[0], $shareSpec[1], $shareSpec[2], $shareSpec[3], $shareSpec[4], $shareSpec[5]);
|
||||
}, $groupShares);
|
||||
|
||||
$this->user->expects($this->any())
|
||||
->method('getUID')
|
||||
->willReturn('user1');
|
||||
|
||||
// tests regarding circles are made in the app itself.
|
||||
$circleShares = [];
|
||||
$roomShares = [];
|
||||
$deckShares = [];
|
||||
$path = '/';
|
||||
|
||||
// no expected shares? then no calls are performed to providers
|
||||
$expectedProviderCalls = \count($expectedShares) ? 5 : 0;
|
||||
$this->shareManager->expects($this->exactly($expectedProviderCalls))
|
||||
->method('getSharedWithByPath')
|
||||
->willReturnMap([
|
||||
['user1', IShare::TYPE_USER, $path, true, -1, 0, $userShares],
|
||||
['user1', IShare::TYPE_GROUP, $path, true, -1, 0, $groupShares],
|
||||
['user1', IShare::TYPE_CIRCLE, $path, true, -1, 0, $circleShares],
|
||||
['user1', IShare::TYPE_ROOM, $path, true, -1, 0, $roomShares],
|
||||
['user1', IShare::TYPE_DECK, $path, true, -1, 0, $deckShares],
|
||||
]);
|
||||
|
||||
$this->shareManager->expects($this->any())
|
||||
->method('newShare')
|
||||
->willReturnCallback(function () use ($rootFolder, $userManager) {
|
||||
return new Share($rootFolder, $userManager);
|
||||
});
|
||||
|
||||
if ($moveFails) {
|
||||
$this->shareManager->expects($this->any())
|
||||
->method('moveShare')
|
||||
->willThrowException(new \InvalidArgumentException());
|
||||
}
|
||||
|
||||
$mountArgs = [];
|
||||
foreach ($expectedShares as $share) {
|
||||
$mountInfo = $this->createMock(ICachedMountInfo::class);
|
||||
$mountInfo->method('getUser')->willReturn($this->user);
|
||||
$mountInfo->method('getRootId')->willReturn($share[1]);
|
||||
$rootCacheEntry = $this->createMock(ICacheEntry::class);
|
||||
$mountArg = new MountProviderArgs($mountInfo, $rootCacheEntry);
|
||||
$mountArgs[] = $mountArg;
|
||||
}
|
||||
|
||||
if (count($mountArgs) === 0) {
|
||||
$mounts = [];
|
||||
} else {
|
||||
$mounts = $this->provider->getMountsForPath('/', true, $mountArgs, $this->loader);
|
||||
}
|
||||
|
||||
|
||||
$this->assertCount(\count($expectedShares), $mounts);
|
||||
|
||||
foreach (array_values($mounts) as $index => $mount) {
|
||||
$expectedShare = $expectedShares[$index];
|
||||
$this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mount);
|
||||
|
||||
// supershare
|
||||
/** @var SharedMount $mount */
|
||||
$share = $mount->getShare();
|
||||
|
||||
$this->assertEquals($expectedShare[0], $share->getId());
|
||||
$this->assertEquals($expectedShare[1], $share->getNodeId());
|
||||
$this->assertEquals($expectedShare[2], $share->getShareOwner());
|
||||
$this->assertEquals($expectedShare[3], $share->getTarget());
|
||||
$this->assertEquals($expectedShare[4], $share->getPermissions());
|
||||
if ($expectedShare[5] === null) {
|
||||
$this->assertNull($share->getAttributes());
|
||||
} else {
|
||||
$this->assertEquals($expectedShare[5], $share->getAttributes()->toArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,5 +210,19 @@ class AddMissingIndicesListener implements IEventListener {
|
|||
'unique_category_per_user',
|
||||
['uid', 'type', 'category']
|
||||
);
|
||||
|
||||
$event->addMissingIndex(
|
||||
'share',
|
||||
'share_with_file_target_index',
|
||||
['share_with', 'file_target'],
|
||||
['lengths' => [null, 128]]
|
||||
);
|
||||
|
||||
$event->addMissingIndex(
|
||||
'share_external',
|
||||
'user_mountpoint_index',
|
||||
['user', 'mountpoint'],
|
||||
['lengths' => [null, 128]]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep {
|
|||
$table->addIndex(['file_source'], 'file_source_index');
|
||||
$table->addIndex(['token'], 'token_index');
|
||||
$table->addIndex(['share_with'], 'share_with_index');
|
||||
$table->addIndex(['share_with', 'file_target'], 'share_with_file_target_index', [], ['lengths' => [null, 128]]);
|
||||
$table->addIndex(['parent'], 'parent_index');
|
||||
$table->addIndex(['uid_owner'], 'owner_index');
|
||||
$table->addIndex(['uid_initiator'], 'initiator_index');
|
||||
|
|
|
|||
|
|
@ -111,6 +111,17 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
|
|||
);
|
||||
}
|
||||
|
||||
$userId = null;
|
||||
$user = null;
|
||||
foreach ($mountProviderArgs as $mountProviderArg) {
|
||||
if ($userId === null) {
|
||||
$user = $mountProviderArg->mountInfo->getUser();
|
||||
$userId = $user->getUID();
|
||||
} elseif ($userId !== $mountProviderArg->mountInfo->getUser()->getUID()) {
|
||||
throw new \LogicException('Mounts must belong to the same user!');
|
||||
}
|
||||
}
|
||||
|
||||
return $provider->getMountsForPath(
|
||||
$path,
|
||||
$forChildren,
|
||||
|
|
|
|||
|
|
@ -507,8 +507,7 @@ class SetupManager {
|
|||
$mountProvider = $cachedMount->getMountProvider();
|
||||
$mountPoint = $cachedMount->getMountPoint();
|
||||
$isMountProviderSetup = in_array($mountProvider, $setupProviders);
|
||||
$isPathSetupAsAuthoritative
|
||||
= $this->isPathSetup($mountPoint);
|
||||
$isPathSetupAsAuthoritative = $this->isPathSetup($mountPoint);
|
||||
if (!$isMountProviderSetup && !$isPathSetupAsAuthoritative) {
|
||||
if ($mountProvider === '') {
|
||||
$this->logger->debug('mount at ' . $cachedMount->getMountPoint() . ' has no provider set, performing full setup');
|
||||
|
|
@ -539,8 +538,7 @@ class SetupManager {
|
|||
} else {
|
||||
$currentProviders[] = $mountProvider;
|
||||
$setupProviders[] = $mountProvider;
|
||||
$fullProviderMounts[]
|
||||
= $this->mountProviderCollection->getUserMountsForProviderClasses($user, [$mountProvider]);
|
||||
$fullProviderMounts[] = $this->mountProviderCollection->getUserMountsForProviderClasses($user, [$mountProvider]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -721,6 +719,7 @@ class SetupManager {
|
|||
$this->fullSetupRequired = [];
|
||||
$this->rootSetup = false;
|
||||
$this->mountManager->clear();
|
||||
$this->userMountCache->clear();
|
||||
$this->eventDispatcher->dispatchTyped(new FilesystemTornDownEvent());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -964,12 +964,12 @@ class DefaultShareProvider implements
|
|||
|
||||
$groups = array_filter($groups);
|
||||
|
||||
$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
|
||||
->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
|
||||
$qb->andWhere($qb->expr()->eq('s.share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
|
||||
->andWhere($qb->expr()->in('s.share_with', $qb->createNamedParameter(
|
||||
$groups,
|
||||
IQueryBuilder::PARAM_STR_ARRAY
|
||||
)))
|
||||
->andWhere($qb->expr()->in('item_type', $qb->createNamedParameter(['file', 'folder'], IQueryBuilder::PARAM_STR_ARRAY)));
|
||||
->andWhere($qb->expr()->in('s.item_type', $qb->createNamedParameter(['file', 'folder'], IQueryBuilder::PARAM_STR_ARRAY)));
|
||||
|
||||
$cursor = $qb->executeQuery();
|
||||
while ($data = $cursor->fetch()) {
|
||||
|
|
|
|||
|
|
@ -1299,16 +1299,19 @@ class Manager implements IManager {
|
|||
throw new \RuntimeException(\get_class($provider) . ' must implement IPartialShareProvider');
|
||||
}
|
||||
|
||||
$shares = $provider->getSharedWithByPath($userId,
|
||||
$shares = $provider->getSharedWithByPath(
|
||||
$userId,
|
||||
$shareType,
|
||||
$path,
|
||||
$forChildren,
|
||||
$limit,
|
||||
$offset
|
||||
$offset,
|
||||
);
|
||||
|
||||
if (\is_array($shares)) {
|
||||
$shares = new ArrayIterator($shares);
|
||||
} elseif (!$shares instanceof \Iterator) {
|
||||
$shares = new \IteratorIterator($shares);
|
||||
}
|
||||
|
||||
return new \CallbackFilterIterator($shares, function (IShare $share) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue