Skip to main content

Attributi di Configurazione AutoPermissions

Il sistema AutoPermissions utilizza attributi PHP 8+ per configurare il comportamento di generazione e verificazione dei permessi. Ogni attributo ha uno scopo specifico e può essere utilizzato per personalizzare finemente il sistema.

Policy Required

L'attributo #[AutoPermissions] deve essere usato insieme a Laravel Policies per la verifica dei permessi. Il middleware automatico è stato rimosso in favore di un approccio più esplicito e testabile tramite $this->authorize() nei controller e BasePolicy per la verifica automatica dei permessi.

Attributo #[AutoPermissions]

L'attributo principale che attiva il sistema AutoPermissions su un controller.

Utilizzo

use App\Shared\Attributes\Permissions\AutoPermissions;

#[AutoPermissions]
class UserController extends Controller
{
// Tutti i metodi pubblici avranno permessi auto-generati
}

Parametri

ParametroTipoDefaultDescrizione
excludeMethodsarray<string>[]Array di nomi metodi da escludere
enabledbooltrueAbilita/disabilita il sistema per questo controller

Esempi Avanzati

Esclusione di Metodi Specifici

#[AutoPermissions(excludeMethods: ['index', 'show'])]
class UserController extends Controller
{
public function index() { } // ❌ Nessun permesso generato
public function show() { } // ❌ Nessun permesso generato
public function create() { } // ✅ Genera: shared.users.create
public function store() { } // ✅ Genera: shared.users.store
}

Disabilitazione Temporanea

#[AutoPermissions(enabled: false)]
class UserController extends Controller
{
// Nessun permesso verrà generato per questo controller
}

Configurazione Completa

#[AutoPermissions(
excludeMethods: ['publicMethod', 'guestAccess'],
enabled: true
)]
class ApiController extends Controller
{
public function publicMethod() { } // Accesso pubblico
public function guestAccess() { } // Accesso ospite
public function protectedData() { } // Richiede permesso
}

Attributo #[PermissionNaming]

Personalizza il naming delle risorse e permessi per un controller.

Utilizzo

use App\Shared\Attributes\Permissions\PermissionNaming;

#[PermissionNaming(resourceName: 'admin_users', moduleName: 'admin')]
class UserController extends Controller
{
public function index() { } // Genera: admin.admin_users.index
}

Parametri

ParametroTipoRichiestoDescrizione
resourceNamestringNome della risorsa (es: 'users', 'products')
moduleNamestringNome del modulo (es: 'shared', 'mc')

Regole di Validazione

  • Caratteri consentiti: solo lettere minuscole, numeri e underscore (a-z0-9_)
  • Lunghezza massima: 50 caratteri
  • Non consentiti: underscore consecutivi (__), underscore iniziale/finale
  • Formato: snake_case obbligatorio

Esempi Pratici

Naming Standard

#[PermissionNaming(resourceName: 'user_profiles', moduleName: 'shared')]
class ProfileController extends Controller
{
public function index() { } // shared.user_profiles.index
public function update() { } // shared.user_profiles.update
}

Con Modulo Specifico

#[PermissionNaming(resourceName: 'users', moduleName: 'admin')]
class AdminUserController extends Controller
{
public function index() { } // admin.users.index
public function delete() { } // admin.users.delete
}

Risoluzione Conflitti

// Controller API
#[PermissionNaming(resourceName: 'users', moduleName: 'api')]
class ApiUserController extends Controller
{
public function index() { } // api.users.index
}

// Controller Admin
#[PermissionNaming(resourceName: 'users', moduleName: 'admin')]
class AdminUserController extends Controller
{
public function index() { } // admin.users.index
}

Attributo #[CustomPermission]

Personalizza i metadati del permesso (titolo, descrizione, ordinamento) mantenendo l'azione uguale al nome del metodo.

Importante

L'azione del permesso è sempre il nome del metodo. #[CustomPermission] serve solo per personalizzare il titolo, la descrizione e l'ordinamento, non il nome dell'azione.

