Explication sur l’utilisation des informations sur l’utilisateur dans des conditions d’affichage

Edit me

Contexte

L’objectif est de voir comment conditionner l’affichage de boutons en fonction des droits de l’utilisateur.

Principe général : l’utilisation du JSON

Si on se limite au paramétrage d’un projet Voozanoo 4 que l’on pourrait faire depuis EpiCraft, il s’agit d’exploiter au mieux le JSON dont on dispose.

Extrait d’un JSON de formulaire

Ce JSON contient beaucoup d’information, dont les datasets utilisés. C’est d’ailleurs cette partie qui est le plus couramment utilisée pour des conditions d’affichage avec la syntaxe {mon_varset.ma_variable} == 1.

La demande est ici d’exploiter les droits de l’utilisateur. Ainsi, du JSON du formulaire, on n’expose ici que le début, la partie qui concerne l’utilisateur :

"oUser":{
  "oGroups":{
    "1":{"label":"ICPS","disabled":false,"level":0},
    "17":{"label":"Ho4pital Privé Jacques Cartier (Massy)","disabled":false,"level":1},
    "19":{"label":"Hopital Privé Claude Galien (Quincy)","disabled":false,"level":1}
  },
  "oRoles":{
    "1":"admin"
  },
  "oAccess":[
    "form/frame/get",
    "form/frame/save",
    "form/frame/delete",
    "upload/upload",
    "migration/index/tests",
    "ws/user",
    "listing/index",
    "listing/builder",
    "export/index",
    "export/prepare",
    "export/builder",
    "logo",
    "my-identite",
    "menu.controler",
    "menu.controler.coherence",
    "menu.controler.calculatedvar",
    "menu.controler.doublons",
    "menu.analyser",
    "menu.analyser.listing",
    "menu.analyser.export",
    "menu.analyser.filtre",
    "menu.administrer",
    "menu.administrer.group",
    "menu.administrer.role",
    "menu.administrer.user",
    "menu.administrer.dico",
    "menu.administrer.resource",
    "menu.administrer.epinit",
    "menu.administrer.project",
    "menu.administrer.editeur",
    "patient.editer",
    "patient.supprimer",
    "evt.editer",
    "evt.supprimer",
    "bdd.info.voir",
    "id.formulaire.editer"
  ]
}

On y voit :

  1. Une partie oGroups contenant les groupes dont fait parti l’utilisateur
  2. Une partie oRoles contenant les rôles de l’utilisateur
  3. Une partie oAccess contenant certains droits de l’utilisateur

Dans la suite, on décrit l’utilisation de chaque partie mais le principe est toujours le même.

L’exploitation de la partie oGroups

Cas général

On peut exploiter la partie oGroups en JavaScript de la manière suivante :

{user->groups}.indexOf('ICPS') != -1

Réponse :

  • true si l’utilisateur fait partie du groupe ICPS
  • false si l’utilisateur ne fait pas partie du groupe ICPS

Avertissement dans EpiCraft :

Dans EpiCraft, le message “undefined: Utilisation des accolades invalide dans [votre condition]” apparaîtra. Il peut être ignoré.

Exemple

Dans notre exemple, on a le JSON suivant :

"oUser":{
  "oGroups":{
    "1":{"label":"ICPS","disabled":false,"level":0},
    "17":{"label":"Ho4pital Privé Jacques Cartier (Massy)","disabled":false,"level":1},
    "19":{"label":"Hopital Privé Claude Galien (Quincy)","disabled":false,"level":1}
  }
}

Ainsi :

  • {user->groups}.indexOf('ICPS') != -1 vaut true
  • {user->groups}.indexOf('Autre') != -1 vaut false

L’exploitation de la partie oRoles

Cas général

On peut exploiter la partie oRoles en JavaScript de la manière suivante :

{user->roles}.indexOf('admin') != -1

Réponse :

  • true si l’utilisateur a admin parmis ses rôles
  • false si l’utilisateur n’a pas admin parmi ses rôles

Attention : C’est le nom technique du rôle qu’il faut utiliser, pas son libellé.

Avertissement dans EpiCraft :

Dans EpiCraft, le message “undefined: Utilisation des accolades invalide dans [votre condition]” apparaîtra. Il peut être ignoré.

Exemple

Dans notre exemple, on a le JSON suivant :

"oUser":{
  "oRoles":{
    "1":"admin"
  }
}

