LookupPlugin.php 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OC\Collaboration\Collaborators;
  7. use OCP\Collaboration\Collaborators\ISearchPlugin;
  8. use OCP\Collaboration\Collaborators\ISearchResult;
  9. use OCP\Collaboration\Collaborators\SearchResultType;
  10. use OCP\Federation\ICloudIdManager;
  11. use OCP\Http\Client\IClientService;
  12. use OCP\IConfig;
  13. use OCP\IUserSession;
  14. use OCP\Share\IShare;
  15. use Psr\Log\LoggerInterface;
  16. class LookupPlugin implements ISearchPlugin {
  17. /** @var string remote part of the current user's cloud id */
  18. private string $currentUserRemote;
  19. public function __construct(
  20. private IConfig $config,
  21. private IClientService $clientService,
  22. IUserSession $userSession,
  23. private ICloudIdManager $cloudIdManager,
  24. private LoggerInterface $logger,
  25. ) {
  26. $currentUserCloudId = $userSession->getUser()->getCloudId();
  27. $this->currentUserRemote = $cloudIdManager->resolveCloudId($currentUserCloudId)->getRemote();
  28. }
  29. public function search($search, $limit, $offset, ISearchResult $searchResult): bool {
  30. $isGlobalScaleEnabled = $this->config->getSystemValueBool('gs.enabled', false);
  31. $isLookupServerEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
  32. $hasInternetConnection = $this->config->getSystemValueBool('has_internet_connection', true);
  33. // if case of Global Scale we always search the lookup server
  34. if (!$isGlobalScaleEnabled && (!$isLookupServerEnabled || !$hasInternetConnection)) {
  35. return false;
  36. }
  37. $lookupServerUrl = $this->config->getSystemValueString('lookup_server', 'https://lookup.nextcloud.com');
  38. if (empty($lookupServerUrl)) {
  39. return false;
  40. }
  41. $lookupServerUrl = rtrim($lookupServerUrl, '/');
  42. $result = [];
  43. try {
  44. $client = $this->clientService->newClient();
  45. $response = $client->get(
  46. $lookupServerUrl . '/users?search=' . urlencode($search),
  47. [
  48. 'timeout' => 10,
  49. 'connect_timeout' => 3,
  50. ]
  51. );
  52. $body = json_decode($response->getBody(), true);
  53. foreach ($body as $lookup) {
  54. try {
  55. $remote = $this->cloudIdManager->resolveCloudId($lookup['federationId'])->getRemote();
  56. } catch (\Exception $e) {
  57. $this->logger->error('Can not parse federated cloud ID "' . $lookup['federationId'] . '"', [
  58. 'exception' => $e,
  59. ]);
  60. continue;
  61. }
  62. if ($this->currentUserRemote === $remote) {
  63. continue;
  64. }
  65. $name = $lookup['name']['value'] ?? '';
  66. $label = empty($name) ? $lookup['federationId'] : $name . ' (' . $lookup['federationId'] . ')';
  67. $result[] = [
  68. 'label' => $label,
  69. 'value' => [
  70. 'shareType' => IShare::TYPE_REMOTE,
  71. 'globalScale' => $isGlobalScaleEnabled,
  72. 'shareWith' => $lookup['federationId'],
  73. ],
  74. 'extra' => $lookup,
  75. ];
  76. }
  77. } catch (\Exception $e) {
  78. }
  79. $type = new SearchResultType('lookup');
  80. $searchResult->addResultSet($type, $result, []);
  81. return false;
  82. }
  83. }