nextcloud / fulltextsearch

🔍 Core of the full-text search framework for Nextcloud
GNU Affero General Public License v3.0
210 stars 51 forks source link

Nextcloud 28.0.8 app not working with Group Folders #856

Open equillibrium opened 4 weeks ago

equillibrium commented 4 weeks ago

Nextcloud 28.0.8, fulltextsearch 28.0.1 When both fulltextsearch and Group Folders are enabled, can't login to nextcloud - Internal server error.

occ fulltextsearch:test

.Testing your current setup: Creating mocked content provider. An unhandled exception has been thrown: ArgumentCountError: Too few arguments to function OCA\GroupFolders\Folder\FolderManager::__construct(), 4 passed in /mnt/ncdata/nextcloud/apps/files_fulltextsearch/lib/Service/GroupFoldersService.php on line 67 and exactly 5 expected in /mnt/ncdata/nextcloud/apps/groupfolders/lib/Folder/FolderManager.php:52 Stack trace:

0 /mnt/ncdata/nextcloud/apps/files_fulltextsearch/lib/Service/GroupFoldersService.php(67): OCA\GroupFolders\Folder\FolderManager->__construct()

1 [internal function]: OCA\Files_FullTextSearch\Service\GroupFoldersService->__construct()

2 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(83): ReflectionClass->newInstanceArgs()

3 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(128): OC\AppFramework\Utility\SimpleContainer->buildClass()

4 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(146): OC\AppFramework\Utility\SimpleContainer->resolve()

5 /mnt/ncdata/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(470): OC\AppFramework\Utility\SimpleContainer->query()

6 /mnt/ncdata/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(442): OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback()

7 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(96): OC\AppFramework\DependencyInjection\DIContainer->query()

8 [internal function]: OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility{closure}()

9 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(83): array_map()

10 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(128): OC\AppFramework\Utility\SimpleContainer->buildClass()

11 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(146): OC\AppFramework\Utility\SimpleContainer->resolve()

12 /mnt/ncdata/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(470): OC\AppFramework\Utility\SimpleContainer->query()

13 /mnt/ncdata/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(442): OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback()

14 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(96): OC\AppFramework\DependencyInjection\DIContainer->query()

15 [internal function]: OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility{closure}()

16 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(83): array_map()

17 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(128): OC\AppFramework\Utility\SimpleContainer->buildClass()

18 /mnt/ncdata/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(146): OC\AppFramework\Utility\SimpleContainer->resolve()

19 /mnt/ncdata/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(470): OC\AppFramework\Utility\SimpleContainer->query()

20 /mnt/ncdata/nextcloud/lib/private/ServerContainer.php(155): OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback()

21 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Service/ProviderService.php(121): OC\ServerContainer->query()

22 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Service/ProviderService.php(267): OCA\FullTextSearch\Service\ProviderService->loadProvider()

23 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Service/ProviderService.php(238): OCA\FullTextSearch\Service\ProviderService->loadProvidersFromList()

24 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Service/ProviderService.php(101): OCA\FullTextSearch\Service\ProviderService->loadProvidersFromApp()

25 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Service/ProviderService.php(145): OCA\FullTextSearch\Service\ProviderService->loadProviders()

26 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Service/ProviderService.php(199): OCA\FullTextSearch\Service\ProviderService->getProviders()

27 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Command/Test.php(206): OCA\FullTextSearch\Service\ProviderService->getProvider()

28 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Command/Test.php(265): OCA\FullTextSearch\Command\Test->generateMockProvider()

29 /mnt/ncdata/nextcloud/apps/fulltextsearch/lib/Command/Test.php(156): OCA\FullTextSearch\Command\Test->testCreatingProvider()

30 /mnt/ncdata/nextcloud/3rdparty/symfony/console/Command/Command.php(298): OCA\FullTextSearch\Command\Test->execute()

31 /mnt/ncdata/nextcloud/core/Command/Base.php(177): Symfony\Component\Console\Command\Command->run()