Ainsi :

  • {user->roles}.indexOf('admin') != -1 vaut true
  • {user->roles}.indexOf('medecin') != -1 vaut false

L’exploitation de la partie standard de oAccess

De quoi s’agit-il ?

Par “partie standard” on entend ici celle-ci :

"oUser":{
  "oAccess":[
    "form/frame/get",
    "form/frame/save",
    "form/frame/delete",
    "upload/upload",
    "migration/index/tests",
    "ws/user",
    "listing/index",
    "listing/builder",
    "export/index",
    "export/prepare",
    "export/builder"
  ]
}

Elle correspond point par point aux premiers blocs de l’onglet Fonctionalités du formulaire d’édition d’un rôle dans Voozanoo 4. explication_droits_1.png

Cas général

Ces éléments sont utilisés par le noyau pour autoriser ou interdire l’accès à certains modules/controlleurs/actions. Il est rare qu’on est besoin de les exploiter en JavaScript.

On peut cependant le faire de la manière suivante :

{user->access}.indexOf('migration/index/tests') != -1

Réponse :

  • true si l’utilisateur a migration/index/tests parmis ses “access”
  • false si l’utilisateur migration/index/tests parmis ses “access”

Avertissement dans EpiCraft :

Dans EpiCraft, le message “undefined: Utilisation des accolades invalide dans [votre condition]” apparaîtra. Il peut être ignoré.

D’un point de vue métier, ceci teste si, dans la configuration des rôles de l’utilisateur, la case à cocher Tests de l’application est cochée dans le groupe Gestion des projets.

explication_droits_2.png

Exemple

Dans notre exemple, on a le JSON suivant :

"oUser":{
  "oAccess":[
    "form/frame/get",
    "form/frame/save",
    "form/frame/delete",
    "upload/upload",
    "migration/index/tests",
    "ws/user",
    "listing/index",
    "listing/builder",
    "export/index",
    "export/prepare",
    "export/builder"
  ]
}

Ainsi :

  • {user->access}.indexOf('migration/index/tests') != -1 vaut true
  • {user->access}.indexOf('truc/machin/chose') != -1 vaut false

L’exploitation de la partie spécifique de oAccess

De quoi s’agit-il ?

Par “partie spécifique” on entend ici celle-ci dans notre exemple :

"oUser":{
  "oAccess":[
    "logo",
    "my-identite",
    "menu.controler",
    "menu.controler.coherence",
    "menu.controler.calculatedvar",
    "menu.controler.doublons",
    "menu.analyser",
    "menu.analyser.listing",
    "menu.analyser.export",
    "menu.analyser.filtre",
    "menu.administrer",
    "menu.administrer.group",
    "menu.administrer.role",
    "menu.administrer.user",
    "menu.administrer.dico",
    "menu.administrer.resource",
    "menu.administrer.epinit",
    "menu.administrer.project",
    "menu.administrer.editeur",
    "patient.editer",
    "patient.supprimer",
    "evt.editer",
    "evt.supprimer",
    "bdd.info.voir",
    "id.formulaire.editer"
  ]
}

Elle correspond point par point aux derniers blocs de l’onglet Fonctionalités du formulaire d’édition d’un rôle dans Voozanoo 4.

explication_droits_3.png

Ces cases à cocher ne viennent pas du noyau de Voozanoo. Une équipe métier a décidé que, pour ce projet en particulier, il sera nécessaire d’ajouter des droits spécifiques fonctionnalités par fonctionnalités. Ces entrées ont donc été ajoutées pour pouvoir être utilisées dans des conditions d’affichage ou dans le code.

Cas général

On peut exploiter la partie oRoles en JavaScript de la manière suivante :

{user->access}.indexOf('bdd.info.voir') != -1

Réponse :

  • true si l’utilisateur a bdd.info.voir parmis ses “access”
  • false si l’utilisateur bdd.info.voir parmis ses “access”

Avertissement dans EpiCraft :

Dans EpiCraft, le message “undefined: Utilisation des accolades invalide dans [votre condition]” apparaîtra. Il peut être ignoré.

D’un point de vue métier, ceci teste si, dans la configuration des rôles de l’utilisateur, la case à cocher Afficher les infos sur les modifications en base de données est cochée dans le groupe Informations sur la base de données et administration.

explication_droits_4.png

Exemple

