diff --git a/Console/GetReEncryptedCloudEnvironmentsKeys.php b/Console/GetReEncryptedCloudEnvironmentsKeys.php new file mode 100644 index 0000000..56ae34f --- /dev/null +++ b/Console/GetReEncryptedCloudEnvironmentsKeys.php @@ -0,0 +1,102 @@ +setName('gene:encryption-key-manager:get-cloud-keys'); + $this->setDescription('Reencrypt cloud encrypted keys based on $_ENV variable. ' . + 'The CLI command don\'t save new values. It has to be done manually.'); + $this->setDefinition([ + new InputOption( + self::INPUT_KEY_SHOW_DECRYPTED, + null, + InputOption::VALUE_NONE, + 'Whether to show decrypted values.' + ), + ]); + parent::configure(); + } + + /** + * Execute the command + * + * @param InputInterface $input + * @param OutputInterface $output + * + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $showDecrypted = !!$input->getOption(self::INPUT_KEY_SHOW_DECRYPTED); + + try { + // get old encrypted, decrypted and new encrypted values + $config = $this->reencryptCloudEnvKeysCommand->execute(); + + if (!count($config)) { + $output->writeln('There is no old encrypted environment variables found'); + return CLI::RETURN_SUCCESS; + } + + $output->writeln("The CLI command doesn't rewrite values. " . + "You have to update them manually in cloud console!"); + $output->writeln("Rows count: " . count($config) . ""); + + foreach ($config as $name => $arr) { + $output->writeln(str_pad('', 120, '#')); + + /** @var $arr array{value:string, newValue:string, decryptedValue:string} */ + $output->writeln("Name: {$name}"); + if ($showDecrypted) { + $output->writeln("Dectypted value: {$arr['decryptedValue']}"); + } + $output->writeln("Old Encrypted Value: {$arr['value']}"); + $output->writeln("New Encrypted Value: {$arr['newValue']}"); + } + + } catch (\Exception|\Throwable $e) { + $this->logger->critical("Something went wrong while trying to reencrypt cloud variables.", [ + 'msg' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]); + $output->writeln("" . $e->getMessage() . ""); + + return CLI::RETURN_FAILURE; + } + + return CLI::RETURN_SUCCESS; + } +} diff --git a/Model/EncodingHelper.php b/Model/EncodingHelper.php new file mode 100644 index 0000000..3ca7a61 --- /dev/null +++ b/Model/EncodingHelper.php @@ -0,0 +1,59 @@ +deploymentConfig->get('crypt/key'))); + } catch (\Exception) { + return 0; + } + return count($keys) -1; + } + + /** + * Validate whether the value looks like digit:digit:string + * + * @param string $value + * @return bool + */ + public function isEncryptedValue(string $value): bool + { + preg_match('/^\d:\d:\S+/', $value, $matches); + return !!count($matches); + } + + /** + * Returns whether the value is already encrypted + * + * @param string $encryptedValue + * @return bool + */ + public function isAlreadyUpdated(string $encryptedValue): bool + { + return str_starts_with($encryptedValue, $this->getLatestKeyNumber() . ":"); + } +} diff --git a/Model/ReEncryptCloudEnvKeysCommand.php b/Model/ReEncryptCloudEnvKeysCommand.php new file mode 100644 index 0000000..4a79b86 --- /dev/null +++ b/Model/ReEncryptCloudEnvKeysCommand.php @@ -0,0 +1,67 @@ +placeholder = $placeholderFactory->create(PlaceholderFactory::TYPE_ENVIRONMENT); + } + + /** + * Execute the command + * + * @param array|null $environmentVariables + * @return array + * @throws \Exception + */ + public function execute(array $environmentVariables = null): array + { + if ($environmentVariables === null) { + if (!isset($_ENV)) { + throw new \Exception("No environment variables defined"); + } + $environmentVariables = $_ENV; + } + + $config = []; + + foreach ($environmentVariables as $template => $value) { + if (!$this->placeholder->isApplicable($template) + || !$this->helper->isEncryptedValue($value) + || $this->helper->isAlreadyUpdated($value)) { + continue; + } + + $decryptedValue = $this->encryptor->decrypt($value); + $newValue = $this->encryptor->encrypt($decryptedValue); + $config[$template] = compact('value', 'newValue', 'decryptedValue'); + } + + return $config; + } +} diff --git a/README.md b/README.md index 8158ffd..a6c2676 100644 --- a/README.md +++ b/README.md @@ -237,3 +237,31 @@ Dry run mode, no changes have been made ######################################################################################################################## Done ``` + +## bin/magento gene:encryption-key-manager:get-cloud-keys + +This command to get re-encrypted cloud environments variables. +This one DOESN'T update existing values, it just returns new ones in console. +The Dev has to update them manually in cloud console. + +```bash +# No keys example +$ bin/magento gene:encryption-key-manager:get-cloud-keys +There is no old encrypted environment variables found + +# There is some encoded +$ bin/magento gene:encryption-key-manager:get-cloud-keys --show-decrypted +There is no old encrypted environment variables found +The CLI command doesn\'t rewrite values. You have to update them manually in cloud console! +Rows count: 4 +################################################################## +Name: CONFIG__DEFAULT__SOME_KEY +Dectypted value: dectypted_value +Old Encrypted Value: 0:3:AAA1 +New Encrypted Value: 1:3:BBB1 +################################################################## +Name: CONFIG__DEFAULT__SOME_KEY_2 +Dectypted value: dectypted_value_2 +Old Encrypted Value: 0:3:AAA2 +New Encrypted Value: 1:3:BBB2 +``` diff --git a/etc/di.xml b/etc/di.xml index 326a21d..60462a8 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -37,6 +37,8 @@ Gene\EncryptionKeyManager\Console\ReencryptUnhandledCoreConfigData Gene\EncryptionKeyManager\Console\ReencryptColumn Gene\EncryptionKeyManager\Console\ReencryptTfaData + Gene\EncryptionKeyManager\Console\GetReEncryptedCloudEnvironmentsKeys