Utilizzo

use App\Shared\Attributes\Permissions\CustomPermission;

class UserController extends Controller
{
#[CustomPermission(title: 'Esportazione multipla utenti')]
public function exportUsers() { }
// Genera: shared.users.exportUsers
// Con titolo personalizzato: "Esportazione multipla utenti"
}

Parametri

ParametroTipoRichiestoDescrizione
titlestring|nullTitolo personalizzato del permesso (se null, usa auto-generazione)
descriptionstring|nullDescrizione opzionale del permesso
orderint|nullOrdine per il sorting nell'interfaccia (0-9999)

Regole di Validazione

  • Title:
    • Caratteri consentiti: lettere, numeri, spazi e caratteri di punteggiatura comuni
    • Lunghezza massima: 255 caratteri
    • Non consentiti: caratteri HTML pericolosi (<>"')
    • Opzionale: se non specificato, viene usata l'auto-generazione
  • Limitazione: solo un attributo CustomPermission per metodo
  • Order: deve essere un numero intero tra 0 e 9999 (numeri più bassi appaiono prima)

Esempi Avanzati

Titoli Descrittivi con Ordinamento

class DocumentController extends Controller
{
#[CustomPermission(
title: 'Visualizzare documento',
description: 'View document details',
order: 10
)]
public function show() { }
// Genera: shared.documents.show

Personalizzazione Titoli per Report

class ReportController extends Controller
{
#[CustomPermission(
title: 'Generare report PDF',
description: 'Generate PDF reports',
order: 1
)]
public function generatePdf() { }
// Genera: shared.reports.generatePdf

#[CustomPermission(
title: 'Programmare generazione automatica',
description: 'Schedule automatic report generation',
order: 99
)]
public function scheduleGeneration() { }
// Genera: shared.reports.scheduleGeneration
}

Attributo #[ExcludeFromPermissions]

Esclude metodi specifici dalla generazione automatica dei permessi.

Utilizzo

use App\Shared\Attributes\Permissions\ExcludeFromPermissions;

class UserController extends Controller
{
public function index() { } // ✅ Genera permesso

#[ExcludeFromPermissions]
public function healthCheck() { } // ❌ Nessun permesso

#[ExcludeFromPermissions(reason: 'Public endpoint')]
public function publicInfo() { } // ❌ Nessun permesso
}

Parametri

ParametroTipoRichiestoDescrizione
reasonstring|nullMotivo dell'esclusione (per documentazione)

Casi d'Uso Comuni

Endpoint Pubblici

class ApiController extends Controller
{
#[ExcludeFromPermissions(reason: 'Public API endpoint')]
public function version() { }

#[ExcludeFromPermissions(reason: 'Health check endpoint')]
public function health() { }

public function users() { } // Richiede permesso
}

Metodi di Utility

class BaseController extends Controller
{
#[ExcludeFromPermissions(reason: 'Internal helper method')]
public function validateInput() { }

#[ExcludeFromPermissions(reason: 'Response formatting')]
public function formatResponse() { }

public function getData() { } // Richiede permesso
}

Sistema di Priorità per i Titoli

Il sistema AutoPermissions gestisce i titoli dei permessi con una logica di priorità intelligente:

Priorità dei Titoli

  1. Titolo Personalizzato (massima priorità)

    • Se specificato nell'attributo #[CustomPermission(title: '...')]
    • Viene sempre utilizzato, sovrascrivendo qualsiasi altro titolo
  2. Titolo Auto-generato (priorità media)

    • Se non è specificato un titolo personalizzato
    • Utilizza le traduzioni dal file di lingua lang/it/permissions.php
    • Formato: {azione} {risorsa} (es: "Visualizzare utenti")
  3. Nessun Titolo (priorità minima)

    • Se entrambi i metodi falliscono
    • Il campo title rimane vuoto

Esempi di Priorità

