diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 9fe18fe7a..83006e4a1 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -54,6 +54,7 @@ class Kernel extends HttpKernel 'permission:read-api', 'company.identify', 'bindings', + 'read.only', 'language', 'firewall.all', ], @@ -62,12 +63,14 @@ class Kernel extends HttpKernel 'web', 'company.identify', 'bindings', + 'read.only', 'wizard.redirect', ], 'guest' => [ 'web', 'auth.redirect', + 'read.only', ], 'admin' => [ @@ -76,6 +79,7 @@ class Kernel extends HttpKernel 'auth.disabled', 'company.identify', 'bindings', + 'read.only', 'wizard.redirect', 'menu.admin', 'permission:read-admin-panel', @@ -96,6 +100,7 @@ class Kernel extends HttpKernel 'auth.disabled', 'company.identify', 'bindings', + 'read.only', 'menu.portal', 'permission:read-client-portal', ], @@ -109,6 +114,7 @@ class Kernel extends HttpKernel 'signature', 'company.identify', 'bindings', + 'read.only', 'header.x', 'language', 'firewall.all', @@ -157,6 +163,7 @@ class Kernel extends HttpKernel 'install.can' => \App\Http\Middleware\CanInstall::class, 'install.redirect' => \App\Http\Middleware\RedirectIfNotInstalled::class, 'money' => \App\Http\Middleware\Money::class, + 'read.only' => \App\Http\Middleware\CheckForReadOnlyMode::class, 'wizard.redirect' => \App\Http\Middleware\RedirectIfWizardNotCompleted::class, // Vendor diff --git a/app/Http/Middleware/CheckForReadOnlyMode.php b/app/Http/Middleware/CheckForReadOnlyMode.php new file mode 100644 index 000000000..e6f1847e8 --- /dev/null +++ b/app/Http/Middleware/CheckForReadOnlyMode.php @@ -0,0 +1,68 @@ +routeIs(config('read-only.login_route')); + $is_logout = $request->routeIs(config('read-only.logout_route')); + + if ($is_login || $is_logout) { + return $next($request); + } + } + + foreach (config('read-only.whitelist') as $method => $route) { + if (! $request->isMethod($method) || ! $request->routeIs($route)) { + continue; + } + + return $next($request); + } + + foreach (config('read-only.livewire') as $path) { + $url = company_id() . '/livewire/message/' . $path; + + if (! $request->isMethod('post') || ! $request->is($url)) { + continue; + } + + return $next($request); + } + + foreach (config('read-only.methods') as $method) { + if (! $request->isMethod(strtolower($method))) { + continue; + } + + //abort(Response::HTTP_UNAUTHORIZED); + + return response()->json([ + 'success' => false, + 'error' => true, + 'data' => null, + 'message' => trans('maintenance.read_only'), + ], Response::HTTP_UNAUTHORIZED); + } + + return $next($request); + } +} diff --git a/app/Http/ViewComposers/ReadOnlyNotification.php b/app/Http/ViewComposers/ReadOnlyNotification.php new file mode 100644 index 000000000..1e8d488bc --- /dev/null +++ b/app/Http/ViewComposers/ReadOnlyNotification.php @@ -0,0 +1,17 @@ +getFactory()->startPush('content_content_start', view('partials.read-only')); + } +} diff --git a/app/Listeners/Common/SkipScheduleInReadOnlyMode.php b/app/Listeners/Common/SkipScheduleInReadOnlyMode.php new file mode 100644 index 000000000..fe72f3b7a --- /dev/null +++ b/app/Listeners/Common/SkipScheduleInReadOnlyMode.php @@ -0,0 +1,30 @@ +task->skip(true); + + $schedule = app(Schedule::class); + + foreach ($schedule->events() as $task) { + $task->skip(true); + } + } +} diff --git a/app/Providers/Blade.php b/app/Providers/Blade.php index 2073f81c3..d0c1e99ea 100644 --- a/app/Providers/Blade.php +++ b/app/Providers/Blade.php @@ -24,6 +24,10 @@ class Blade extends ServiceProvider Facade::directive('widget', function ($expression) { return ""; }); + + Facade::if('readonly', function () { + return config('read-only.enabled'); + }); } /** diff --git a/app/Providers/Event.php b/app/Providers/Event.php index d792276a7..1bd084658 100644 --- a/app/Providers/Event.php +++ b/app/Providers/Event.php @@ -48,6 +48,10 @@ class Event extends Provider 'Illuminate\Auth\Events\Logout' => [ 'App\Listeners\Auth\Logout', ], + //'Illuminate\Console\Events\ScheduledTaskStarting' => [ + 'Illuminate\Console\Events\CommandStarting' => [ + 'App\Listeners\Common\SkipScheduleInReadOnlyMode', + ], 'App\Events\Auth\LandingPageShowing' => [ 'App\Listeners\Auth\AddLandingPages', ], diff --git a/app/Providers/ViewComposer.php b/app/Providers/ViewComposer.php index 9b1114be5..53425626f 100644 --- a/app/Providers/ViewComposer.php +++ b/app/Providers/ViewComposer.php @@ -66,6 +66,11 @@ class ViewComposer extends Provider View::composer( 'layouts.wizard', 'App\Http\ViewComposers\Wizard' ); + + View::composer( + ['partials.admin.content'], + 'App\Http\ViewComposers\ReadOnlyNotification' + ); } /** diff --git a/config/read-only.php b/config/read-only.php new file mode 100644 index 000000000..6e1040424 --- /dev/null +++ b/config/read-only.php @@ -0,0 +1,50 @@ + env('READ_ONLY_ENABLED', false), + + /* + |-------------------------------------------------------------------------- + | Enable read-only mode but still allow users to login + |-------------------------------------------------------------------------- + */ + 'allow_login' => env('READ_ONLY_LOGIN', true), + + /* + |-------------------------------------------------------------------------- + | The login/logout routes to allow if allow_login=true + |-------------------------------------------------------------------------- + */ + 'login_route' => 'login.store', + 'logout_route' => 'logout', + + /* + |-------------------------------------------------------------------------- + | The request methods that you want to block + |-------------------------------------------------------------------------- + */ + 'methods' => explode(',', env('READ_ONLY_METHODS', 'post,put,patch,delete')), + + /* + |-------------------------------------------------------------------------- + | Whitelist certain request methods to certain routes + |-------------------------------------------------------------------------- + */ + 'whitelist' => [ + // 'post' => 'dashboard', + ], + + /* + |-------------------------------------------------------------------------- + | Skip livewire paths + |-------------------------------------------------------------------------- + */ + 'livewire' => explode(',', env('READ_ONLY_LIVEWIRE', 'common.search')), + +]; diff --git a/resources/lang/en-GB/maintenance.php b/resources/lang/en-GB/maintenance.php index 49b62ed72..645b59fed 100644 --- a/resources/lang/en-GB/maintenance.php +++ b/resources/lang/en-GB/maintenance.php @@ -6,4 +6,6 @@ return [ 'message' => 'Sorry, we\'re down for maintenance. Please, try again later!', + 'read_only' => 'Read-only mode is enabled. You are allowed to view but not change anything!', + ]; diff --git a/resources/views/partials/read-only.blade.php b/resources/views/partials/read-only.blade.php new file mode 100644 index 000000000..17cd9e41c --- /dev/null +++ b/resources/views/partials/read-only.blade.php @@ -0,0 +1,3 @@ +