netgescon-master/docs/archived/02-SPECIFICHE-AUTENTICAZIONE.md
Pikappa2 480e7eafbd 🎯 NETGESCON - Setup iniziale repository completo
📋 Commit iniziale con:
-  Documentazione unificata in docs/
-  Codice Laravel in netgescon-laravel/
-  Script automazione in scripts/
-  Configurazione sync rsync
-  Struttura organizzata e pulita

🔄 Versione: 2025.07.19-1644
🎯 Sistema pronto per Git distribuito
2025-07-19 16:44:47 +02:00

10 KiB

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

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

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

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

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Services\AuthService;

class CodeAuthMiddleware
{
    protected $authService;

    public function __construct(AuthService $authService)
    {
        $this->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

namespace App\Services;

use App\Models\User;
use App\Models\UserSession;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;

class AuthService
{
    public function authenticateByCode(string $userCode, string $ipAddress, string $userAgent): ?User
    {
        // Valida formato codice
        if (!$this->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