diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 71dd0e8..e7302ad 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -82,16 +82,7 @@ class AppServiceProvider extends ServiceProvider ->to($notifiable->getEmailForPasswordReset()) ); - Gate::define('viewApiDocs', function ($user = null) { - // Option A : Autoriser tout le monde (Attention : la doc sera publique hors local) - return true; - - /* // Option B : Autoriser seulement certains emails - return in_array($user?->email, [ - 'admin@tondomaine.com', - ], true); - */ - }); + Gate::define('viewApiDocs', fn (?User $user): bool => $user?->isAdmin() === true); Health::checks([ DatabaseCheck::new(), diff --git a/app/Providers/Filament/DashboardPanelProvider.php b/app/Providers/Filament/DashboardPanelProvider.php index 17a69e6..d2acdb1 100644 --- a/app/Providers/Filament/DashboardPanelProvider.php +++ b/app/Providers/Filament/DashboardPanelProvider.php @@ -13,7 +13,6 @@ use Filament\Panel; use Filament\PanelProvider; use Filament\Support\Colors\Color; use Filament\Widgets\AccountWidget; -use Filament\Widgets\FilamentInfoWidget; use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; use Illuminate\Cookie\Middleware\EncryptCookies; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; @@ -42,7 +41,8 @@ class DashboardPanelProvider extends PanelProvider ->url(url('/horizon'), shouldOpenInNewTab: true) ->icon('heroicon-o-queue-list') ->group('Settings') - ->sort(3), + ->sort(3) + ->visible(fn (): bool => auth()->user()?->isAdmin() === true), ]) ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') ->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages') diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php index 8699835..12ed16e 100644 --- a/app/Providers/HorizonServiceProvider.php +++ b/app/Providers/HorizonServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Models\User; use Illuminate\Support\Facades\Gate; use Laravel\Horizon\Horizon; use Laravel\Horizon\HorizonApplicationServiceProvider; @@ -27,8 +28,6 @@ class HorizonServiceProvider extends HorizonApplicationServiceProvider */ protected function gate(): void { - Gate::define('viewHorizon', function ($user = null) { - return true; - }); + Gate::define('viewHorizon', fn (?User $user): bool => $user?->isAdmin() === true); } } diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index b54cbe5..7cc2b59 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -32,6 +32,10 @@ services: image: adminer:latest container_name: bemeal-adminer restart: unless-stopped + profiles: + - debug + ports: + - "127.0.0.1:${ADMINER_PORT:-8080}:8080" environment: ADMINER_DEFAULT_SERVER: bemeal-pgsql networks: diff --git a/tests/Feature/ProductionToolingAccessTest.php b/tests/Feature/ProductionToolingAccessTest.php new file mode 100644 index 0000000..b27b604 --- /dev/null +++ b/tests/Feature/ProductionToolingAccessTest.php @@ -0,0 +1,67 @@ +create([ + 'role' => UserRole::ADMIN, + ]); + $moderator = User::factory()->create([ + 'role' => UserRole::MODERATOR, + ]); + $user = User::factory()->create([ + 'role' => UserRole::USER, + ]); + + expect(Gate::forUser($admin)->allows('viewHorizon'))->toBeTrue() + ->and(Gate::forUser($admin)->allows('viewApiDocs'))->toBeTrue() + ->and(Gate::forUser($moderator)->allows('viewHorizon'))->toBeFalse() + ->and(Gate::forUser($moderator)->allows('viewApiDocs'))->toBeFalse() + ->and(Gate::forUser($user)->allows('viewHorizon'))->toBeFalse() + ->and(Gate::forUser($user)->allows('viewApiDocs'))->toBeFalse() + ->and(Gate::allows('viewHorizon'))->toBeFalse() + ->and(Gate::allows('viewApiDocs'))->toBeFalse(); +}); + +it('protects the horizon dashboard outside local environments', function (): void { + $admin = User::factory()->create([ + 'role' => UserRole::ADMIN, + ]); + $moderator = User::factory()->create([ + 'role' => UserRole::MODERATOR, + ]); + + $this->get('/horizon')->assertForbidden(); + + $this->actingAs($moderator) + ->get('/horizon') + ->assertForbidden(); + + $this->actingAs($admin) + ->get('/horizon') + ->assertSuccessful(); +}); + +it('protects the scramble documentation outside local environments', function (): void { + $admin = User::factory()->create([ + 'role' => UserRole::ADMIN, + ]); + $user = User::factory()->create([ + 'role' => UserRole::USER, + ]); + + $this->get('/docs/api')->assertForbidden(); + + $this->actingAs($user) + ->get('/docs/api') + ->assertForbidden(); + + $this->actingAs($admin) + ->get('/docs/api') + ->assertSuccessful(); +});