Dans notre exemple, on a le JSON suivant :

"oUser":{
  "oAccess":[
    "logo",
    "my-identite",
    "menu.controler",
    "menu.controler.coherence",
    "menu.controler.calculatedvar",
    "menu.controler.doublons",
    "menu.analyser",
    "menu.analyser.listing",
    "menu.analyser.export",
    "menu.analyser.filtre",
    "menu.administrer",
    "menu.administrer.group",
    "menu.administrer.role",
    "menu.administrer.user",
    "menu.administrer.dico",
    "menu.administrer.resource",
    "menu.administrer.epinit",
    "menu.administrer.project",
    "menu.administrer.editeur",
    "patient.editer",
    "patient.supprimer",
    "evt.editer",
    "evt.supprimer",
    "bdd.info.voir",
    "id.formulaire.editer"
  ]
}

Ainsi :

  • {user->access}.indexOf('bdd.info.voir') != -1 vaut true
  • {user->access}.indexOf('bdd.info.editer') != -1 vaut false

Mais d’où viennent ses cases-à-cocher supplémentaires ?

Pour le moment, la procédure à suivre est la suivante, mais il serait bon que la ressource puisse être créée directement dans EpiCraft prochainement.

Pour définir vous-mêmes ces cases-à-cocher, il faut :

  1. Créer une ressource de type Ressources ACL dans l’application Voozanoo.
  2. Y écrire les groupes de fonctionnalités à ajouté pour votre projet.

Le XML de cette ressource suit le format suivant :

<?xml version="1.0" encoding="UTF-8"?>
<acl_resources>
  <group label="Droits spécifiques sur les fiches patients">
    <resource name="patient.editer" label="Editer des fiches patients"/>
    <resource name="patient.supprimer" label="Supprimer des fiches patients"/>
  </group>
  <group label="Droits spécifiques sur les fiches évènements">
    <resource name="evt.editer" label="Editer des fiches évènements"/>
    <resource name="evt.supprimer" label="Supprimer des fiches évènements"/>
  </group>
  <group label="Informations sur la base de données et administration">
    <resource name="bdd.info.voir" label="Afficher les infos sur les modifications en base de données"/>
    <resource name="id.formulaire.editer" label="Editer les identifiants de formulaires liés aux types d'évènements"/>
  </group>
</acl_resources>

Dans ce format :

  • Les balises <group> ne servent qu’à segmenter l’affichage sur le formulaire des rôles.
  • Les balises <resource> sont les droits par fonctionnalité :
    • Leur attribut name est le nom technique à utililiser dans les conditions d’affiche et le code.
    • Leur attribut label est le libellé qui apparaîtra dans le formulaire de rôle.

L’exemple ci-dessus donne le résultat suivant dans le formulaire des rôles :

explication_droits_5.png

Remarque personnelle de BFU

De mon point de vue, cette pratique est nettement préférable à l’utilisation de {user->roles}.indexOf('admin') != -1 parce que :

  • Elle est plus précise (fonctionalité par fonctionnalité).
  • Elle permet de coller au métier (droits, mais aussi vocabulaire utilisé).
  • Elle est beaucoup plus souple (en cas de changement d’avis, il suffit de cocher ou de décocher une case).
  • Elle reste accessible à un non-développeur.

L’exploitation des droits en lecture/écriture/suppression sur les données

Le problème

Les droits en lecture/écriture/suppression sur les données sont paramétrés depuis l’onglet Données du formulaire d’édition d’un rôle de Voozanoo 4 :

explication_droits_6.png

Mais ces informations ne sont pas dans le JSON. Elles ne sont donc pas exploitables comme les autres ci-dessus.

Une solution

Imaginons que vous souhaitiez n’afficher le bouton Ajouter un patient seulement pour les utilisateurs qui ont réellement le droit d’éditer les patients.

Une solution serait de créer un droits spécifique de ce type :

<resource name="patient.editer" label="Editer des fiches patients"/>

Et de l’utiliser comme condition d’affichage sur le bouton d’ajout de patient :

<form_row>
  <option output="html" option_name="show_on" value="{user->access}.indexOf('patient.editer') != -1"/>
  <button label="Ajouter un patient" action="exit">
    <redirection module="form" ctrl="frame" action="get">
      <params>
        <value alias="sid">zdlbfgblvg1499158900254</value>
      </params>
    </redirection>
  </button>
</form_row>