From d868e1c2c982572d627f81b25431027d31aa3ad7 Mon Sep 17 00:00:00 2001 From: Eleazar Resendez Date: Mon, 8 Dec 2025 10:21:45 -0600 Subject: [PATCH] Protect designer route with shared gate and add forbidden access test --- ProcessMaker/Http/Middleware/GenerateMenus.php | 3 ++- ProcessMaker/Providers/AuthServiceProvider.php | 9 ++++----- routes/web.php | 2 +- tests/Feature/Api/DesignerControllerTest.php | 15 ++++++++++++++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ProcessMaker/Http/Middleware/GenerateMenus.php b/ProcessMaker/Http/Middleware/GenerateMenus.php index f714b52ac5..bd97b0be17 100644 --- a/ProcessMaker/Http/Middleware/GenerateMenus.php +++ b/ProcessMaker/Http/Middleware/GenerateMenus.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Gate; use Lavary\Menu\Facade as Menu; use ProcessMaker\Models\Permission; use ProcessMaker\Models\Setting; @@ -50,7 +51,7 @@ public function handle(Request $request, Closure $next) ['route' => 'tasks.index', 'id' => 'tasks'] )->active('tasks/*'); }); - if (\Auth::check() && \Auth::user()->canAny('view-processes|view-process-categories|view-scripts|view-screens|view-environment_variables|view-projects')) { + if (Gate::allows('view-designer')) { $menu->group(['prefix' => 'designer'], function ($request_items) { $request_items->add( __('Designer'), diff --git a/ProcessMaker/Providers/AuthServiceProvider.php b/ProcessMaker/Providers/AuthServiceProvider.php index 6f0572a392..07a076d9fe 100644 --- a/ProcessMaker/Providers/AuthServiceProvider.php +++ b/ProcessMaker/Providers/AuthServiceProvider.php @@ -5,23 +5,18 @@ use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Cache; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Schema; -use Illuminate\Support\Str; use Laravel\Passport\Passport; use ProcessMaker\Events\TenantResolved; use ProcessMaker\Models\AnonymousUser; use ProcessMaker\Models\Media; -use ProcessMaker\Models\Notification; use ProcessMaker\Models\Permission; use ProcessMaker\Models\Process; use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\ProcessRequestToken; use ProcessMaker\Models\ProcessVersion; -use ProcessMaker\Models\Screen; use ProcessMaker\Models\Script; use ProcessMaker\Models\User; use ProcessMaker\Policies\MediaPolicy; @@ -101,6 +96,10 @@ public function defineGates() return $user->hasPermission($permission); }); } + + Gate::define('view-designer', function ($user) { + return $user->canAny('view-processes|view-process-categories|view-scripts|view-screens|view-environment_variables|view-projects'); + }); } catch (\Exception $e) { Log::notice('Unable to register gates. Either no database connection or no permissions table exists.'); } diff --git a/routes/web.php b/routes/web.php index 30f1cdaa35..30c5c058ba 100644 --- a/routes/web.php +++ b/routes/web.php @@ -111,7 +111,7 @@ Route::get('designer/screens/categories', [ScreenController::class, 'index'])->name('screen-categories.index')->middleware('can:view-screen-categories'); Route::get('designer/scripts/categories', [ScriptController::class, 'index'])->name('script-categories.index')->middleware('can:view-script-categories'); - Route::get('designer', [DesignerController::class, 'index'])->name('designer.index'); + Route::get('designer', [DesignerController::class, 'index'])->name('designer.index')->middleware('can:view-designer'); Route::get('process-browser/{process?}', [ProcessesCatalogueController::class, 'index']) ->name('process.browser.index') diff --git a/tests/Feature/Api/DesignerControllerTest.php b/tests/Feature/Api/DesignerControllerTest.php index 4b2700e849..dbe0dd7ef4 100644 --- a/tests/Feature/Api/DesignerControllerTest.php +++ b/tests/Feature/Api/DesignerControllerTest.php @@ -2,7 +2,7 @@ namespace Tests\Feature\Api; -use Auth; +use Illuminate\Support\Facades\Auth; use ProcessMaker\Models\User; use Tests\TestCase; @@ -24,4 +24,17 @@ public function testIndexMethod() $response->assertStatus(200); $response->assertViewIs('designer.index'); } + + public function testIndexIsForbiddenWithoutDesignerPermissions(): void + { + $user = User::factory()->create([ + 'is_administrator' => false, + ]); + + Auth::login($user); + + $response = $this->get('/designer'); + + $response->assertForbidden(); + } }