MountProviderCollection.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Morris Jobke <hey@morrisjobke.de>
  6. * @author Robin Appelman <robin@icewind.nl>
  7. *
  8. * @license AGPL-3.0
  9. *
  10. * This code is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License, version 3,
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License, version 3,
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>
  21. *
  22. */
  23. namespace OC\Files\Config;
  24. use OC\Hooks\Emitter;
  25. use OC\Hooks\EmitterTrait;
  26. use OCP\Files\Config\IHomeMountProvider;
  27. use OCP\Files\Config\IMountProviderCollection;
  28. use OCP\Files\Config\IMountProvider;
  29. use OCP\Files\Config\IUserMountCache;
  30. use OCP\Files\Mount\IMountManager;
  31. use OCP\Files\Mount\IMountPoint;
  32. use OCP\Files\Storage\IStorageFactory;
  33. use OCP\IUser;
  34. class MountProviderCollection implements IMountProviderCollection, Emitter {
  35. use EmitterTrait;
  36. /**
  37. * @var \OCP\Files\Config\IHomeMountProvider[]
  38. */
  39. private $homeProviders = [];
  40. /**
  41. * @var \OCP\Files\Config\IMountProvider[]
  42. */
  43. private $providers = array();
  44. /**
  45. * @var \OCP\Files\Storage\IStorageFactory
  46. */
  47. private $loader;
  48. /**
  49. * @var \OCP\Files\Config\IUserMountCache
  50. */
  51. private $mountCache;
  52. /** @var callable[] */
  53. private $mountFilters = [];
  54. /**
  55. * @param \OCP\Files\Storage\IStorageFactory $loader
  56. * @param IUserMountCache $mountCache
  57. */
  58. public function __construct(IStorageFactory $loader, IUserMountCache $mountCache) {
  59. $this->loader = $loader;
  60. $this->mountCache = $mountCache;
  61. }
  62. /**
  63. * Get all configured mount points for the user
  64. *
  65. * @param \OCP\IUser $user
  66. * @return \OCP\Files\Mount\IMountPoint[]
  67. */
  68. public function getMountsForUser(IUser $user) {
  69. $loader = $this->loader;
  70. $mounts = array_map(function (IMountProvider $provider) use ($user, $loader) {
  71. return $provider->getMountsForUser($user, $loader);
  72. }, $this->providers);
  73. $mounts = array_filter($mounts, function ($result) {
  74. return is_array($result);
  75. });
  76. $mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) {
  77. return array_merge($mounts, $providerMounts);
  78. }, array());
  79. return $this->filterMounts($user, $mounts);
  80. }
  81. public function addMountForUser(IUser $user, IMountManager $mountManager) {
  82. // shared mount provider gets to go last since it needs to know existing files
  83. // to check for name collisions
  84. $firstMounts = [];
  85. $firstProviders = array_filter($this->providers, function (IMountProvider $provider) {
  86. return (get_class($provider) !== 'OCA\Files_Sharing\MountProvider');
  87. });
  88. $lastProviders = array_filter($this->providers, function (IMountProvider $provider) {
  89. return (get_class($provider) === 'OCA\Files_Sharing\MountProvider');
  90. });
  91. foreach ($firstProviders as $provider) {
  92. $mounts = $provider->getMountsForUser($user, $this->loader);
  93. if (is_array($mounts)) {
  94. $firstMounts = array_merge($firstMounts, $mounts);
  95. }
  96. }
  97. $firstMounts = $this->filterMounts($user, $firstMounts);
  98. array_walk($firstMounts, [$mountManager, 'addMount']);
  99. $lateMounts = [];
  100. foreach ($lastProviders as $provider) {
  101. $mounts = $provider->getMountsForUser($user, $this->loader);
  102. if (is_array($mounts)) {
  103. $lateMounts = array_merge($lateMounts, $mounts);
  104. }
  105. }
  106. $lateMounts = $this->filterMounts($user, $lateMounts);
  107. array_walk($lateMounts, [$mountManager, 'addMount']);
  108. return array_merge($lateMounts, $firstMounts);
  109. }
  110. /**
  111. * Get the configured home mount for this user
  112. *
  113. * @param \OCP\IUser $user
  114. * @return \OCP\Files\Mount\IMountPoint
  115. * @since 9.1.0
  116. */
  117. public function getHomeMountForUser(IUser $user) {
  118. /** @var \OCP\Files\Config\IHomeMountProvider[] $providers */
  119. $providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin
  120. foreach ($providers as $homeProvider) {
  121. if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) {
  122. $mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect
  123. return $mount;
  124. }
  125. }
  126. throw new \Exception('No home storage configured for user ' . $user);
  127. }
  128. /**
  129. * Add a provider for mount points
  130. *
  131. * @param \OCP\Files\Config\IMountProvider $provider
  132. */
  133. public function registerProvider(IMountProvider $provider) {
  134. $this->providers[] = $provider;
  135. $this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]);
  136. }
  137. public function registerMountFilter(callable $filter) {
  138. $this->mountFilters[] = $filter;
  139. }
  140. private function filterMounts(IUser $user, array $mountPoints) {
  141. return array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) {
  142. foreach ($this->mountFilters as $filter) {
  143. if ($filter($mountPoint, $user) === false) {
  144. return false;
  145. }
  146. }
  147. return true;
  148. });
  149. }
  150. /**
  151. * Add a provider for home mount points
  152. *
  153. * @param \OCP\Files\Config\IHomeMountProvider $provider
  154. * @since 9.1.0
  155. */
  156. public function registerHomeProvider(IHomeMountProvider $provider) {
  157. $this->homeProviders[] = $provider;
  158. $this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]);
  159. }
  160. /**
  161. * Cache mounts for user
  162. *
  163. * @param IUser $user
  164. * @param IMountPoint[] $mountPoints
  165. */
  166. public function registerMounts(IUser $user, array $mountPoints) {
  167. $this->mountCache->registerMounts($user, $mountPoints);
  168. }
  169. /**
  170. * Get the mount cache which can be used to search for mounts without setting up the filesystem
  171. *
  172. * @return IUserMountCache
  173. */
  174. public function getMountCache() {
  175. return $this->mountCache;
  176. }
  177. }