Commit 066989f0 by Qiang Xue

Fixes #4425: generate cookie validation keys in local config files.

parent 2a8ca600
...@@ -13,10 +13,6 @@ return [ ...@@ -13,10 +13,6 @@ return [
'bootstrap' => ['log'], 'bootstrap' => ['log'],
'modules' => [], 'modules' => [],
'components' => [ 'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
'user' => [ 'user' => [
'identityClass' => 'common\models\User', 'identityClass' => 'common\models\User',
'enableAutoLogin' => true, 'enableAutoLogin' => true,
......
...@@ -32,8 +32,7 @@ ...@@ -32,8 +32,7 @@
}, },
"scripts": { "scripts": {
"post-create-project-cmd": [ "post-create-project-cmd": [
"yii\\composer\\Installer::setPermission", "yii\\composer\\Installer::setPermission"
"yii\\composer\\Installer::generateCookieValidationKey"
] ]
}, },
"config": { "config": {
...@@ -46,10 +45,6 @@ ...@@ -46,10 +45,6 @@
"frontend/runtime", "frontend/runtime",
"frontend/web/assets" "frontend/web/assets"
],
"config": [
"frontend/config/main.php",
"backend/config/main.php"
] ]
} }
} }
<?php <?php
$config = []; $config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];
if (!YII_ENV_TEST) { if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment // configuration adjustments for 'dev' environment
......
<?php <?php
$config = []; $config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];
if (!YII_ENV_TEST) { if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment // configuration adjustments for 'dev' environment
......
...@@ -9,9 +9,15 @@ ...@@ -9,9 +9,15 @@
* return [ * return [
* 'environment name' => [ * 'environment name' => [
* 'path' => 'directory storing the local files', * 'path' => 'directory storing the local files',
* 'writable' => [ * 'setWritable' => [
* // list of directories that should be set writable * // list of directories that should be set writable
* ], * ],
* 'setExecutable' => [
* // list of directories that should be set executable
* ],
* 'setCookieValidationKey' => [
* // list of config files that need to be inserted with automatically generated cookie validation keys
* ],
* ], * ],
* ]; * ];
* ``` * ```
...@@ -19,26 +25,34 @@ ...@@ -19,26 +25,34 @@
return [ return [
'Development' => [ 'Development' => [
'path' => 'dev', 'path' => 'dev',
'writable' => [ 'setWritable' => [
'backend/runtime', 'backend/runtime',
'backend/web/assets', 'backend/web/assets',
'frontend/runtime', 'frontend/runtime',
'frontend/web/assets', 'frontend/web/assets',
], ],
'executable' => [ 'setExecutable' => [
'yii', 'yii',
], ],
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
],
], ],
'Production' => [ 'Production' => [
'path' => 'prod', 'path' => 'prod',
'writable' => [ 'setWritable' => [
'backend/runtime', 'backend/runtime',
'backend/web/assets', 'backend/web/assets',
'frontend/runtime', 'frontend/runtime',
'frontend/web/assets', 'frontend/web/assets',
], ],
'executable' => [ 'setExecutable' => [
'yii', 'yii',
], ],
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
],
], ],
]; ];
<?php <?php
return [ return [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
]; ];
<?php <?php
return [ return [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
]; ];
...@@ -12,10 +12,6 @@ return [ ...@@ -12,10 +12,6 @@ return [
'bootstrap' => ['log'], 'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers', 'controllerNamespace' => 'frontend\controllers',
'components' => [ 'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
'user' => [ 'user' => [
'identityClass' => 'common\models\User', 'identityClass' => 'common\models\User',
'enableAutoLogin' => true, 'enableAutoLogin' => true,
......
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
if (!extension_loaded('mcrypt')) {
die('The mcrypt PHP extension is required by Yii2.');
}
$params = getParams(); $params = getParams();
$root = str_replace('\\', '/', __DIR__); $root = str_replace('\\', '/', __DIR__);
$envs = require("$root/environments/index.php"); $envs = require("$root/environments/index.php");
...@@ -23,147 +27,169 @@ echo "Yii Application Initialization Tool v1.0\n\n"; ...@@ -23,147 +27,169 @@ echo "Yii Application Initialization Tool v1.0\n\n";
$envName = null; $envName = null;
if (empty($params['env']) || $params['env'] === '1') { if (empty($params['env']) || $params['env'] === '1') {
echo "Which environment do you want the application to be initialized in?\n\n"; echo "Which environment do you want the application to be initialized in?\n\n";
foreach ($envNames as $i => $name) { foreach ($envNames as $i => $name) {
echo " [$i] $name\n"; echo " [$i] $name\n";
} }
echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] '; echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] ';
$answer = trim(fgets(STDIN)); $answer = trim(fgets(STDIN));
if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) { if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) {
echo "\n Quit initialization.\n"; echo "\n Quit initialization.\n";
exit(0); exit(0);
} }
if (isset($envNames[$answer])) { if (isset($envNames[$answer])) {
$envName = $envNames[$answer]; $envName = $envNames[$answer];
} }
} else { } else {
$envName = $params['env']; $envName = $params['env'];
} }
if (!in_array($envName, $envNames)) { if (!in_array($envName, $envNames)) {
$envsList = implode(', ', $envNames); $envsList = implode(', ', $envNames);
echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n"; echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n";
exit(2); exit(2);
} }
$env = $envs[$envName]; $env = $envs[$envName];
if (empty($params['env'])) { if (empty($params['env'])) {
echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] "; echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] ";
$answer = trim(fgets(STDIN)); $answer = trim(fgets(STDIN));
if (strncasecmp($answer, 'y', 1)) { if (strncasecmp($answer, 'y', 1)) {
echo "\n Quit initialization.\n"; echo "\n Quit initialization.\n";
exit(0); exit(0);
} }
} }
echo "\n Start initialization ...\n\n"; echo "\n Start initialization ...\n\n";
$files = getFileList("$root/environments/{$env['path']}"); $files = getFileList("$root/environments/{$env['path']}");
$all = false; $all = false;
foreach ($files as $file) { foreach ($files as $file) {
if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) { if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) {
break; break;
} }
}
if (isset($env['writable'])) {
foreach ($env['writable'] as $writable) {
echo " chmod 0777 $writable\n";
@chmod("$root/$writable", 0777);
}
} }
if (isset($env['executable'])) { $callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable'];
foreach ($env['executable'] as $executable) { foreach ($callbacks as $callback) {
echo " chmod 0755 $executable\n"; if (!empty($env[$callback])) {
@chmod("$root/$executable", 0755); $callback($root, $env[$callback]);
} }
} }
echo "\n ... initialization completed.\n\n"; echo "\n ... initialization completed.\n\n";
function getFileList($root, $basePath = '') function getFileList($root, $basePath = '')
{ {
$files = []; $files = [];
$handle = opendir($root); $handle = opendir($root);
while (($path = readdir($handle)) !== false) { while (($path = readdir($handle)) !== false) {
if ($path === '.svn' || $path === '.' || $path === '..') { if ($path === '.svn' || $path === '.' || $path === '..') {
continue; continue;
} }
$fullPath = "$root/$path"; $fullPath = "$root/$path";
$relativePath = $basePath === '' ? $path : "$basePath/$path"; $relativePath = $basePath === '' ? $path : "$basePath/$path";
if (is_dir($fullPath)) { if (is_dir($fullPath)) {
$files = array_merge($files, getFileList($fullPath, $relativePath)); $files = array_merge($files, getFileList($fullPath, $relativePath));
} else { } else {
$files[] = $relativePath; $files[] = $relativePath;
} }
} }
closedir($handle); closedir($handle);
return $files; return $files;
} }
function copyFile($root, $source, $target, &$all, $params) function copyFile($root, $source, $target, &$all, $params)
{ {
if (!is_file($root . '/' . $source)) { if (!is_file($root . '/' . $source)) {
echo " skip $target ($source not exist)\n"; echo " skip $target ($source not exist)\n";
return true; return true;
} }
if (is_file($root . '/' . $target)) { if (is_file($root . '/' . $target)) {
if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) { if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
echo " unchanged $target\n"; echo " unchanged $target\n";
return true; return true;
} }
if ($all) { if ($all) {
echo " overwrite $target\n"; echo " overwrite $target\n";
} else { } else {
echo " exist $target\n"; echo " exist $target\n";
echo " ...overwrite? [Yes|No|All|Quit] "; echo " ...overwrite? [Yes|No|All|Quit] ";
$answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN)); $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));
if (!strncasecmp($answer, 'q', 1)) { if (!strncasecmp($answer, 'q', 1)) {
return false; return false;
} else { } else {
if (!strncasecmp($answer, 'y', 1)) { if (!strncasecmp($answer, 'y', 1)) {
echo " overwrite $target\n"; echo " overwrite $target\n";
} else { } else {
if (!strncasecmp($answer, 'a', 1)) { if (!strncasecmp($answer, 'a', 1)) {
echo " overwrite $target\n"; echo " overwrite $target\n";
$all = true; $all = true;
} else { } else {
echo " skip $target\n"; echo " skip $target\n";
return true; return true;
} }
} }
} }
} }
file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
return true; return true;
} }
echo " generate $target\n"; echo " generate $target\n";
@mkdir(dirname($root . '/' . $target), 0777, true); @mkdir(dirname($root . '/' . $target), 0777, true);
file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
return true; return true;
} }
function getParams() function getParams()
{ {
$rawParams = []; $rawParams = [];
if (isset($_SERVER['argv'])) { if (isset($_SERVER['argv'])) {
$rawParams = $_SERVER['argv']; $rawParams = $_SERVER['argv'];
array_shift($rawParams); array_shift($rawParams);
} }
$params = []; $params = [];
foreach ($rawParams as $param) { foreach ($rawParams as $param) {
if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) { if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) {
$name = $matches[1]; $name = $matches[1];
$params[$name] = isset($matches[3]) ? $matches[3] : true; $params[$name] = isset($matches[3]) ? $matches[3] : true;
} else { } else {
$params[] = $param; $params[] = $param;
} }
} }
return $params; return $params;
}
function setWritable($root, $paths)
{
foreach ($paths as $writable) {
echo " chmod 0777 $writable\n";
@chmod("$root/$writable", 0777);
}
}
function setExecutable($root, $paths)
{
foreach ($paths as $executable) {
echo " chmod 0755 $executable\n";
@chmod("$root/$executable", 0755);
}
}
function setCookieValidationKey($root, $paths)
{
foreach ($paths as $file) {
echo " generating cookie validation key $file\n";
$file = $root . '/' . $file;
$length = 32;
$bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
$key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
$content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
file_put_contents($file, $content);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment