Skip to content

Commit

Permalink
create .env if non-existing
Browse files Browse the repository at this point in the history
  • Loading branch information
murrant committed Jun 27, 2020
1 parent b1f526b commit d1ceb14
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 60 deletions.
4 changes: 0 additions & 4 deletions .env.example
@@ -1,7 +1,3 @@
#
# Remember to run "php artisan optimize" after changing this file
#

APP_KEY=

#DB_HOST=
Expand Down
38 changes: 18 additions & 20 deletions LibreNMS/ComposerHelper.php
Expand Up @@ -26,6 +26,7 @@
namespace LibreNMS;

use Composer\Script\Event;
use LibreNMS\Exceptions\FileWriteFailedException;
use LibreNMS\Util\EnvHelper;

class ComposerHelper
Expand Down Expand Up @@ -78,13 +79,6 @@ public static function preInstall(Event $event)
*/
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' => '',
Expand All @@ -99,19 +93,23 @@ private static function populateEnv()

@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()
Expand Down
23 changes: 23 additions & 0 deletions LibreNMS/Exceptions/FileWriteFailedException.php
Expand Up @@ -29,8 +29,31 @@

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,
// ]);
// }
}
79 changes: 46 additions & 33 deletions LibreNMS/Util/EnvHelper.php
Expand Up @@ -25,33 +25,12 @@

namespace LibreNMS\Util;

use Artisan;
use ErrorException;
use LibreNMS\Exceptions\FileWriteFailedException;

class EnvHelper
{
/**
* 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
*/
public static function writeEnv($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) {
file_put_contents($file, $new_content);
}

return $new_content;
}

/**
* Set a setting in .env file.
* Will only set non-empty unset variables
Expand All @@ -62,24 +41,28 @@ public static function writeEnv($settings, $unset = [], $file = '.env')
* @return string
* @throws \LibreNMS\Exceptions\FileWriteFailedException
*/
public static function tryWriteEnv($settings, $unset = [], $file = '.env')
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) {
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
Expand Down Expand Up @@ -120,6 +103,36 @@ public static function setEnv($content, $settings, $unset = [])
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
*
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Install/FinalizeController.php
Expand Up @@ -79,7 +79,7 @@ private function writeEnvFile()
{
$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"),
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Controllers/Install/MakeUserController.php
Expand Up @@ -28,6 +28,7 @@
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
Expand Down Expand Up @@ -76,7 +77,7 @@ public function create(Request $request)

public function complete(): bool
{
return User::adminOnly()->exists();
return Eloquent::isConnected() && User::adminOnly()->exists();
}

public function enabled(): bool
Expand Down
9 changes: 8 additions & 1 deletion app/Http/Middleware/CheckInstalled.php
Expand Up @@ -27,6 +27,7 @@

use Closure;
use Illuminate\Auth\Access\AuthorizationException;
use LibreNMS\Util\EnvHelper;

class CheckInstalled
{
Expand All @@ -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');
Expand Down
4 changes: 4 additions & 0 deletions resources/lang/en/exceptions.php
Expand Up @@ -7,6 +7,10 @@
'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'
Expand Down

0 comments on commit d1ceb14

Please sign in to comment.