Dans une précédente vie j'ai travaillé sur une API du TMForum qui concerne la digitalisation de nombreux objets et les identités en particulier. Dans cet API on trouve bien un objet Person qui est le porteur humain de l'identité et aussi sa représentation digital dans l'objet DigitalIdentity.
Dans syncope nous n'avons qu'un seul objet User qui est à la fois le porteur des attributs d'identification et de compte. C'est à mon sens une simplification qui sera une source de complexité.
Cela dit Syncope dispose d'un moyen de lier des objets entre eux et l'on explorera ce moyen pour réintroduire la distinction identité / comptes.
On commence par un fichier csv simple, enfin pas tant:
__UID__;firstname;lastname;email;managerId;operationalUnit;projects
cmiller;Charlie;Miller;cmiller@example.com;;Management;""
asmith;Alice;Smith;asmith@example.com;cmiller;Finance;"Project X,Project Y,Project Z"
jdoe;John;Doe;jdoe@example.com;asmith;IT-Operations;"Project A,Project B"
D'après ChatGPT (mais comment lui faire confiance) pour le connecteur CSVDIR il faut une colonne __UID__ pour identifier la clé unique, pourtant dans le mapping on désigne cette colonne donc pourquoi ce nom de colonne ?
Autre astuce ce fichier définit un lien hiérarchique entre personne et une liste de projets.
J'ai pas mal galéré pour faire l'intégration via la GUI.
La première opération consiste à définir le schéma des attributs que l'on va utiliser dans le fichier et qui ne sont pas déjà connus.
Pour cela dans Configuration et Types, puis Schemas on ajoute les attributs
Ensuite on définit la classe d'objet __ACCOUNT__ à laquelle on ajoute les attributs
Enfin on associe à USER la classe __ACCOUNT__, normalement l'email est hérité de BaseUser
Ensuite on va dans Topology et on clique sur file://opt... et là on ajoute un connecteur
Puis on ajoute la ressource qui décrit le mapping et autres caractéristiques
En fin compte on peut faire la même chose avec l'API et un JSON une fois le connecteurs créé:
[ { "key": "users", "connector": "019a8d86-d1f2-7034-8d82-60f08f3a6f12", "connectorDisplayName": "identites", "provisions": [ { "anyType": "USER", "objectClass": "__ACCOUNT__", "auxClasses": [], "syncToken": null, "ignoreCaseMatch": true, "uidOnCreate": "__UID__", "mapping": { "items": [ { "intAttrName": "username", "extAttrName": "__UID__", "connObjectKey": true, "password": false, "mandatoryCondition": "true", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] }, { "intAttrName": "email", "extAttrName": "email", "connObjectKey": false, "password": false, "mandatoryCondition": "true", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] }, { "intAttrName": "firstname", "extAttrName": "firstname", "connObjectKey": false, "password": false, "mandatoryCondition": "true", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] }, { "intAttrName": "lastname", "extAttrName": "lastname", "connObjectKey": false, "password": false, "mandatoryCondition": "true", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] }, { "intAttrName": "managerId", "extAttrName": "managerId", "connObjectKey": false, "password": false, "mandatoryCondition": "false", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] }, { "intAttrName": "organisationalUnit", "extAttrName": "operationalUnit", "connObjectKey": false, "password": false, "mandatoryCondition": "false", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] }, { "intAttrName": "projects", "extAttrName": "projects", "connObjectKey": false, "password": false, "mandatoryCondition": "false", "purpose": "BOTH", "propagationJEXLTransformer": null, "pullJEXLTransformer": null, "transformers": [] } ], "connObjectLink": null } } ], "orgUnit": null, "propagationPriority": 0, "enforceMandatoryCondition": false, "createTraceLevel": "ALL", "updateTraceLevel": "ALL", "deleteTraceLevel": "ALL", "provisioningTraceLevel": "ALL", "passwordPolicy": null, "accountPolicy": null, "propagationPolicy": null, "inboundPolicy": null, "pushPolicy": null, "provisionSorter": null, "authPolicy": null, "accessPolicy": null, "confOverrideFlag": true, "confOverrideValue": [], "capabilitiesOverrideFlag": false, "capabilitiesOverrideValue": null, "propagationActions": [] }]Mais malgré tous mes efforts rien ne fonctionne et laisse une place à un doute: quand on définit le connecteur on définit un chemin d'accès absolu à un répertoire, mais sur quel volume et pour quel container ?
Même en confiant le fichier au répertoire /tmp, l'intégration des données par le collecteur échoue sur une erreur de la base H2 qui est utilisée comme parser temporaire de la source.
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: USER_EX91937
at org.hsqldb.error.Error.error(Unknown Source)
Mais rien n'est perdu car il existe un mode de chargement directement d'un fichier csv via la GUI, mais qui ne répond pas à la problématique de synchronisation et de cycle de vie. Juste un dépannage pour une démo.
Sélecteur resource
utilisateurs importés