create .env if non-existing

This commit is contained in:
Tony Murray 2020-06-20 08:10:52 -05:00
parent b1f526be48
commit d1ceb14b9a
8 changed files with 102 additions and 60 deletions

View File

@ -1,7 +1,3 @@
#
# Remember to run "php artisan optimize" after changing this file
#
APP_KEY=
#DB_HOST=

View File

@ -26,6 +26,7 @@
namespace LibreNMS;
use Composer\Script\Event;
use LibreNMS\Exceptions\FileWriteFailedException;
use LibreNMS\Util\EnvHelper;
class ComposerHelper
@ -78,13 +79,6 @@ class ComposerHelper
*/
private static function populateEnv()
{
$install = false;
if (!file_exists('.env')) {
copy('.env.example', '.env');
self::exec('php artisan key:generate');
$install = true;
}
$config = [
'db_host' => '',
'db_port' => '',
@ -99,19 +93,23 @@ class ComposerHelper
@include 'config.php';
EnvHelper::writeEnv([
'NODE_ID' => uniqid(),
'DB_HOST' => $config['db_host'],
'DB_PORT' => $config['db_port'],
'DB_USERNAME' => $config['db_user'],
'DB_PASSWORD' => $config['db_pass'],
'DB_DATABASE' => $config['db_name'],
'DB_SOCKET' => $config['db_socket'],
'APP_URL' => $config['base_url'],
'LIBRENMS_USER' => $config['user'],
'LIBRENMS_GROUP' => $config['group'],
'INSTALL' => $install,
]);
try {
EnvHelper::init();
EnvHelper::writeEnv([
'NODE_ID' => uniqid(),
'DB_HOST' => $config['db_host'],
'DB_PORT' => $config['db_port'],
'DB_USERNAME' => $config['db_user'],
'DB_PASSWORD' => $config['db_pass'],
'DB_DATABASE' => $config['db_name'],
'DB_SOCKET' => $config['db_socket'],
'APP_URL' => $config['base_url'],
'LIBRENMS_USER' => $config['user'],
'LIBRENMS_GROUP' => $config['group'],
]);
} catch (FileWriteFailedException $exception) {
echo $exception->getMessage() . PHP_EOL;
}
}
private static function setPermissions()

View File

@ -29,8 +29,31 @@ use Throwable;
class FileWriteFailedException extends \Exception
{
protected $file;
public function __construct($file, $code = 0, Throwable $previous = null)
{
$this->file = $file;
parent::__construct("Failed to write file: $file", $code, $previous);
}
// /**
// * Render the exception into an HTTP or JSON response.
// *
// * @param \Illuminate\Http\Request
// * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
// */
// public function render(\Illuminate\Http\Request $request)
// {
// $title = trans('exceptions.file_write_failed.title');
// $message = trans('exceptions.file_write_failed.message', ['file' => $this->file]);
//
// return $request->wantsJson() ? response()->json([
// 'status' => 'error',
// 'message' => "$title: $message",
// ]) : response()->view('errors.generic', [
// 'title' => $title,
// 'content' => $message,
// ]);
// }
}

View File

@ -25,6 +25,8 @@
namespace LibreNMS\Util;
use Artisan;
use ErrorException;
use LibreNMS\Exceptions\FileWriteFailedException;
class EnvHelper
@ -37,49 +39,30 @@ class EnvHelper
* @param array $unset Remove the given KEYS from the config
* @param string $file
* @return string
* @throws \LibreNMS\Exceptions\FileWriteFailedException
*/
public static function writeEnv($settings, $unset = [], $file = '.env')
{
$original_content = file_get_contents($file);
try {
$original_content = file_get_contents($file);
$new_content = self::setEnv($original_content, $settings, $unset);
$new_content = self::setEnv($original_content, $settings, $unset);
// only write if the content has changed
if ($new_content !== $original_content) {
file_put_contents($file, $new_content);
}
return $new_content;
}
/**
* Set a setting in .env file.
* Will only set non-empty unset variables
*
* @param array $settings KEY => value list of settings
* @param array $unset Remove the given KEYS from the config
* @param string $file
* @return string
* @throws \LibreNMS\Exceptions\FileWriteFailedException
*/
public static function tryWriteEnv($settings, $unset = [], $file = '.env')
{
$original_content = file_get_contents($file);
$new_content = self::setEnv($original_content, $settings, $unset);
// only write if the content has changed
if ($new_content !== $original_content) {
if(!file_put_contents($file, $new_content)) {
throw new FileWriteFailedException($file);
// only write if the content has changed
if ($new_content !== $original_content) {
if (!file_put_contents($file, $new_content)) {
throw new FileWriteFailedException($file);
}
}
}
return $new_content;
return $new_content;
} catch (ErrorException $e) {
throw new FileWriteFailedException($file, 0, $e);
}
}
/**
* Set a setting in .env file.
* Set a setting in .env file content.
* Will only set non-empty unset variables
*
* @param string $content
@ -120,6 +103,36 @@ class EnvHelper
return self::fixComments($content);
}
/**
* Copy the example .env file and set APP_KEY
*
* @return bool|string
* @throws \LibreNMS\Exceptions\FileWriteFailedException
*/
public static function init()
{
$env_file = base_path('.env');
try {
if (!file_exists($env_file)) {
Artisan::call('key:generate', ['--show' => true]);
$key = trim(Artisan::output());
config(['app.key' => $key]);
copy(base_path('.env.example'), $env_file);
self::writeEnv([
'APP_KEY' => $key,
'INSTALL' => !file_exists(base_path('config.php')) ? 'true' : false, // if both .env and config.php are missing, assume install is needed
], [], $env_file);
return $key;
}
return false;
} catch (ErrorException $e) {
throw new FileWriteFailedException($env_file, 0, $e);
}
}
/**
* Fix .env with # in them without a space before it
*

View File

@ -79,7 +79,7 @@ class FinalizeController extends InstallationController implements InstallerStep
{
$this->configureDatabase();
$connection = config('database.default', $this->connection);
return EnvHelper::tryWriteEnv([
return EnvHelper::writeEnv([
'NODE_ID' => uniqid(),
'DB_HOST' => config("database.connections.$connection.host"),
'DB_PORT' => config("database.connections.$connection.port"),

View File

@ -28,6 +28,7 @@ namespace App\Http\Controllers\Install;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use LibreNMS\DB\Eloquent;
use LibreNMS\Interfaces\InstallerStep;
class MakeUserController extends InstallationController implements InstallerStep
@ -76,7 +77,7 @@ class MakeUserController extends InstallationController implements InstallerStep
public function complete(): bool
{
return User::adminOnly()->exists();
return Eloquent::isConnected() && User::adminOnly()->exists();
}
public function enabled(): bool

View File

@ -27,6 +27,7 @@ namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\Access\AuthorizationException;
use LibreNMS\Util\EnvHelper;
class CheckInstalled
{
@ -39,11 +40,17 @@ class CheckInstalled
*/
public function handle($request, Closure $next)
{
config(['app.debug' => true]);
$installed = !config('librenms.install') && file_exists(base_path('.env'));
$is_install_route = $request->is('install*');
// further middleware will fail without an app key, init one
if (empty(config('app.key'))) {
config(['app.key' => EnvHelper::init()]);
}
if (!$installed && !$is_install_route) {
// no config.php does so let's redirect to the install
// redirect to install if not installed
return redirect()->route('install');
} elseif ($installed && $is_install_route) {
throw new AuthorizationException('This should only be called during install');

View File

@ -7,6 +7,10 @@ return [
'title' => 'It is unsafe to run Dusk in production',
'message' => 'Run ":command" to remove Dusk or if you are a developer set the appropriate APP_ENV'
],
'file_write_failed' => [
'title' => 'Error: Could not write to file',
'message' => 'Failed to write to file (:file). Please check permissions and SELinux/AppArmor if applicable.'
],
'ldap_missing' => [
'title' => 'PHP LDAP support missing',
'message' => 'PHP does not support LDAP, please install or enable the PHP LDAP extension'