resolves #5: modified the installer to write a flag to the .env file when installed so naughty people can't create admin accounts etc by directly accessing the installer. First version tested fully encoded with SG :)
This commit is contained in:
parent
227de6baf6
commit
e81dfcd1fd
@ -32,9 +32,4 @@ class Configuration extends Model
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'configuration';
|
||||
|
||||
public static function installCompleted()
|
||||
{
|
||||
return (!is_null(Configuration::where('key', 'install_completed')->first()));
|
||||
}
|
||||
}
|
@ -37,6 +37,23 @@ class MiscHelper
|
||||
return (int) $val;
|
||||
}
|
||||
|
||||
public static function getEnvironmentFilePath()
|
||||
{
|
||||
return sprintf('%s/.env', dirname(dirname(__DIR__)));
|
||||
}
|
||||
|
||||
public static function getEnvironmentSetting($settingName)
|
||||
{
|
||||
$envFile = MiscHelper::getEnvironmentFilePath();
|
||||
$matches = null;
|
||||
if (preg_match(sprintf('/^\s*%s\s*=\s*(.+)$/im', preg_quote($settingName)), file_get_contents($envFile), $matches))
|
||||
{
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function gravatarUrl($emailAddress, $size = 48, $default = 'identicon')
|
||||
{
|
||||
$hash = md5(strtolower(trim($emailAddress)));
|
||||
@ -68,4 +85,14 @@ class MiscHelper
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function setEnvironmentSetting($settingName, $value)
|
||||
{
|
||||
if (is_null(MiscHelper::getEnvironmentSetting($settingName)))
|
||||
{
|
||||
return file_put_contents(MiscHelper::getEnvironmentFilePath(), sprintf('%s=%s', $settingName, $value) . PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Configuration;
|
||||
use App\Helpers\MiscHelper;
|
||||
use App\Http\Requests\StoreUserRequest;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
@ -11,7 +12,7 @@ use Illuminate\Support\Facades\DB;
|
||||
|
||||
class InstallController extends Controller
|
||||
{
|
||||
public function administrator(Request $request)
|
||||
public function administrator(StoreUserRequest $request)
|
||||
{
|
||||
// Validate we're at the required stage
|
||||
$stage = 3;
|
||||
@ -20,6 +21,16 @@ class InstallController extends Controller
|
||||
return redirect(route('install.check'));
|
||||
}
|
||||
|
||||
// If we already have an admin account, this step can be skipped
|
||||
$canSkip = User::where('is_admin', true)->count() > 0;
|
||||
|
||||
if ($canSkip && $request->has('skip'))
|
||||
{
|
||||
MiscHelper::setEnvironmentSetting('APP_INSTALLED', true);
|
||||
|
||||
return redirect(route('home'));
|
||||
}
|
||||
|
||||
if ($request->method() == 'POST')
|
||||
{
|
||||
$user = new User();
|
||||
@ -30,10 +41,16 @@ class InstallController extends Controller
|
||||
$user->is_activated = true;
|
||||
$user->save();
|
||||
|
||||
return redirect(url('login'));
|
||||
MiscHelper::setEnvironmentSetting('APP_INSTALLED', true);
|
||||
|
||||
$request->session()->flash('success', trans('installer.install_completed_message'));
|
||||
|
||||
return redirect(route('home'));
|
||||
}
|
||||
|
||||
return view('install.administrator');
|
||||
return view('install.administrator', [
|
||||
'can_skip' => $canSkip
|
||||
]);
|
||||
}
|
||||
|
||||
public function check(Request $request)
|
||||
@ -47,6 +64,15 @@ class InstallController extends Controller
|
||||
}
|
||||
|
||||
$canContinue = true;
|
||||
$runtimeMinimum = '5.6.4'; // this minimum is imposed by Laravel 5.3
|
||||
$runtimeVersion = phpversion();
|
||||
$phpIsValid = version_compare($runtimeVersion, $runtimeMinimum) >= 0;
|
||||
|
||||
if (!$phpIsValid)
|
||||
{
|
||||
$canContinue = false;
|
||||
}
|
||||
|
||||
$requiredModules = [
|
||||
'curl' => 'installer.php_modules.curl',
|
||||
'pdo_mysql' => 'installer.php_modules.mysql',
|
||||
@ -71,6 +97,9 @@ class InstallController extends Controller
|
||||
return view('install.check', [
|
||||
'available_modules' => $availableModules,
|
||||
'can_continue' => $canContinue,
|
||||
'php_is_valid' => $phpIsValid,
|
||||
'php_version_current' => $runtimeVersion,
|
||||
'php_version_required' => $runtimeMinimum,
|
||||
'post_max_size' => ($postMaxSize / 1024 / 1024),
|
||||
'post_max_size_warning' => $postMaxSize < $recommendedMinimum,
|
||||
'recommended_minimum_upload' => ($recommendedMinimum / 1024 / 1024),
|
||||
@ -126,7 +155,7 @@ class InstallController extends Controller
|
||||
Artisan::call('cache:clear');
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
|
||||
$result = Configuration::where('key', 'install_date')->first();
|
||||
$result = Configuration::where('key', 'install_completed')->first();
|
||||
if (is_null($result))
|
||||
{
|
||||
$result = new Configuration();
|
||||
@ -135,6 +164,8 @@ class InstallController extends Controller
|
||||
$result->save();
|
||||
}
|
||||
|
||||
// Now the database is up-to-date, we can enable database sessions
|
||||
|
||||
$request->session()->set('install_stage', 3);
|
||||
return redirect(route('install.administrator'));
|
||||
}
|
||||
|
@ -44,22 +44,25 @@ class AppInstallation
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// See if the successful flag has been written to the .env file
|
||||
$isAppInstalled = MiscHelper::getEnvironmentSetting('APP_INSTALLED');
|
||||
|
||||
if ($request->is('install/*'))
|
||||
{
|
||||
// Already in the installer
|
||||
// For security reasons, don't allow the installer to be used if it has been previously completed
|
||||
if (boolval($isAppInstalled))
|
||||
{
|
||||
return redirect(route('home'));
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
try
|
||||
if ($isAppInstalled)
|
||||
{
|
||||
if (Configuration::installCompleted())
|
||||
{
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
catch (\Exception $ex)
|
||||
{
|
||||
// Empty catch block to allow falling through to the redirect below
|
||||
// App is configured, continue on
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return redirect(route('install.check'));
|
||||
|
@ -7,6 +7,7 @@ use App\Facade\Theme;
|
||||
use App\Facade\UserConfig;
|
||||
use App\Helpers\DbHelper;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Mailer;
|
||||
@ -67,8 +68,8 @@ class GlobalConfiguration
|
||||
|
||||
if (function_exists('sg_get_const'))
|
||||
{
|
||||
$licenseName = sg_get_const('license_name');
|
||||
$licenseNo = sg_get_const('license_number');
|
||||
$licenseName = sg_get_const('lic_name');
|
||||
$licenseNo = sg_get_const('lic_num');
|
||||
}
|
||||
|
||||
View::share('license_name', strlen($licenseName) == 0 ? '**UNLICENSED**' : $licenseName);
|
||||
@ -110,7 +111,14 @@ class GlobalConfiguration
|
||||
$password = UserConfig::get('smtp_password');
|
||||
if (!is_null($password))
|
||||
{
|
||||
$transport->setPassword(decrypt($password));
|
||||
try
|
||||
{
|
||||
$transport->setPassword(decrypt($password));
|
||||
}
|
||||
catch (DecryptException $ex)
|
||||
{
|
||||
// Unable to decrypt the password - presumably the app's key has changed
|
||||
}
|
||||
}
|
||||
|
||||
if (UserConfig::get('smtp_encryption'))
|
||||
|
@ -10,6 +10,10 @@
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)/$ /$1 [L,R=301]
|
||||
|
||||
# Remove index.php from URL...
|
||||
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
|
||||
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
|
||||
|
||||
# Handle Front Controller...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
|
@ -41,6 +41,7 @@ echo 'Removing build files...' . PHP_EOL . PHP_EOL;
|
||||
// Remove development-related files
|
||||
system(sprintf('rm -rf %s/resources/build', $appRoot));
|
||||
system(sprintf('rm -rf %s/tests', $appRoot));
|
||||
@unlink(sprintf('%s/composer.phar', $appRoot));
|
||||
@unlink(sprintf('%s/server.php', $appRoot));
|
||||
|
||||
// Can't use Artisan once encoded
|
||||
|
@ -3,8 +3,13 @@ return [
|
||||
'administrator_intro' => 'You will need an administrator account to access Blue Twilight. Complete the form below to create your administrator account.',
|
||||
'administrator_title' => 'Create an administrator account',
|
||||
'app_name' => 'Blue Twilight - Install',
|
||||
'core' => [
|
||||
'heading' => 'Core Requirements',
|
||||
'php_version' => 'Requires PHP :minimum minimum'
|
||||
],
|
||||
'database_intro' => 'Please provide the connection details for an empty MySQL or MariaDB database.',
|
||||
'database_title' => 'Connect to a Database',
|
||||
'install_completed_message' => 'Congratulations, Blue Twilight has been installed successfully. You can now login with an administrator account using the "Login" link above.',
|
||||
'php_config' => [
|
||||
'heading' => 'PHP configuration:',
|
||||
'post_max_size' => 'Maximum POST request size:',
|
||||
|
@ -4,9 +4,19 @@
|
||||
<h3>@lang('installer.administrator_title')</h3>
|
||||
<p>@lang('installer.administrator_intro')</p>
|
||||
|
||||
@if (count($errors) > 0)
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $form_error)
|
||||
<li>{{ $form_error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="row" style="margin-top: 30px;">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form action="{{ url('/install') }}" method="post">
|
||||
<form action="{{ route('install.administrator') }}" method="post">
|
||||
{{ csrf_field() }}
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
@ -25,10 +35,13 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password-confirm">Confirm Password:</label>
|
||||
<input type="password" class="form-control" id="password-confirm" name="password-confirm" value="{{ old('password-confirm') }}" />
|
||||
<input type="password" class="form-control" id="password-confirm" name="password_confirmation" value="{{ old('password-confirm') }}" />
|
||||
</div>
|
||||
|
||||
<div class="form-group text-right">
|
||||
@if ($can_skip)
|
||||
<a class="btn btn-default" href="{{ route('install.administrator', ['skip' => 1]) }}">Skip</a>
|
||||
@endif
|
||||
<button type="submit" class="btn btn-success">Create account</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -8,9 +8,20 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>@lang('installer.core.heading')</b></td>
|
||||
<td style="width: 30%;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>@lang('installer.core.php_version', ['minimum' => $php_version_required])</td>
|
||||
<td>
|
||||
{{ $php_version_current }}
|
||||
<i class="fa fa-fw fa-{{ $php_is_valid ? 'check text-success' : 'times text-danger' }}"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>@lang('installer.php_modules.heading')</b></td>
|
||||
<td style="width: 15%;"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
@foreach ($required_modules as $key => $value)
|
||||
<tr>
|
||||
|
@ -4,8 +4,8 @@
|
||||
<ul class="nav nav-pills">
|
||||
<li role="presentation"><a href="{{ route('albums.index') }}"><i class="fa fa-fw fa-picture-o"></i> @lang('navigation.breadcrumb.albums')</a></li>
|
||||
<li role="presentation"><a href="{{ route('user.index') }}"><i class="fa fa-fw fa-user"></i> @lang('navigation.breadcrumb.users')</a></li>
|
||||
<li role="presentation"><a href="{{ route('admin.settings') }}"><i class="fa fa-fw fa-cog"></i> @lang('navigation.breadcrumb.settings')</a></li>
|
||||
<li role="presentation"><a href="{{ route('storage.index') }}"><i class="fa fa-fw fa-folder"></i> @lang('navigation.breadcrumb.storage')</a></li>
|
||||
<li role="presentation"><a href="{{ route('admin.settings') }}"><i class="fa fa-fw fa-cog"></i> @lang('navigation.breadcrumb.settings')</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
@ -3,5 +3,27 @@
|
||||
"version": "1.0",
|
||||
"author": "Andy Heathershaw",
|
||||
"author_email": "andy@andys.eu",
|
||||
"navbar_class": "navbar-default navbar-static-top"
|
||||
"navbar_class": "navbar-default navbar-static-top",
|
||||
"thumbnails": [
|
||||
{
|
||||
"name": "fullsize",
|
||||
"height": 600,
|
||||
"width": 800
|
||||
},
|
||||
{
|
||||
"name": "preview",
|
||||
"height": 300,
|
||||
"width": 400
|
||||
},
|
||||
{
|
||||
"name": "admin-preview",
|
||||
"height": 112,
|
||||
"width": 150
|
||||
},
|
||||
{
|
||||
"name": "slideshow-tiny",
|
||||
"height": 75,
|
||||
"width": 100
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user