From b08c498b13ef247913ee024c32dd0256b54024ba Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Fri, 8 Nov 2024 08:47:49 +0100 Subject: [PATCH] Create command to rename API keys --- module/CLI/config/cli.config.php | 1 + module/CLI/config/dependencies.config.php | 2 + .../src/Command/Api/RenameApiKeyCommand.php | 77 +++++++++++++++++++ module/Rest/src/Service/ApiKeyService.php | 3 + 4 files changed, 83 insertions(+) create mode 100644 module/CLI/src/Command/Api/RenameApiKeyCommand.php diff --git a/module/CLI/config/cli.config.php b/module/CLI/config/cli.config.php index 8283a7b6..a554db40 100644 --- a/module/CLI/config/cli.config.php +++ b/module/CLI/config/cli.config.php @@ -28,6 +28,7 @@ return [ Command\Api\DisableKeyCommand::NAME => Command\Api\DisableKeyCommand::class, Command\Api\ListKeysCommand::NAME => Command\Api\ListKeysCommand::class, Command\Api\InitialApiKeyCommand::NAME => Command\Api\InitialApiKeyCommand::class, + Command\Api\RenameApiKeyCommand::NAME => Command\Api\RenameApiKeyCommand::class, Command\Tag\ListTagsCommand::NAME => Command\Tag\ListTagsCommand::class, Command\Tag\RenameTagCommand::NAME => Command\Tag\RenameTagCommand::class, diff --git a/module/CLI/config/dependencies.config.php b/module/CLI/config/dependencies.config.php index 2f098998..76e7c4f5 100644 --- a/module/CLI/config/dependencies.config.php +++ b/module/CLI/config/dependencies.config.php @@ -59,6 +59,7 @@ return [ Command\Api\DisableKeyCommand::class => ConfigAbstractFactory::class, Command\Api\ListKeysCommand::class => ConfigAbstractFactory::class, Command\Api\InitialApiKeyCommand::class => ConfigAbstractFactory::class, + Command\Api\RenameApiKeyCommand::class => ConfigAbstractFactory::class, Command\Tag\ListTagsCommand::class => ConfigAbstractFactory::class, Command\Tag\RenameTagCommand::class => ConfigAbstractFactory::class, @@ -120,6 +121,7 @@ return [ Command\Api\DisableKeyCommand::class => [ApiKeyService::class], Command\Api\ListKeysCommand::class => [ApiKeyService::class], Command\Api\InitialApiKeyCommand::class => [ApiKeyService::class], + Command\Api\RenameApiKeyCommand::class => [ApiKeyService::class], Command\Tag\ListTagsCommand::class => [TagService::class], Command\Tag\RenameTagCommand::class => [TagService::class], diff --git a/module/CLI/src/Command/Api/RenameApiKeyCommand.php b/module/CLI/src/Command/Api/RenameApiKeyCommand.php new file mode 100644 index 00000000..f7e24992 --- /dev/null +++ b/module/CLI/src/Command/Api/RenameApiKeyCommand.php @@ -0,0 +1,77 @@ +setName(self::NAME) + ->setDescription('Renames an API key by name') + ->addArgument('oldName', InputArgument::REQUIRED, 'Current name of the API key to rename') + ->addArgument('newName', InputArgument::REQUIRED, 'New name to set to the API key'); + } + + protected function interact(InputInterface $input, OutputInterface $output): void + { + $io = new SymfonyStyle($input, $output); + $oldName = $input->getArgument('oldName'); + $newName = $input->getArgument('newName'); + + if ($oldName === null) { + $apiKeys = $this->apiKeyService->listKeys(); + $requestedOldName = $io->choice( + 'What API key do you want to rename?', + map($apiKeys, static fn (ApiKey $apiKey) => $apiKey->name), + ); + + $input->setArgument('oldName', $requestedOldName); + } + + if ($newName === null) { + $requestedNewName = $io->ask( + 'What is the new name you want to set?', + validator: static fn (string|null $value): string => $value !== null + ? $value + : throw new InvalidArgumentException('The new name cannot be empty'), + ); + + $input->setArgument('newName', $requestedNewName); + } + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $oldName = $input->getArgument('oldName'); + $newName = $input->getArgument('newName'); + + $this->apiKeyService->renameApiKey(Renaming::fromNames($oldName, $newName)); + $io->success('API key properly renamed'); + + return ExitCode::EXIT_SUCCESS; + } +} diff --git a/module/Rest/src/Service/ApiKeyService.php b/module/Rest/src/Service/ApiKeyService.php index 38ed004d..66876204 100644 --- a/module/Rest/src/Service/ApiKeyService.php +++ b/module/Rest/src/Service/ApiKeyService.php @@ -87,6 +87,9 @@ readonly class ApiKeyService implements ApiKeyServiceInterface /** * @inheritDoc + * @todo This method should be transactional and to a SELECT ... FROM UPDATE when checking if the new name exists, + * to avoid a race condition where the method is called twice in parallel for a new name that doesn't exist, + * causing two API keys to end up with the same name. */ public function renameApiKey(Renaming $apiKeyRenaming): ApiKey {