ListCommand.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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\Command;
  8. use OC\Core\Command\Base;
  9. use OC\User\NoUserException;
  10. use OCA\Files_External\Lib\StorageConfig;
  11. use OCA\Files_External\Service\GlobalStoragesService;
  12. use OCA\Files_External\Service\StoragesService;
  13. use OCA\Files_External\Service\UserStoragesService;
  14. use OCP\IUserManager;
  15. use OCP\IUserSession;
  16. use Symfony\Component\Console\Helper\Table;
  17. use Symfony\Component\Console\Input\InputArgument;
  18. use Symfony\Component\Console\Input\InputInterface;
  19. use Symfony\Component\Console\Input\InputOption;
  20. use Symfony\Component\Console\Output\OutputInterface;
  21. class ListCommand extends Base {
  22. public const ALL = -1;
  23. public function __construct(
  24. protected GlobalStoragesService $globalService,
  25. protected UserStoragesService $userService,
  26. protected IUserSession $userSession,
  27. protected IUserManager $userManager,
  28. ) {
  29. parent::__construct();
  30. }
  31. protected function configure(): void {
  32. $this
  33. ->setName('files_external:list')
  34. ->setDescription('List configured admin or personal mounts')
  35. ->addArgument(
  36. 'user_id',
  37. InputArgument::OPTIONAL,
  38. 'user id to list the personal mounts for, if no user is provided admin mounts will be listed'
  39. )->addOption(
  40. 'show-password',
  41. '',
  42. InputOption::VALUE_NONE,
  43. 'show passwords and secrets'
  44. )->addOption(
  45. 'full',
  46. null,
  47. InputOption::VALUE_NONE,
  48. 'don\'t truncate long values in table output'
  49. )->addOption(
  50. 'all',
  51. 'a',
  52. InputOption::VALUE_NONE,
  53. 'show both system wide mounts and all personal mounts'
  54. );
  55. parent::configure();
  56. }
  57. protected function execute(InputInterface $input, OutputInterface $output): int {
  58. /** @var StorageConfig[] $mounts */
  59. if ($input->getOption('all')) {
  60. $mounts = $this->globalService->getStorageForAllUsers();
  61. $userId = self::ALL;
  62. } else {
  63. $userId = (string)$input->getArgument('user_id');
  64. $storageService = $this->getStorageService($userId);
  65. $mounts = $storageService->getAllStorages();
  66. }
  67. $this->listMounts($userId, $mounts, $input, $output);
  68. return self::SUCCESS;
  69. }
  70. /**
  71. * @param ?string|ListCommand::ALL $userId
  72. * @param StorageConfig[] $mounts
  73. */
  74. public function listMounts($userId, array $mounts, InputInterface $input, OutputInterface $output): void {
  75. $outputType = $input->getOption('output');
  76. if (count($mounts) === 0) {
  77. if ($outputType === self::OUTPUT_FORMAT_JSON || $outputType === self::OUTPUT_FORMAT_JSON_PRETTY) {
  78. $output->writeln('[]');
  79. } else {
  80. if ($userId === self::ALL) {
  81. $output->writeln('<info>No mounts configured</info>');
  82. } elseif ($userId) {
  83. $output->writeln("<info>No mounts configured by $userId</info>");
  84. } else {
  85. $output->writeln('<info>No admin mounts configured</info>');
  86. }
  87. }
  88. return;
  89. }
  90. $headers = ['Mount ID', 'Mount Point', 'Storage', 'Authentication Type', 'Configuration', 'Options'];
  91. if (!$userId || $userId === self::ALL) {
  92. $headers[] = 'Applicable Users';
  93. $headers[] = 'Applicable Groups';
  94. }
  95. if ($userId === self::ALL) {
  96. $headers[] = 'Type';
  97. }
  98. if (!$input->getOption('show-password')) {
  99. $hideKeys = ['key', 'bucket', 'secret', 'password', 'refresh_token', 'token', 'client_secret', 'public_key', 'private_key'];
  100. foreach ($mounts as $mount) {
  101. $config = $mount->getBackendOptions();
  102. foreach ($config as $key => $value) {
  103. if (in_array($key, $hideKeys)) {
  104. $mount->setBackendOption($key, '***REMOVED SENSITIVE VALUE***');
  105. }
  106. }
  107. }
  108. }
  109. if ($outputType === self::OUTPUT_FORMAT_JSON || $outputType === self::OUTPUT_FORMAT_JSON_PRETTY) {
  110. $keys = array_map(function ($header) {
  111. return strtolower(str_replace(' ', '_', $header));
  112. }, $headers);
  113. $pairs = array_map(function (StorageConfig $config) use ($keys, $userId) {
  114. $values = [
  115. $config->getId(),
  116. $config->getMountPoint(),
  117. $config->getBackend()->getStorageClass(),
  118. $config->getAuthMechanism()->getIdentifier(),
  119. $config->getBackendOptions(),
  120. $config->getMountOptions()
  121. ];
  122. if (!$userId || $userId === self::ALL) {
  123. $values[] = $config->getApplicableUsers();
  124. $values[] = $config->getApplicableGroups();
  125. }
  126. if ($userId === self::ALL) {
  127. $values[] = $config->getType() === StorageConfig::MOUNT_TYPE_ADMIN ? 'admin' : 'personal';
  128. }
  129. return array_combine($keys, $values);
  130. }, $mounts);
  131. if ($outputType === self::OUTPUT_FORMAT_JSON) {
  132. $output->writeln(json_encode(array_values($pairs)));
  133. } else {
  134. $output->writeln(json_encode(array_values($pairs), JSON_PRETTY_PRINT));
  135. }
  136. } else {
  137. $full = $input->getOption('full');
  138. $defaultMountOptions = [
  139. 'encrypt' => true,
  140. 'previews' => true,
  141. 'filesystem_check_changes' => 1,
  142. 'enable_sharing' => false,
  143. 'encoding_compatibility' => false,
  144. 'readonly' => false,
  145. ];
  146. $rows = array_map(function (StorageConfig $config) use ($userId, $defaultMountOptions, $full) {
  147. $storageConfig = $config->getBackendOptions();
  148. $keys = array_keys($storageConfig);
  149. $values = array_values($storageConfig);
  150. if (!$full) {
  151. $values = array_map(function ($value) {
  152. if (is_string($value) && strlen($value) > 32) {
  153. return substr($value, 0, 6) . '...' . substr($value, -6, 6);
  154. } else {
  155. return $value;
  156. }
  157. }, $values);
  158. }
  159. $configStrings = array_map(function ($key, $value) {
  160. return $key . ': ' . json_encode($value);
  161. }, $keys, $values);
  162. $configString = implode(', ', $configStrings);
  163. $mountOptions = $config->getMountOptions();
  164. // hide defaults
  165. foreach ($mountOptions as $key => $value) {
  166. if ($value === $defaultMountOptions[$key]) {
  167. unset($mountOptions[$key]);
  168. }
  169. }
  170. $keys = array_keys($mountOptions);
  171. $values = array_values($mountOptions);
  172. $optionsStrings = array_map(function ($key, $value) {
  173. return $key . ': ' . json_encode($value);
  174. }, $keys, $values);
  175. $optionsString = implode(', ', $optionsStrings);
  176. $values = [
  177. $config->getId(),
  178. $config->getMountPoint(),
  179. $config->getBackend()->getText(),
  180. $config->getAuthMechanism()->getText(),
  181. $configString,
  182. $optionsString
  183. ];
  184. if (!$userId || $userId === self::ALL) {
  185. $applicableUsers = implode(', ', $config->getApplicableUsers());
  186. $applicableGroups = implode(', ', $config->getApplicableGroups());
  187. if ($applicableUsers === '' && $applicableGroups === '') {
  188. $applicableUsers = 'All';
  189. }
  190. $values[] = $applicableUsers;
  191. $values[] = $applicableGroups;
  192. }
  193. if ($userId === self::ALL) {
  194. $values[] = $config->getType() === StorageConfig::MOUNT_TYPE_ADMIN ? 'Admin' : 'Personal';
  195. }
  196. return $values;
  197. }, $mounts);
  198. $table = new Table($output);
  199. $table->setHeaders($headers);
  200. $table->setRows($rows);
  201. $table->render();
  202. }
  203. }
  204. protected function getStorageService(string $userId): StoragesService {
  205. if (empty($userId)) {
  206. return $this->globalService;
  207. }
  208. $user = $this->userManager->get($userId);
  209. if (is_null($user)) {
  210. throw new NoUserException("user $userId not found");
  211. }
  212. $this->userSession->setUser($user);
  213. return $this->userService;
  214. }
  215. }