# SPECIFICHE AUTENTICAZIONE - NetGesCon Unified Platform ## 🎯 OBIETTIVO Implementare un sistema di autenticazione unificato tramite **codice utente unico** che sostituisce il sistema tradizionale username/password, con gestione centralizzata delle sessioni e accesso alle cartelle dati specifiche per utente/ruolo. ## πŸ”‘ SISTEMA AUTENTICAZIONE CODICE UNICO ### STRUTTURA CODICE UTENTE ``` Formato: [PREFISSO]-[IDENTIFICATIVO]-[CHECKSUM] Esempio: ADM-001234-A7B CON-098765-K3Z FOR-543210-M9P ``` ### PREFISSI RUOLO - **SUP** - Super Admin - **ADM** - Amministratore - **CON** - Condomino - **FOR** - Fornitore - **COL** - Collaboratore ### GENERAZIONE CODICI - **Algoritmo:** Base su hash di dati utente + timestamp - **Checksum:** 3 caratteri alfanumerici per validazione - **UnicitΓ :** Controllo globale su tutti i ruoli - **Regenerazione:** Possibile in caso di compromissione ## πŸ“‚ STRUTTURA CARTELLE DATI ### CARTELLA PRINCIPALE ``` /data/users/ β”œβ”€β”€ SUP-000001-X9Z/ # Super Admin β”‚ β”œβ”€β”€ config/ # Configurazioni globali β”‚ β”œβ”€β”€ logs/ # Log sistema β”‚ β”œβ”€β”€ backups/ # Backup automatici β”‚ └── reports/ # Report globali β”œβ”€β”€ ADM-001234-A7B/ # Amministratore Rossi β”‚ β”œβ”€β”€ condominii/ # Dati condominii gestiti β”‚ β”‚ β”œβ”€β”€ stabile_001/ β”‚ β”‚ β”œβ”€β”€ stabile_002/ β”‚ β”‚ └── ... β”‚ β”œβ”€β”€ documenti/ # Documenti personali β”‚ β”œβ”€β”€ templates/ # Template personalizzati β”‚ └── reports/ # Report specifici β”œβ”€β”€ CON-098765-K3Z/ # Condomino Bianchi β”‚ β”œβ”€β”€ documenti/ # Documenti ricevuti β”‚ β”œβ”€β”€ comunicazioni/ # Comunicazioni con admin β”‚ β”œβ”€β”€ estratti_conto/ # Estratti conto personali β”‚ └── pagamenti/ # Storico pagamenti └── FOR-543210-M9P/ # Fornitore VerdiSrl β”œβ”€β”€ preventivi/ # Preventivi inviati β”œβ”€β”€ fatture/ # Fatture emesse β”œβ”€β”€ ordini/ # Ordini ricevuti └── comunicazioni/ # Comunicazioni ``` ### PERMESSI CARTELLE - **Lettura/Scrittura:** Solo proprietario cartella - **Backup Admin:** Super admin accesso sola lettura - **Condivisione:** Tramite sistema interno (no accesso diretto) - **Audit:** Log di tutti gli accessi ## πŸ” IMPLEMENTAZIONE TECNICA ### DATABASE SCHEMA #### Tabella `users` ```sql CREATE TABLE users ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_code VARCHAR(20) UNIQUE NOT NULL, -- Codice utente unico email VARCHAR(255) UNIQUE, -- Email opzionale phone VARCHAR(20), -- Telefono opzionale role_id BIGINT NOT NULL, -- FK a roles status ENUM('active', 'suspended', 'disabled') DEFAULT 'active', data_folder VARCHAR(255) NOT NULL, -- Percorso cartella dati last_login TIMESTAMP NULL, login_attempts INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_user_code (user_code), INDEX idx_role_id (role_id), INDEX idx_status (status) ); ``` #### Tabella `user_sessions` ```sql CREATE TABLE user_sessions ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, session_token VARCHAR(255) NOT NULL, ip_address VARCHAR(45), user_agent TEXT, expires_at TIMESTAMP NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_user_id (user_id), INDEX idx_session_token (session_token), INDEX idx_expires_at (expires_at), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); ``` #### Tabella `login_logs` ```sql CREATE TABLE login_logs ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_code VARCHAR(20), ip_address VARCHAR(45), user_agent TEXT, login_success BOOLEAN NOT NULL, failure_reason VARCHAR(255) NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_user_code (user_code), INDEX idx_login_success (login_success), INDEX idx_created_at (created_at) ); ``` ### MIDDLEWARE AUTHENTICATION #### `CodeAuthMiddleware.php` ```php authService = $authService; } public function handle(Request $request, Closure $next) { // Verifica presenza codice utente nella sessione $userCode = $request->session()->get('user_code'); if (!$userCode) { return redirect()->route('login'); } // Valida sessione attiva if (!$this->authService->validateSession($userCode)) { $request->session()->flush(); return redirect()->route('login')->with('error', 'Sessione scaduta'); } // Carica dati utente nel request $user = $this->authService->getUserByCode($userCode); $request->merge(['auth_user' => $user]); return $next($request); } } ``` ### SERVICE LAYER #### `AuthService.php` ```php validateCodeFormat($userCode)) { $this->logFailedLogin($userCode, $ipAddress, $userAgent, 'Invalid code format'); return null; } // Cerca utente $user = User::where('user_code', $userCode) ->where('status', 'active') ->first(); if (!$user) { $this->logFailedLogin($userCode, $ipAddress, $userAgent, 'User not found'); return null; } // Crea sessione $sessionToken = $this->createSession($user, $ipAddress, $userAgent); // Log login riuscito $this->logSuccessfulLogin($userCode, $ipAddress, $userAgent); return $user; } public function generateUserCode(string $rolePrefix, array $userData): string { // Genera ID progressivo $lastUser = User::where('user_code', 'LIKE', $rolePrefix . '-%') ->orderBy('user_code', 'desc') ->first(); $nextId = 1; if ($lastUser) { $parts = explode('-', $lastUser->user_code); $nextId = intval($parts[1]) + 1; } $identifier = sprintf('%06d', $nextId); // Genera checksum $checksum = $this->generateChecksum($rolePrefix, $identifier, $userData); return $rolePrefix . '-' . $identifier . '-' . $checksum; } private function generateChecksum(string $prefix, string $identifier, array $userData): string { $data = $prefix . $identifier . json_encode($userData) . config('app.key'); $hash = hash('sha256', $data); // Prendi i primi 3 caratteri e convertili in alfanumerico $checksum = ''; for ($i = 0; $i < 6; $i += 2) { $hex = substr($hash, $i, 2); $dec = hexdec($hex); $checksum .= base_convert($dec, 10, 36); } return strtoupper(substr($checksum, 0, 3)); } private function validateCodeFormat(string $code): bool { // Formato: XXX-NNNNNN-XXX $pattern = '/^[A-Z]{3}-\d{6}-[A-Z0-9]{3}$/'; return preg_match($pattern, $code); } public function createDataFolder(User $user): bool { $basePath = config('filesystems.disks.user_data.root', storage_path('app/user_data')); $userPath = $basePath . '/' . $user->user_code; if (!file_exists($userPath)) { return mkdir($userPath, 0755, true) && $this->createUserSubfolders($userPath, $user->role->name); } return true; } private function createUserSubfolders(string $userPath, string $roleName): bool { $subfolders = match($roleName) { 'super-admin' => ['config', 'logs', 'backups', 'reports'], 'admin' => ['condominii', 'documenti', 'templates', 'reports'], 'condomino' => ['documenti', 'comunicazioni', 'estratti_conto', 'pagamenti'], 'fornitore' => ['preventivi', 'fatture', 'ordini', 'comunicazioni'], 'collaboratore' => ['documenti', 'task', 'comunicazioni'], default => ['documenti', 'comunicazioni'] }; foreach ($subfolders as $folder) { $path = $userPath . '/' . $folder; if (!mkdir($path, 0755, true)) { return false; } } return true; } } ``` ## πŸ”„ FLUSSO AUTENTICAZIONE ### LOGIN PROCESS 1. **Input:** Utente inserisce codice unico 2. **Validazione:** Controllo formato e checksum 3. **Ricerca:** Query database per codice 4. **Verifica:** Controllo stato utente attivo 5. **Sessione:** Creazione token sessione 6. **Redirect:** Invio alla dashboard appropriata ### LOGOUT PROCESS 1. **Trigger:** Logout manuale o timeout 2. **Cleanup:** Rimozione token sessione 3. **Audit:** Log dell'operazione 4. **Redirect:** Invio alla pagina login ### SESSION MANAGEMENT - **Durata:** 8 ore lavorative (configurabile) - **Refresh:** Automatico su attivitΓ  - **Concurrent:** Massimo 3 sessioni attive per utente - **Cleanup:** Job automatico rimozione sessioni scadute ## πŸ›‘οΈ SICUREZZA ### PROTEZIONI - **Rate Limiting:** Max 5 tentativi login/minuto per IP - **Account Lockout:** Dopo 5 tentativi falliti (15 min block) - **Session Hijacking:** Controllo IP e User-Agent - **CSRF Protection:** Token su tutte le form ### AUDIT E MONITORING - **Login Logs:** Tutti i tentativi di accesso - **Access Logs:** Accesso a file/cartelle utente - **Error Logs:** Tentativi non autorizzati - **Performance:** Tempi di risposta autenticazione --- **Ultima modifica:** $(Get-Date -Format "dd/MM/yyyy HH:mm") **Versione:** 1.0 **Stato:** Da Implementare