ProviderFactory.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Bjoern Schiessle <bjoern@schiessle.org>
  6. * @author Björn Schießle <bjoern@schiessle.org>
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Daniel Calviño Sánchez <danxuliu@gmail.com>
  9. * @author Joas Schilling <coding@schilljs.com>
  10. * @author John Molakvoæ <skjnldsv@protonmail.com>
  11. * @author Julius Härtl <jus@bitgrid.net>
  12. * @author Lukas Reschke <lukas@statuscode.ch>
  13. * @author Maxence Lange <maxence@nextcloud.com>
  14. * @author Morris Jobke <hey@morrisjobke.de>
  15. * @author Robin Appelman <robin@icewind.nl>
  16. * @author Roeland Jago Douma <roeland@famdouma.nl>
  17. * @author Samuel <faust64@gmail.com>
  18. *
  19. * @license AGPL-3.0
  20. *
  21. * This code is free software: you can redistribute it and/or modify
  22. * it under the terms of the GNU Affero General Public License, version 3,
  23. * as published by the Free Software Foundation.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28. * GNU Affero General Public License for more details.
  29. *
  30. * You should have received a copy of the GNU Affero General Public License, version 3,
  31. * along with this program. If not, see <http://www.gnu.org/licenses/>
  32. *
  33. */
  34. namespace OC\Share20;
  35. use OC\Share20\Exception\ProviderException;
  36. use OCA\FederatedFileSharing\AddressHandler;
  37. use OCA\FederatedFileSharing\FederatedShareProvider;
  38. use OCA\FederatedFileSharing\Notifications;
  39. use OCA\FederatedFileSharing\TokenHandler;
  40. use OCA\ShareByMail\Settings\SettingsManager;
  41. use OCA\ShareByMail\ShareByMailProvider;
  42. use OCA\Talk\Share\RoomShareProvider;
  43. use OCP\AppFramework\Utility\ITimeFactory;
  44. use OCP\Defaults;
  45. use OCP\EventDispatcher\IEventDispatcher;
  46. use OCP\IServerContainer;
  47. use OCP\Share\IManager;
  48. use OCP\Share\IProviderFactory;
  49. use OCP\Share\IShare;
  50. use OCP\Share\IShareProvider;
  51. use Psr\Log\LoggerInterface;
  52. /**
  53. * Class ProviderFactory
  54. *
  55. * @package OC\Share20
  56. */
  57. class ProviderFactory implements IProviderFactory {
  58. /** @var IServerContainer */
  59. private $serverContainer;
  60. /** @var DefaultShareProvider */
  61. private $defaultProvider = null;
  62. /** @var FederatedShareProvider */
  63. private $federatedProvider = null;
  64. /** @var ShareByMailProvider */
  65. private $shareByMailProvider;
  66. /** @var \OCA\Circles\ShareByCircleProvider */
  67. private $shareByCircleProvider = null;
  68. /** @var bool */
  69. private $circlesAreNotAvailable = false;
  70. /** @var \OCA\Talk\Share\RoomShareProvider */
  71. private $roomShareProvider = null;
  72. private $registeredShareProviders = [];
  73. private $shareProviders = [];
  74. /**
  75. * IProviderFactory constructor.
  76. *
  77. * @param IServerContainer $serverContainer
  78. */
  79. public function __construct(IServerContainer $serverContainer) {
  80. $this->serverContainer = $serverContainer;
  81. }
  82. public function registerProvider(string $shareProviderClass): void {
  83. $this->registeredShareProviders[] = $shareProviderClass;
  84. }
  85. /**
  86. * Create the default share provider.
  87. *
  88. * @return DefaultShareProvider
  89. */
  90. protected function defaultShareProvider() {
  91. if ($this->defaultProvider === null) {
  92. $this->defaultProvider = new DefaultShareProvider(
  93. $this->serverContainer->getDatabaseConnection(),
  94. $this->serverContainer->getUserManager(),
  95. $this->serverContainer->getGroupManager(),
  96. $this->serverContainer->getLazyRootFolder(),
  97. $this->serverContainer->getMailer(),
  98. $this->serverContainer->query(Defaults::class),
  99. $this->serverContainer->getL10NFactory(),
  100. $this->serverContainer->getURLGenerator(),
  101. $this->serverContainer->query(ITimeFactory::class),
  102. );
  103. }
  104. return $this->defaultProvider;
  105. }
  106. /**
  107. * Create the federated share provider
  108. *
  109. * @return FederatedShareProvider
  110. */
  111. protected function federatedShareProvider() {
  112. if ($this->federatedProvider === null) {
  113. /*
  114. * Check if the app is enabled
  115. */
  116. $appManager = $this->serverContainer->getAppManager();
  117. if (!$appManager->isEnabledForUser('federatedfilesharing')) {
  118. return null;
  119. }
  120. /*
  121. * TODO: add factory to federated sharing app
  122. */
  123. $l = $this->serverContainer->getL10N('federatedfilesharing');
  124. $addressHandler = new AddressHandler(
  125. $this->serverContainer->getURLGenerator(),
  126. $l,
  127. $this->serverContainer->getCloudIdManager()
  128. );
  129. $notifications = new Notifications(
  130. $addressHandler,
  131. $this->serverContainer->getHTTPClientService(),
  132. $this->serverContainer->query(\OCP\OCS\IDiscoveryService::class),
  133. $this->serverContainer->getJobList(),
  134. \OC::$server->getCloudFederationProviderManager(),
  135. \OC::$server->getCloudFederationFactory(),
  136. $this->serverContainer->query(IEventDispatcher::class),
  137. $this->serverContainer->get(LoggerInterface::class),
  138. );
  139. $tokenHandler = new TokenHandler(
  140. $this->serverContainer->getSecureRandom()
  141. );
  142. $this->federatedProvider = new FederatedShareProvider(
  143. $this->serverContainer->getDatabaseConnection(),
  144. $addressHandler,
  145. $notifications,
  146. $tokenHandler,
  147. $l,
  148. $this->serverContainer->getLazyRootFolder(),
  149. $this->serverContainer->getConfig(),
  150. $this->serverContainer->getUserManager(),
  151. $this->serverContainer->getCloudIdManager(),
  152. $this->serverContainer->getGlobalScaleConfig(),
  153. $this->serverContainer->getCloudFederationProviderManager(),
  154. $this->serverContainer->get(LoggerInterface::class),
  155. );
  156. }
  157. return $this->federatedProvider;
  158. }
  159. /**
  160. * Create the federated share provider
  161. *
  162. * @return ShareByMailProvider
  163. */
  164. protected function getShareByMailProvider() {
  165. if ($this->shareByMailProvider === null) {
  166. /*
  167. * Check if the app is enabled
  168. */
  169. $appManager = $this->serverContainer->getAppManager();
  170. if (!$appManager->isEnabledForUser('sharebymail')) {
  171. return null;
  172. }
  173. $settingsManager = new SettingsManager($this->serverContainer->getConfig());
  174. $this->shareByMailProvider = new ShareByMailProvider(
  175. $this->serverContainer->getConfig(),
  176. $this->serverContainer->getDatabaseConnection(),
  177. $this->serverContainer->getSecureRandom(),
  178. $this->serverContainer->getUserManager(),
  179. $this->serverContainer->getLazyRootFolder(),
  180. $this->serverContainer->getL10N('sharebymail'),
  181. $this->serverContainer->get(LoggerInterface::class),
  182. $this->serverContainer->getMailer(),
  183. $this->serverContainer->getURLGenerator(),
  184. $this->serverContainer->getActivityManager(),
  185. $settingsManager,
  186. $this->serverContainer->query(Defaults::class),
  187. $this->serverContainer->getHasher(),
  188. $this->serverContainer->get(IEventDispatcher::class),
  189. $this->serverContainer->get(IManager::class)
  190. );
  191. }
  192. return $this->shareByMailProvider;
  193. }
  194. /**
  195. * Create the circle share provider
  196. *
  197. * @return FederatedShareProvider
  198. *
  199. * @suppress PhanUndeclaredClassMethod
  200. */
  201. protected function getShareByCircleProvider() {
  202. if ($this->circlesAreNotAvailable) {
  203. return null;
  204. }
  205. if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
  206. !class_exists('\OCA\Circles\ShareByCircleProvider')
  207. ) {
  208. $this->circlesAreNotAvailable = true;
  209. return null;
  210. }
  211. if ($this->shareByCircleProvider === null) {
  212. $this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
  213. $this->serverContainer->getDatabaseConnection(),
  214. $this->serverContainer->getSecureRandom(),
  215. $this->serverContainer->getUserManager(),
  216. $this->serverContainer->getLazyRootFolder(),
  217. $this->serverContainer->getL10N('circles'),
  218. $this->serverContainer->getLogger(),
  219. $this->serverContainer->getURLGenerator()
  220. );
  221. }
  222. return $this->shareByCircleProvider;
  223. }
  224. /**
  225. * Create the room share provider
  226. *
  227. * @return RoomShareProvider
  228. */
  229. protected function getRoomShareProvider() {
  230. if ($this->roomShareProvider === null) {
  231. /*
  232. * Check if the app is enabled
  233. */
  234. $appManager = $this->serverContainer->getAppManager();
  235. if (!$appManager->isEnabledForUser('spreed')) {
  236. return null;
  237. }
  238. try {
  239. /**
  240. * @psalm-suppress UndefinedClass
  241. */
  242. $this->roomShareProvider = $this->serverContainer->get(RoomShareProvider::class);
  243. } catch (\Throwable $e) {
  244. $this->serverContainer->get(LoggerInterface::class)->error(
  245. $e->getMessage(),
  246. ['exception' => $e]
  247. );
  248. return null;
  249. }
  250. }
  251. return $this->roomShareProvider;
  252. }
  253. /**
  254. * @inheritdoc
  255. */
  256. public function getProvider($id) {
  257. $provider = null;
  258. if (isset($this->shareProviders[$id])) {
  259. return $this->shareProviders[$id];
  260. }
  261. if ($id === 'ocinternal') {
  262. $provider = $this->defaultShareProvider();
  263. } elseif ($id === 'ocFederatedSharing') {
  264. $provider = $this->federatedShareProvider();
  265. } elseif ($id === 'ocMailShare') {
  266. $provider = $this->getShareByMailProvider();
  267. } elseif ($id === 'ocCircleShare') {
  268. $provider = $this->getShareByCircleProvider();
  269. } elseif ($id === 'ocRoomShare') {
  270. $provider = $this->getRoomShareProvider();
  271. }
  272. foreach ($this->registeredShareProviders as $shareProvider) {
  273. try {
  274. /** @var IShareProvider $instance */
  275. $instance = $this->serverContainer->get($shareProvider);
  276. $this->shareProviders[$instance->identifier()] = $instance;
  277. } catch (\Throwable $e) {
  278. $this->serverContainer->get(LoggerInterface::class)->error(
  279. $e->getMessage(),
  280. ['exception' => $e]
  281. );
  282. }
  283. }
  284. if (isset($this->shareProviders[$id])) {
  285. $provider = $this->shareProviders[$id];
  286. }
  287. if ($provider === null) {
  288. throw new ProviderException('No provider with id .' . $id . ' found.');
  289. }
  290. return $provider;
  291. }
  292. /**
  293. * @inheritdoc
  294. */
  295. public function getProviderForType($shareType) {
  296. $provider = null;
  297. if ($shareType === IShare::TYPE_USER ||
  298. $shareType === IShare::TYPE_GROUP ||
  299. $shareType === IShare::TYPE_LINK
  300. ) {
  301. $provider = $this->defaultShareProvider();
  302. } elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) {
  303. $provider = $this->federatedShareProvider();
  304. } elseif ($shareType === IShare::TYPE_EMAIL) {
  305. $provider = $this->getShareByMailProvider();
  306. } elseif ($shareType === IShare::TYPE_CIRCLE) {
  307. $provider = $this->getShareByCircleProvider();
  308. } elseif ($shareType === IShare::TYPE_ROOM) {
  309. $provider = $this->getRoomShareProvider();
  310. } elseif ($shareType === IShare::TYPE_DECK) {
  311. $provider = $this->getProvider('deck');
  312. } elseif ($shareType === IShare::TYPE_SCIENCEMESH) {
  313. $provider = $this->getProvider('sciencemesh');
  314. }
  315. if ($provider === null) {
  316. throw new ProviderException('No share provider for share type ' . $shareType);
  317. }
  318. return $provider;
  319. }
  320. public function getAllProviders() {
  321. $shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
  322. $shareByMail = $this->getShareByMailProvider();
  323. if ($shareByMail !== null) {
  324. $shares[] = $shareByMail;
  325. }
  326. $shareByCircle = $this->getShareByCircleProvider();
  327. if ($shareByCircle !== null) {
  328. $shares[] = $shareByCircle;
  329. }
  330. $roomShare = $this->getRoomShareProvider();
  331. if ($roomShare !== null) {
  332. $shares[] = $roomShare;
  333. }
  334. foreach ($this->registeredShareProviders as $shareProvider) {
  335. try {
  336. /** @var IShareProvider $instance */
  337. $instance = $this->serverContainer->get($shareProvider);
  338. } catch (\Throwable $e) {
  339. $this->serverContainer->get(LoggerInterface::class)->error(
  340. $e->getMessage(),
  341. ['exception' => $e]
  342. );
  343. continue;
  344. }
  345. if (!isset($this->shareProviders[$instance->identifier()])) {
  346. $this->shareProviders[$instance->identifier()] = $instance;
  347. }
  348. $shares[] = $this->shareProviders[$instance->identifier()];
  349. }
  350. return $shares;
  351. }
  352. }