From 3ad4ef5893a911505188e4cf95161003280763f7 Mon Sep 17 00:00:00 2001 From: Dane Powell Date: Thu, 14 Nov 2024 11:36:08 -0800 Subject: [PATCH] CLI-1415: [auth:acsf-login] validate factory URL --- src/Command/App/LogTailCommand.php | 2 +- src/Command/Auth/AuthAcsfLoginCommand.php | 9 ++++--- src/Command/CommandBase.php | 25 ++++++++++++++++++- .../Email/ConfigurePlatformEmailCommand.php | 2 +- src/Command/Remote/DrushCommand.php | 5 +++- .../src/Commands/Acsf/AcsfCommandTestBase.php | 2 +- 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/Command/App/LogTailCommand.php b/src/Command/App/LogTailCommand.php index feaf60209..eb00a1337 100644 --- a/src/Command/App/LogTailCommand.php +++ b/src/Command/App/LogTailCommand.php @@ -54,7 +54,7 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $environment = $this->determineEnvironment($input, $output); + $environment = $this->determineEnvironment($input, $output, true); $acquiaCloudClient = $this->cloudApiClientService->getClient(); $logs = $this->promptChooseLogs(); $logTypes = array_map(static function (mixed $log) { diff --git a/src/Command/Auth/AuthAcsfLoginCommand.php b/src/Command/Auth/AuthAcsfLoginCommand.php index 3011e9b34..04772ad7b 100644 --- a/src/Command/Auth/AuthAcsfLoginCommand.php +++ b/src/Command/Auth/AuthAcsfLoginCommand.php @@ -22,6 +22,9 @@ protected function configure(): void ->addOption('factory-url', 'f', InputOption::VALUE_REQUIRED, "Your Site Factory URL (including https://)"); } + /** + * @throws \Acquia\Cli\Exception\AcquiaCliException + */ protected function execute(InputInterface $input, OutputInterface $output): int { if ($input->getOption('factory-url')) { @@ -37,7 +40,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int ]; $factory = $this->promptChooseFromObjectsOrArrays($factoryChoices, 'url', 'url', 'Choose a Factory to login to'); if ($factory['url'] === 'Enter a new factory URL') { - $factoryUrl = $this->io->ask('Enter the full URL of the factory'); + $factoryUrl = $this->determineOption('factory-url', false, $this->validateUrl(...)); $factory = [ 'url' => $factoryUrl, 'users' => [], @@ -61,11 +64,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::SUCCESS; } } else { - $factoryUrl = $this->determineOption('factory-url'); + $factoryUrl = $this->determineOption('factory-url', false, $this->validateUrl(...)); } $username = $this->determineOption('username'); - $key = $this->determineOption('key', true); + $key = $this->determineOption('key', true, $this->validateApiKey(...)); $this->writeAcsfCredentialsToDisk($factoryUrl, $username, $key); $output->writeln("Saved credentials"); diff --git a/src/Command/CommandBase.php b/src/Command/CommandBase.php index 6b4632a60..fb1583bd9 100644 --- a/src/Command/CommandBase.php +++ b/src/Command/CommandBase.php @@ -67,6 +67,7 @@ use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Regex; +use Symfony\Component\Validator\Constraints\Url; use Symfony\Component\Validator\Exception\ValidatorException; use Symfony\Component\Validator\Validation; use Symfony\Component\Yaml\Yaml; @@ -610,6 +611,9 @@ private function promptChooseDatabases( return [$environmentDatabases[$chosenDatabaseIndex]]; } + /** + * @throws \Acquia\Cli\Exception\AcquiaCliException + */ protected function determineEnvironment(InputInterface $input, OutputInterface $output, bool $allowProduction = false, bool $allowNode = false): array|string|EnvironmentResponse { if ($input->getArgument('environmentId')) { @@ -628,6 +632,10 @@ protected function determineEnvironment(InputInterface $input, OutputInterface $ } // Todo: obviously combine this with promptChooseEnvironment. + + /** + * @throws \Acquia\Cli\Exception\AcquiaCliException + */ private function promptChooseEnvironmentConsiderProd(Client $acquiaCloudClient, string $applicationUuid, bool $allowProduction, bool $allowNode): EnvironmentResponse { $environmentResource = new Environments($acquiaCloudClient); @@ -1657,12 +1665,15 @@ protected function promptOpenBrowserToCreateToken( } } + /** + * @throws \Acquia\Cli\Exception\AcquiaCliException + */ protected function determineApiKey(): string { return $this->determineOption('key', false, $this->validateApiKey(...)); } - private function validateApiKey(mixed $key): string + protected static function validateApiKey(mixed $key): string { $violations = Validation::createValidator()->validate($key, [ new Length(['min' => 10]), @@ -1678,6 +1689,18 @@ private function validateApiKey(mixed $key): string return $key; } + protected static function validateUrl(?string $url): string + { + $violations = Validation::createValidator()->validate($url, [ + new NotBlank(), + new Url(), + ]); + if (count($violations)) { + throw new ValidatorException($violations->get(0)->getMessage()); + } + return $url; + } + protected function determineApiSecret(): string { return $this->determineOption('secret', true, $this->validateApiKey(...)); diff --git a/src/Command/Email/ConfigurePlatformEmailCommand.php b/src/Command/Email/ConfigurePlatformEmailCommand.php index 368c60707..60696032f 100644 --- a/src/Command/Email/ConfigurePlatformEmailCommand.php +++ b/src/Command/Email/ConfigurePlatformEmailCommand.php @@ -225,7 +225,7 @@ private function addDomainToSubscriptionApplications(Client $client, Subscriptio /** * Validates the URL entered as the base domain name. */ - public static function validateUrl(string $url): string + public static function validateUrl(?string $url): string { $constraintsList = [new NotBlank()]; $urlParts = parse_url($url); diff --git a/src/Command/Remote/DrushCommand.php b/src/Command/Remote/DrushCommand.php index be04d1400..2bc1f906c 100644 --- a/src/Command/Remote/DrushCommand.php +++ b/src/Command/Remote/DrushCommand.php @@ -31,9 +31,12 @@ protected function configure(): void ->addUsage('myapp.dev -- status --fields=db-status'); } + /** + * @throws \Acquia\Cli\Exception\AcquiaCliException + */ protected function execute(InputInterface $input, OutputInterface $output): ?int { - $environment = $this->determineEnvironment($input, $output); + $environment = $this->determineEnvironment($input, $output, true); $alias = self::getEnvironmentAlias($environment); $acliArguments = $input->getArguments(); $drushArguments = (array) $acliArguments['drush_command']; diff --git a/tests/phpunit/src/Commands/Acsf/AcsfCommandTestBase.php b/tests/phpunit/src/Commands/Acsf/AcsfCommandTestBase.php index 4265046ec..745619ca3 100644 --- a/tests/phpunit/src/Commands/Acsf/AcsfCommandTestBase.php +++ b/tests/phpunit/src/Commands/Acsf/AcsfCommandTestBase.php @@ -22,7 +22,7 @@ abstract class AcsfCommandTestBase extends CommandTestBase protected static string $acsfUsername = 'tester'; - protected static string $acsfKey = 'h@x0r'; + protected static string $acsfKey = 'abcdefghijklmnop'; protected string $apiCommandPrefix = 'acsf';