class UserController extends Controller
{
// ✅ Priorità 1: Titolo personalizzato
#[CustomPermission(title: 'Eliminazione multipla di utenti')]
public function deleteMultiple() { }
// Genera: shared.users.deleteMultiple
// Titolo: "Eliminazione multipla di utenti"

// ✅ Priorità 2: Titolo auto-generato
public function exportUsers() { }
// Genera: shared.users.exportUsers
// Titolo: "Esportare utenti" (dalle traduzioni)
}

Combinazione di Attributi

Gli attributi possono essere combinati per configurazioni complesse:

Esempio Completo

#[AutoPermissions(excludeMethods: ['health', 'version'])]
#[PermissionNaming(resourceName: 'api_users', moduleName: 'api')]
class ApiUserController extends Controller
{
// Escluso tramite AutoPermissions
public function health() { }

// Escluso tramite AutoPermissions
public function version() { }

// Escluso tramite attributo specifico
#[ExcludeFromPermissions(reason: 'Public documentation')]
public function docs() { }

// Permesso personalizzato
#[CustomPermission(
title: 'Operazioni multiple su utenti',
description: 'Esegue operazioni su più utenti contemporaneamente'
)]
public function bulkUpdate() { }
// Genera: api.api_users.bulkUpdate

// Permesso standard
public function index() { }
// Genera: api.api_users.index
}

Errori Comuni e Troubleshooting

Errore: Caratteri Non Validi

// ❌ ERRORE
#[PermissionNaming(resourceName: 'User-Profiles', moduleName: 'shared')]
// InvalidArgumentException: contains invalid characters

// ✅ CORRETTO
#[PermissionNaming(resourceName: 'user_profiles', moduleName: 'shared')]

Errore: Attributi Multipli

// ❌ ERRORE: Solo un CustomPermission per metodo
#[CustomPermission(title: 'Creare utente')]
#[CustomPermission(title: 'Salvare utente')]
public function createUser() { }

// ✅ CORRETTO
#[CustomPermission(title: 'Creare e salvare utente')]
public function createUser() { }
// Genera: shared.users.createUser

Errore: Titolo con Caratteri Non Validi

// ❌ ERRORE
#[CustomPermission(title: 'Eliminare <utente>')]
// InvalidArgumentException: contains potentially dangerous characters

// ✅ CORRETTO
#[CustomPermission(title: 'Eliminare utente')]
public function delete() { }
// Genera: shared.users.delete

Best Practices

1. Naming Consistente

// ✅ Usa convenzioni chiare
#[PermissionNaming(resourceName: 'user_documents', moduleName: 'admin')]

// ❌ Evita nomi ambigui
#[PermissionNaming(resourceName: 'docs', moduleName: 'a')]

2. Documentazione delle Esclusioni

// ✅ Sempre specifica il motivo
#[ExcludeFromPermissions(reason: 'Public health check endpoint')]
public function health() { }

// ❌ Evita esclusioni senza motivo
#[ExcludeFromPermissions]
public function someMethod() { }

3. Risoluzione Proattiva dei Conflitti

// ✅ Usa prefissi per evitare conflitti
#[PermissionNaming(resourceName: 'users', moduleName: 'admin')]
class AdminUserController { }

#[PermissionNaming(resourceName: 'users', moduleName: 'api')]
class ApiUserController { }

4. Ordinamento Logico dei Permessi

class UserController extends Controller
{
// ✅ Usa order per raggruppare logicamente
#[CustomPermission(order: 1)]
public function show() { } // Lettura

#[CustomPermission(order: 10)]
public function create() { } // Creazione

#[CustomPermission(order: 20)]
public function update() { } // Modifica

#[CustomPermission(order: 30)]
public function destroy() { } // Eliminazione

#[CustomPermission(order: 40)]
public function export() { } // Export

#[CustomPermission(order: 100)]
public function adminAccess() { } // Admin

// ❌ Evita order casuali
#[CustomPermission(order: 5)]
public function destroy() { } // Eliminazione prima della lettura

#[CustomPermission(order: 50)]
public function show() { } // Lettura dopo operazioni avanzate
}