Création utilisateur

4.0
Création utilisateur
0
Tags: #<Tag:0x00007f13dd4d2158>

(NDIO) #1

Bonjour,

J’ai un objet Personne dans mon projet. J’aimerai que lors de la création d’une nouvelle personne, qu’elle soit (la personne nouvellement créée) un potentiel utilisateur de l’application.
Est-il possible de créer un nouvel utilisateur de l’application sans toute fois passer par l’interface de gestion des utilisateurs de Simplicité? Si oui pourrai-je avoir s’il vous plait la procédure à suivre? Ou du moins avoir des solutions qui vont dans ce sens.

Merci d’avance


(David AZOULAY) #2

Tous les objets système Simplicité sont des objets métier comme les autres (c’est justement une des forces de Simplicité de se gérer lui même comme il gère le reste).

L’objet User est donc manipulable de la même manière que tout objet moyennant, bien sûr, d’utiliser un grant habilité à le manipuler. Dans votre cas vu que vous allez implementer du code serveur je vous suggère donc d’utiliser Grant.getSystemAdmin() qui est déjà habilité sur User plutôt que this.getGrant() qui vous obligerait à habiliter un autre groupe sur User ce qui serait un potentiel pb de sécurité.

NB1: Il y a une subtilité à savoir sur l’objet User, il y a une règle de gestion qui empêche l’activation de plus de users qu’autorisés par la clé de licence.

NB2: au delà du user je pense que vous devrez aussi lui créer des responsabilités


(David AZOULAY) #3

PS: un pattern classique dans Simplicité est de faire hériter de User votre objet métier qui représente une personne physique, je pense que dans votre cas c’est trop tard pour appliquer ce pattern…


(NDIO) #4

Bonjour,

J’ai essayé de mettre en relation mon objet Personne avec l’objet user, mais lors de la création d’une nouvelle personne, il me faut également créer un nouvel user ou en choisir un existant. Je ne sais pas si c’est le bon pattern à utiliser, mais cette façon de faire ne résout pas complètement mon problème car l’objet user est en relation avec plusieurs autres objets du système et je n’ai pas forcement besoin de tout çà.

Ensuite j’ai essayé d’hériter de User mon objet métier représentant les personnes physiques, sauf que la création de personne est identique à la création d’un utilisateur sur simplicité
De plus, j’ai cette erreur lorsque j’essaie d’afficher l’interface de mon objet Personne :

Pourrai-je avoir un peu plus d’explications s’il vous plait?

Merci davance


(David AZOULAY) #5

Les 2 patterns sont possibles, ils ont chacun des avantages et des inconvenients.

Pattern relation 0-1 entre User et Personne : en général avec ce pattern à la création d’une personne il faut créer le user correspondant (et, en général, aussi ses responsabilités) et à la suppression de la personne il faut le supprimer (à faire dans les postCreate et postDelete de Personne). L’avantage principal de ce pattern est de pouvoir avoir des personnes sans user et réciproquement.

Pattern Personne hérite de User (avec souvent un search spec statique pour limiter les users vus en tant que personne): avec ce pattern l’avantage est de n’avoir à gérer qu’un seul objet métier.

Bref la 1ère question à se poser pour choisir le pattern est déjà de savoir si ces “personnes” sont toujours des users de l’application ou pas forcément.

Pour le reste:

  1. je ne comprends pas du tout ce que vous voulez dire par " mais cette façon de faire ne résout pas complètement mon problème car l’objet user est en relation avec plusieurs autres objets du système et je n’ai pas forcement besoin de tout çà", oui forcément un User est un objet système en relation avec plein d’autres choses mais en quoi cela vous pose-t-il problème ? A minima un user a besoin de responsabilités (sinon il n’aura aucun droits et ce n’est sans doute pas ce que vous voulez), les autres relations n’ont pas besoin d’être exploitées.

  2. dans le pattern d’héritage votre objet Personne hérite de User et doit bien évidemment dans ce cas particulier d’héritage pointer sur la même table que User à savoir m_user (sinon vos personnes ne seront pas des users mais uniquement des données métier qui ressemblent à des users).


(NDIO) #6

En effet, toutes les personnes ne sont pas forcément des users. Donc c’est le pattern relation 0-1 entre User et Personnequi doit être utilisé si j’ai bien compris.
Et vous avez raison, pour les relations entre User et les autres objets du système, je n’ai pas besoin de les exploiter.
Je regarde çà et je vous fais un retour


(David AZOULAY) #7

Ok si vous partez sur un pattern relation 0-N pensez bien à gérer les responsabilités et le statut du user à la création et en mise à jour

Attention: la transition d’un user vers le statut actif est conditionnée par votre clé de license (qui n’autorise que N users actifs).

Pensez aussi à synchroniser les infos comme nom, prénom, email etc. lors des mises à jour de personne

Etc.

Et surtout pensez bien à supprimer (ou au moins à inactiver) le user à la suppression de votre personne.


(NDIO) #8

Que pensez vous de cette méthode : plutôt que créer des liens entre User et Personne, il serait aussi interessant de créer un utilisateur avec un script qui ressemble à celui ci (je l’ai trouvé dans la doc) :

