diff --git a/.gitignore b/.gitignore index 5bc40922..6349f299 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ storage/*.sqlite .vscode storage/oauth-public.key storage/oauth-private.key +storage/install.lock .phpunit.result.cache diff --git a/app/Console/Commands/BsInstallCommand.php b/app/Console/Commands/BsInstallCommand.php index 5d44b65e..7fb1a7df 100644 --- a/app/Console/Commands/BsInstallCommand.php +++ b/app/Console/Commands/BsInstallCommand.php @@ -4,6 +4,7 @@ namespace App\Console\Commands; use App\Models\User; use Illuminate\Console\Command; +use Illuminate\Filesystem\Filesystem; class BsInstallCommand extends Command { @@ -11,9 +12,9 @@ class BsInstallCommand extends Command protected $description = 'Execute installation and create a super administrator.'; - public function handle() + public function handle(Filesystem $filesystem) { - if (\App\Http\Controllers\SetupController::checkTablesExist()) { + if ($filesystem->exists(storage_path('install.lock'))) { $this->info('You have installed Blessing Skin Server. Nothing to do.'); return; @@ -44,6 +45,8 @@ class BsInstallCommand extends Command $admin->verified = true; $admin->save(); + $filesystem->put(storage_path('install.lock'), ''); + $this->info('Installation completed!'); $this->info('We recommend to modify your "Site URL" option if incorrect.'); } diff --git a/app/Http/Controllers/SetupController.php b/app/Http/Controllers/SetupController.php index 452e5c0c..34a6b7fb 100644 --- a/app/Http/Controllers/SetupController.php +++ b/app/Http/Controllers/SetupController.php @@ -6,23 +6,22 @@ use DB; use Log; use File; use Option; -use Schema; use Artisan; -use Storage; use App\Models\User; +use Illuminate\Support\Str; use Illuminate\Http\Request; use Composer\Semver\Comparator; +use Illuminate\Filesystem\Filesystem; use App\Exceptions\PrettyPageException; +use Symfony\Component\Finder\SplFileInfo; class SetupController extends Controller { - public function welcome() + public function welcome(Filesystem $filesystem) { - // @codeCoverageIgnoreStart - if (! File::exists(base_path('.env'))) { - File::copy(base_path('.env.example'), base_path('.env')); + if (! $filesystem->exists(base_path('.env'))) { + $filesystem->copy(base_path('.env.example'), base_path('.env')); } - // @codeCoverageIgnoreEnd return view('setup.wizard.welcome'); } @@ -104,31 +103,7 @@ class SetupController extends Controller return redirect('setup/info'); } - public function info() - { - $existingTables = static::checkTablesExist([], true); - - // Not installed completely - if (count($existingTables) > 0) { - Log::info('Remaining tables detected, exit setup wizard now', [$existingTables]); - - $existingTables = array_map(function ($item) { - return get_db_config()['prefix'].$item; - }, $existingTables); - - throw new PrettyPageException(trans('setup.database.table-already-exists', ['tables' => json_encode($existingTables)]), 1); - } - - // @codeCoverageIgnoreStart - if (! function_exists('escapeshellarg')) { - throw new PrettyPageException(trans('setup.disabled-functions.escapeshellarg'), 1); - } - // @codeCoverageIgnoreEnd - - return view('setup.wizard.info'); - } - - public function finish(Request $request) + public function finish(Request $request, Filesystem $filesystem) { $data = $this->validate($request, [ 'email' => 'required|email', @@ -158,7 +133,7 @@ class SetupController extends Controller $siteUrl = url('/'); - if (ends_with($siteUrl, '/index.php')) { + if (Str::endsWith($siteUrl, '/index.php')) { $siteUrl = substr($siteUrl, 0, -10); // @codeCoverageIgnore } @@ -179,7 +154,7 @@ class SetupController extends Controller $user->save(); - $this->createDirectories(); + $filesystem->put(storage_path('install.lock'), ''); return view('setup.wizard.finish')->with([ 'email' => $request->input('email'), @@ -187,102 +162,22 @@ class SetupController extends Controller ]); } - public function update() + public function update(Filesystem $filesystem) { - if (Comparator::lessThanOrEqualTo(config('app.version'), option('version'))) { - // No updates available - return view('setup.locked'); - } - - return view('setup.updates.welcome'); - } - - public function doUpdate() - { - $resource = opendir(database_path('update_scripts')); - $updateScriptExist = false; - - while ($filename = @readdir($resource)) { - if ($filename != '.' && $filename != '..') { - preg_match('/update-(.*)-to-(.*).php/', $filename, $matches); - - // Skip if the file is not valid or expired - if (! isset($matches[2]) || - Comparator::lessThan($matches[2], config('app.version'))) { - continue; - } - - $tips = require database_path('update_scripts')."/$filename"; - $updateScriptExist = true; - } - } - closedir($resource); - - foreach (config('options') as $key => $value) { - if (! Option::has($key)) { - Option::set($key, $value); - } - } - Option::set('version', config('app.version')); + collect($filesystem->files(database_path('update_scripts'))) + ->filter(function (SplFileInfo $file) { + $name = $file->getFilenameWithoutExtension(); + return preg_match('/^\d+\.\d+\.\d+$/', $name) > 0 + && Comparator::greaterThanOrEqualTo($name, option('version')); + }) + ->each(function (SplFileInfo $file) use ($filesystem) { + $filesystem->getRequire($file->getPathname()); + }); + option(['version' => config('app.version')]); Artisan::call('view:clear'); + $filesystem->put(storage_path('install.lock'), ''); - return view('setup.updates.success', ['tips' => $tips ?? []]); - } - - /** - * Check if the given tables exist in current database. - * - * @param array $tables - * @param bool $returnExisting - * @return bool|array - */ - public static function checkTablesExist($tables = [], $returnExistingTables = false) - { - $existingTables = []; - $tables = $tables ?: [ - 'users', - 'user_closet', - 'players', - 'textures', - 'options', - 'reports', - ]; - - foreach ($tables as $tableName) { - if (Schema::hasTable($tableName)) { - $existingTables[] = $tableName; - } - } - - if (count($existingTables) == count($tables)) { - return $returnExistingTables ? $existingTables : true; - } else { - return $returnExistingTables ? $existingTables : false; - } - } - - public static function checkDirectories() - { - $directories = ['storage/textures', 'plugins']; - - try { - foreach ($directories as $dir) { - if (! Storage::disk('root')->has($dir)) { - if (! Storage::disk('root')->makeDirectory($dir)) { - return false; // @codeCoverageIgnore - } - } - } - - return true; - } catch (\Exception $e) { - return false; - } - } - - protected function createDirectories() - { - return self::checkDirectories(); + return view('setup.updates.success'); } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index dd6b548e..5d3f0897 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -31,8 +31,9 @@ class Kernel extends HttpKernel \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \App\Http\Middleware\ForbiddenIE::class, \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class, + \App\Http\Middleware\ForbiddenIE::class, + \App\Http\Middleware\RedirectToSetup::class, ], 'api' => [ diff --git a/app/Http/Middleware/CheckInstallation.php b/app/Http/Middleware/CheckInstallation.php index 6ec0abb5..19ab0076 100644 --- a/app/Http/Middleware/CheckInstallation.php +++ b/app/Http/Middleware/CheckInstallation.php @@ -2,17 +2,15 @@ namespace App\Http\Middleware; +use Illuminate\Filesystem\Filesystem; use App\Http\Controllers\SetupController; class CheckInstallation { public function handle($request, \Closure $next) { - if (config('database.default') == 'dummy') { - return $next($request); // @codeCoverageIgnore - } - - if (SetupController::checkTablesExist()) { + $hasLock = resolve(Filesystem::class)->exists(storage_path('install.lock')); + if ($hasLock && ! $request->is('setup/*update')) { return response()->view('setup.locked'); } diff --git a/app/Http/Middleware/LockUpdatePage.php b/app/Http/Middleware/LockUpdatePage.php deleted file mode 100644 index 142e35e0..00000000 --- a/app/Http/Middleware/LockUpdatePage.php +++ /dev/null @@ -1,16 +0,0 @@ -user()->permission < User::SUPER_ADMIN, 503); - - return $next($request); - } -} diff --git a/app/Http/Middleware/RedirectToSetup.php b/app/Http/Middleware/RedirectToSetup.php new file mode 100644 index 00000000..8b610232 --- /dev/null +++ b/app/Http/Middleware/RedirectToSetup.php @@ -0,0 +1,30 @@ +is('setup*') && Comparator::greaterThan($version, option('version', $version))) { + $user = $request->user(); + if ($user && $user->isAdmin()) { + return redirect('/setup/update'); + } else { + abort(503); + } + } + + $hasLock = resolve(Filesystem::class)->exists(storage_path('install.lock')); + if ($hasLock || $request->is('setup*')) { + return $next($request); + } + + return redirect('/setup'); + } +} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 15eebd0c..8c602214 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -20,16 +20,6 @@ class RouteServiceProvider extends ServiceProvider */ protected $namespace = 'App\Http\Controllers'; - /** - * Define your route model bindings, pattern filters, etc. - * - * @return void - */ - public function boot() - { - parent::boot(); - } - /** * Define the routes for the application. * @@ -38,8 +28,6 @@ class RouteServiceProvider extends ServiceProvider */ public function map(Router $router) { - $this->mapSetupRoutes($router); - $this->mapStaticRoutes($router); $this->mapWebRoutes($router); @@ -74,22 +62,6 @@ class RouteServiceProvider extends ServiceProvider }); } - /** - * Define the "setup" routes for the application. - * - * The routes for setup wizard. - * - * @param \Illuminate\Routing\Router $router - * @return void - */ - protected function mapSetupRoutes(Router $router) - { - Route::prefix('setup') - ->namespace($this->namespace) - ->middleware('web') - ->group(base_path('routes/setup.php')); - } - /** * Define the "static" routes for the application. * diff --git a/app/Providers/RuntimeCheckServiceProvider.php b/app/Providers/RuntimeCheckServiceProvider.php deleted file mode 100644 index 1d16167a..00000000 --- a/app/Providers/RuntimeCheckServiceProvider.php +++ /dev/null @@ -1,43 +0,0 @@ -is('setup*') || $this->app->runningInConsole()) { - return; - } - - $this->checkInstallation(); // @codeCoverageIgnore - } - - /** - * @codeCoverageIgnore - */ - protected function checkInstallation() - { - // Redirect to setup wizard - if (config('database.default') == 'dummy' || ! SetupController::checkTablesExist()) { - return redirect('/setup')->send(); - } - - if (Comparator::greaterThan(config('app.version'), option('version'))) { - return redirect('/setup/update')->send(); - } - - return true; - } -} diff --git a/config/app.php b/config/app.php index d3be00da..867beeab 100644 --- a/config/app.php +++ b/config/app.php @@ -170,7 +170,6 @@ return [ /* * Application Service Providers... */ - App\Providers\RuntimeCheckServiceProvider::class, App\Providers\AppServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\PluginServiceProvider::class, diff --git a/config/captcha.php b/config/captcha.php deleted file mode 100644 index 6d349b25..00000000 --- a/config/captcha.php +++ /dev/null @@ -1,45 +0,0 @@ - '2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ', - - 'default' => [ - 'length' => 5, - 'width' => 100, - 'height' => 34, - 'quality' => 90, - ], - - 'flat' => [ - 'length' => 6, - 'width' => 160, - 'height' => 46, - 'quality' => 90, - 'lines' => 6, - 'bgImage' => false, - 'bgColor' => '#ecf2f4', - 'fontColors'=> ['#2c3e50', '#c0392b', '#16a085', '#c0392b', '#8e44ad', '#303f9f', '#f57c00', '#795548'], - 'contrast' => -5, - ], - - 'mini' => [ - 'length' => 3, - 'width' => 60, - 'height' => 32, - ], - - 'inverse' => [ - 'length' => 5, - 'width' => 120, - 'height' => 36, - 'quality' => 90, - 'sensitive' => true, - 'angle' => 12, - 'sharpen' => 10, - 'blur' => 2, - 'invert' => true, - 'contrast' => -5, - ], - -]; diff --git a/resources/lang/en/setup.yml b/resources/lang/en/setup.yml index 7e950e5f..a5ee0be1 100644 --- a/resources/lang/en/setup.yml +++ b/resources/lang/en/setup.yml @@ -15,7 +15,7 @@ disabled-functions: locked: title: Already installed - text: It appears that you have already installed Blessing Skin Server. To reinstall, please delete the tables in your database first, or use a new table prefix. + text: It appears that you have already installed Blessing Skin Server. To reinstall, please delete the "install.lock" file under "storage" directory. button: Back to homepage updates: diff --git a/resources/lang/zh_CN/setup.yml b/resources/lang/zh_CN/setup.yml index 3bcb6642..c2e37050 100644 --- a/resources/lang/zh_CN/setup.yml +++ b/resources/lang/zh_CN/setup.yml @@ -14,7 +14,7 @@ disabled-functions: locked: title: 已安装过 - text: Blessing Skin Server 看起来已经安装妥当。如果想重新安装,请删除数据库中的旧数据表,或者换一个数据表前缀。 + text: Blessing Skin Server 看起来已经安装妥当。如果想重新安装,请删除 storage 目录下的 install.lock 文件。 button: 返回首页 updates: diff --git a/resources/misc/changelogs/en/next.md b/resources/misc/changelogs/en/next.md index d5a99633..a52fb783 100644 --- a/resources/misc/changelogs/en/next.md +++ b/resources/misc/changelogs/en/next.md @@ -14,6 +14,7 @@ - Tweaked policy of retrieve CA cert for GuzzleHttp. - Refactor account system. - PHP version requirement is increased to 7.2.0. +- Use `install.lock` file to detect status of installation. ## Fixed diff --git a/resources/misc/changelogs/zh_CN/next.md b/resources/misc/changelogs/zh_CN/next.md index 289b3064..773dbccf 100644 --- a/resources/misc/changelogs/zh_CN/next.md +++ b/resources/misc/changelogs/zh_CN/next.md @@ -14,6 +14,7 @@ - 修改 GuzzleHttp 库获取 CA 证书的策略 - 重构用户系统 - PHP 版本最低要求为 7.2.0 +- 使用 `install.lock` 文件来检测安装状态 ## 修复 diff --git a/resources/views/setup/updates/success.blade.php b/resources/views/setup/updates/success.blade.php index 315f6fad..8e2e5db8 100644 --- a/resources/views/setup/updates/success.blade.php +++ b/resources/views/setup/updates/success.blade.php @@ -8,16 +8,6 @@
@lang('setup.updates.success.text', ['version' => config('app.version')])
-{{-- if any tip is given --}} -@if (is_array($tips) && count($tips) > 0) -@lang('setup.updates.success.tips')
-{!! $tip !!}