From 5a83263f7a7e3cf78ac1bf5c1b2a301609d6bd47 Mon Sep 17 00:00:00 2001 From: Joel Wedemire Date: Tue, 28 Jul 2026 16:53:29 -0400 Subject: [PATCH] Gate my-tickets and prefs; leave attachments to their own finer check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit my-tickets and prefs.save carried only `app.access:ticketing`, which means "you hold ANY ticketing.* permission" — so ticketing.settings alone opened the submitter's own surface. They now require ticketing.view or ticketing.manage, matching the either-or this route file already uses everywhere else; ticketing.view is literally described as "Submit tickets and view own ticket history", so it is the right key. attachments.show stays UNGATED on purpose. TicketAttachmentController::show already authorises submitter-or-agent for that specific attachment, which is finer than any permission can be — a key in front of it would either duplicate the check or contradict it, and contradiction is what this consolidation exists to remove. Part of consolidating Central onto one authorisation mechanism: permissions, held by groups. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01RDA3fQbsa3gaHCFoV1Q8Gg --- src/routes/ticketing.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/routes/ticketing.php b/src/routes/ticketing.php index 65ca592..6017c1f 100644 --- a/src/routes/ticketing.php +++ b/src/routes/ticketing.php @@ -13,8 +13,20 @@ Route::middleware(['web', 'auth', 'app.access:ticketing']) // ── Fixed paths first (before any /{ticket} wildcards) ──────────────── - Route::get('/my-tickets', [TicketController::class, 'myTickets'])->name('my-tickets'); - Route::post('/prefs', [TicketController::class, 'savePrefs']) ->name('prefs.save'); + // my-tickets and prefs carried only `app.access:ticketing`, which means "you hold + // ANY ticketing.* permission" — so ticketing.settings alone opened them. They are + // the submitter's own surface, and ticketing.view is literally described as + // "Submit tickets and view own ticket history", so it is the right key; managers + // hold it implicitly via the same either-or the rest of this file uses. + Route::middleware('permission:ticketing.view,ticketing.manage')->group(function () { + Route::get('/my-tickets', [TicketController::class, 'myTickets'])->name('my-tickets'); + Route::post('/prefs', [TicketController::class, 'savePrefs']) ->name('prefs.save'); + }); + + // Attachments stay ungated ON PURPOSE: TicketAttachmentController::show already + // authorises submitter-or-agent per attachment, which is finer than any + // permission could be. A key here would either duplicate that check or + // contradict it. Route::get('/attachments/{attachment}', [TicketAttachmentController::class, 'show'])->name('attachments.show'); Route::middleware('permission:ticketing.view,ticketing.manage')->group(function () {