mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Code to facilitate #1123
This commit is contained in:
parent
e2d1de94b7
commit
fb5323c283
72
app/Http/Controllers/System/InstallController.php
Normal file
72
app/Http/Controllers/System/InstallController.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* InstallController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\System;
|
||||
|
||||
|
||||
use Artisan;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use Laravel\Passport\Passport;
|
||||
use phpseclib\Crypt\RSA;
|
||||
|
||||
/**
|
||||
* Class InstallController
|
||||
*/
|
||||
class InstallController extends Controller
|
||||
{
|
||||
/**
|
||||
* InstallController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// empty on purpose.
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function migrate()
|
||||
{
|
||||
Artisan::call('migrate', ['--seed' => true]);
|
||||
|
||||
// create keys manually because for some reason the passport namespace
|
||||
// does not exist
|
||||
$rsa = new RSA();
|
||||
$keys = $rsa->createKey(4096);
|
||||
|
||||
list($publicKey, $privateKey) = [
|
||||
Passport::keyPath('oauth-public.key'),
|
||||
Passport::keyPath('oauth-private.key'),
|
||||
];
|
||||
|
||||
if ((file_exists($publicKey) || file_exists($privateKey))) {
|
||||
return redirect(route('index'));
|
||||
}
|
||||
|
||||
file_put_contents($publicKey, array_get($keys, 'publickey'));
|
||||
file_put_contents($privateKey, array_get($keys, 'privatekey'));
|
||||
|
||||
return redirect(route('index'));
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,7 @@ use FireflyIII\Http\Middleware\Authenticate;
|
||||
use FireflyIII\Http\Middleware\AuthenticateTwoFactor;
|
||||
use FireflyIII\Http\Middleware\Binder;
|
||||
use FireflyIII\Http\Middleware\EncryptCookies;
|
||||
use FireflyIII\Http\Middleware\Installer;
|
||||
use FireflyIII\Http\Middleware\IsAdmin;
|
||||
use FireflyIII\Http\Middleware\Range;
|
||||
use FireflyIII\Http\Middleware\RedirectIfAuthenticated;
|
||||
@ -66,6 +67,7 @@ class Kernel extends HttpKernel
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
TrustProxies::class,
|
||||
Installer::class
|
||||
];
|
||||
|
||||
/**
|
||||
@ -90,6 +92,7 @@ class Kernel extends HttpKernel
|
||||
|
||||
// MUST NOT be logged in. Does not care about 2FA or confirmation.
|
||||
'user-not-logged-in' => [
|
||||
Installer::class,
|
||||
Sandstorm::class,
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
@ -103,6 +106,7 @@ class Kernel extends HttpKernel
|
||||
// MUST NOT have 2FA
|
||||
// don't care about confirmation:
|
||||
'user-logged-in-no-2fa' => [
|
||||
Installer::class,
|
||||
Sandstorm::class,
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
|
86
app/Http/Middleware/Installer.php
Normal file
86
app/Http/Middleware/Installer.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use DB;
|
||||
use FireflyConfig;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Installer
|
||||
*/
|
||||
class Installer
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$url = $request->url();
|
||||
$strpos = stripos($url, '/install');
|
||||
if (!($strpos === false)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// no tables present?
|
||||
try {
|
||||
DB::table('users')->count();
|
||||
} catch (QueryException $e) {
|
||||
$message = $e->getMessage();
|
||||
Log::error('Access denied: ' . $message);
|
||||
if ($this->isAccessDenied($message)) {
|
||||
throw new FireflyException('It seems your database configuration is not correct. Please verify the username and password in your .env file.');
|
||||
}
|
||||
if ($this->noTablesExist($message)) {
|
||||
// redirect to UpdateController
|
||||
Log::warning('There are no Firefly III tables present. Redirect to migrate routine.');
|
||||
|
||||
return response()->redirectTo(route('installer.migrate'));
|
||||
}
|
||||
throw new FireflyException(sprintf('Could not access the database: %s', $message));
|
||||
}
|
||||
|
||||
// older version in config than database?
|
||||
$configVersion = intval(config('firefly.db_version'));
|
||||
$dbVersion = intval(FireflyConfig::get('db_version', 1)->data);
|
||||
if ($configVersion > $dbVersion) {
|
||||
Log::warning(sprintf(
|
||||
'The current installed version (%d) is older than the required version (%d). Redirect to migrate routine.', $dbVersion, $configVersion
|
||||
));
|
||||
|
||||
// redirect to migrate routine:
|
||||
return response()->redirectTo(route('installer.migrate'));
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAccessDenied(string $message): bool
|
||||
{
|
||||
return !(stripos($message, 'Access denied') === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function noTablesExist(string $message): bool
|
||||
{
|
||||
return !(stripos($message, 'Base table or view not found') === false);
|
||||
}
|
||||
}
|
37
database/seeds/ConfigSeeder.php
Normal file
37
database/seeds/ConfigSeeder.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use FireflyIII\Models\Configuration;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* Class ConfigSeeder
|
||||
*/
|
||||
class ConfigSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$entry = Configuration::where('name', 'db_version')->first();
|
||||
if (is_null($entry)) {
|
||||
Log::warning('No database version entry is present. Database is assumed to be OLD (version 1).');
|
||||
// FF old or no version present. Put at 1:
|
||||
Configuration::create(
|
||||
[
|
||||
'name' => 'db_version',
|
||||
'data' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!is_null($entry)) {
|
||||
$version = intval(config('firefly.db_version'));
|
||||
$entry->data = $version;
|
||||
$entry->save();
|
||||
|
||||
Log::warning(sprintf('Database entry exists. Update to latest version (%d)', $version));
|
||||
}
|
||||
}
|
||||
}
|
@ -37,5 +37,6 @@ class DatabaseSeeder extends Seeder
|
||||
$this->call(TransactionTypeSeeder::class);
|
||||
$this->call(PermissionSeeder::class);
|
||||
$this->call(LinkTypeSeeder::class);
|
||||
$this->call(ConfigSeeder::class);
|
||||
}
|
||||
}
|
||||
|
13
resources/views/install/index.twig
Normal file
13
resources/views/install/index.twig
Normal file
@ -0,0 +1,13 @@
|
||||
{% extends "./layout/install" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="login-box-body">
|
||||
<p class="login-box-msg">Please wait...</p>
|
||||
<div class="row">
|
||||
<div class="col-xs-8">
|
||||
Hello
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
33
resources/views/layout/install.twig
Normal file
33
resources/views/layout/install.twig
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="{{ route('index') }}/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="robots" content="noindex, nofollow, noarchive, noodp, NoImageIndex, noydir">
|
||||
<title>Firefly III - Installation and update</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
||||
<link href="css/app.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="lib/adminlte/css/AdminLTE.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="css/firefly.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="js/lib/html5shiv.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script src="js/lib/respond.min.js?v={{ FF_VERSION }}"></script>
|
||||
<![endif]-->
|
||||
|
||||
{# favicons #}
|
||||
{% include('partials.favicons') %}
|
||||
|
||||
</head>
|
||||
<body class="login-page">
|
||||
<div class="login-box">
|
||||
<div class="login-logo">
|
||||
<b>Firefly</b>III<br />
|
||||
<span style="font-family: monospace;font-size:16pt;">installation and upgrade</span>
|
||||
</div>
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<script src="js/app.js?v={{ FF_VERSION }}" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
@ -22,6 +22,15 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
Route::group(
|
||||
['namespace' => 'FireflyIII\Http\Controllers\System',
|
||||
'as' => 'installer.', 'prefix' => 'install'], function () {
|
||||
Route::get('', ['uses' => 'InstallController@index', 'as' => 'index']);
|
||||
|
||||
Route::get('migrate', ['uses' => 'InstallController@migrate', 'as' => 'migrate']);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* These routes only work when the user is NOT logged in.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user