32 /mnt/ncdata/nextcloud/3rdparty/symfony/console/Application.php(1040): OC\Core\Command\Base->run()

33 /mnt/ncdata/nextcloud/3rdparty/symfony/console/Application.php(301): Symfony\Component\Console\Application->doRunCommand()

34 /mnt/ncdata/nextcloud/3rdparty/symfony/console/Application.php(171): Symfony\Component\Console\Application->doRun()

35 /mnt/ncdata/nextcloud/lib/private/Console/Application.php(213): Symfony\Component\Console\Application->run()

36 /mnt/ncdata/nextcloud/console.php(100): OC\Console\Application->run()

37 /mnt/ncdata/nextcloud/occ(11): require_once('...')

Disabling Group Folders or Fulltextsearch resolves the Internal server error issue.

Nextcloud log:

{"file":"/mnt/ncdata/nextcloud/index.php","line":39,"function":"handleRequest","class":"OC","type":"::"}],"File":"/mnt/ncdata/nextcloud/apps/groupfolders/lib/Folder/FolderManager.php","Line":52,"message":"Too few arguments to function OCA\GroupFolders\Folder\FolderManager::__construct(), 4 passed in /mnt/ncdata/nextcloud/apps/files_fulltextsearch/lib/Service/GroupFoldersService.php on line 67 and exactly 5 expected","exception":{},"CustomMessage":"Too few arguments to function OCA\GroupFolders\Folder\FolderManager::__construct(), 4 passed in /mnt/ncdata/nextcloud/apps/files_fulltextsearch/lib/Service/GroupFoldersService.php on line 67 and exactly 5 expected"}}

equillibrium commented 4 weeks ago

Latest release of groupfolders breaks GroupFoldersService.php #265 from files_fulltextsearch repo actually resolves the issue. The modified file is: `<?php

declare(strict_types=1);

/**

namespace OCA\Files_FullTextSearch\Service;

use Exception; use OCA\Files_FullTextSearch\Exceptions\FileIsNotIndexableException; use OCA\Files_FullTextSearch\Exceptions\GroupFolderNotFoundException; use OCA\Files_FullTextSearch\Exceptions\KnownFileSourceException; use OCA\Files_FullTextSearch\Model\FilesDocument; use OCA\Files_FullTextSearch\Model\MountPoint; use OCA\Files_FullTextSearch\Tools\Traits\TArrayTools; use OCA\GroupFolders\Folder\FolderManager; use OCP\App\IAppManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IMimeTypeLoader; use OCP\Files\Node; use OCP\FullTextSearch\Model\IIndex; use OCP\IDBConnection; use OCP\IGroupManager; use Psr\Log\LoggerInterface;

class GroupFoldersService { use TArrayTools;

private ?FolderManager $folderManager = null;
/** @var MountPoint[] */
private array $groupFolders = [];

public function __construct(
    IDBConnection $dbConnection,
    IAppManager $appManager,
    IMimeTypeLoader $mimeTypeLoader,
    private IGroupManager $groupManager,
    private LocalFilesService $localFilesService,
    ConfigService $configService,
    private LoggerInterface $logger,
    private IEventDispatcher $eventDispatcher
) {
    if ($configService->getAppValue(ConfigService::FILES_GROUP_FOLDERS) === '1'
        && $appManager->isEnabledForUser('groupfolders')) {
        try {
            $this->folderManager = new FolderManager(
                $dbConnection,
                $groupManager,
                $mimeTypeLoader,
                $logger,
                $eventDispatcher
            );
        } catch (Exception $e) {
            return;
        }
    }
}

/**
 * @param string $userId
 */
public function initGroupSharesForUser(string $userId): void {
    if ($this->folderManager === null) {
        return;
    }

    $this->logger->debug('initGroupSharesForUser request', ['userId' => $userId]);
    $this->groupFolders = $this->getMountPoints($userId);
    $this->logger->debug('initGroupSharesForUser result', ['groupFolders' => $this->groupFolders]);
}

