From c505708ae2a1bb5c00fd2ce0c264019dc27caf08 Mon Sep 17 00:00:00 2001 From: Francesco Picone Date: Sat, 25 Jul 2026 22:58:29 +0200 Subject: [PATCH] ++ fix campagna --- HANDOFF.md | 11 +++++++++++ app/Livewire/Campagne/CampagnaEdit.php | 7 +++++++ app/Livewire/Campagne/CampagnaIndex.php | 5 +++++ .../views/livewire/campagne/campagna-index.blade.php | 2 +- .../views/livewire/campagne/campagna-show.blade.php | 2 +- routes/web.php | 6 +++++- 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/HANDOFF.md b/HANDOFF.md index 0bf69e0..8b04c71 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -112,6 +112,17 @@ drift per i database esistenti: revoca `settings.manage` dal ruolo `assistente` se presente. È idempotente (no-op sul baseline) e volutamente irreversibile — il `down()` non ripristina il permesso. +Stesso principio per le **campagne**: creazione e visualizzazione restano su +`campagne.manage` (che ha anche l'assistente), ma **modifica ed eliminazione +sono riservate all'amministratore** (`settings.manage`). Il gate è su tre +livelli: la route `campagne/{campagna}/edit` è nel gruppo `settings.manage`; +`CampagnaEdit::mount()`/`save()` e `CampagnaIndex::deleteCampagna()` chiamano +`$this->authorize('settings.manage')` (l'index è raggiungibile da chi ha +`campagne.manage`, quindi il delete va protetto nel metodo, non solo in route); +i pulsanti Modifica/Elimina in `campagna-index`/`campagna-show` sono sotto +`@can('settings.manage')`. Nota: `Campagna` non ha soft delete — l'eliminazione +è definitiva. + ### Export/Import XML: backup completo e round-trip `Livewire/Settings/XmlExchange` esporta e reimporta **tutti** i dati gestionali, diff --git a/app/Livewire/Campagne/CampagnaEdit.php b/app/Livewire/Campagne/CampagnaEdit.php index d3aa790..99c19c6 100644 --- a/app/Livewire/Campagne/CampagnaEdit.php +++ b/app/Livewire/Campagne/CampagnaEdit.php @@ -14,6 +14,9 @@ class CampagnaEdit extends Component public function mount(Campagna $campagna) { + // Modifica campagne riservata all'amministratore. + $this->authorize('settings.manage'); + $this->campagna = $campagna; $this->descrizione = $campagna->descrizione; $this->start_date = $campagna->start_date->format('Y-m-d'); @@ -31,6 +34,10 @@ class CampagnaEdit extends Component public function save() { + // Re-check on the update request: route middleware guards the initial + // load, but the action can be replayed on a persisted component. + $this->authorize('settings.manage'); + $this->validate(); $this->campagna->update([ diff --git a/app/Livewire/Campagne/CampagnaIndex.php b/app/Livewire/Campagne/CampagnaIndex.php index 6722664..84cf51d 100644 --- a/app/Livewire/Campagne/CampagnaIndex.php +++ b/app/Livewire/Campagne/CampagnaIndex.php @@ -12,6 +12,11 @@ class CampagnaIndex extends Component public function deleteCampagna(int $id) { + // Eliminazione campagne riservata all'amministratore. La index è + // accessibile a chiunque abbia campagne.manage, quindi il gate deve + // stare qui, non solo sul middleware di route. + $this->authorize('settings.manage'); + $campagna = Campagna::findOrFail($id); $campagna->delete(); session()->flash('success', "Campagna '{$campagna->descrizione}' eliminata."); diff --git a/resources/views/livewire/campagne/campagna-index.blade.php b/resources/views/livewire/campagne/campagna-index.blade.php index 4d8dc03..fdaf1c9 100644 --- a/resources/views/livewire/campagne/campagna-index.blade.php +++ b/resources/views/livewire/campagne/campagna-index.blade.php @@ -50,7 +50,7 @@ - @can('campagne.manage') + @can('settings.manage') diff --git a/resources/views/livewire/campagne/campagna-show.blade.php b/resources/views/livewire/campagne/campagna-show.blade.php index 900c648..219ba80 100644 --- a/resources/views/livewire/campagne/campagna-show.blade.php +++ b/resources/views/livewire/campagne/campagna-show.blade.php @@ -7,7 +7,7 @@

{{ $campagna->descrizione }}

- @can('campagne.manage') + @can('settings.manage') Modifica diff --git a/routes/web.php b/routes/web.php index 48f339e..cd564c0 100644 --- a/routes/web.php +++ b/routes/web.php @@ -92,11 +92,15 @@ Route::middleware('auth')->group(function () { Route::get('assegnazioni/{assegnazione}/rientra', Rientra::class)->name('assegnazioni.rientra'); }); - // Campagne + // Campagne — creazione/visualizzazione per chi ha campagne.manage. Route::middleware('permission:campagne.manage')->group(function () { Route::get('campagne', CampagnaIndex::class)->name('campagne.index'); Route::get('campagne/create', CampagnaCreate::class)->name('campagne.create'); Route::get('campagne/{campagna}', CampagnaShow::class)->name('campagne.show'); + }); + // Modifica campagne: solo amministratore (settings.manage). L'eliminazione + // vive in CampagnaIndex::deleteCampagna(), protetta lì con lo stesso gate. + Route::middleware('permission:settings.manage')->group(function () { Route::get('campagne/{campagna}/edit', CampagnaEdit::class)->name('campagne.edit'); });