Documentazione Tecnica
Guida completa all'architettura, all'installazione e all'utilizzo del portale O-Hub.
1.1 Panoramica
O-Hub è un portale web modulare progettato per ospitare e distribuire applicazioni web (utility, strumenti didattici, tool di produttività) con un sistema di controllo degli accessi basato su livelli.
1.2 Stack Tecnologico
- Backend: PHP 8.x (procedurale con funzioni organizzate)
- Database: MariaDB/MySQL con charset UTF-8 MB4
- Frontend: HTML5, CSS3 (custom, senza framework), JavaScript vanilla
- Sicurezza: bcrypt, CSRF tokens, prepared statements, rate limiting
- Server: Apache con mod_rewrite
1.3 Design Pattern
Il sistema adotta un approccio page-based (ogni file PHP è una pagina completa) con componenti condivisi tramite include. Questo modello è stato scelto per:
- Semplicità didattica: ogni file è autoesplicativo e può essere studiato isolatamente;
- Basso overhead: nessun framework, nessun autoloader complesso, caricamento diretto;
- Manutenibilità: le funzioni comuni sono centralizzate in
functions.php.
1.4 Diagramma di Flusso
Utente
|
v
[Browser] --HTTPS--> [Apache + mod_rewrite]
| |
| [index.php]
| [login.php]
| [register.php] --> [mail()]
| [admin.php]
| [profile.php]
| |
| [includes/]
| ├── config.php (costanti)
| ├── functions.php (logica)
| ├── header.php (template)
| └── footer.php (template)
| |
| [PDO] --> [MariaDB: o_hub]
| ├── users
| └── login_log
|
v
[/apps/**/appinfo.txt] --> Scanner --> Card Grid
/var/www/html/o/
├── index.php # Pagina principale (elenco app)
├── login.php # Autenticazione utente
├── logout.php # Disconnessione e distruzione sessione
├── register.php # Registrazione nuovo utente
├── activate.php # Verifica email (via token)
├── profile.php # Profilo utente (modifica password, eliminazione)
├── admin.php # Pannello di amministrazione
├── disclaimer.php # Privacy policy + disclaimer GPL
├── .htaccess # Configurazione Apache
│
├── includes/
│ ├── config.php # Costanti di configurazione
│ ├── functions.php # Funzioni di utilità (DB, auth, scanner, email)
│ ├── header.php # Template header + navbar
│ └── footer.php # Template footer + system monitor
│
├── assets/
│ └── style.css # Foglio di stile principale
│
├── docs/
│ └── index.php # Questa documentazione
│
└── apps/ # Directory delle applicazioni
└── pdf_manager/ # Esempio di applicazione
├── appinfo.txt # Metadati dell'applicazione
├── index.html # Interfaccia dell'applicazione
└── api.php # Backend dell'applicazione
3.1 Tabella users
Contiene tutti gli utenti registrati del sistema.
| Campo | Tipo | Descrizione |
|---|---|---|
id | INT AUTO_INCREMENT | Chiave primaria |
nome | VARCHAR(100) | Nome dell'utente |
cognome | VARCHAR(100) | Cognome dell'utente |
email | VARCHAR(255) UNIQUE | Email (usata come username) |
password_hash | VARCHAR(255) | Hash bcrypt della password |
tipo | ENUM('studente','docente','altro') | Profilo utente |
sito_web | VARCHAR(255) NULL | URL sito web (opzionale) |
livello | TINYINT UNSIGNED | Livello di accesso (0-9) |
stato | ENUM('in_attesa','attivo','bloccato') | Stato dell'account |
token_attivazione | VARCHAR(64) NULL | Token per verifica email |
email_verificata | TINYINT(1) | Flag verifica email |
approvato_admin | TINYINT(1) | Flag approvazione admin |
data_registrazione | DATETIME | Data di registrazione |
ultimo_accesso | DATETIME NULL | Data ultimo login riuscito |
3.2 Tabella login_log
Registro cronologico di tutti i tentativi di accesso per sicurezza e auditing.
| Campo | Tipo | Descrizione |
|---|---|---|
id | INT AUTO_INCREMENT | Chiave primaria |
user_id | INT NULL (FK) | Riferimento all'utente |
ip | VARCHAR(45) | Indirizzo IP (supporta IPv6) |
user_agent | TEXT | Stringa User-Agent del browser |
esito | ENUM('successo','fallito') | Esito del tentativo |
created_at | TIMESTAMP | Data e ora del tentativo |
Il sistema implementa un flusso di registrazione a doppia verifica (email + admin), progettato per garantire che solo utenti verificati e autorizzati possano accedere alle risorse.
4.1 Registrazione
- L'utente compila il modulo con: nome, cognome, email, tipo, password e (opzionalmente) sito web.
- L'utente accetta l'informativa sulla privacy (checkbox obbligatorio).
- Il sistema valida tutti i campi (lunghezza, formato email, unicità, forza password).
- La password viene hashata con
password_hash()usando bcrypt (cost 12). - Viene generato un token di attivazione casuale di 64 caratteri esadecimali (
random_bytes(32)). - L'utente viene inserito nel DB con stato
in_attesa, livello1. - Viene inviata un'email con il link di attivazione.
- L'amministratore riceve una notifica email.
4.2 Attivazione Email
- L'utente clicca il link nell'email.
- Il sistema verifica il token (esistenza, formato, scadenza di 24 ore).
- Il campo
email_verificataviene impostato a1. - Il token viene invalidato (impostato a
NULL).
4.3 Approvazione Admin
- L'amministratore accede al pannello admin.
- Nella sezione "Utenti" visualizza gli account in attesa.
- Cliccando "Approva", il campo
approvato_adminviene impostato a1e lo stato diventaattivo. - L'utente riceve un'email di conferma attivazione.
4.4 Login
- L'utente inserisce email e password.
- Il sistema verifica il rate limiting (max 5 tentativi falliti in 15 minuti).
- La password viene verificata con
password_verify()contro l'hash bcrypt. - Il sistema controlla: email verificata, approvazione admin, account non bloccato.
- La sessione viene rigenerata (
session_regenerate_id(true)) per prevenire session fixation. - L'ultimo accesso viene aggiornato e l'evento viene registrato in
login_log.
Il sistema implementa una gerarchia di accesso a 10 livelli (0–9). Ogni applicazione dichiara nel file appinfo.txt il livello minimo richiesto per l'accesso.
| Livello | Nome | Descrizione |
|---|---|---|
| 0 | Pubblico | Accesso pubblico, senza autenticazione. Le app di livello 0 sono visibili a tutti. |
| 1 | Utente Base | Livello predefinito per i nuovi utenti registrati. Accesso alle app base. |
| 2 | Utente Avanzato | Utente con permessi estesi. Accesso a strumenti avanzati. |
| 3 | Collaboratore | Collaboratore del progetto. Accesso a strumenti di gestione contenuti. |
| 4 | Editore | Editore. Può accedere a strumenti di pubblicazione. |
| 5 | Moderatore | Moderatore. Accesso a strumenti di moderazione. |
| 6 | Gestore | Gestore. Accesso a strumenti gestionali avanzati. |
| 7 | Amministratore Jr. | Amministratore junior. Accesso quasi completo. |
| 8 | Amministratore | Amministratore. Accesso completo al pannello admin. |
| 9 | Super Amministratore | Super amministratore. Controllo totale del sistema. |
Ogni applicazione deve contenere un file appinfo.txt nella propria directory root. Il file utilizza un formato chiave-valore semplice (una coppia per riga, separata da :).
6.1 Campi Supportati
| Campo | Obbligatorio | Default | Descrizione |
|---|---|---|---|
nome | Si | — | Nome visualizzato dell'applicazione |
versione | No | 1.0 | Versione corrente (semantic versioning) |
descrizione | No | vuoto | Descrizione breve dell'applicazione |
livello | No | 0 | Livello minimo richiesto (0–9) |
pubblicato | No | no | Visibilità (si/no/yes/true/1) |
icona | No | 📦 | Emoji o carattere usato come icona |
6.2 Esempio Completo
nome: PDF Manager versione: 1.0.0 descrizione: Strumento per unire, dividere e comprimere file PDF livello: 1 pubblicato: si icona: 📄
6.3 Note Importanti
- Il parser è case-insensitive per le chiavi (
Nome,NOME,nomesono equivalenti). - Sono supportate anche le varianti inglesi:
name,version,description,level,published,icon. - Le app senza
appinfo.txtvengono mostrate nel pannello admin ma non nella pagina pubblica. - Il campo
pubblicatoaccetta:si,sì,yes,1,true(case-insensitive).
Aggiungere una nuova applicazione al portale è un processo semplice in tre passi:
Passo 1: Crea la directory
mkdir /var/www/html/o/apps/mia_app
Passo 2: Crea il file appinfo.txt
nome: La Mia App versione: 1.0.0 descrizione: Descrizione della mia applicazione livello: 1 pubblicato: si icona: ⚙
Passo 3: Inserisci i file dell'applicazione
Inserisci nella directory tutti i file dell'applicazione (index.html/index.php, CSS, JavaScript, ecc.). Il sistema punta automaticamente alla root della directory.
Il sistema implementa multiple difese a più livelli, seguendo il principio della defense in depth:
8.1 Autenticazione
- bcrypt (cost 12): algoritmo di hashing adattivo che rende impraticabili gli attacchi di forza bruta offline.
- Rate limiting: massimo 5 tentativi di login falliti per IP in 15 minuti.
- Session regeneration: l'ID di sessione viene rigenerato al login per prevenire session fixation.
- Doppia verifica: email + approvazione admin prima dell'attivazione.
8.2 Protezione da Attacchi
- CSRF: ogni form include un token CSRF univoco verificato server-side.
- SQL Injection: tutte le query usano prepared statements (PDO).
- XSS: tutti gli output sono sanitizzati con
htmlspecialchars()(funzionee()). - Cookie sicuri: flag HttpOnly, Secure e SameSite=Strict.
- Input validation: tutti gli input vengono validati e sanitizzati.
8.3 Accesso ai File
- La directory
includes/è protetta da accesso diretto via.htaccess. - Il file
config.phpcontiene le credenziali e non deve mai essere esposto.
Il file includes/functions.php espone le seguenti funzioni pubbliche:
Database
db(): PDO— Ritorna un'istanza singleton della connessione PDO al database.
Sessione & Autenticazione
init_session(): void— Inizializza la sessione con parametri di sicurezza.is_logged_in(): bool— Verifica se l'utente è autenticato.current_user(): ?array— Ritorna i dati dell'utente corrente (cached).require_login(): void— Redirect a login se non autenticato.require_admin(): void— Blocca con 403 se livello < 8.user_level(): int— Ritorna il livello numerico dell'utente (0 se non loggato).
Sicurezza
csrf_token(): string— Genera/ritorna il token CSRF della sessione.csrf_field(): string— Ritorna l'input hidden HTML con il token CSRF.verify_csrf(): bool— Verifica il token CSRF dal POST.e(string): string— Alias perhtmlspecialchars()con flag sicuri.clean_input(string): string— Trim e strip_tags dell'input.
Scanner Applicazioni
scan_apps(int $level): array— Scansiona le app accessibili al livello dato.scan_all_apps(): array— Scansiona tutte le app (per il pannello admin).parse_appinfo(string $path): ?array— Parsa un singolo file appinfo.txt.
Sistema
system_load(): array— Ritorna CPU load, memoria, disco e uptime.format_bytes(float, int): string— Formatta bytes in unità leggibili.
send_activation_email(email, nome, token): bool— Invia l'email di attivazione.send_admin_notification(nome, cognome, email, tipo): bool— Notifica l'admin.
Flash Messages
flash(type, message): void— Accoda un messaggio flash.get_flashes(): array— Ritorna e svuota i messaggi flash.render_flashes(): string— Genera l'HTML dei messaggi flash.
10.1 Credenziali Admin Predefinite
- Email:
admin@localhost - Password:
admin - Livello: 9 (Super Amministratore)
10.2 Pulizia Log di Accesso
I log di accesso possono crescere nel tempo. Per ripulirli (mantenendo gli ultimi 90 giorni):
DELETE FROM login_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY);
10.3 Backup
Per un backup completo del sistema:
# Backup database mysqldump o_hub > o_hub_backup_$(date +%Y%m%d).sql # Backup file tar -czf o_hub_files_$(date +%Y%m%d).tar.gz /var/www/html/o/
10.4 Aggiornamento
Per aggiornare il sistema, sostituire i file PHP mantenendo inalterati config.php e la directory apps/. Verificare sempre la compatibilità dello schema del database.