# 🔐 PERMISSIONS - Documentazione Completa NetGescon > **Sistema Permessi dell'interfaccia universale** > **📅 Creato:** 21/07/2025 > **🔄 Ultimo aggiornamento:** 21/07/2025 > **🎯 Priorità:** ⚡ ALTO --- ## 📋 **OVERVIEW PERMISSIONS SYSTEM** Il Sistema Permessi NetGescon gestisce **ACCESSO GRANULARE** per: - 👤 **User Roles** (Super Admin, Admin, Manager, User, Guest) - 🔑 **Permissions** (Create, Read, Update, Delete, Execute) - 🏢 **Resource Access** (Stabili, Condomini, Unità, Reports) - 📊 **Data Visibility** (Own, Team, Company, All) - 🎛️ **UI Components** (Navigation, Actions, Features) ### 🎯 **Security Philosophy** - **Least Privilege** - Accesso minimo necessario per default - **Role-Based Access** - Permessi basati su ruoli definiti - **Resource-Level Security** - Controllo granulare per ogni risorsa - **UI-Driven Permissions** - Interfaccia che si adatta ai permessi --- ## 👥 **ROLE SYSTEM** ### 🔑 **Role Definitions** ```php // app/Models/User.php class User extends Authenticatable implements HasMedia { // Role constants const ROLE_SUPER_ADMIN = 'super_admin'; const ROLE_ADMIN = 'admin'; const ROLE_MANAGER = 'manager'; const ROLE_USER = 'user'; const ROLE_GUEST = 'guest'; // Permission levels const PERMISSION_ALL = 'all'; const PERMISSION_COMPANY = 'company'; const PERMISSION_TEAM = 'team'; const PERMISSION_OWN = 'own'; const PERMISSION_NONE = 'none'; /** * Get user role */ public function getRole() { return $this->role ?? self::ROLE_USER; } /** * Check if user has role */ public function hasRole($role) { return $this->getRole() === $role; } /** * Check if user has any of the roles */ public function hasAnyRole(array $roles) { return in_array($this->getRole(), $roles); } /** * Check if user is admin or above */ public function isAdmin() { return $this->hasAnyRole([ self::ROLE_SUPER_ADMIN, self::ROLE_ADMIN ]); } /** * Check if user is manager or above */ public function isManager() { return $this->hasAnyRole([ self::ROLE_SUPER_ADMIN, self::ROLE_ADMIN, self::ROLE_MANAGER ]); } /** * Get permission level for resource */ public function getPermissionLevel($resource) { $permissions = $this->permissions ?? []; return $permissions[$resource] ?? $this->getDefaultPermissionLevel(); } /** * Get default permission level based on role */ public function getDefaultPermissionLevel() { return match($this->getRole()) { self::ROLE_SUPER_ADMIN => self::PERMISSION_ALL, self::ROLE_ADMIN => self::PERMISSION_COMPANY, self::ROLE_MANAGER => self::PERMISSION_TEAM, self::ROLE_USER => self::PERMISSION_OWN, self::ROLE_GUEST => self::PERMISSION_NONE, default => self::PERMISSION_NONE }; } } ``` ### 🏢 **Role Matrix** ```php // config/roles.php return [ 'roles' => [ 'super_admin' => [ 'name' => 'Super Amministratore', 'description' => 'Accesso completo al sistema', 'color' => 'danger', 'icon' => 'fas fa-crown', 'permissions' => [ 'users' => 'all', 'companies' => 'all', 'stabili' => 'all', 'condomini' => 'all', 'unita' => 'all', 'reports' => 'all', 'settings' => 'all', 'logs' => 'all' ] ], 'admin' => [ 'name' => 'Amministratore', 'description' => 'Gestione completa della company', 'color' => 'warning', 'icon' => 'fas fa-user-shield', 'permissions' => [ 'users' => 'company', 'stabili' => 'company', 'condomini' => 'company', 'unita' => 'company', 'reports' => 'company', 'settings' => 'company' ] ], 'manager' => [ 'name' => 'Manager', 'description' => 'Gestione team e risorse assegnate', 'color' => 'info', 'icon' => 'fas fa-user-tie', 'permissions' => [ 'users' => 'team', 'stabili' => 'team', 'condomini' => 'team', 'unita' => 'team', 'reports' => 'team' ] ], 'user' => [ 'name' => 'Utente', 'description' => 'Accesso alle proprie risorse', 'color' => 'success', 'icon' => 'fas fa-user', 'permissions' => [ 'stabili' => 'own', 'condomini' => 'own', 'unita' => 'own', 'reports' => 'own' ] ], 'guest' => [ 'name' => 'Ospite', 'description' => 'Accesso solo lettura limitato', 'color' => 'secondary', 'icon' => 'fas fa-eye', 'permissions' => [ 'stabili' => 'none', 'condomini' => 'none', 'unita' => 'none', 'reports' => 'none' ] ] ], 'resources' => [ 'users' => 'Gestione Utenti', 'companies' => 'Gestione Aziende', 'stabili' => 'Gestione Stabili', 'condomini' => 'Gestione Condomini', 'unita' => 'Unità Immobiliari', 'reports' => 'Reports e Analytics', 'settings' => 'Impostazioni Sistema', 'logs' => 'Logs di Sistema' ], 'actions' => [ 'create' => 'Creare', 'read' => 'Visualizzare', 'update' => 'Modificare', 'delete' => 'Eliminare', 'execute' => 'Eseguire' ] ]; ``` --- ## 🛡️ **PERMISSION MIDDLEWARE** ### 🔐 **Role Middleware** ```php // app/Http/Middleware/CheckRole.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CheckRole { /** * Handle an incoming request. */ public function handle(Request $request, Closure $next, ...$roles) { if (!Auth::check()) { return redirect('login'); } $user = Auth::user(); if (!$user->hasAnyRole($roles)) { abort(403, 'Non hai i permessi per accedere a questa risorsa.'); } return $next($request); } } ``` ### 🔑 **Permission Middleware** ```php // app/Http/Middleware/CheckPermission.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CheckPermission { /** * Handle an incoming request. */ public function handle(Request $request, Closure $next, string $resource, string $action = 'read') { if (!Auth::check()) { return redirect('login'); } $user = Auth::user(); if (!$this->hasPermission($user, $resource, $action)) { if ($request->expectsJson()) { return response()->json([ 'message' => 'Non hai i permessi per eseguire questa azione.' ], 403); } abort(403, 'Non hai i permessi per eseguire questa azione.'); } return $next($request); } /** * Check if user has permission for resource action */ private function hasPermission($user, $resource, $action) { $permissionLevel = $user->getPermissionLevel($resource); // Super admin has all permissions if ($user->hasRole(User::ROLE_SUPER_ADMIN)) { return true; } // No permission if ($permissionLevel === User::PERMISSION_NONE) { return false; } // All permission if ($permissionLevel === User::PERMISSION_ALL) { return true; } // Check specific action permissions return $this->checkActionPermission($user, $resource, $action, $permissionLevel); } /** * Check action-specific permissions */ private function checkActionPermission($user, $resource, $action, $permissionLevel) { // Define action requirements $actionPermissions = [ 'create' => ['company', 'team', 'own'], 'read' => ['company', 'team', 'own'], 'update' => ['company', 'team', 'own'], 'delete' => ['company', 'team'], 'execute' => ['company', 'team'] ]; $requiredLevels = $actionPermissions[$action] ?? ['company']; return in_array($permissionLevel, $requiredLevels); } } ``` --- ## 🎛️ **UI PERMISSION GATES** ### 🎨 **Blade Directives** ```php // app/Providers/AppServiceProvider.php use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Auth; public function boot() { // Role-based directives Blade::if('role', function ($role) { return Auth::check() && Auth::user()->hasRole($role); }); Blade::if('anyrole', function (...$roles) { return Auth::check() && Auth::user()->hasAnyRole($roles); }); // Permission-based directives Blade::if('can', function ($resource, $action = 'read') { if (!Auth::check()) return false; $user = Auth::user(); $permissionLevel = $user->getPermissionLevel($resource); if ($user->hasRole(User::ROLE_SUPER_ADMIN)) return true; if ($permissionLevel === User::PERMISSION_NONE) return false; if ($permissionLevel === User::PERMISSION_ALL) return true; // Check action permissions $actionPermissions = [ 'create' => ['company', 'team', 'own'], 'read' => ['company', 'team', 'own'], 'update' => ['company', 'team', 'own'], 'delete' => ['company', 'team'], 'execute' => ['company', 'team'] ]; $requiredLevels = $actionPermissions[$action] ?? ['company']; return in_array($permissionLevel, $requiredLevels); }); // Admin check Blade::if('admin', function () { return Auth::check() && Auth::user()->isAdmin(); }); // Manager check Blade::if('manager', function () { return Auth::check() && Auth::user()->isManager(); }); } ``` ### 🧩 **Permission Components** ```blade @props([ 'resource' => '', 'action' => 'read', 'role' => null, 'fallback' => null ]) @php $hasPermission = false; if ($role) { $hasPermission = Auth::check() && Auth::user()->hasAnyRole(is_array($role) ? $role : [$role]); } elseif ($resource) { $hasPermission = Auth::check() && Auth::user()->hasPermission($resource, $action); } @endphp @if($hasPermission) {{ $slot }} @elseif($fallback) {!! $fallback !!} @endif ``` ```blade @props(['user' => null]) @php $user = $user ?? Auth::user(); $roleConfig = config('roles.roles')[$user->getRole()] ?? null; @endphp @if($roleConfig) {{ $roleConfig['name'] }} @endif ``` --- ## 🔧 **JAVASCRIPT PERMISSIONS** ### ⚡ **Permission Manager** ```javascript // /public/js/permissions/permission-manager.js class PermissionManager { constructor() { this.permissions = {}; this.user = null; this.init(); } async init() { // Load user permissions from API or meta tags await this.loadPermissions(); // Apply UI permissions this.applyUIPermissions(); // Setup dynamic permission checks this.setupDynamicChecks(); } async loadPermissions() { try { // Try to load from meta tag first const permissionsMeta = document.querySelector('meta[name="user-permissions"]'); if (permissionsMeta) { this.permissions = JSON.parse(permissionsMeta.content); return; } // Fallback to API const response = await fetch('/api/user/permissions'); if (response.ok) { const data = await response.json(); this.permissions = data.permissions; this.user = data.user; } } catch (error) { console.warn('Failed to load permissions:', error); this.permissions = {}; } } applyUIPermissions() { // Hide/show elements based on permissions document.querySelectorAll('[data-permission]').forEach(element => { const permission = element.dataset.permission; const action = element.dataset.action || 'read'; if (!this.can(permission, action)) { element.style.display = 'none'; element.setAttribute('aria-hidden', 'true'); } }); // Hide/show based on roles document.querySelectorAll('[data-role]').forEach(element => { const roles = element.dataset.role.split(','); if (!this.hasAnyRole(roles)) { element.style.display = 'none'; element.setAttribute('aria-hidden', 'true'); } }); // Disable buttons/links document.querySelectorAll('[data-permission-action]').forEach(element => { const permission = element.dataset.permissionAction; const action = element.dataset.action || 'execute'; if (!this.can(permission, action)) { element.disabled = true; element.classList.add('disabled'); element.setAttribute('aria-disabled', 'true'); // Remove click handlers element.onclick = (e) => { e.preventDefault(); this.showPermissionDenied(); return false; }; } }); } setupDynamicChecks() { // Intercept form submissions document.addEventListener('submit', (e) => { const form = e.target; const permission = form.dataset.permission; const action = form.dataset.action || 'create'; if (permission && !this.can(permission, action)) { e.preventDefault(); this.showPermissionDenied(); return false; } }); // Intercept navigation document.addEventListener('click', (e) => { const link = e.target.closest('a[data-permission]'); if (link) { const permission = link.dataset.permission; const action = link.dataset.action || 'read'; if (!this.can(permission, action)) { e.preventDefault(); this.showPermissionDenied(); return false; } } }); // Intercept AJAX requests const originalFetch = window.fetch; window.fetch = (...args) => { const [url, options = {}] = args; // Check if request has permission requirements if (options.permission) { const action = options.action || 'read'; if (!this.can(options.permission, action)) { return Promise.reject(new Error('Permission denied')); } } return originalFetch.apply(this, args); }; } can(resource, action = 'read') { // Super admin can do everything if (this.hasRole('super_admin')) { return true; } const permissionLevel = this.permissions[resource]; if (!permissionLevel || permissionLevel === 'none') { return false; } if (permissionLevel === 'all') { return true; } // Check action-specific permissions const actionPermissions = { 'create': ['company', 'team', 'own'], 'read': ['company', 'team', 'own'], 'update': ['company', 'team', 'own'], 'delete': ['company', 'team'], 'execute': ['company', 'team'] }; const requiredLevels = actionPermissions[action] || ['company']; return requiredLevels.includes(permissionLevel); } hasRole(role) { return this.user && this.user.role === role; } hasAnyRole(roles) { return this.user && roles.includes(this.user.role); } isAdmin() { return this.hasAnyRole(['super_admin', 'admin']); } isManager() { return this.hasAnyRole(['super_admin', 'admin', 'manager']); } showPermissionDenied() { if (window.NetGesconNotifications) { NetGesconNotifications.error('Non hai i permessi per eseguire questa azione.'); } else { alert('Non hai i permessi per eseguire questa azione.'); } } // Permission-based navigation navigate(url, permission = null, action = 'read') { if (permission && !this.can(permission, action)) { this.showPermissionDenied(); return false; } window.location.href = url; return true; } // Dynamic permission checking for AJAX async checkPermissionAPI(resource, action = 'read') { try { const response = await fetch('/api/check-permission', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ resource, action }) }); return response.ok; } catch (error) { console.error('Permission check failed:', error); return false; } } // Refresh permissions async refreshPermissions() { await this.loadPermissions(); this.applyUIPermissions(); } } // Initialize permission manager document.addEventListener('DOMContentLoaded', () => { window.PermissionManager = new PermissionManager(); }); ``` --- ## 📱 **RESPONSIVE PERMISSIONS** ### 🎛️ **Permission-Aware Navigation** ```blade ``` ### 🎯 **Permission-Based Actions** ```blade
Gestisci tutti gli stabili del tuo portafoglio