Dans le développement d’applications modernes, la sécurisation et la gestion fine de l’accès aux données sont essentielles. Grâce à l’événement restrict de 4D, il est possible de filtrer dynamiquement les données accessibles à un utilisateur en fonction de son profil, de ses privilèges et des informations stockées dans sa session.
Ce blog explique comment exploiter cet événement, notamment dans le cadre d’une intégration avec 4D Qodly Pro, pour s’assurer que seules les données pertinentes sont exposées.
Performance Review Application
Comprendre l’événement restrict
L’événement restrict est un mécanisme de filtrage automatique appliqué aux entités d’une dataclass dans ORDA. Il est déclenché pour restreindre les résultats des requêtes (all(), query(), API REST access, etc.) sur la base d’un contexte spécifique (informations sur l’utilisateur, privilèges, etc.).
Principaux avantages :
- Filtrage dynamique : Chaque fois qu’une requête est exécutée, le filtre défini par restrict est automatiquement appliqué.
- Contrôle d’accès granulaire : L’accès peut être entièrement restreint ou limité à des enregistrements spécifiques en fonction du rôle de l’utilisateur, de ses privilèges ou de données contextuelles telles que l’emplacement géographique ou le service.
- Séparation de la logique : La mise en œuvre de ce filtrage est indépendante de la logique commerciale de l’application, ce qui facilite la maintenance et les mises à jour de sécurité.
Pour plus de détails, la documentation officielle de 4D sur le filtrage des entités fournit un aperçu complet de cette fonctionnalité.
Privilège et restriction : Principales différences
Dans 4D, le contrôle d’accès est géré par le biais de privilèges et de restrictions, qui fonctionnent ensemble pour garantir un accès sécurisé et granulaire aux données. Il est essentiel de comprendre la distinction entre ces deux mécanismes pour concevoir un modèle de sécurité solide.
Privilèges : Contrôle de l’accès aux structures de données
Un privilège détermine si un utilisateur est autorisé à accéder à une table, à un champ ou à une fonction de la base de données. Il s’agit d’un mécanisme de contrôle d’accès de haut niveau qui accorde ou refuse l’accès à l’ensemble d’un jeu de données ou d’une fonctionnalité.
Exemples de cas d’utilisation :
- Un utilisateur de base peut avoir un accès en lecture seule à la table Employés, il ne peut ni modifier ni supprimer des enregistrements.
- Un responsable peut disposer de privilèges supplémentaires lui permettant de modifier les enregistrements de salariés au sein de son service.
- Un administrateur des ressources humaines peut se voir accorder l’accès à des champs sensibles tels que les informations salariales, alors que les employés ordinaires ne peuvent pas voir ces détails.
Restrictions : Affiner l’accès au niveau de l’enregistrement
Alors que les privilèges contrôlent l’accès à un niveau structurel, les restrictions déterminent les enregistrements spécifiques d’une table autorisée qu’un utilisateur peut voir ou avec lesquels il peut interagir. L’événement on restrict filtre dynamiquement les données en fonction du contexte de l’utilisateur, ce qui garantit que les utilisateurs n’accèdent qu’aux enregistrements pertinents tout en respectant les règles de sécurité prédéfinies.
Exemple de cas d’utilisation :
- Un collaborateur ne peut accéder qu’à ses propres enregistrements dans la table Employés.
- Un manager peut consulter les enregistrements de ses subordonnés directs.
- Un administrateur RH peut être en mesure de voir tous les employés.
Cas d’utilisation
Exemple 1 : Combinaison de privilèges et de contexte de session pour restreindre les données
Dans cet exemple, nous implémentons l’événement restrict dans la dataclass Employee pour filtrer la liste des employés renvoyée. Le code suivant illustre comment utiliser les informations de session et les privilèges pour déterminer l’accès aux données :
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
Comment cela fonctionne-t-il ?
- Filtrage basé sur les privilèges : La fonction hasPrivilege() vérifie si la session de l’utilisateur comprend des privilèges spécifiques. Par exemple, les employés des ressources humaines disposant du privilège « hr » ont accès à tous les dossiers des employés.
- Élévation temporaire des rôles : Pour des actions telles que l’authentification, la génération de documents ou la création de révisions, la promotion des privilèges permet d’accorder temporairement des droits étendus sans modifier les paramètres globaux de l’utilisateur.
- Filtrage basé sur la session : La propriété du rôle (stockée dans le stockage ou la session) dicte les niveaux d’accès. Les collaborateurs ne peuvent voir que leurs propres enregistrements, les responsables peuvent accéder aux employés qui leur sont subordonnés et le personnel des ressources humaines peut voir tous les employés.
- Retour sécurisé par défaut : Si aucune condition n’est remplie, This.newSelection() garantit que l’utilisateur ne reçoit aucune donnée plutôt qu’un accès illimité.
Remarque : le privilège webadmin est utilisé par le Data Explorer dans 4D. Si vous souhaitez que vos données soient accessibles via le Data Explorer, vous devez gérer le cas du privilège webadmin. Dans notre exemple, nous accordons un accès complet au Data Explorer en renvoyant This.all() lorsque ce privilège est présent.
Exemple 2 : Intégration dans Qodly Studio à l’aide d’actions ou de fonctions standard
Ce deuxième exemple montre comment restreindre l’accès aux évaluations dans la classe de données Review en fonction du rôle de l’utilisateur.
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
Utilisation d’actions standard
Dans la page collaborateur de l’application Qodly, l’utilisateur a le rôle de collaborateur et ne peut consulter que ses propres évaluations.
Dans Qodly Studio, nous définissons l’action standard All pour remplir le tableau de données lors de l’événement on load de la page collaborateur. Normalement, l’action standard All récupère tous les avis. Mais comme nous avons ajouté l’événement restrict à la classe de données des Review, nous ne récupérons que les Review autorisés par le collaborateur.
Utilisation de fonctions personnalisées
Sur la page Manager, les utilisateurs ayant le rôle « Manager » peuvent consulter tous les Review liés à leurs subordonnés. Nous ajoutons une fonction de filtrage avancé pour affiner les résultats par année et par statut.
Dans la dataclass Review, nous avons la fonction 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
Dans Qodly Studio, cette fonction est déclenchée par l’événement « on data change » pour les sources de données « year » et « status ».
Pour l’input year:
Pour la select box status:
Le filtre personnalisé est combiné avec la restriction globale fournie par on restrict, ce qui vous permet d’affiner vos résultats tout en respectant les règles de sécurité définies à l’avance.
Et après
L’événement restrict de 4D s’avère être un outil puissant pour gérer dynamiquement l’accès aux données. En s’appuyant sur les privilèges des utilisateurs et le stockage des sessions, il assure un contrôle d’accès granulaire sans ajouter de complexité à la logique d’entreprise. En outre, l’intégration avec des mécanismes complémentaires tels que la promotion et l’ajout de filtres personnalisés offrent une flexibilité accrue pour répondre à des exigences spécifiques.
Pour approfondir votre compréhension de ce sujet, reportez-vous à la documentation officielle sur les entités ORDA ainsi qu’au blog de 4D consacré au filtrage des données.