You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.4 KiB

  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Files_External\Service;
  8. use OCA\Files_External\Lib\StorageConfig;
  9. use OCP\EventDispatcher\IEventDispatcher;
  10. use OCP\Files\Config\IUserMountCache;
  11. use OCP\IAppConfig;
  12. use OCP\IGroupManager;
  13. use OCP\IUser;
  14. use OCP\IUserSession;
  15. /**
  16. * Service class to read global storages applicable to the user
  17. * Read-only access available, attempting to write will throw DomainException
  18. */
  19. class UserGlobalStoragesService extends GlobalStoragesService {
  20. use UserTrait;
  21. public function __construct(
  22. BackendService $backendService,
  23. DBConfigService $dbConfig,
  24. IUserSession $userSession,
  25. protected IGroupManager $groupManager,
  26. IUserMountCache $userMountCache,
  27. IEventDispatcher $eventDispatcher,
  28. IAppConfig $appConfig,
  29. ) {
  30. parent::__construct($backendService, $dbConfig, $userMountCache, $eventDispatcher, $appConfig);
  31. $this->userSession = $userSession;
  32. }
  33. /**
  34. * Replace config hash ID with real IDs, for migrating legacy storages
  35. *
  36. * @param StorageConfig[] $storages Storages with real IDs
  37. * @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
  38. */
  39. protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
  40. // as a read-only view, storage IDs don't need to be real
  41. foreach ($storagesWithConfigHash as $storage) {
  42. $storages[$storage->getId()] = $storage;
  43. }
  44. }
  45. protected function readDBConfig() {
  46. $userMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
  47. $globalMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
  48. $groups = $this->groupManager->getUserGroupIds($this->getUser());
  49. if (count($groups) !== 0) {
  50. $groupMounts = $this->dbConfig->getAdminMountsForMultiple(DBConfigService::APPLICABLE_TYPE_GROUP, $groups);
  51. } else {
  52. $groupMounts = [];
  53. }
  54. return array_merge($userMounts, $groupMounts, $globalMounts);
  55. }
  56. public function addStorage(StorageConfig $newStorage) {
  57. throw new \DomainException('UserGlobalStoragesService writing disallowed');
  58. }
  59. public function updateStorage(StorageConfig $updatedStorage) {
  60. throw new \DomainException('UserGlobalStoragesService writing disallowed');
  61. }
  62. /**
  63. * @param integer $id
  64. */
  65. public function removeStorage($id) {
  66. throw new \DomainException('UserGlobalStoragesService writing disallowed');
  67. }
  68. /**
  69. * Get unique storages, in case two are defined with the same mountpoint
  70. * Higher priority storages take precedence
  71. *
  72. * @return StorageConfig[]
  73. */
  74. public function getUniqueStorages() {
  75. $storages = $this->getStorages();
  76. $storagesByMountpoint = [];
  77. foreach ($storages as $storage) {
  78. $storagesByMountpoint[$storage->getMountPoint()][] = $storage;
  79. }
  80. $result = [];
  81. foreach ($storagesByMountpoint as $storageList) {
  82. $storage = array_reduce($storageList, function ($carry, $item) {
  83. if (isset($carry)) {
  84. $carryPriorityType = $this->getPriorityType($carry);
  85. $itemPriorityType = $this->getPriorityType($item);
  86. if ($carryPriorityType > $itemPriorityType) {
  87. return $carry;
  88. } elseif ($carryPriorityType === $itemPriorityType) {
  89. if ($carry->getPriority() > $item->getPriority()) {
  90. return $carry;
  91. }
  92. }
  93. }
  94. return $item;
  95. });
  96. $result[$storage->getID()] = $storage;
  97. }
  98. return $result;
  99. }
  100. /**
  101. * Get a priority 'type', where a bigger number means higher priority
  102. * user applicable > group applicable > 'all'
  103. *
  104. * @param StorageConfig $storage
  105. * @return int
  106. */
  107. protected function getPriorityType(StorageConfig $storage) {
  108. $applicableUsers = $storage->getApplicableUsers();
  109. $applicableGroups = $storage->getApplicableGroups();
  110. if ($applicableUsers && $applicableUsers[0] !== 'all') {
  111. return 2;
  112. }
  113. if ($applicableGroups) {
  114. return 1;
  115. }
  116. return 0;
  117. }
  118. protected function isApplicable(StorageConfig $config) {
  119. $applicableUsers = $config->getApplicableUsers();
  120. $applicableGroups = $config->getApplicableGroups();
  121. if (count($applicableUsers) === 0 && count($applicableGroups) === 0) {
  122. return true;
  123. }
  124. if (in_array($this->getUser()->getUID(), $applicableUsers, true)) {
  125. return true;
  126. }
  127. $groupIds = $this->groupManager->getUserGroupIds($this->getUser());
  128. foreach ($groupIds as $groupId) {
  129. if (in_array($groupId, $applicableGroups, true)) {
  130. return true;
  131. }
  132. }
  133. return false;
  134. }
  135. /**
  136. * Gets all storages for the user, admin, personal, global, etc
  137. *
  138. * @param IUser|null $user user to get the storages for, if not set the currently logged in user will be used
  139. * @return StorageConfig[] array of storage configs
  140. */
  141. public function getAllStoragesForUser(?IUser $user = null) {
  142. if (is_null($user)) {
  143. $user = $this->getUser();
  144. }
  145. if (is_null($user)) {
  146. return [];
  147. }
  148. $groupIds = $this->groupManager->getUserGroupIds($user);
  149. $mounts = $this->dbConfig->getMountsForUser($user->getUID(), $groupIds);
  150. $configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
  151. $configs = array_filter($configs, function ($config) {
  152. return $config instanceof StorageConfig;
  153. });
  154. $keys = array_map(function (StorageConfig $config) {
  155. return $config->getId();
  156. }, $configs);
  157. $storages = array_combine($keys, $configs);
  158. return array_filter($storages, [$this, 'validateStorage']);
  159. }
  160. }