Nello sviluppo di applicazioni moderne, la sicurezza e la gestione accurata dell’accesso ai dati sono essenziali. Grazie all’evento restrict di 4D, è possibile filtrare dinamicamente i dati accessibili a un utente in base al suo profilo, ai privilegi e alle informazioni memorizzate nella sessione.
Questo blog spiega come sfruttare questo evento, in particolare nel contesto di un’integrazione con 4D Qodly Pro, per garantire che vengano esposti solo i dati rilevanti.
Performance Review Application
Capire l’evento restrict
L’evento restrict è un meccanismo di filtraggio automatico applicato alle entità di una classe di dati in ORDA. Viene attivato per limitare i risultati delle query (all(), query(), accesso API REST, ecc.) in base a un contesto specifico (informazioni sull’utente, privilegi, ecc.).
Vantaggi principali:
- Filtraggio dinamico: Ogni volta che viene eseguita una query, il filtro definito da restrict viene applicato automaticamente.
- Controllo granulare dell’accesso: L’accesso può essere completamente ristretto o limitato a record specifici in base ai ruoli dell’utente, ai privilegi o a dati contestuali come la posizione geografica o il reparto.
- Separazione della logica: L’implementazione di questo filtro è indipendente dalla logica di business dell’applicazione, facilitando la manutenzione e gli aggiornamenti di sicurezza.
Per maggiori dettagli, la documentazione ufficiale di 4D sul filtraggio delle entità fornisce una panoramica completa di questa funzione.
Privilegi e restrizioni: Differenze chiave
In 4D, il controllo degli accessi è gestito attraverso privilegi e restrizioni, che lavorano insieme per garantire un accesso sicuro e granulare ai dati. La comprensione della distinzione tra questi due meccanismi è fondamentale per progettare un modello di sicurezza solido.
Privilegi: Controllo dell’accesso alle strutture di dati
Un privilegio determina se un utente è autorizzato ad accedere a una tabella, a un campo o a una funzione del database. Agisce come un meccanismo di controllo degli accessi di alto livello che concede o nega l’accesso a un intero set di dati o a una funzione.
Esempi di casi d’uso:
- Un utente di base può avere accesso in sola lettura alla tabella Dipendenti, ma non può modificare o cancellare i record.
- Un manager può avere privilegi aggiuntivi che gli consentono di modificare i record dei dipendenti all’interno del proprio reparto.
- Un amministratore delle risorse umane può avere accesso a campi sensibili, come le informazioni sullo stipendio, mentre i dipendenti standard non possono vedere questi dettagli.
Restrizioni: Affinare l’accesso a livello di record
Mentre i privilegi controllano l’accesso a livello strutturale, le restrizioni determinano quali record specifici all’interno di una tabella autorizzata un utente può vedere o interagire. L’evento on restrict filtra dinamicamente i dati in base al contesto dell’utente, garantendo che gli utenti accedano solo ai record pertinenti, rispettando le regole di sicurezza predefinite.
Esempi di casi d’uso:
- Un collaboratore può accedere solo ai propri record nella tabella Employee.
- Un manager può visualizzare i record dei suoi riporti diretti.
- Un amministratore delle risorse umane può vedere tutti i dipendenti.
Casi d’uso
Esempio 1: Combinazione di privilegi e contesto di sessione per limitare i dati
In questo esempio, si implementa l’evento restrict all’interno della classe di dati Employee per filtrare l’elenco dei dipendenti restituito. Il codice seguente illustra come utilizzare le informazioni di sessione e i privilegi per determinare l’accesso ai dati:
Function event restrict() : cs.EmployeeSelection
var $obj : Object
If (Session=Null)
$obj:=Storage
Else
$obj:=Session.storage
End if
Case of
: (Session.hasPrivilege("authentify"))
return This.all()
: (Session.hasPrivilege("generatePDF"))
return This.all()
: (Session.hasPrivilege("createReview"))
return This.all()
: (Session.hasPrivilege("webadmin"))
return This.all()
: ($obj.Employee.role="Collaborator")
return This.query("ID = :1"; $obj.Employee.ID)
: ($obj.Employee.role="Manager")
return This.query("ID_Supervisor = :1"; $obj.Employee.ID)
: (($obj.Employee.role="HR") && (Session.hasPrivilege("hr")))
return This.all()
Else
return This.newSelection()
End case
Come funziona
- Filtro basato sui privilegi: La funzione hasPrivilege() verifica se la sessione dell’utente include privilegi specifici. Ad esempio, i dipendenti delle risorse umane con il privilegio “hr” possono accedere a tutti i record dei dipendenti.
- Elevazione temporanea dei ruoli: Per azioni quali l’autenticazione, la generazione di documenti o la creazione di revisioni, la promozione dei privilegi può concedere temporaneamente diritti estesi senza alterare le impostazioni globali dell’utente.
- Filtro basato sulla sessione: La proprietà del ruolo (memorizzata in Storage o Session storage) determina i livelli di accesso. I collaboratori possono vedere solo i propri record, i manager possono accedere ai dipendenti subordinati e il personale delle risorse umane può vedere tutti i dipendenti.
- Ritorno predefinito sicuro: Se non sono soddisfatte le condizioni, This.newSelection() assicura che l’utente non riceva alcun dato piuttosto che un accesso illimitato.
Nota: il privilegio webadmin è utilizzato da Data Explorer in 4D. Se si desidera che i propri dati siano accessibili attraverso Data Explorer, è necessario gestire il caso del privilegio webadmin. Nel nostro esempio, garantiamo l’accesso completo al Data Explorer restituendo This.all() quando questo privilegio è presente.
Esempio 2: Integrazione in Qodly Studio tramite azioni o funzioni standard
Questo secondo esempio mostra come limitare l’accesso alle recensioni nella classe di dati Review in base al ruolo dell’utente.
Function event restrict() : cs.ReviewSelection
var $obj : Object
If (Session=Null)
$obj:=Storage
Else
$obj:=Session.storage
End if
If ($obj.Employee.role=Null)
return Null
End if
Case of
: (($obj.Employee.role="HR") && (Session.hasPrivilege("hr")))
return This.all().orderBy("Date desc")
: ($obj.Employee.role="Manager")
return This.query("Employee.ID_Supervisor = :1"; $obj.Employee.ID).orderBy("Date desc")
: ($obj.Employee.role="Collaborator")
return This.query("ID_Employee = :1"; $obj.Employee.ID).orderBy("Date desc")
: (Session.hasPrivilege("webadmin"))
return This.all()
Else
return This.newSelection()
End case
Utilizzo di azioni standard
Nella pagina dei collaboratori dell’applicazione Qodly, l’utente ha il ruolo di collaboratore e può consultare solo le proprie recensioni.
In Qodly Studio, definiamo l’azione standard All per riempire la tabella dei dati sull’evento on load della pagina del collaboratore. Normalmente, l’azione standard All recupera tutte le recensioni. Ma, poiché abbiamo aggiunto l’evento restrict alla classe di dati delle recensioni. Recuperiamo solo le recensioni autorizzate con il ruolo di collaboratore.
Utilizzo di funzioni personalizzate
Nella pagina Manager, gli utenti con il ruolo “Manager” possono visualizzare tutte le recensioni relative ai loro subordinati. Aggiungiamo una funzione di filtraggio avanzato per affinare i risultati in base all’anno e allo stato.
Nella classe di dati Review, abbiamo la funzione loadReviews:
exposed Function loadReviews($departement : cs.DepartementEntity; $year : Integer; $status : cs.ReviewStatusEntity) : cs.ReviewSelection
Case of
: (($departement=Null) && ($status=Null))
return This.query("Date >= :1 AND Date <= :2"; String($year)+"/01/01"; String($year)+"/12/31")
: (($departement#Null) && ($status=Null))
return This.query("Employee.ID_Departement = :1 AND Date >= :2 AND Date <= :3"; $departement.ID; String($year)+"/01/01"; String($year)+"/12/31")
: (($departement=Null) && ($status#Null))
return This.query("ID_Status = :1 AND Date >= :2 AND Date <= :3"; $status.ID; String($year)+"/01/01"; String($year)+"/12/31")
: (($departement#Null) && ($status#Null))
return This.query("Employee.ID_Departement = :1 AND ID_Status = :2 AND Date >= :3 AND Date <= :4"; $departement.ID; $status.ID; String($year)+"/01/01"; String($year)+"/12/31")
Else
return This.newSelection()
End case
In Qodly Studio, questa funzione viene attivata dall’evento di modifica dei dati per le fonti di dati anno e stato.
Per l’input dell ‘anno:
Per la casella di selezione dello stato:
Il filtro personalizzato si combina con la restrizione globale fornita da on restrict, consentendo di affinare i risultati rispettando le regole di sicurezza definite in precedenza.
Avanti
L’evento restrict in 4D si rivela uno strumento potente per gestire dinamicamente l’accesso ai dati. Sfruttando i privilegi degli utenti e la memorizzazione delle sessioni, garantisce un controllo granulare degli accessi senza aggiungere complessità alla logica aziendale. Inoltre, l’integrazione con meccanismi complementari come promote e l’aggiunta di filtri personalizzati offrono una maggiore flessibilità per soddisfare requisiti specifici.
Per approfondire questo argomento, consultate la documentazione ufficiale sulle entità ORDA e il blog di 4D dedicato al filtraggio dei dati.