/**
 * @param Node $file
 * @param string $source
 *
 * @throws KnownFileSourceException
 */
public function getFileSource(Node $file, string &$source): void {
    if ($file->getMountPoint()
             ->getMountType() !== 'group'
        || $this->folderManager === null) {
        return;
    }

    try {
        $this->getMountPoint($file);
    } catch (FileIsNotIndexableException $e) {
        return;
    }

    $source = ConfigService::FILES_GROUP_FOLDERS;
    throw new KnownFileSourceException();
}

/**
 * @param FilesDocument $document
 * @param Node $file
 */
public function updateDocumentAccess(FilesDocument $document, Node $file): void {
    if ($document->getSource() !== ConfigService::FILES_GROUP_FOLDERS) {
        return;
    }

    try {
        $mount = $this->getMountPoint($file);
    } catch (FileIsNotIndexableException $e) {
        return;
    }

    $access = $document->getAccess();
    foreach ($mount->getGroups() as $group) {
        if ($this->groupManager->get($group) === null) {
            $access->addCircle($group);
        } else {
            $access->addGroup($group);
        }
    }

    $document->getIndex()
             ->addOptionInt('group_folder_id', $mount->getId());
    $document->setAccess($access);
}

/**
 * @param FilesDocument $document
 * @param array $users
 */
public function getShareUsers(FilesDocument $document, array &$users): void {
    if ($document->getSource() !== ConfigService::FILES_GROUP_FOLDERS) {
        return;
    }

    $this->localFilesService->getSharedUsersFromAccess($document->getAccess(), $users);
}

/**
 * @param Node $file
 *
 * @return MountPoint
 * @throws FileIsNotIndexableException
 */
private function getMountPoint(Node $file): MountPoint {
    foreach ($this->groupFolders as $mount) {
        if (str_starts_with($file->getPath(), $mount->getPath())) {
            return $mount;
        }
    }

    throw new FileIsNotIndexableException();
}

/**
 * @param string $userId
 *
 * @return MountPoint[]
 */
private function getMountPoints(string $userId): array {
    $mountPoints = [];
    $mounts = $this->folderManager->getAllFolders();

    foreach ($mounts as $path => $mount) {
        $mountPoint = new MountPoint();
        $mountPoint->setId($this->getInt('id', $mount, -1))
                   ->setPath('/' . $userId . '/files/' . $mount['mount_point'])
                   ->setGroups(array_keys($mount['groups']));
        $mountPoints[] = $mountPoint;
    }

    return $mountPoints;
}

/**
 * @param IIndex $index
 */
public function impersonateOwner(IIndex $index): void {
    if ($index->getSource() !== ConfigService::FILES_GROUP_FOLDERS) {
        return;
    }

    if ($this->folderManager === null) {
        return;
    }

    $groupFolderId = $index->getOptionInt('group_folder_id', 0);
    try {
        $mount = $this->getGroupFolderById($groupFolderId);
    } catch (GroupFolderNotFoundException $e) {
        return;
    }

    $index->setOwnerId($this->getRandomUserFromGroups(array_keys($mount['groups'])));
}

/**
 * @param int $groupFolderId
 *
 * @return array
 * @throws GroupFolderNotFoundException
 */
private function getGroupFolderById(int $groupFolderId): array {
    if ($groupFolderId === 0) {
        throw new GroupFolderNotFoundException();
    }

    $mounts = $this->folderManager->getAllFolders();
    foreach ($mounts as $path => $mount) {
        if ($mount['id'] === $groupFolderId) {
            return $mount;
        }
    }

    throw new GroupFolderNotFoundException();
}

/**
 * @param array $groups
 *
 * @return string
 */
private function getRandomUserFromGroups(array $groups): string {
    foreach ($groups as $groupName) {
        $group = $this->groupManager->get($groupName);
        $users = $group->getUsers();
        if (sizeof($users) > 0) {
            return array_keys($users)[0];
        }
    }

    return '';
}

} `

joergmschulz commented 4 weeks ago

same for nc 29.