@@ -22,143 +22,143 @@ |
||
| 22 | 22 | use Symfony\Component\Console\Output\OutputInterface; |
| 23 | 23 | |
| 24 | 24 | class ResetRenderedTexts extends Command { |
| 25 | - public function __construct( |
|
| 26 | - protected IDBConnection $connection, |
|
| 27 | - protected IUserManager $userManager, |
|
| 28 | - protected IAvatarManager $avatarManager, |
|
| 29 | - private Root $previewFolder, |
|
| 30 | - private IMimeTypeLoader $mimeTypeLoader, |
|
| 31 | - ) { |
|
| 32 | - parent::__construct(); |
|
| 33 | - } |
|
| 34 | - |
|
| 35 | - protected function configure() { |
|
| 36 | - $this |
|
| 37 | - ->setName('preview:reset-rendered-texts') |
|
| 38 | - ->setDescription('Deletes all generated avatars and previews of text and md files') |
|
| 39 | - ->addOption('dry', 'd', InputOption::VALUE_NONE, 'Dry mode - will not delete any files - in combination with the verbose mode one could check the operations.'); |
|
| 40 | - } |
|
| 41 | - |
|
| 42 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 43 | - $dryMode = $input->getOption('dry'); |
|
| 44 | - |
|
| 45 | - if ($dryMode) { |
|
| 46 | - $output->writeln('INFO: The command is run in dry mode and will not modify anything.'); |
|
| 47 | - $output->writeln(''); |
|
| 48 | - } |
|
| 49 | - |
|
| 50 | - $this->deleteAvatars($output, $dryMode); |
|
| 51 | - $this->deletePreviews($output, $dryMode); |
|
| 52 | - |
|
| 53 | - return 0; |
|
| 54 | - } |
|
| 55 | - |
|
| 56 | - private function deleteAvatars(OutputInterface $output, bool $dryMode): void { |
|
| 57 | - $avatarsToDeleteCount = 0; |
|
| 58 | - |
|
| 59 | - foreach ($this->getAvatarsToDelete() as [$userId, $avatar]) { |
|
| 60 | - $output->writeln('Deleting avatar for ' . $userId, OutputInterface::VERBOSITY_VERBOSE); |
|
| 61 | - |
|
| 62 | - $avatarsToDeleteCount++; |
|
| 63 | - |
|
| 64 | - if ($dryMode) { |
|
| 65 | - continue; |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - try { |
|
| 69 | - $avatar->remove(); |
|
| 70 | - } catch (NotFoundException $e) { |
|
| 71 | - // continue |
|
| 72 | - } catch (NotPermittedException $e) { |
|
| 73 | - // continue |
|
| 74 | - } |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - $output->writeln('Deleted ' . $avatarsToDeleteCount . ' avatars'); |
|
| 78 | - $output->writeln(''); |
|
| 79 | - } |
|
| 80 | - |
|
| 81 | - private function getAvatarsToDelete(): \Iterator { |
|
| 82 | - foreach ($this->userManager->searchDisplayName('') as $user) { |
|
| 83 | - $avatar = $this->avatarManager->getAvatar($user->getUID()); |
|
| 84 | - |
|
| 85 | - if (!$avatar->isCustomAvatar()) { |
|
| 86 | - yield [$user->getUID(), $avatar]; |
|
| 87 | - } |
|
| 88 | - } |
|
| 89 | - } |
|
| 90 | - |
|
| 91 | - private function deletePreviews(OutputInterface $output, bool $dryMode): void { |
|
| 92 | - $previewsToDeleteCount = 0; |
|
| 93 | - |
|
| 94 | - foreach ($this->getPreviewsToDelete() as ['name' => $previewFileId, 'path' => $filePath]) { |
|
| 95 | - $output->writeln('Deleting previews for ' . $filePath, OutputInterface::VERBOSITY_VERBOSE); |
|
| 96 | - |
|
| 97 | - $previewsToDeleteCount++; |
|
| 98 | - |
|
| 99 | - if ($dryMode) { |
|
| 100 | - continue; |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - try { |
|
| 104 | - $preview = $this->previewFolder->getFolder((string)$previewFileId); |
|
| 105 | - $preview->delete(); |
|
| 106 | - } catch (NotFoundException $e) { |
|
| 107 | - // continue |
|
| 108 | - } catch (NotPermittedException $e) { |
|
| 109 | - // continue |
|
| 110 | - } |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - $output->writeln('Deleted ' . $previewsToDeleteCount . ' previews'); |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - // Copy pasted and adjusted from |
|
| 117 | - // "lib/private/Preview/BackgroundCleanupJob.php". |
|
| 118 | - private function getPreviewsToDelete(): \Iterator { |
|
| 119 | - $qb = $this->connection->getQueryBuilder(); |
|
| 120 | - $qb->select('path', 'mimetype') |
|
| 121 | - ->from('filecache') |
|
| 122 | - ->where($qb->expr()->eq('fileid', $qb->createNamedParameter($this->previewFolder->getId()))); |
|
| 123 | - $cursor = $qb->executeQuery(); |
|
| 124 | - $data = $cursor->fetch(); |
|
| 125 | - $cursor->closeCursor(); |
|
| 126 | - |
|
| 127 | - if ($data === null) { |
|
| 128 | - return []; |
|
| 129 | - } |
|
| 130 | - |
|
| 131 | - /* |
|
| 25 | + public function __construct( |
|
| 26 | + protected IDBConnection $connection, |
|
| 27 | + protected IUserManager $userManager, |
|
| 28 | + protected IAvatarManager $avatarManager, |
|
| 29 | + private Root $previewFolder, |
|
| 30 | + private IMimeTypeLoader $mimeTypeLoader, |
|
| 31 | + ) { |
|
| 32 | + parent::__construct(); |
|
| 33 | + } |
|
| 34 | + |
|
| 35 | + protected function configure() { |
|
| 36 | + $this |
|
| 37 | + ->setName('preview:reset-rendered-texts') |
|
| 38 | + ->setDescription('Deletes all generated avatars and previews of text and md files') |
|
| 39 | + ->addOption('dry', 'd', InputOption::VALUE_NONE, 'Dry mode - will not delete any files - in combination with the verbose mode one could check the operations.'); |
|
| 40 | + } |
|
| 41 | + |
|
| 42 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 43 | + $dryMode = $input->getOption('dry'); |
|
| 44 | + |
|
| 45 | + if ($dryMode) { |
|
| 46 | + $output->writeln('INFO: The command is run in dry mode and will not modify anything.'); |
|
| 47 | + $output->writeln(''); |
|
| 48 | + } |
|
| 49 | + |
|
| 50 | + $this->deleteAvatars($output, $dryMode); |
|
| 51 | + $this->deletePreviews($output, $dryMode); |
|
| 52 | + |
|
| 53 | + return 0; |
|
| 54 | + } |
|
| 55 | + |
|
| 56 | + private function deleteAvatars(OutputInterface $output, bool $dryMode): void { |
|
| 57 | + $avatarsToDeleteCount = 0; |
|
| 58 | + |
|
| 59 | + foreach ($this->getAvatarsToDelete() as [$userId, $avatar]) { |
|
| 60 | + $output->writeln('Deleting avatar for ' . $userId, OutputInterface::VERBOSITY_VERBOSE); |
|
| 61 | + |
|
| 62 | + $avatarsToDeleteCount++; |
|
| 63 | + |
|
| 64 | + if ($dryMode) { |
|
| 65 | + continue; |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + try { |
|
| 69 | + $avatar->remove(); |
|
| 70 | + } catch (NotFoundException $e) { |
|
| 71 | + // continue |
|
| 72 | + } catch (NotPermittedException $e) { |
|
| 73 | + // continue |
|
| 74 | + } |
|
| 75 | + } |
|
| 76 | + |
|
| 77 | + $output->writeln('Deleted ' . $avatarsToDeleteCount . ' avatars'); |
|
| 78 | + $output->writeln(''); |
|
| 79 | + } |
|
| 80 | + |
|
| 81 | + private function getAvatarsToDelete(): \Iterator { |
|
| 82 | + foreach ($this->userManager->searchDisplayName('') as $user) { |
|
| 83 | + $avatar = $this->avatarManager->getAvatar($user->getUID()); |
|
| 84 | + |
|
| 85 | + if (!$avatar->isCustomAvatar()) { |
|
| 86 | + yield [$user->getUID(), $avatar]; |
|
| 87 | + } |
|
| 88 | + } |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + private function deletePreviews(OutputInterface $output, bool $dryMode): void { |
|
| 92 | + $previewsToDeleteCount = 0; |
|
| 93 | + |
|
| 94 | + foreach ($this->getPreviewsToDelete() as ['name' => $previewFileId, 'path' => $filePath]) { |
|
| 95 | + $output->writeln('Deleting previews for ' . $filePath, OutputInterface::VERBOSITY_VERBOSE); |
|
| 96 | + |
|
| 97 | + $previewsToDeleteCount++; |
|
| 98 | + |
|
| 99 | + if ($dryMode) { |
|
| 100 | + continue; |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + try { |
|
| 104 | + $preview = $this->previewFolder->getFolder((string)$previewFileId); |
|
| 105 | + $preview->delete(); |
|
| 106 | + } catch (NotFoundException $e) { |
|
| 107 | + // continue |
|
| 108 | + } catch (NotPermittedException $e) { |
|
| 109 | + // continue |
|
| 110 | + } |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + $output->writeln('Deleted ' . $previewsToDeleteCount . ' previews'); |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + // Copy pasted and adjusted from |
|
| 117 | + // "lib/private/Preview/BackgroundCleanupJob.php". |
|
| 118 | + private function getPreviewsToDelete(): \Iterator { |
|
| 119 | + $qb = $this->connection->getQueryBuilder(); |
|
| 120 | + $qb->select('path', 'mimetype') |
|
| 121 | + ->from('filecache') |
|
| 122 | + ->where($qb->expr()->eq('fileid', $qb->createNamedParameter($this->previewFolder->getId()))); |
|
| 123 | + $cursor = $qb->executeQuery(); |
|
| 124 | + $data = $cursor->fetch(); |
|
| 125 | + $cursor->closeCursor(); |
|
| 126 | + |
|
| 127 | + if ($data === null) { |
|
| 128 | + return []; |
|
| 129 | + } |
|
| 130 | + |
|
| 131 | + /* |
|
| 132 | 132 | * This lovely like is the result of the way the new previews are stored |
| 133 | 133 | * We take the md5 of the name (fileid) and split the first 7 chars. That way |
| 134 | 134 | * there are not a gazillion files in the root of the preview appdata. |
| 135 | 135 | */ |
| 136 | - $like = $this->connection->escapeLikeParameter($data['path']) . '/_/_/_/_/_/_/_/%'; |
|
| 137 | - |
|
| 138 | - $qb = $this->connection->getQueryBuilder(); |
|
| 139 | - $qb->select('a.name', 'b.path') |
|
| 140 | - ->from('filecache', 'a') |
|
| 141 | - ->leftJoin('a', 'filecache', 'b', $qb->expr()->eq( |
|
| 142 | - $qb->expr()->castColumn('a.name', IQueryBuilder::PARAM_INT), 'b.fileid' |
|
| 143 | - )) |
|
| 144 | - ->where( |
|
| 145 | - $qb->expr()->andX( |
|
| 146 | - $qb->expr()->like('a.path', $qb->createNamedParameter($like)), |
|
| 147 | - $qb->expr()->eq('a.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('httpd/unix-directory'))), |
|
| 148 | - $qb->expr()->orX( |
|
| 149 | - $qb->expr()->eq('b.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/plain'))), |
|
| 150 | - $qb->expr()->eq('b.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/markdown'))), |
|
| 151 | - $qb->expr()->eq('b.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/x-markdown'))) |
|
| 152 | - ) |
|
| 153 | - ) |
|
| 154 | - ); |
|
| 155 | - |
|
| 156 | - $cursor = $qb->executeQuery(); |
|
| 157 | - |
|
| 158 | - while ($row = $cursor->fetch()) { |
|
| 159 | - yield $row; |
|
| 160 | - } |
|
| 161 | - |
|
| 162 | - $cursor->closeCursor(); |
|
| 163 | - } |
|
| 136 | + $like = $this->connection->escapeLikeParameter($data['path']) . '/_/_/_/_/_/_/_/%'; |
|
| 137 | + |
|
| 138 | + $qb = $this->connection->getQueryBuilder(); |
|
| 139 | + $qb->select('a.name', 'b.path') |
|
| 140 | + ->from('filecache', 'a') |
|
| 141 | + ->leftJoin('a', 'filecache', 'b', $qb->expr()->eq( |
|
| 142 | + $qb->expr()->castColumn('a.name', IQueryBuilder::PARAM_INT), 'b.fileid' |
|
| 143 | + )) |
|
| 144 | + ->where( |
|
| 145 | + $qb->expr()->andX( |
|
| 146 | + $qb->expr()->like('a.path', $qb->createNamedParameter($like)), |
|
| 147 | + $qb->expr()->eq('a.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('httpd/unix-directory'))), |
|
| 148 | + $qb->expr()->orX( |
|
| 149 | + $qb->expr()->eq('b.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/plain'))), |
|
| 150 | + $qb->expr()->eq('b.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/markdown'))), |
|
| 151 | + $qb->expr()->eq('b.mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/x-markdown'))) |
|
| 152 | + ) |
|
| 153 | + ) |
|
| 154 | + ); |
|
| 155 | + |
|
| 156 | + $cursor = $qb->executeQuery(); |
|
| 157 | + |
|
| 158 | + while ($row = $cursor->fetch()) { |
|
| 159 | + yield $row; |
|
| 160 | + } |
|
| 161 | + |
|
| 162 | + $cursor->closeCursor(); |
|
| 163 | + } |
|
| 164 | 164 | } |
@@ -11,37 +11,37 @@ |
||
| 11 | 11 | use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; |
| 12 | 12 | |
| 13 | 13 | class Base extends \OC\Core\Command\Base { |
| 14 | - public function __construct( |
|
| 15 | - ?string $name, |
|
| 16 | - protected IUserManager $userManager, |
|
| 17 | - ) { |
|
| 18 | - parent::__construct($name); |
|
| 19 | - } |
|
| 14 | + public function __construct( |
|
| 15 | + ?string $name, |
|
| 16 | + protected IUserManager $userManager, |
|
| 17 | + ) { |
|
| 18 | + parent::__construct($name); |
|
| 19 | + } |
|
| 20 | 20 | |
| 21 | - /** |
|
| 22 | - * Return possible values for the named option |
|
| 23 | - * |
|
| 24 | - * @param string $optionName |
|
| 25 | - * @param CompletionContext $context |
|
| 26 | - * @return string[] |
|
| 27 | - */ |
|
| 28 | - public function completeOptionValues($optionName, CompletionContext $context) { |
|
| 29 | - return []; |
|
| 30 | - } |
|
| 21 | + /** |
|
| 22 | + * Return possible values for the named option |
|
| 23 | + * |
|
| 24 | + * @param string $optionName |
|
| 25 | + * @param CompletionContext $context |
|
| 26 | + * @return string[] |
|
| 27 | + */ |
|
| 28 | + public function completeOptionValues($optionName, CompletionContext $context) { |
|
| 29 | + return []; |
|
| 30 | + } |
|
| 31 | 31 | |
| 32 | - /** |
|
| 33 | - * Return possible values for the named argument |
|
| 34 | - * |
|
| 35 | - * @param string $argumentName |
|
| 36 | - * @param CompletionContext $context |
|
| 37 | - * @return string[] |
|
| 38 | - */ |
|
| 39 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 40 | - if ($argumentName === 'uid') { |
|
| 41 | - return array_map(function (IUser $user) { |
|
| 42 | - return $user->getUID(); |
|
| 43 | - }, $this->userManager->searchDisplayName($context->getCurrentWord(), 100)); |
|
| 44 | - } |
|
| 45 | - return []; |
|
| 46 | - } |
|
| 32 | + /** |
|
| 33 | + * Return possible values for the named argument |
|
| 34 | + * |
|
| 35 | + * @param string $argumentName |
|
| 36 | + * @param CompletionContext $context |
|
| 37 | + * @return string[] |
|
| 38 | + */ |
|
| 39 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 40 | + if ($argumentName === 'uid') { |
|
| 41 | + return array_map(function (IUser $user) { |
|
| 42 | + return $user->getUID(); |
|
| 43 | + }, $this->userManager->searchDisplayName($context->getCurrentWord(), 100)); |
|
| 44 | + } |
|
| 45 | + return []; |
|
| 46 | + } |
|
| 47 | 47 | } |
@@ -38,7 +38,7 @@ |
||
| 38 | 38 | */ |
| 39 | 39 | public function completeArgumentValues($argumentName, CompletionContext $context) { |
| 40 | 40 | if ($argumentName === 'uid') { |
| 41 | - return array_map(function (IUser $user) { |
|
| 41 | + return array_map(function(IUser $user) { |
|
| 42 | 42 | return $user->getUID(); |
| 43 | 43 | }, $this->userManager->searchDisplayName($context->getCurrentWord(), 100)); |
| 44 | 44 | } |
@@ -21,109 +21,109 @@ |
||
| 21 | 21 | use Symfony\Component\Console\Question\Question; |
| 22 | 22 | |
| 23 | 23 | class ResetPassword extends Base { |
| 24 | - public function __construct( |
|
| 25 | - protected IUserManager $userManager, |
|
| 26 | - private IAppManager $appManager, |
|
| 27 | - ) { |
|
| 28 | - parent::__construct(); |
|
| 29 | - } |
|
| 30 | - |
|
| 31 | - protected function configure() { |
|
| 32 | - $this |
|
| 33 | - ->setName('user:resetpassword') |
|
| 34 | - ->setDescription('Resets the password of the named user') |
|
| 35 | - ->addArgument( |
|
| 36 | - 'user', |
|
| 37 | - InputArgument::REQUIRED, |
|
| 38 | - 'Login to reset password' |
|
| 39 | - ) |
|
| 40 | - ->addOption( |
|
| 41 | - 'password-from-env', |
|
| 42 | - null, |
|
| 43 | - InputOption::VALUE_NONE, |
|
| 44 | - 'read password from environment variable NC_PASS/OC_PASS' |
|
| 45 | - ) |
|
| 46 | - ; |
|
| 47 | - } |
|
| 48 | - |
|
| 49 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 50 | - $username = $input->getArgument('user'); |
|
| 51 | - |
|
| 52 | - $user = $this->userManager->get($username); |
|
| 53 | - if (is_null($user)) { |
|
| 54 | - $output->writeln('<error>User does not exist</error>'); |
|
| 55 | - return 1; |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - if ($input->getOption('password-from-env')) { |
|
| 59 | - $password = getenv('NC_PASS') ?: getenv('OC_PASS'); |
|
| 60 | - if (!$password) { |
|
| 61 | - $output->writeln('<error>--password-from-env given, but NC_PASS/OC_PASS is empty!</error>'); |
|
| 62 | - return 1; |
|
| 63 | - } |
|
| 64 | - } elseif ($input->isInteractive()) { |
|
| 65 | - /** @var QuestionHelper $helper */ |
|
| 66 | - $helper = $this->getHelper('question'); |
|
| 67 | - |
|
| 68 | - if ($this->appManager->isEnabledForUser('encryption', $user)) { |
|
| 69 | - $output->writeln( |
|
| 70 | - '<error>Warning: Resetting the password when using encryption will result in data loss!</error>' |
|
| 71 | - ); |
|
| 72 | - |
|
| 73 | - $question = new ConfirmationQuestion('Do you want to continue?'); |
|
| 74 | - if (!$helper->ask($input, $output, $question)) { |
|
| 75 | - return 1; |
|
| 76 | - } |
|
| 77 | - } |
|
| 78 | - |
|
| 79 | - $question = new Question('Enter a new password: '); |
|
| 80 | - $question->setHidden(true); |
|
| 81 | - $password = $helper->ask($input, $output, $question); |
|
| 82 | - |
|
| 83 | - if ($password === null) { |
|
| 84 | - $output->writeln('<error>Password cannot be empty!</error>'); |
|
| 85 | - return 1; |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - $question = new Question('Confirm the new password: '); |
|
| 89 | - $question->setHidden(true); |
|
| 90 | - $confirm = $helper->ask($input, $output, $question); |
|
| 91 | - |
|
| 92 | - if ($password !== $confirm) { |
|
| 93 | - $output->writeln('<error>Passwords did not match!</error>'); |
|
| 94 | - return 1; |
|
| 95 | - } |
|
| 96 | - } else { |
|
| 97 | - $output->writeln('<error>Interactive input or --password-from-env is needed for entering a new password!</error>'); |
|
| 98 | - return 1; |
|
| 99 | - } |
|
| 100 | - |
|
| 101 | - |
|
| 102 | - try { |
|
| 103 | - $success = $user->setPassword($password); |
|
| 104 | - } catch (\Exception $e) { |
|
| 105 | - $output->writeln('<error>' . $e->getMessage() . '</error>'); |
|
| 106 | - return 1; |
|
| 107 | - } |
|
| 108 | - |
|
| 109 | - if ($success) { |
|
| 110 | - $output->writeln('<info>Successfully reset password for ' . $username . '</info>'); |
|
| 111 | - } else { |
|
| 112 | - $output->writeln('<error>Error while resetting password!</error>'); |
|
| 113 | - return 1; |
|
| 114 | - } |
|
| 115 | - return 0; |
|
| 116 | - } |
|
| 117 | - |
|
| 118 | - /** |
|
| 119 | - * @param string $argumentName |
|
| 120 | - * @param CompletionContext $context |
|
| 121 | - * @return string[] |
|
| 122 | - */ |
|
| 123 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 124 | - if ($argumentName === 'user') { |
|
| 125 | - return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 126 | - } |
|
| 127 | - return []; |
|
| 128 | - } |
|
| 24 | + public function __construct( |
|
| 25 | + protected IUserManager $userManager, |
|
| 26 | + private IAppManager $appManager, |
|
| 27 | + ) { |
|
| 28 | + parent::__construct(); |
|
| 29 | + } |
|
| 30 | + |
|
| 31 | + protected function configure() { |
|
| 32 | + $this |
|
| 33 | + ->setName('user:resetpassword') |
|
| 34 | + ->setDescription('Resets the password of the named user') |
|
| 35 | + ->addArgument( |
|
| 36 | + 'user', |
|
| 37 | + InputArgument::REQUIRED, |
|
| 38 | + 'Login to reset password' |
|
| 39 | + ) |
|
| 40 | + ->addOption( |
|
| 41 | + 'password-from-env', |
|
| 42 | + null, |
|
| 43 | + InputOption::VALUE_NONE, |
|
| 44 | + 'read password from environment variable NC_PASS/OC_PASS' |
|
| 45 | + ) |
|
| 46 | + ; |
|
| 47 | + } |
|
| 48 | + |
|
| 49 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 50 | + $username = $input->getArgument('user'); |
|
| 51 | + |
|
| 52 | + $user = $this->userManager->get($username); |
|
| 53 | + if (is_null($user)) { |
|
| 54 | + $output->writeln('<error>User does not exist</error>'); |
|
| 55 | + return 1; |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + if ($input->getOption('password-from-env')) { |
|
| 59 | + $password = getenv('NC_PASS') ?: getenv('OC_PASS'); |
|
| 60 | + if (!$password) { |
|
| 61 | + $output->writeln('<error>--password-from-env given, but NC_PASS/OC_PASS is empty!</error>'); |
|
| 62 | + return 1; |
|
| 63 | + } |
|
| 64 | + } elseif ($input->isInteractive()) { |
|
| 65 | + /** @var QuestionHelper $helper */ |
|
| 66 | + $helper = $this->getHelper('question'); |
|
| 67 | + |
|
| 68 | + if ($this->appManager->isEnabledForUser('encryption', $user)) { |
|
| 69 | + $output->writeln( |
|
| 70 | + '<error>Warning: Resetting the password when using encryption will result in data loss!</error>' |
|
| 71 | + ); |
|
| 72 | + |
|
| 73 | + $question = new ConfirmationQuestion('Do you want to continue?'); |
|
| 74 | + if (!$helper->ask($input, $output, $question)) { |
|
| 75 | + return 1; |
|
| 76 | + } |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + $question = new Question('Enter a new password: '); |
|
| 80 | + $question->setHidden(true); |
|
| 81 | + $password = $helper->ask($input, $output, $question); |
|
| 82 | + |
|
| 83 | + if ($password === null) { |
|
| 84 | + $output->writeln('<error>Password cannot be empty!</error>'); |
|
| 85 | + return 1; |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + $question = new Question('Confirm the new password: '); |
|
| 89 | + $question->setHidden(true); |
|
| 90 | + $confirm = $helper->ask($input, $output, $question); |
|
| 91 | + |
|
| 92 | + if ($password !== $confirm) { |
|
| 93 | + $output->writeln('<error>Passwords did not match!</error>'); |
|
| 94 | + return 1; |
|
| 95 | + } |
|
| 96 | + } else { |
|
| 97 | + $output->writeln('<error>Interactive input or --password-from-env is needed for entering a new password!</error>'); |
|
| 98 | + return 1; |
|
| 99 | + } |
|
| 100 | + |
|
| 101 | + |
|
| 102 | + try { |
|
| 103 | + $success = $user->setPassword($password); |
|
| 104 | + } catch (\Exception $e) { |
|
| 105 | + $output->writeln('<error>' . $e->getMessage() . '</error>'); |
|
| 106 | + return 1; |
|
| 107 | + } |
|
| 108 | + |
|
| 109 | + if ($success) { |
|
| 110 | + $output->writeln('<info>Successfully reset password for ' . $username . '</info>'); |
|
| 111 | + } else { |
|
| 112 | + $output->writeln('<error>Error while resetting password!</error>'); |
|
| 113 | + return 1; |
|
| 114 | + } |
|
| 115 | + return 0; |
|
| 116 | + } |
|
| 117 | + |
|
| 118 | + /** |
|
| 119 | + * @param string $argumentName |
|
| 120 | + * @param CompletionContext $context |
|
| 121 | + * @return string[] |
|
| 122 | + */ |
|
| 123 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 124 | + if ($argumentName === 'user') { |
|
| 125 | + return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 126 | + } |
|
| 127 | + return []; |
|
| 128 | + } |
|
| 129 | 129 | } |
@@ -16,50 +16,50 @@ |
||
| 16 | 16 | use Symfony\Component\Console\Output\OutputInterface; |
| 17 | 17 | |
| 18 | 18 | class Disable extends Base { |
| 19 | - public function __construct( |
|
| 20 | - protected IUserManager $userManager, |
|
| 21 | - ) { |
|
| 22 | - parent::__construct(); |
|
| 23 | - } |
|
| 19 | + public function __construct( |
|
| 20 | + protected IUserManager $userManager, |
|
| 21 | + ) { |
|
| 22 | + parent::__construct(); |
|
| 23 | + } |
|
| 24 | 24 | |
| 25 | - protected function configure() { |
|
| 26 | - $this |
|
| 27 | - ->setName('user:disable') |
|
| 28 | - ->setDescription('disables the specified user') |
|
| 29 | - ->addArgument( |
|
| 30 | - 'uid', |
|
| 31 | - InputArgument::REQUIRED, |
|
| 32 | - 'the username' |
|
| 33 | - ); |
|
| 34 | - } |
|
| 25 | + protected function configure() { |
|
| 26 | + $this |
|
| 27 | + ->setName('user:disable') |
|
| 28 | + ->setDescription('disables the specified user') |
|
| 29 | + ->addArgument( |
|
| 30 | + 'uid', |
|
| 31 | + InputArgument::REQUIRED, |
|
| 32 | + 'the username' |
|
| 33 | + ); |
|
| 34 | + } |
|
| 35 | 35 | |
| 36 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 37 | - $user = $this->userManager->get($input->getArgument('uid')); |
|
| 38 | - if (is_null($user)) { |
|
| 39 | - $output->writeln('<error>User does not exist</error>'); |
|
| 40 | - return 1; |
|
| 41 | - } |
|
| 36 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 37 | + $user = $this->userManager->get($input->getArgument('uid')); |
|
| 38 | + if (is_null($user)) { |
|
| 39 | + $output->writeln('<error>User does not exist</error>'); |
|
| 40 | + return 1; |
|
| 41 | + } |
|
| 42 | 42 | |
| 43 | - $user->setEnabled(false); |
|
| 44 | - $output->writeln('<info>The specified user is disabled</info>'); |
|
| 45 | - return 0; |
|
| 46 | - } |
|
| 43 | + $user->setEnabled(false); |
|
| 44 | + $output->writeln('<info>The specified user is disabled</info>'); |
|
| 45 | + return 0; |
|
| 46 | + } |
|
| 47 | 47 | |
| 48 | - /** |
|
| 49 | - * @param string $argumentName |
|
| 50 | - * @param CompletionContext $context |
|
| 51 | - * @return string[] |
|
| 52 | - */ |
|
| 53 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 54 | - if ($argumentName === 'uid') { |
|
| 55 | - return array_map( |
|
| 56 | - static fn (IUser $user) => $user->getUID(), |
|
| 57 | - array_filter( |
|
| 58 | - $this->userManager->searchDisplayName($context->getCurrentWord()), |
|
| 59 | - static fn (IUser $user) => $user->isEnabled() |
|
| 60 | - ) |
|
| 61 | - ); |
|
| 62 | - } |
|
| 63 | - return []; |
|
| 64 | - } |
|
| 48 | + /** |
|
| 49 | + * @param string $argumentName |
|
| 50 | + * @param CompletionContext $context |
|
| 51 | + * @return string[] |
|
| 52 | + */ |
|
| 53 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 54 | + if ($argumentName === 'uid') { |
|
| 55 | + return array_map( |
|
| 56 | + static fn (IUser $user) => $user->getUID(), |
|
| 57 | + array_filter( |
|
| 58 | + $this->userManager->searchDisplayName($context->getCurrentWord()), |
|
| 59 | + static fn (IUser $user) => $user->isEnabled() |
|
| 60 | + ) |
|
| 61 | + ); |
|
| 62 | + } |
|
| 63 | + return []; |
|
| 64 | + } |
|
| 65 | 65 | } |
@@ -16,50 +16,50 @@ |
||
| 16 | 16 | use Symfony\Component\Console\Output\OutputInterface; |
| 17 | 17 | |
| 18 | 18 | class Enable extends Base { |
| 19 | - public function __construct( |
|
| 20 | - protected IUserManager $userManager, |
|
| 21 | - ) { |
|
| 22 | - parent::__construct(); |
|
| 23 | - } |
|
| 19 | + public function __construct( |
|
| 20 | + protected IUserManager $userManager, |
|
| 21 | + ) { |
|
| 22 | + parent::__construct(); |
|
| 23 | + } |
|
| 24 | 24 | |
| 25 | - protected function configure() { |
|
| 26 | - $this |
|
| 27 | - ->setName('user:enable') |
|
| 28 | - ->setDescription('enables the specified user') |
|
| 29 | - ->addArgument( |
|
| 30 | - 'uid', |
|
| 31 | - InputArgument::REQUIRED, |
|
| 32 | - 'the username' |
|
| 33 | - ); |
|
| 34 | - } |
|
| 25 | + protected function configure() { |
|
| 26 | + $this |
|
| 27 | + ->setName('user:enable') |
|
| 28 | + ->setDescription('enables the specified user') |
|
| 29 | + ->addArgument( |
|
| 30 | + 'uid', |
|
| 31 | + InputArgument::REQUIRED, |
|
| 32 | + 'the username' |
|
| 33 | + ); |
|
| 34 | + } |
|
| 35 | 35 | |
| 36 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 37 | - $user = $this->userManager->get($input->getArgument('uid')); |
|
| 38 | - if (is_null($user)) { |
|
| 39 | - $output->writeln('<error>User does not exist</error>'); |
|
| 40 | - return 1; |
|
| 41 | - } |
|
| 36 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 37 | + $user = $this->userManager->get($input->getArgument('uid')); |
|
| 38 | + if (is_null($user)) { |
|
| 39 | + $output->writeln('<error>User does not exist</error>'); |
|
| 40 | + return 1; |
|
| 41 | + } |
|
| 42 | 42 | |
| 43 | - $user->setEnabled(true); |
|
| 44 | - $output->writeln('<info>The specified user is enabled</info>'); |
|
| 45 | - return 0; |
|
| 46 | - } |
|
| 43 | + $user->setEnabled(true); |
|
| 44 | + $output->writeln('<info>The specified user is enabled</info>'); |
|
| 45 | + return 0; |
|
| 46 | + } |
|
| 47 | 47 | |
| 48 | - /** |
|
| 49 | - * @param string $argumentName |
|
| 50 | - * @param CompletionContext $context |
|
| 51 | - * @return string[] |
|
| 52 | - */ |
|
| 53 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 54 | - if ($argumentName === 'uid') { |
|
| 55 | - return array_map( |
|
| 56 | - static fn (IUser $user) => $user->getUID(), |
|
| 57 | - array_filter( |
|
| 58 | - $this->userManager->searchDisplayName($context->getCurrentWord()), |
|
| 59 | - static fn (IUser $user) => !$user->isEnabled() |
|
| 60 | - ) |
|
| 61 | - ); |
|
| 62 | - } |
|
| 63 | - return []; |
|
| 64 | - } |
|
| 48 | + /** |
|
| 49 | + * @param string $argumentName |
|
| 50 | + * @param CompletionContext $context |
|
| 51 | + * @return string[] |
|
| 52 | + */ |
|
| 53 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 54 | + if ($argumentName === 'uid') { |
|
| 55 | + return array_map( |
|
| 56 | + static fn (IUser $user) => $user->getUID(), |
|
| 57 | + array_filter( |
|
| 58 | + $this->userManager->searchDisplayName($context->getCurrentWord()), |
|
| 59 | + static fn (IUser $user) => !$user->isEnabled() |
|
| 60 | + ) |
|
| 61 | + ); |
|
| 62 | + } |
|
| 63 | + return []; |
|
| 64 | + } |
|
| 65 | 65 | } |
@@ -17,79 +17,79 @@ |
||
| 17 | 17 | use Symfony\Component\Console\Output\OutputInterface; |
| 18 | 18 | |
| 19 | 19 | class LastSeen extends Base { |
| 20 | - public function __construct( |
|
| 21 | - protected IUserManager $userManager, |
|
| 22 | - ) { |
|
| 23 | - parent::__construct(); |
|
| 24 | - } |
|
| 20 | + public function __construct( |
|
| 21 | + protected IUserManager $userManager, |
|
| 22 | + ) { |
|
| 23 | + parent::__construct(); |
|
| 24 | + } |
|
| 25 | 25 | |
| 26 | - protected function configure(): void { |
|
| 27 | - $this |
|
| 28 | - ->setName('user:lastseen') |
|
| 29 | - ->setDescription('shows when the user was logged in last time') |
|
| 30 | - ->addArgument( |
|
| 31 | - 'uid', |
|
| 32 | - InputArgument::OPTIONAL, |
|
| 33 | - 'the username' |
|
| 34 | - ) |
|
| 35 | - ->addOption( |
|
| 36 | - 'all', |
|
| 37 | - null, |
|
| 38 | - InputOption::VALUE_NONE, |
|
| 39 | - 'shows a list of when all users were last logged in' |
|
| 40 | - ) |
|
| 41 | - ; |
|
| 42 | - } |
|
| 26 | + protected function configure(): void { |
|
| 27 | + $this |
|
| 28 | + ->setName('user:lastseen') |
|
| 29 | + ->setDescription('shows when the user was logged in last time') |
|
| 30 | + ->addArgument( |
|
| 31 | + 'uid', |
|
| 32 | + InputArgument::OPTIONAL, |
|
| 33 | + 'the username' |
|
| 34 | + ) |
|
| 35 | + ->addOption( |
|
| 36 | + 'all', |
|
| 37 | + null, |
|
| 38 | + InputOption::VALUE_NONE, |
|
| 39 | + 'shows a list of when all users were last logged in' |
|
| 40 | + ) |
|
| 41 | + ; |
|
| 42 | + } |
|
| 43 | 43 | |
| 44 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 45 | - $singleUserId = $input->getArgument('uid'); |
|
| 44 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 45 | + $singleUserId = $input->getArgument('uid'); |
|
| 46 | 46 | |
| 47 | - if ($singleUserId) { |
|
| 48 | - $user = $this->userManager->get($singleUserId); |
|
| 49 | - if (is_null($user)) { |
|
| 50 | - $output->writeln('<error>User does not exist</error>'); |
|
| 51 | - return 1; |
|
| 52 | - } |
|
| 47 | + if ($singleUserId) { |
|
| 48 | + $user = $this->userManager->get($singleUserId); |
|
| 49 | + if (is_null($user)) { |
|
| 50 | + $output->writeln('<error>User does not exist</error>'); |
|
| 51 | + return 1; |
|
| 52 | + } |
|
| 53 | 53 | |
| 54 | - $lastLogin = $user->getLastLogin(); |
|
| 55 | - if ($lastLogin === 0) { |
|
| 56 | - $output->writeln($user->getUID() . ' has never logged in.'); |
|
| 57 | - } else { |
|
| 58 | - $date = new \DateTime(); |
|
| 59 | - $date->setTimestamp($lastLogin); |
|
| 60 | - $output->writeln($user->getUID() . "'s last login: " . $date->format('Y-m-d H:i:s T')); |
|
| 61 | - } |
|
| 54 | + $lastLogin = $user->getLastLogin(); |
|
| 55 | + if ($lastLogin === 0) { |
|
| 56 | + $output->writeln($user->getUID() . ' has never logged in.'); |
|
| 57 | + } else { |
|
| 58 | + $date = new \DateTime(); |
|
| 59 | + $date->setTimestamp($lastLogin); |
|
| 60 | + $output->writeln($user->getUID() . "'s last login: " . $date->format('Y-m-d H:i:s T')); |
|
| 61 | + } |
|
| 62 | 62 | |
| 63 | - return 0; |
|
| 64 | - } |
|
| 63 | + return 0; |
|
| 64 | + } |
|
| 65 | 65 | |
| 66 | - if (!$input->getOption('all')) { |
|
| 67 | - $output->writeln('<error>Please specify a username, or "--all" to list all</error>'); |
|
| 68 | - return 1; |
|
| 69 | - } |
|
| 66 | + if (!$input->getOption('all')) { |
|
| 67 | + $output->writeln('<error>Please specify a username, or "--all" to list all</error>'); |
|
| 68 | + return 1; |
|
| 69 | + } |
|
| 70 | 70 | |
| 71 | - $this->userManager->callForAllUsers(static function (IUser $user) use ($output): void { |
|
| 72 | - $lastLogin = $user->getLastLogin(); |
|
| 73 | - if ($lastLogin === 0) { |
|
| 74 | - $output->writeln($user->getUID() . ' has never logged in.'); |
|
| 75 | - } else { |
|
| 76 | - $date = new \DateTime(); |
|
| 77 | - $date->setTimestamp($lastLogin); |
|
| 78 | - $output->writeln($user->getUID() . "'s last login: " . $date->format('Y-m-d H:i:s T')); |
|
| 79 | - } |
|
| 80 | - }); |
|
| 81 | - return 0; |
|
| 82 | - } |
|
| 71 | + $this->userManager->callForAllUsers(static function (IUser $user) use ($output): void { |
|
| 72 | + $lastLogin = $user->getLastLogin(); |
|
| 73 | + if ($lastLogin === 0) { |
|
| 74 | + $output->writeln($user->getUID() . ' has never logged in.'); |
|
| 75 | + } else { |
|
| 76 | + $date = new \DateTime(); |
|
| 77 | + $date->setTimestamp($lastLogin); |
|
| 78 | + $output->writeln($user->getUID() . "'s last login: " . $date->format('Y-m-d H:i:s T')); |
|
| 79 | + } |
|
| 80 | + }); |
|
| 81 | + return 0; |
|
| 82 | + } |
|
| 83 | 83 | |
| 84 | - /** |
|
| 85 | - * @param string $argumentName |
|
| 86 | - * @param CompletionContext $context |
|
| 87 | - * @return string[] |
|
| 88 | - */ |
|
| 89 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 90 | - if ($argumentName === 'uid') { |
|
| 91 | - return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 92 | - } |
|
| 93 | - return []; |
|
| 94 | - } |
|
| 84 | + /** |
|
| 85 | + * @param string $argumentName |
|
| 86 | + * @param CompletionContext $context |
|
| 87 | + * @return string[] |
|
| 88 | + */ |
|
| 89 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 90 | + if ($argumentName === 'uid') { |
|
| 91 | + return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 92 | + } |
|
| 93 | + return []; |
|
| 94 | + } |
|
| 95 | 95 | } |
@@ -21,214 +21,214 @@ |
||
| 21 | 21 | use Symfony\Component\Console\Output\OutputInterface; |
| 22 | 22 | |
| 23 | 23 | class Profile extends Base { |
| 24 | - public function __construct( |
|
| 25 | - protected IUserManager $userManager, |
|
| 26 | - protected IAccountManager $accountManager, |
|
| 27 | - ) { |
|
| 28 | - parent::__construct(); |
|
| 29 | - } |
|
| 30 | - |
|
| 31 | - protected function configure() { |
|
| 32 | - parent::configure(); |
|
| 33 | - $this |
|
| 34 | - ->setName('user:profile') |
|
| 35 | - ->setDescription('Read and modify user profile properties') |
|
| 36 | - ->addArgument( |
|
| 37 | - 'uid', |
|
| 38 | - InputArgument::REQUIRED, |
|
| 39 | - 'Account ID used to login' |
|
| 40 | - ) |
|
| 41 | - ->addArgument( |
|
| 42 | - 'key', |
|
| 43 | - InputArgument::OPTIONAL, |
|
| 44 | - 'Profile property to set, get or delete', |
|
| 45 | - '' |
|
| 46 | - ) |
|
| 47 | - |
|
| 48 | - // Get |
|
| 49 | - ->addOption( |
|
| 50 | - 'default-value', |
|
| 51 | - null, |
|
| 52 | - InputOption::VALUE_REQUIRED, |
|
| 53 | - '(Only applicable on get) If no default value is set and the property does not exist, the command will exit with 1' |
|
| 54 | - ) |
|
| 55 | - |
|
| 56 | - // Set |
|
| 57 | - ->addArgument( |
|
| 58 | - 'value', |
|
| 59 | - InputArgument::OPTIONAL, |
|
| 60 | - 'The new value of the property', |
|
| 61 | - null |
|
| 62 | - ) |
|
| 63 | - ->addOption( |
|
| 64 | - 'update-only', |
|
| 65 | - null, |
|
| 66 | - InputOption::VALUE_NONE, |
|
| 67 | - 'Only updates the value, if it is not set before, it is not being added' |
|
| 68 | - ) |
|
| 69 | - |
|
| 70 | - // Delete |
|
| 71 | - ->addOption( |
|
| 72 | - 'delete', |
|
| 73 | - null, |
|
| 74 | - InputOption::VALUE_NONE, |
|
| 75 | - 'Specify this option to delete the property value' |
|
| 76 | - ) |
|
| 77 | - ->addOption( |
|
| 78 | - 'error-if-not-exists', |
|
| 79 | - null, |
|
| 80 | - InputOption::VALUE_NONE, |
|
| 81 | - 'Checks whether the property exists before deleting it' |
|
| 82 | - ) |
|
| 83 | - ; |
|
| 84 | - } |
|
| 85 | - |
|
| 86 | - protected function checkInput(InputInterface $input): IUser { |
|
| 87 | - $uid = $input->getArgument('uid'); |
|
| 88 | - $user = $this->userManager->get($uid); |
|
| 89 | - if (!$user) { |
|
| 90 | - throw new \InvalidArgumentException('The user "' . $uid . '" does not exist.'); |
|
| 91 | - } |
|
| 92 | - // normalize uid |
|
| 93 | - $input->setArgument('uid', $user->getUID()); |
|
| 94 | - |
|
| 95 | - $key = $input->getArgument('key'); |
|
| 96 | - if ($key === '') { |
|
| 97 | - if ($input->hasParameterOption('--default-value')) { |
|
| 98 | - throw new \InvalidArgumentException('The "default-value" option can only be used when specifying a key.'); |
|
| 99 | - } |
|
| 100 | - if ($input->getArgument('value') !== null) { |
|
| 101 | - throw new \InvalidArgumentException('The value argument can only be used when specifying a key.'); |
|
| 102 | - } |
|
| 103 | - if ($input->getOption('delete')) { |
|
| 104 | - throw new \InvalidArgumentException('The "delete" option can only be used when specifying a key.'); |
|
| 105 | - } |
|
| 106 | - } |
|
| 107 | - |
|
| 108 | - if ($input->getArgument('value') !== null && $input->hasParameterOption('--default-value')) { |
|
| 109 | - throw new \InvalidArgumentException('The value argument can not be used together with "default-value".'); |
|
| 110 | - } |
|
| 111 | - if ($input->getOption('update-only') && $input->getArgument('value') === null) { |
|
| 112 | - throw new \InvalidArgumentException('The "update-only" option can only be used together with "value".'); |
|
| 113 | - } |
|
| 114 | - |
|
| 115 | - if ($input->getOption('delete') && $input->hasParameterOption('--default-value')) { |
|
| 116 | - throw new \InvalidArgumentException('The "delete" option can not be used together with "default-value".'); |
|
| 117 | - } |
|
| 118 | - if ($input->getOption('delete') && $input->getArgument('value') !== null) { |
|
| 119 | - throw new \InvalidArgumentException('The "delete" option can not be used together with "value".'); |
|
| 120 | - } |
|
| 121 | - if ($input->getOption('error-if-not-exists') && !$input->getOption('delete')) { |
|
| 122 | - throw new \InvalidArgumentException('The "error-if-not-exists" option can only be used together with "delete".'); |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - return $user; |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 129 | - try { |
|
| 130 | - $user = $this->checkInput($input); |
|
| 131 | - } catch (\InvalidArgumentException $e) { |
|
| 132 | - $output->writeln('<error>' . $e->getMessage() . '</error>'); |
|
| 133 | - return self::FAILURE; |
|
| 134 | - } |
|
| 135 | - |
|
| 136 | - $uid = $input->getArgument('uid'); |
|
| 137 | - $key = $input->getArgument('key'); |
|
| 138 | - $userAccount = $this->accountManager->getAccount($user); |
|
| 139 | - |
|
| 140 | - if ($key === '') { |
|
| 141 | - $settings = $this->getAllProfileProperties($userAccount); |
|
| 142 | - $this->writeArrayInOutputFormat($input, $output, $settings); |
|
| 143 | - return self::SUCCESS; |
|
| 144 | - } |
|
| 145 | - |
|
| 146 | - $value = $this->getStoredValue($userAccount, $key); |
|
| 147 | - $inputValue = $input->getArgument('value'); |
|
| 148 | - if ($inputValue !== null) { |
|
| 149 | - if ($input->hasParameterOption('--update-only') && $value === null) { |
|
| 150 | - $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>'); |
|
| 151 | - return self::FAILURE; |
|
| 152 | - } |
|
| 153 | - |
|
| 154 | - return $this->editProfileProperty($output, $userAccount, $key, $inputValue); |
|
| 155 | - } elseif ($input->hasParameterOption('--delete')) { |
|
| 156 | - if ($input->hasParameterOption('--error-if-not-exists') && $value === null) { |
|
| 157 | - $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>'); |
|
| 158 | - return self::FAILURE; |
|
| 159 | - } |
|
| 160 | - |
|
| 161 | - return $this->deleteProfileProperty($output, $userAccount, $key); |
|
| 162 | - } elseif ($value !== null) { |
|
| 163 | - $output->writeln($value); |
|
| 164 | - } elseif ($input->hasParameterOption('--default-value')) { |
|
| 165 | - $output->writeln($input->getOption('default-value')); |
|
| 166 | - } else { |
|
| 167 | - $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>'); |
|
| 168 | - return self::FAILURE; |
|
| 169 | - } |
|
| 170 | - |
|
| 171 | - return self::SUCCESS; |
|
| 172 | - } |
|
| 173 | - |
|
| 174 | - private function deleteProfileProperty(OutputInterface $output, IAccount $userAccount, string $key): int { |
|
| 175 | - return $this->editProfileProperty($output, $userAccount, $key, ''); |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - private function editProfileProperty(OutputInterface $output, IAccount $userAccount, string $key, string $value): int { |
|
| 179 | - try { |
|
| 180 | - $userAccount->getProperty($key)->setValue($value); |
|
| 181 | - } catch (PropertyDoesNotExistException $exception) { |
|
| 182 | - $output->writeln('<error>' . $exception->getMessage() . '</error>'); |
|
| 183 | - return self::FAILURE; |
|
| 184 | - } |
|
| 185 | - |
|
| 186 | - $this->accountManager->updateAccount($userAccount); |
|
| 187 | - return self::SUCCESS; |
|
| 188 | - } |
|
| 189 | - |
|
| 190 | - private function getStoredValue(IAccount $userAccount, string $key): ?string { |
|
| 191 | - try { |
|
| 192 | - $property = $userAccount->getProperty($key); |
|
| 193 | - } catch (PropertyDoesNotExistException) { |
|
| 194 | - return null; |
|
| 195 | - } |
|
| 196 | - return $property->getValue() === '' ? null : $property->getValue(); |
|
| 197 | - } |
|
| 198 | - |
|
| 199 | - private function getAllProfileProperties(IAccount $userAccount): array { |
|
| 200 | - $properties = []; |
|
| 201 | - |
|
| 202 | - foreach ($userAccount->getAllProperties() as $property) { |
|
| 203 | - if ($property->getValue() !== '') { |
|
| 204 | - $properties[$property->getName()] = $property->getValue(); |
|
| 205 | - } |
|
| 206 | - } |
|
| 207 | - |
|
| 208 | - return $properties; |
|
| 209 | - } |
|
| 210 | - |
|
| 211 | - /** |
|
| 212 | - * @param string $argumentName |
|
| 213 | - * @param CompletionContext $context |
|
| 214 | - * @return string[] |
|
| 215 | - */ |
|
| 216 | - public function completeArgumentValues($argumentName, CompletionContext $context): array { |
|
| 217 | - if ($argumentName === 'uid') { |
|
| 218 | - return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 219 | - } |
|
| 220 | - if ($argumentName === 'key') { |
|
| 221 | - $userId = $context->getWordAtIndex($context->getWordIndex() - 1); |
|
| 222 | - $user = $this->userManager->get($userId); |
|
| 223 | - if (!($user instanceof IUser)) { |
|
| 224 | - return []; |
|
| 225 | - } |
|
| 226 | - |
|
| 227 | - $account = $this->accountManager->getAccount($user); |
|
| 228 | - |
|
| 229 | - $properties = $this->getAllProfileProperties($account); |
|
| 230 | - return array_keys($properties); |
|
| 231 | - } |
|
| 232 | - return []; |
|
| 233 | - } |
|
| 24 | + public function __construct( |
|
| 25 | + protected IUserManager $userManager, |
|
| 26 | + protected IAccountManager $accountManager, |
|
| 27 | + ) { |
|
| 28 | + parent::__construct(); |
|
| 29 | + } |
|
| 30 | + |
|
| 31 | + protected function configure() { |
|
| 32 | + parent::configure(); |
|
| 33 | + $this |
|
| 34 | + ->setName('user:profile') |
|
| 35 | + ->setDescription('Read and modify user profile properties') |
|
| 36 | + ->addArgument( |
|
| 37 | + 'uid', |
|
| 38 | + InputArgument::REQUIRED, |
|
| 39 | + 'Account ID used to login' |
|
| 40 | + ) |
|
| 41 | + ->addArgument( |
|
| 42 | + 'key', |
|
| 43 | + InputArgument::OPTIONAL, |
|
| 44 | + 'Profile property to set, get or delete', |
|
| 45 | + '' |
|
| 46 | + ) |
|
| 47 | + |
|
| 48 | + // Get |
|
| 49 | + ->addOption( |
|
| 50 | + 'default-value', |
|
| 51 | + null, |
|
| 52 | + InputOption::VALUE_REQUIRED, |
|
| 53 | + '(Only applicable on get) If no default value is set and the property does not exist, the command will exit with 1' |
|
| 54 | + ) |
|
| 55 | + |
|
| 56 | + // Set |
|
| 57 | + ->addArgument( |
|
| 58 | + 'value', |
|
| 59 | + InputArgument::OPTIONAL, |
|
| 60 | + 'The new value of the property', |
|
| 61 | + null |
|
| 62 | + ) |
|
| 63 | + ->addOption( |
|
| 64 | + 'update-only', |
|
| 65 | + null, |
|
| 66 | + InputOption::VALUE_NONE, |
|
| 67 | + 'Only updates the value, if it is not set before, it is not being added' |
|
| 68 | + ) |
|
| 69 | + |
|
| 70 | + // Delete |
|
| 71 | + ->addOption( |
|
| 72 | + 'delete', |
|
| 73 | + null, |
|
| 74 | + InputOption::VALUE_NONE, |
|
| 75 | + 'Specify this option to delete the property value' |
|
| 76 | + ) |
|
| 77 | + ->addOption( |
|
| 78 | + 'error-if-not-exists', |
|
| 79 | + null, |
|
| 80 | + InputOption::VALUE_NONE, |
|
| 81 | + 'Checks whether the property exists before deleting it' |
|
| 82 | + ) |
|
| 83 | + ; |
|
| 84 | + } |
|
| 85 | + |
|
| 86 | + protected function checkInput(InputInterface $input): IUser { |
|
| 87 | + $uid = $input->getArgument('uid'); |
|
| 88 | + $user = $this->userManager->get($uid); |
|
| 89 | + if (!$user) { |
|
| 90 | + throw new \InvalidArgumentException('The user "' . $uid . '" does not exist.'); |
|
| 91 | + } |
|
| 92 | + // normalize uid |
|
| 93 | + $input->setArgument('uid', $user->getUID()); |
|
| 94 | + |
|
| 95 | + $key = $input->getArgument('key'); |
|
| 96 | + if ($key === '') { |
|
| 97 | + if ($input->hasParameterOption('--default-value')) { |
|
| 98 | + throw new \InvalidArgumentException('The "default-value" option can only be used when specifying a key.'); |
|
| 99 | + } |
|
| 100 | + if ($input->getArgument('value') !== null) { |
|
| 101 | + throw new \InvalidArgumentException('The value argument can only be used when specifying a key.'); |
|
| 102 | + } |
|
| 103 | + if ($input->getOption('delete')) { |
|
| 104 | + throw new \InvalidArgumentException('The "delete" option can only be used when specifying a key.'); |
|
| 105 | + } |
|
| 106 | + } |
|
| 107 | + |
|
| 108 | + if ($input->getArgument('value') !== null && $input->hasParameterOption('--default-value')) { |
|
| 109 | + throw new \InvalidArgumentException('The value argument can not be used together with "default-value".'); |
|
| 110 | + } |
|
| 111 | + if ($input->getOption('update-only') && $input->getArgument('value') === null) { |
|
| 112 | + throw new \InvalidArgumentException('The "update-only" option can only be used together with "value".'); |
|
| 113 | + } |
|
| 114 | + |
|
| 115 | + if ($input->getOption('delete') && $input->hasParameterOption('--default-value')) { |
|
| 116 | + throw new \InvalidArgumentException('The "delete" option can not be used together with "default-value".'); |
|
| 117 | + } |
|
| 118 | + if ($input->getOption('delete') && $input->getArgument('value') !== null) { |
|
| 119 | + throw new \InvalidArgumentException('The "delete" option can not be used together with "value".'); |
|
| 120 | + } |
|
| 121 | + if ($input->getOption('error-if-not-exists') && !$input->getOption('delete')) { |
|
| 122 | + throw new \InvalidArgumentException('The "error-if-not-exists" option can only be used together with "delete".'); |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + return $user; |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 129 | + try { |
|
| 130 | + $user = $this->checkInput($input); |
|
| 131 | + } catch (\InvalidArgumentException $e) { |
|
| 132 | + $output->writeln('<error>' . $e->getMessage() . '</error>'); |
|
| 133 | + return self::FAILURE; |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + $uid = $input->getArgument('uid'); |
|
| 137 | + $key = $input->getArgument('key'); |
|
| 138 | + $userAccount = $this->accountManager->getAccount($user); |
|
| 139 | + |
|
| 140 | + if ($key === '') { |
|
| 141 | + $settings = $this->getAllProfileProperties($userAccount); |
|
| 142 | + $this->writeArrayInOutputFormat($input, $output, $settings); |
|
| 143 | + return self::SUCCESS; |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + $value = $this->getStoredValue($userAccount, $key); |
|
| 147 | + $inputValue = $input->getArgument('value'); |
|
| 148 | + if ($inputValue !== null) { |
|
| 149 | + if ($input->hasParameterOption('--update-only') && $value === null) { |
|
| 150 | + $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>'); |
|
| 151 | + return self::FAILURE; |
|
| 152 | + } |
|
| 153 | + |
|
| 154 | + return $this->editProfileProperty($output, $userAccount, $key, $inputValue); |
|
| 155 | + } elseif ($input->hasParameterOption('--delete')) { |
|
| 156 | + if ($input->hasParameterOption('--error-if-not-exists') && $value === null) { |
|
| 157 | + $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>'); |
|
| 158 | + return self::FAILURE; |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + return $this->deleteProfileProperty($output, $userAccount, $key); |
|
| 162 | + } elseif ($value !== null) { |
|
| 163 | + $output->writeln($value); |
|
| 164 | + } elseif ($input->hasParameterOption('--default-value')) { |
|
| 165 | + $output->writeln($input->getOption('default-value')); |
|
| 166 | + } else { |
|
| 167 | + $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>'); |
|
| 168 | + return self::FAILURE; |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + return self::SUCCESS; |
|
| 172 | + } |
|
| 173 | + |
|
| 174 | + private function deleteProfileProperty(OutputInterface $output, IAccount $userAccount, string $key): int { |
|
| 175 | + return $this->editProfileProperty($output, $userAccount, $key, ''); |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + private function editProfileProperty(OutputInterface $output, IAccount $userAccount, string $key, string $value): int { |
|
| 179 | + try { |
|
| 180 | + $userAccount->getProperty($key)->setValue($value); |
|
| 181 | + } catch (PropertyDoesNotExistException $exception) { |
|
| 182 | + $output->writeln('<error>' . $exception->getMessage() . '</error>'); |
|
| 183 | + return self::FAILURE; |
|
| 184 | + } |
|
| 185 | + |
|
| 186 | + $this->accountManager->updateAccount($userAccount); |
|
| 187 | + return self::SUCCESS; |
|
| 188 | + } |
|
| 189 | + |
|
| 190 | + private function getStoredValue(IAccount $userAccount, string $key): ?string { |
|
| 191 | + try { |
|
| 192 | + $property = $userAccount->getProperty($key); |
|
| 193 | + } catch (PropertyDoesNotExistException) { |
|
| 194 | + return null; |
|
| 195 | + } |
|
| 196 | + return $property->getValue() === '' ? null : $property->getValue(); |
|
| 197 | + } |
|
| 198 | + |
|
| 199 | + private function getAllProfileProperties(IAccount $userAccount): array { |
|
| 200 | + $properties = []; |
|
| 201 | + |
|
| 202 | + foreach ($userAccount->getAllProperties() as $property) { |
|
| 203 | + if ($property->getValue() !== '') { |
|
| 204 | + $properties[$property->getName()] = $property->getValue(); |
|
| 205 | + } |
|
| 206 | + } |
|
| 207 | + |
|
| 208 | + return $properties; |
|
| 209 | + } |
|
| 210 | + |
|
| 211 | + /** |
|
| 212 | + * @param string $argumentName |
|
| 213 | + * @param CompletionContext $context |
|
| 214 | + * @return string[] |
|
| 215 | + */ |
|
| 216 | + public function completeArgumentValues($argumentName, CompletionContext $context): array { |
|
| 217 | + if ($argumentName === 'uid') { |
|
| 218 | + return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 219 | + } |
|
| 220 | + if ($argumentName === 'key') { |
|
| 221 | + $userId = $context->getWordAtIndex($context->getWordIndex() - 1); |
|
| 222 | + $user = $this->userManager->get($userId); |
|
| 223 | + if (!($user instanceof IUser)) { |
|
| 224 | + return []; |
|
| 225 | + } |
|
| 226 | + |
|
| 227 | + $account = $this->accountManager->getAccount($user); |
|
| 228 | + |
|
| 229 | + $properties = $this->getAllProfileProperties($account); |
|
| 230 | + return array_keys($properties); |
|
| 231 | + } |
|
| 232 | + return []; |
|
| 233 | + } |
|
| 234 | 234 | } |
@@ -19,96 +19,96 @@ |
||
| 19 | 19 | use Symfony\Component\Console\Output\OutputInterface; |
| 20 | 20 | |
| 21 | 21 | class Info extends Base { |
| 22 | - public function __construct( |
|
| 23 | - protected IUserManager $userManager, |
|
| 24 | - protected IGroupManager $groupManager, |
|
| 25 | - protected SetupManager $setupManager, |
|
| 26 | - ) { |
|
| 27 | - parent::__construct(); |
|
| 28 | - } |
|
| 22 | + public function __construct( |
|
| 23 | + protected IUserManager $userManager, |
|
| 24 | + protected IGroupManager $groupManager, |
|
| 25 | + protected SetupManager $setupManager, |
|
| 26 | + ) { |
|
| 27 | + parent::__construct(); |
|
| 28 | + } |
|
| 29 | 29 | |
| 30 | - protected function configure() { |
|
| 31 | - $this |
|
| 32 | - ->setName('user:info') |
|
| 33 | - ->setDescription('show user info') |
|
| 34 | - ->addArgument( |
|
| 35 | - 'user', |
|
| 36 | - InputArgument::REQUIRED, |
|
| 37 | - 'user to show' |
|
| 38 | - )->addOption( |
|
| 39 | - 'output', |
|
| 40 | - null, |
|
| 41 | - InputOption::VALUE_OPTIONAL, |
|
| 42 | - 'Output format (plain, json or json_pretty, default is plain)', |
|
| 43 | - $this->defaultOutputFormat |
|
| 44 | - ); |
|
| 45 | - } |
|
| 30 | + protected function configure() { |
|
| 31 | + $this |
|
| 32 | + ->setName('user:info') |
|
| 33 | + ->setDescription('show user info') |
|
| 34 | + ->addArgument( |
|
| 35 | + 'user', |
|
| 36 | + InputArgument::REQUIRED, |
|
| 37 | + 'user to show' |
|
| 38 | + )->addOption( |
|
| 39 | + 'output', |
|
| 40 | + null, |
|
| 41 | + InputOption::VALUE_OPTIONAL, |
|
| 42 | + 'Output format (plain, json or json_pretty, default is plain)', |
|
| 43 | + $this->defaultOutputFormat |
|
| 44 | + ); |
|
| 45 | + } |
|
| 46 | 46 | |
| 47 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 48 | - $user = $this->userManager->get($input->getArgument('user')); |
|
| 49 | - if (is_null($user)) { |
|
| 50 | - $output->writeln('<error>user not found</error>'); |
|
| 51 | - return 1; |
|
| 52 | - } |
|
| 53 | - $groups = $this->groupManager->getUserGroupIds($user); |
|
| 54 | - $data = [ |
|
| 55 | - 'user_id' => $user->getUID(), |
|
| 56 | - 'display_name' => $user->getDisplayName(), |
|
| 57 | - 'email' => (string)$user->getSystemEMailAddress(), |
|
| 58 | - 'cloud_id' => $user->getCloudId(), |
|
| 59 | - 'enabled' => $user->isEnabled(), |
|
| 60 | - 'groups' => $groups, |
|
| 61 | - 'quota' => $user->getQuota(), |
|
| 62 | - 'storage' => $this->getStorageInfo($user), |
|
| 63 | - 'first_seen' => $this->formatLoginDate($user->getFirstLogin()), |
|
| 64 | - 'last_seen' => $this->formatLoginDate($user->getLastLogin()), |
|
| 65 | - 'user_directory' => $user->getHome(), |
|
| 66 | - 'backend' => $user->getBackendClassName() |
|
| 67 | - ]; |
|
| 68 | - $this->writeArrayInOutputFormat($input, $output, $data); |
|
| 69 | - return 0; |
|
| 70 | - } |
|
| 47 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 48 | + $user = $this->userManager->get($input->getArgument('user')); |
|
| 49 | + if (is_null($user)) { |
|
| 50 | + $output->writeln('<error>user not found</error>'); |
|
| 51 | + return 1; |
|
| 52 | + } |
|
| 53 | + $groups = $this->groupManager->getUserGroupIds($user); |
|
| 54 | + $data = [ |
|
| 55 | + 'user_id' => $user->getUID(), |
|
| 56 | + 'display_name' => $user->getDisplayName(), |
|
| 57 | + 'email' => (string)$user->getSystemEMailAddress(), |
|
| 58 | + 'cloud_id' => $user->getCloudId(), |
|
| 59 | + 'enabled' => $user->isEnabled(), |
|
| 60 | + 'groups' => $groups, |
|
| 61 | + 'quota' => $user->getQuota(), |
|
| 62 | + 'storage' => $this->getStorageInfo($user), |
|
| 63 | + 'first_seen' => $this->formatLoginDate($user->getFirstLogin()), |
|
| 64 | + 'last_seen' => $this->formatLoginDate($user->getLastLogin()), |
|
| 65 | + 'user_directory' => $user->getHome(), |
|
| 66 | + 'backend' => $user->getBackendClassName() |
|
| 67 | + ]; |
|
| 68 | + $this->writeArrayInOutputFormat($input, $output, $data); |
|
| 69 | + return 0; |
|
| 70 | + } |
|
| 71 | 71 | |
| 72 | - private function formatLoginDate(int $timestamp): string { |
|
| 73 | - if ($timestamp < 0) { |
|
| 74 | - return 'unknown'; |
|
| 75 | - } elseif ($timestamp === 0) { |
|
| 76 | - return 'never'; |
|
| 77 | - } else { |
|
| 78 | - return date(\DateTimeInterface::ATOM, $timestamp); // ISO-8601 |
|
| 79 | - } |
|
| 80 | - } |
|
| 72 | + private function formatLoginDate(int $timestamp): string { |
|
| 73 | + if ($timestamp < 0) { |
|
| 74 | + return 'unknown'; |
|
| 75 | + } elseif ($timestamp === 0) { |
|
| 76 | + return 'never'; |
|
| 77 | + } else { |
|
| 78 | + return date(\DateTimeInterface::ATOM, $timestamp); // ISO-8601 |
|
| 79 | + } |
|
| 80 | + } |
|
| 81 | 81 | |
| 82 | - /** |
|
| 83 | - * @param IUser $user |
|
| 84 | - * @return array |
|
| 85 | - */ |
|
| 86 | - protected function getStorageInfo(IUser $user): array { |
|
| 87 | - $this->setupManager->tearDown(); |
|
| 88 | - $this->setupManager->setupForUser($user); |
|
| 89 | - try { |
|
| 90 | - $storage = \OC_Helper::getStorageInfo('/'); |
|
| 91 | - } catch (NotFoundException $e) { |
|
| 92 | - return []; |
|
| 93 | - } |
|
| 94 | - return [ |
|
| 95 | - 'free' => $storage['free'], |
|
| 96 | - 'used' => $storage['used'], |
|
| 97 | - 'total' => $storage['total'], |
|
| 98 | - 'relative' => $storage['relative'], |
|
| 99 | - 'quota' => $storage['quota'], |
|
| 100 | - ]; |
|
| 101 | - } |
|
| 82 | + /** |
|
| 83 | + * @param IUser $user |
|
| 84 | + * @return array |
|
| 85 | + */ |
|
| 86 | + protected function getStorageInfo(IUser $user): array { |
|
| 87 | + $this->setupManager->tearDown(); |
|
| 88 | + $this->setupManager->setupForUser($user); |
|
| 89 | + try { |
|
| 90 | + $storage = \OC_Helper::getStorageInfo('/'); |
|
| 91 | + } catch (NotFoundException $e) { |
|
| 92 | + return []; |
|
| 93 | + } |
|
| 94 | + return [ |
|
| 95 | + 'free' => $storage['free'], |
|
| 96 | + 'used' => $storage['used'], |
|
| 97 | + 'total' => $storage['total'], |
|
| 98 | + 'relative' => $storage['relative'], |
|
| 99 | + 'quota' => $storage['quota'], |
|
| 100 | + ]; |
|
| 101 | + } |
|
| 102 | 102 | |
| 103 | - /** |
|
| 104 | - * @param string $argumentName |
|
| 105 | - * @param CompletionContext $context |
|
| 106 | - * @return string[] |
|
| 107 | - */ |
|
| 108 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 109 | - if ($argumentName === 'user') { |
|
| 110 | - return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 111 | - } |
|
| 112 | - return []; |
|
| 113 | - } |
|
| 103 | + /** |
|
| 104 | + * @param string $argumentName |
|
| 105 | + * @param CompletionContext $context |
|
| 106 | + * @return string[] |
|
| 107 | + */ |
|
| 108 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 109 | + if ($argumentName === 'user') { |
|
| 110 | + return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 111 | + } |
|
| 112 | + return []; |
|
| 113 | + } |
|
| 114 | 114 | } |
@@ -17,63 +17,63 @@ |
||
| 17 | 17 | use Symfony\Component\Console\Output\OutputInterface; |
| 18 | 18 | |
| 19 | 19 | class AddUser extends Base { |
| 20 | - public function __construct( |
|
| 21 | - protected IUserManager $userManager, |
|
| 22 | - protected IGroupManager $groupManager, |
|
| 23 | - ) { |
|
| 24 | - parent::__construct(); |
|
| 25 | - } |
|
| 20 | + public function __construct( |
|
| 21 | + protected IUserManager $userManager, |
|
| 22 | + protected IGroupManager $groupManager, |
|
| 23 | + ) { |
|
| 24 | + parent::__construct(); |
|
| 25 | + } |
|
| 26 | 26 | |
| 27 | - protected function configure() { |
|
| 28 | - $this |
|
| 29 | - ->setName('group:adduser') |
|
| 30 | - ->setDescription('add a user to a group') |
|
| 31 | - ->addArgument( |
|
| 32 | - 'group', |
|
| 33 | - InputArgument::REQUIRED, |
|
| 34 | - 'group to add the user to' |
|
| 35 | - )->addArgument( |
|
| 36 | - 'user', |
|
| 37 | - InputArgument::REQUIRED, |
|
| 38 | - 'user to add to the group' |
|
| 39 | - ); |
|
| 40 | - } |
|
| 27 | + protected function configure() { |
|
| 28 | + $this |
|
| 29 | + ->setName('group:adduser') |
|
| 30 | + ->setDescription('add a user to a group') |
|
| 31 | + ->addArgument( |
|
| 32 | + 'group', |
|
| 33 | + InputArgument::REQUIRED, |
|
| 34 | + 'group to add the user to' |
|
| 35 | + )->addArgument( |
|
| 36 | + 'user', |
|
| 37 | + InputArgument::REQUIRED, |
|
| 38 | + 'user to add to the group' |
|
| 39 | + ); |
|
| 40 | + } |
|
| 41 | 41 | |
| 42 | - protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 43 | - $group = $this->groupManager->get($input->getArgument('group')); |
|
| 44 | - if (is_null($group)) { |
|
| 45 | - $output->writeln('<error>group not found</error>'); |
|
| 46 | - return 1; |
|
| 47 | - } |
|
| 48 | - $user = $this->userManager->get($input->getArgument('user')); |
|
| 49 | - if (is_null($user)) { |
|
| 50 | - $output->writeln('<error>user not found</error>'); |
|
| 51 | - return 1; |
|
| 52 | - } |
|
| 53 | - $group->addUser($user); |
|
| 54 | - return 0; |
|
| 55 | - } |
|
| 42 | + protected function execute(InputInterface $input, OutputInterface $output): int { |
|
| 43 | + $group = $this->groupManager->get($input->getArgument('group')); |
|
| 44 | + if (is_null($group)) { |
|
| 45 | + $output->writeln('<error>group not found</error>'); |
|
| 46 | + return 1; |
|
| 47 | + } |
|
| 48 | + $user = $this->userManager->get($input->getArgument('user')); |
|
| 49 | + if (is_null($user)) { |
|
| 50 | + $output->writeln('<error>user not found</error>'); |
|
| 51 | + return 1; |
|
| 52 | + } |
|
| 53 | + $group->addUser($user); |
|
| 54 | + return 0; |
|
| 55 | + } |
|
| 56 | 56 | |
| 57 | - /** |
|
| 58 | - * @param string $argumentName |
|
| 59 | - * @param CompletionContext $context |
|
| 60 | - * @return string[] |
|
| 61 | - */ |
|
| 62 | - public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 63 | - if ($argumentName === 'group') { |
|
| 64 | - return array_map(static fn (IGroup $group) => $group->getGID(), $this->groupManager->search($context->getCurrentWord())); |
|
| 65 | - } |
|
| 66 | - if ($argumentName === 'user') { |
|
| 67 | - $groupId = $context->getWordAtIndex($context->getWordIndex() - 1); |
|
| 68 | - $group = $this->groupManager->get($groupId); |
|
| 69 | - if ($group === null) { |
|
| 70 | - return []; |
|
| 71 | - } |
|
| 57 | + /** |
|
| 58 | + * @param string $argumentName |
|
| 59 | + * @param CompletionContext $context |
|
| 60 | + * @return string[] |
|
| 61 | + */ |
|
| 62 | + public function completeArgumentValues($argumentName, CompletionContext $context) { |
|
| 63 | + if ($argumentName === 'group') { |
|
| 64 | + return array_map(static fn (IGroup $group) => $group->getGID(), $this->groupManager->search($context->getCurrentWord())); |
|
| 65 | + } |
|
| 66 | + if ($argumentName === 'user') { |
|
| 67 | + $groupId = $context->getWordAtIndex($context->getWordIndex() - 1); |
|
| 68 | + $group = $this->groupManager->get($groupId); |
|
| 69 | + if ($group === null) { |
|
| 70 | + return []; |
|
| 71 | + } |
|
| 72 | 72 | |
| 73 | - $members = array_map(static fn (IUser $user) => $user->getUID(), $group->searchUsers($context->getCurrentWord())); |
|
| 74 | - $users = array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 75 | - return array_diff($users, $members); |
|
| 76 | - } |
|
| 77 | - return []; |
|
| 78 | - } |
|
| 73 | + $members = array_map(static fn (IUser $user) => $user->getUID(), $group->searchUsers($context->getCurrentWord())); |
|
| 74 | + $users = array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->searchDisplayName($context->getCurrentWord())); |
|
| 75 | + return array_diff($users, $members); |
|
| 76 | + } |
|
| 77 | + return []; |
|
| 78 | + } |
|
| 79 | 79 | } |