From a92597064bdf06872099de2533e5a3eb5d19ef49 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Sun, 29 Mar 2020 15:42:46 +0800 Subject: [PATCH] october:env command fixes - Adds quotes around all strings inserted into config files, preventing them from being interpreted as constants. - Changed all private methods in OctoberEnv.php to protected. - Updated test to check some config files for expected changes. --- modules/system/console/OctoberEnv.php | 69 ++++++++++++-------- tests/unit/system/console/OctoberEnvTest.php | 30 +++++++++ 2 files changed, 73 insertions(+), 26 deletions(-) diff --git a/modules/system/console/OctoberEnv.php b/modules/system/console/OctoberEnv.php index 99bfbf66d..cc735c2c4 100644 --- a/modules/system/console/OctoberEnv.php +++ b/modules/system/console/OctoberEnv.php @@ -63,7 +63,7 @@ class OctoberEnv extends Command /** * Overwrite config file */ - private function overwriteConfig() + protected function overwriteConfig() { foreach (array_keys($this->config()) as $config) { $this->config = $config; @@ -75,7 +75,7 @@ class OctoberEnv extends Command /** * Replace config values with env() syntax */ - private function configToEnv() + protected function configToEnv() { $content = $this->parseConfigFile(); @@ -87,7 +87,7 @@ class OctoberEnv extends Command * * @return string */ - private function parseConfigFile() + protected function parseConfigFile() { $lines = []; @@ -107,7 +107,7 @@ class OctoberEnv extends Command * @param $line * @return mixed */ - private function parseLine($line, $keys) + protected function parseLine($line, $keys) { $line = $this->replaceConfigLine($line, $keys); @@ -121,7 +121,7 @@ class OctoberEnv extends Command * @param $keys * @return mixed */ - private function replaceConfigLine($line, $keys) + protected function replaceConfigLine($line, $keys) { foreach ($keys as $envKey => $configKey) { $pattern = $this->buildPattern($configKey); @@ -140,7 +140,7 @@ class OctoberEnv extends Command * @param $line * @return mixed */ - private function replaceDbConfigLine($line) + protected function replaceDbConfigLine($line) { if ($this->config == 'database') { foreach ($this->dbConfig() as $connection => $settings) { @@ -159,7 +159,7 @@ class OctoberEnv extends Command * @param $line * @param $connection */ - private function setCurrentConnection($line, $connection) + protected function setCurrentConnection($line, $connection) { if (preg_match("/['\"]" . $connection . "['\"]" . "\s*=>/", $line)) { $this->connection = $connection; @@ -170,7 +170,7 @@ class OctoberEnv extends Command * @param $configKey * @return string */ - private function buildPattern($configKey) + protected function buildPattern($configKey) { return "/['\"]" . $configKey . "['\"]" . "\s*=>\s*[^,\[]+,/"; } @@ -180,19 +180,19 @@ class OctoberEnv extends Command * @param $configKey * @return \Closure */ - private function buildCallback($envKey, $configKey) + protected function buildCallback($envKey, $configKey) { return function ($matches) use ($envKey, $configKey) { $value = $this->envValue($configKey); - $this->saveEnvSettings($envKey, $value); + $this->saveEnvSettings($envKey, $this->normalizeForEnv($value)); // Remove protected values from the config files if (in_array($envKey, $this->protectedKeys) && !empty($value)) { - $value = "''"; + $value = ''; } - return $this->isEnv($matches[0]) ? $matches[0] : "'$configKey' => env('$envKey', {$value}),"; + return $this->isEnv($matches[0]) ? $matches[0] : "'$configKey' => env('$envKey', {$this->normalizeForConfig($value)}),"; }; } @@ -200,7 +200,7 @@ class OctoberEnv extends Command * @param $key * @param $value */ - private function saveEnvSettings($key, $value) + protected function saveEnvSettings($key, $value) { if (! $this->envKeyExists($key)) { $line = sprintf("%s=%s\n", $key, $value); @@ -216,7 +216,7 @@ class OctoberEnv extends Command /** * @param $line */ - private function writeDbEnvSettings($line) + protected function writeDbEnvSettings($line) { if ($this->connection == config('database.default') || $this->connection == 'redis') { $this->writeToEnv($line); @@ -227,7 +227,7 @@ class OctoberEnv extends Command * @param $configKey * @return string */ - private function envValue($configKey) + protected function envValue($configKey) { $value = config("$this->config.$configKey"); @@ -235,14 +235,14 @@ class OctoberEnv extends Command $value = $this->databaseConfigValue($configKey); } - return $this->normalize($value); + return $value; } /** * @param $configKey * @return string */ - private function databaseConfigValue($configKey) + protected function databaseConfigValue($configKey) { if ($configKey == 'default') { return config('database.default'); @@ -260,10 +260,12 @@ class OctoberEnv extends Command } /** + * Normalizes a value to be inserted into the .env file + * * @param $value * @return string */ - private function normalize($value) + protected function normalizeForEnv($value) { if (is_string($value)) { if (preg_match('/["\'#]/', $value)) { @@ -280,11 +282,26 @@ class OctoberEnv extends Command return $value; } + /** + * Normalizes a value to be inserted into config files. + * + * @param $value + * @return string + */ + protected function normalizeForConfig($value) + { + if (is_string($value)) { + return '\'' . addslashes($value) . '\''; + } + + return $this->normalizeForEnv($value); + } + /** * @param $matches * @return bool */ - private function isEnv($matches) + protected function isEnv($matches) { return strpos($matches, 'env') !== false; } @@ -292,7 +309,7 @@ class OctoberEnv extends Command /** * @param $content */ - private function writeToEnv($content) + protected function writeToEnv($content) { file_put_contents('.env', $content, FILE_APPEND); } @@ -300,7 +317,7 @@ class OctoberEnv extends Command /** * @return string */ - private function readEnvFile() + protected function readEnvFile() { return file_exists('.env') ? file_get_contents('.env') : ''; } @@ -308,7 +325,7 @@ class OctoberEnv extends Command /** * @param $content */ - private function writeToConfigFile($content) + protected function writeToConfigFile($content) { file_put_contents(config_path($this->config . '.php'), $content); } @@ -316,7 +333,7 @@ class OctoberEnv extends Command /** * @return array */ - private function lines() + protected function lines() { return file(config_path($this->config . '.php')); } @@ -325,7 +342,7 @@ class OctoberEnv extends Command * @param $key * @return bool */ - private function envKeyExists($key) + protected function envKeyExists($key) { return strpos($this->readEnvFile(), $key) !== false; } @@ -333,7 +350,7 @@ class OctoberEnv extends Command /** * @return array */ - private function config() + protected function config() { return [ 'app' => [ @@ -375,7 +392,7 @@ class OctoberEnv extends Command /** * @return array */ - private function dbConfig() + protected function dbConfig() { return [ 'sqlite' => [ diff --git a/tests/unit/system/console/OctoberEnvTest.php b/tests/unit/system/console/OctoberEnvTest.php index d05f43794..6170cc739 100644 --- a/tests/unit/system/console/OctoberEnvTest.php +++ b/tests/unit/system/console/OctoberEnvTest.php @@ -50,6 +50,36 @@ class OctoberEnvTest extends TestCase $this->assertContains('DB_PASSWORD="test\\"quotes\'test"', $envFile); $this->assertContains('DB_PORT=3306', $envFile); } + + // Check app.php config file + $appConfigFile = file_get_contents(storage_path('temp/tests/config/app.php')); + + if (method_exists($this, 'assertStringContainsString')) { + $this->assertStringContainsString('\'debug\' => env(\'APP_DEBUG\', true),', $appConfigFile); + $this->assertStringContainsString('\'url\' => env(\'APP_URL\', \'https://localhost\'),', $appConfigFile); + } else { + $this->assertContains('\'debug\' => env(\'APP_DEBUG\', true),', $appConfigFile); + $this->assertContains('\'url\' => env(\'APP_URL\', \'https://localhost\'),', $appConfigFile); + } + + // Check database.php config file + $appConfigFile = file_get_contents(storage_path('temp/tests/config/database.php')); + + if (method_exists($this, 'assertStringContainsString')) { + $this->assertStringContainsString('\'default\' => env(\'DB_CONNECTION\', \'mysql\')', $appConfigFile); + $this->assertStringContainsString('\'port\' => env(\'DB_PORT\', 3306),', $appConfigFile); + // Both the following configurations had values in the original config, they should be stripped out once + // the .env file is generated. + $this->assertStringContainsString('\'username\' => env(\'DB_USERNAME\', \'\'),', $appConfigFile); + $this->assertStringContainsString('\'password\' => env(\'DB_PASSWORD\', \'\'),', $appConfigFile); + } else { + $this->assertContains('\'default\' => env(\'DB_CONNECTION\', \'mysql\')', $appConfigFile); + $this->assertContains('\'port\' => env(\'DB_PORT\', 3306),', $appConfigFile); + // Both the following configurations had values in the original config, they should be stripped out once + // the .env file is generated. + $this->assertContains('\'username\' => env(\'DB_USERNAME\', \'\'),', $appConfigFile); + $this->assertContains('\'password\' => env(\'DB_PASSWORD\', \'\'),', $appConfigFile); + } } protected function tearDown()