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.
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
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
excludeMethods | array<string> | [] | Array di nomi metodi da escludere |
enabled | bool | true | Abilita/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
| Parametro | Tipo | Richiesto | Descrizione |
|---|---|---|---|
resourceName | string | ✅ | Nome della risorsa (es: 'users', 'products') |
moduleName | string | ✅ | Nome 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]
Override del nome azione per metodi specifici mantenendo il namespace della risorsa.
Utilizzo
use App\Shared\Attributes\Permissions\CustomPermission;
class UserController extends Controller
{
#[CustomPermission(action: 'bulk_export')]
public function exportUsers() { }
// Genera: shared.users.bulk_export (invece di shared.users.exportUsers)
}
Parametri
| Parametro | Tipo | Richiesto | Descrizione |
|---|---|---|---|
action | string | ✅ | Nome personalizzato dell'azione |
title | string|null | ❌ | Titolo personalizzato del permesso (se null, usa auto-generazione) |
description | string|null | ❌ | Descrizione opzionale del permesso |
order | int|null | ❌ | Ordine per il sorting nell'interfaccia (0-9999) |
Regole di Validazione
- Action:
- Caratteri consentiti: solo lettere minuscole, numeri e underscore (
a-z0-9_) - Lunghezza massima: 50 caratteri
- Non consentiti: punti (
.), underscore consecutivi, underscore iniziale/finale
- Caratteri consentiti: solo lettere minuscole, numeri e underscore (
- 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
CustomPermissionper metodo - Order: deve essere un numero intero tra 0 e 9999 (numeri più bassi appaiono prima)
Esempi Avanzati
Azioni Descrittive con Ordinamento
class DocumentController extends Controller
{
#[CustomPermission(
action: 'view',
title: 'Visualizzare documento',
description: 'View document details',
order: 10
)]
public function show() { }
#[CustomPermission(
action: 'bulk_download',
title: 'Scaricare documenti multipli',
description: 'Download multiple documents as ZIP',
order: 100
)]
public function downloadMultiple() { }
// Genera: shared.documents.bulk_download
#[CustomPermission(
action: 'advanced_search',
title: 'Ricerca avanzata',
order: 50
)]
public function searchWithFilters() { }
// Genera: shared.documents.advanced_search
}
Operazioni Speciali
class ReportController extends Controller
{
#[CustomPermission(
action: 'generate_pdf',
title: 'Generare report PDF',
description: 'Generate PDF reports',
order: 1
)]
public function createPdfReport() { }
// Genera: shared.reports.generate_pdf
#[CustomPermission(
action: 'schedule_generation',
title: 'Programmare generazione automatica',
description: 'Schedule automatic report generation',
order: 99
)]
public function scheduleReport() { }
// Genera: shared.reports.schedule_generation
}
Mappatura Legacy
class LegacyController extends Controller
{
#[CustomPermission(action: 'view')]
public function displayData() { }
// Genera: shared.legacy.view (invece di shared.legacy.displayData)
#[CustomPermission(action: 'modify')]
public function changeData() { }
// Genera: shared.legacy.modify (invece di shared.legacy.changeData)
}
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
| Parametro | Tipo | Richiesto | Descrizione |
|---|---|---|---|
reason | string|null | ❌ | Motivo 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
-
Titolo Personalizzato (massima priorità)
- Se specificato nell'attributo
#[CustomPermission(title: '...')] - Viene sempre utilizzato, sovrascrivendo qualsiasi altro titolo
- Se specificato nell'attributo
-
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")
-
Nessun Titolo (priorità minima)
- Se entrambi i metodi falliscono
- Il campo
titlerimane vuoto
Esempi di Priorità
class UserController extends Controller
{
// ✅ Priorità 1: Titolo personalizzato
#[CustomPermission(
action: 'bulk_delete',
title: 'Eliminazione multipla di utenti'
)]
public function deleteMultiple() { }
// Titolo: "Eliminazione multipla di utenti"
// ✅ Priorità 2: Titolo auto-generato
#[CustomPermission(action: 'export')]
public function exportUsers() { }
// Titolo: "Esportare utenti" (dalle traduzioni)
// ✅ Priorità 2: Titolo auto-generato
public function index() { }
// Titolo: "Visualizzare 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(
action: 'bulk_operations',
title: 'Operazioni multiple su utenti',
description: 'Esegue operazioni su più utenti contemporaneamente'
)]
public function bulkUpdate() { }
// Genera: api.api_users.bulk_operations
// 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(action: 'create')]
#[CustomPermission(action: 'store')]
public function createUser() { }
// ✅ CORRETTO
#[CustomPermission(action: 'create_user')]
public function createUser() { }
Errore: Punti nel Nome Azione
// ❌ ERRORE
#[CustomPermission(action: 'users.bulk_delete')]
// InvalidArgumentException: cannot contain dots
// ✅ CORRETTO
#[CustomPermission(action: 'bulk_delete')]
public function bulkDelete() { }
// Genera: shared.users.bulk_delete (resource.action)
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. Azioni Descrittive
// ✅ Nomi azioni chiari
#[CustomPermission(action: 'export_user_data')]
#[CustomPermission(action: 'bulk_status_update')]
// ❌ Evita abbreviazioni oscure
#[CustomPermission(action: 'exp_usr')]
#[CustomPermission(action: 'bulk_upd')]
4. Risoluzione Proattiva dei Conflitti
// ✅ Usa prefissi per evitare conflitti
#[PermissionNaming(resourceName: 'users', moduleName: 'admin')]
class AdminUserController { }
#[PermissionNaming(resourceName: 'users', moduleName: 'api')]
class ApiUserController { }
5. Ordinamento Logico dei Permessi
// ✅ Usa order per raggruppare logicamente
#[CustomPermission(action: 'view', order: 1)] // Lettura
#[CustomPermission(action: 'create', order: 10)] // Creazione
#[CustomPermission(action: 'update', order: 20)] // Modifica
#[CustomPermission(action: 'delete', order: 30)] // Eliminazione
#[CustomPermission(action: 'export', order: 40)] // Export
#[CustomPermission(action: 'admin_access', order: 100)] // Admin
// ❌ Evita order casuali
#[CustomPermission(action: 'delete', order: 5)] // Eliminazione prima della lettura
#[CustomPermission(action: 'view', order: 50)] // Lettura dopo operazioni avanzate