UserGlobalStoragesController.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017-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\Controller;
  8. use OCA\Files_External\Lib\Auth\AuthMechanism;
  9. use OCA\Files_External\Lib\Auth\IUserProvided;
  10. use OCA\Files_External\Lib\Auth\Password\UserGlobalAuth;
  11. use OCA\Files_External\Lib\Backend\Backend;
  12. use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
  13. use OCA\Files_External\Lib\StorageConfig;
  14. use OCA\Files_External\NotFoundException;
  15. use OCA\Files_External\Service\UserGlobalStoragesService;
  16. use OCP\AppFramework\Http;
  17. use OCP\AppFramework\Http\Attribute\NoAdminRequired;
  18. use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
  19. use OCP\AppFramework\Http\DataResponse;
  20. use OCP\IConfig;
  21. use OCP\IGroupManager;
  22. use OCP\IL10N;
  23. use OCP\IRequest;
  24. use OCP\IUserSession;
  25. use Psr\Log\LoggerInterface;
  26. /**
  27. * User global storages controller
  28. */
  29. class UserGlobalStoragesController extends StoragesController {
  30. /**
  31. * Creates a new user global storages controller.
  32. *
  33. * @param string $AppName application name
  34. * @param IRequest $request request object
  35. * @param IL10N $l10n l10n service
  36. * @param UserGlobalStoragesService $userGlobalStoragesService storage service
  37. * @param LoggerInterface $logger
  38. * @param IUserSession $userSession
  39. * @param IGroupManager $groupManager
  40. */
  41. public function __construct(
  42. $AppName,
  43. IRequest $request,
  44. IL10N $l10n,
  45. UserGlobalStoragesService $userGlobalStoragesService,
  46. LoggerInterface $logger,
  47. IUserSession $userSession,
  48. IGroupManager $groupManager,
  49. IConfig $config,
  50. ) {
  51. parent::__construct(
  52. $AppName,
  53. $request,
  54. $l10n,
  55. $userGlobalStoragesService,
  56. $logger,
  57. $userSession,
  58. $groupManager,
  59. $config
  60. );
  61. }
  62. /**
  63. * Get all storage entries
  64. *
  65. * @return DataResponse
  66. */
  67. #[NoAdminRequired]
  68. public function index() {
  69. /** @var UserGlobalStoragesService */
  70. $service = $this->service;
  71. $storages = array_map(function ($storage) {
  72. // remove configuration data, this must be kept private
  73. $this->sanitizeStorage($storage);
  74. return $storage->jsonSerialize(true);
  75. }, $service->getUniqueStorages());
  76. return new DataResponse(
  77. $storages,
  78. Http::STATUS_OK
  79. );
  80. }
  81. protected function manipulateStorageConfig(StorageConfig $storage) {
  82. /** @var AuthMechanism */
  83. $authMechanism = $storage->getAuthMechanism();
  84. $authMechanism->manipulateStorageConfig($storage, $this->userSession->getUser());
  85. /** @var Backend */
  86. $backend = $storage->getBackend();
  87. $backend->manipulateStorageConfig($storage, $this->userSession->getUser());
  88. }
  89. /**
  90. * Get an external storage entry.
  91. *
  92. * @param int $id storage id
  93. * @param bool $testOnly whether to storage should only test the connection or do more things
  94. * @return DataResponse
  95. */
  96. #[NoAdminRequired]
  97. public function show($id, $testOnly = true) {
  98. try {
  99. $storage = $this->service->getStorage($id);
  100. $this->updateStorageStatus($storage, $testOnly);
  101. } catch (NotFoundException $e) {
  102. return new DataResponse(
  103. [
  104. 'message' => $this->l10n->t('Storage with ID "%d" not found', [$id])
  105. ],
  106. Http::STATUS_NOT_FOUND
  107. );
  108. }
  109. $this->sanitizeStorage($storage);
  110. $data = $storage->jsonSerialize(true);
  111. $isAdmin = $this->groupManager->isAdmin($this->userSession->getUser()->getUID());
  112. $data['can_edit'] = $storage->getType() === StorageConfig::MOUNT_TYPE_PERSONAL || $isAdmin;
  113. return new DataResponse(
  114. $data,
  115. Http::STATUS_OK
  116. );
  117. }
  118. /**
  119. * Update an external storage entry.
  120. * Only allows setting user provided backend fields
  121. *
  122. * @param int $id storage id
  123. * @param array $backendOptions backend-specific options
  124. * @param bool $testOnly whether to storage should only test the connection or do more things
  125. *
  126. * @return DataResponse
  127. */
  128. #[NoAdminRequired]
  129. #[PasswordConfirmationRequired(strict: true)]
  130. public function update(
  131. $id,
  132. $backendOptions,
  133. $testOnly = true,
  134. ) {
  135. try {
  136. $storage = $this->service->getStorage($id);
  137. $authMechanism = $storage->getAuthMechanism();
  138. if ($authMechanism instanceof IUserProvided || $authMechanism instanceof UserGlobalAuth) {
  139. $authMechanism->saveBackendOptions($this->userSession->getUser(), $id, $backendOptions);
  140. $authMechanism->manipulateStorageConfig($storage, $this->userSession->getUser());
  141. } else {
  142. return new DataResponse(
  143. [
  144. 'message' => $this->l10n->t('Storage with ID "%d" is not editable by non-admins', [$id])
  145. ],
  146. Http::STATUS_FORBIDDEN
  147. );
  148. }
  149. } catch (NotFoundException $e) {
  150. return new DataResponse(
  151. [
  152. 'message' => $this->l10n->t('Storage with ID "%d" not found', [$id])
  153. ],
  154. Http::STATUS_NOT_FOUND
  155. );
  156. }
  157. $this->updateStorageStatus($storage, $testOnly);
  158. $this->sanitizeStorage($storage);
  159. return new DataResponse(
  160. $storage->jsonSerialize(true),
  161. Http::STATUS_OK
  162. );
  163. }
  164. /**
  165. * Remove sensitive data from a StorageConfig before returning it to the user
  166. *
  167. * @param StorageConfig $storage
  168. */
  169. protected function sanitizeStorage(StorageConfig $storage) {
  170. $storage->setBackendOptions([]);
  171. $storage->setMountOptions([]);
  172. if ($storage->getAuthMechanism() instanceof IUserProvided) {
  173. try {
  174. $storage->getAuthMechanism()->manipulateStorageConfig($storage, $this->userSession->getUser());
  175. } catch (InsufficientDataForMeaningfulAnswerException $e) {
  176. // not configured yet
  177. }
  178. }
  179. }
  180. }