Personne.postCreate = function(){
	if (this.getField("Utilisateur").getValue()){
		try{
			// Create user if not exists
		    var usr = Grant.getSystemAdmin().getTmpObject("User");
		    usr.setRowId(ObjectField.DEFAULT_ROW_ID);
		    usr.resetValues(true);
		    usr.setStatus(com.simplicite.objects.System.User.ACTIVE);
		    usr.getField("usr_login").setValue(this.getField("Matricule").getValue());
		    usr.getField("usr_first_name").setValue(this.getField("PrenomPersonne").getValue());
		    usr.getField("usr_last_name").setValue(this.getField("NomPersonne").getValue());
		    new BusinessObjectTool(usr).validateAndCreate();
		    console.log("Nouvel utilisateur crée");
		    
		    // Force a random password to avoid the change password popup
		    usr.resetPassword();
		    
		    // Add responsibilities on designated groups
		    var groups = [ "PartVariableAdmin", "PartVariableDM" ];
		    for (var i = 0; i < groups.length; i++) {
		        var group = groups[i];
		        com.simplicite.objects.System.User.addResponsibility(usr.getRowId(), group, Tool.getCurrentDate(-1), "", true);
		        console.log("Added user " + group + " responsibility");
		    }
		    
		}
		catch(e){
			console.error(e.javaException ? e.javaException.getMessage() : e);
		}
	}
};

J’ajoute un booléen comme propriété de mon objet ¨Personne. Si le booléen est a true, il s’agit d’un utilisateur. Mais avec cette façon de faire, je ne réussi pas à ajouter un groupe à mon utilisateur, ni même générer le mot de passe qui devra être changer à la première connexion.
Je trouve cette approche très interessante, qu’est ce que vous en pensez?

Merci d’avance pour votre retour


(David AZOULAY) #9

Dans votre cas il y a de toute façon un “lien” informel par la correspondance entre le matricule de la personne et le login du user.

En ne paramétrant pas un vrai lien vous perdez juste les features associées à un vrai lien (pas d’onglet, de liens de navigation, de gestion de la suppression cascade, etc.).

Par exemple vous allez devoir écrire du code pour que quand vous supprimez une Personne cela supprime le User correspondant (avec un vrai lien ça se ferait tout seul via la suppression cascade) ou quand vous supprimez le User vous devez mettre votre flag booléen à faux (ce flag serait totalement sans objet avec un vira lien)

Autrement dit vous réinventez la poudre… mais en moins bien.

A vous de voir.


(NDIO) #10

Oui je comprend très bien. En utilisant un lien çà fonctionne, mais je suis obligé de gérer trois objets (Personne, User et Group) en même temps.
Lors de la création d’une nouvelle personne, je crée directement un utilisateur via l’interface de création de la personne, je suis obligé de me rendre dans l’interface de création de l’User pour l’activer et lui attribuer des responsabilités. Je trouve cette démarche un peu longue juste pour créer une personne utilisatrice de l’application. Y a t-il pas un moyen d’initialiser certaines valeurs par défaut (comme le statut et le groupe) qui seront directement appliquées au nouvel utilisateur ?

Merci d’avance


(David AZOULAY) #11

Que ça soit avec un vrai lien ou pas l’idée est bien évidement de géré votre user et ses responsabilités dans le code de votre objet Personne (dans les hooks postCreate/postUpdate/postDelete en fonction de vos règles métier). L’idée n’est bien évidement pas de faire faire les manips à la main par vos utilisateurs !

Ce que je dit c’est que vous devriez tout de même gérer un vrai lien 0-1 entre votre Personne et le User qu’il gère afin d’avoir un modèle relationnel propre et de bénéficier des mécanismes natifs associés à un vrai lien relationnel.

Maintenant si vous voulez vraiment un modèle dénormalisé où le “lien” entre votre personne et son user se fait en devant comparer un login avec un matricule et en gérant un flag surabondant, libre à vous de le faire mais clairement ce n’est vraiment pas ce que je vous conseille de faire car vous vous compliquez inutilement la vie et vous compliquez la vie à ceux qui feront la maintenance de votre application.

Simplicité est nativement fait pour gérer des modèle relationels normalisés, faire de la dénormalisation est donc un contre-sens.


(NDIO) #12

Bonjour,

La gestion des utilisateurs fonctionne. Merci pour votre aide.

Comment est ce que je peux récupérer toutes les infos d’un utilisateur (toutes les infos qui se trouvent dans ma table Personne + celles se trouvant dans la table User) lors de sa session?

Merci d’avance


(David AZOULAY) #13

Les infos de User sont accessible via le Grant (ex: getGrant().getFirstName())

Pour les infos stockées dans votre objet Personne et qui ne seraient pas recopiées dans le User, vous devez écrire du code spécifique dans le grant hook GrantHook.postLoadGrant pour monter en mémoire les infos qui vont bien (par exemple via des getGrant().setParameter(...))


(NDIO) #14

Le grant hook GrantHook.postLoadGrant, s’écrit dans l’objet Personne?

Et monter en memoire les infos qui vont c’est par exemple :
getGrant().setParameter("NomParam", obj.getFieldValue("Matricule")) ?

Merci d’avance ?


(David AZOULAY) #15

Non les grant hooks sont des hooks globaux liés à la session utilisateur, cf. https://www.simplicite.io/resources/documentation/01-core/grant-code-hooks.md

Dans le postLoadGrant vous avez accès aux objets habilité à votre utilisateur (ce qui n’est pas le cas dans des grant hooks appelés plus tôt dans le processus)


(NDIO) #16

Désolé, je ne comprend pas très bien votre réponse


(David AZOULAY) #17

Les grant hooks ne sont pas des hooks associés à des objets metiers ou des processus. Ce sont des hooks globaux liés à la session utilisateur.

Il faut les implementer dans un shared script nommé GrantHooks.

Le document que je vous ai indiqué (https://www.simplicite.io/resources/documentation/01-core/grant-code-hooks.md) explique comment les mettre en place et à quoi ils servent.

Dans votre cas, si je comprends bien votre besoin, votre code est à mettre dans le hook postLoadGrant.

Il y a aussi un exemple qui, je pense, correspond bien à votre besoin de positionner des paramètres pour le temps de la session utilisateur: https://www.simplicite.io/resources/documentation/01-core/advanced-code-examples.md#sessionparam