diff --git a/src/graphql/connectors/connectors.js b/src/graphql/connectors/connectors.js
index d2257cefcf377fbe76ef64991f3300841badeea0..836afcb5032b6464ac51c3fc8816973d6e0f3305 100644
--- a/src/graphql/connectors/connectors.js
+++ b/src/graphql/connectors/connectors.js
@@ -582,7 +582,6 @@ export async function getMetaGroupsFromCallbacks (user, selection){
  * @rights user
  */
 export async function getGroupsFromCallbacks(user, cbList){
-    console.log(cbList);
     let all_simple_groups = await getSimpleGroupsFromCallbacks(user, cbList);
     let all_meta_groups = await getMetaGroupsFromCallbacks(user, cbList);
     return all_simple_groups.concat(all_meta_groups);
diff --git a/src/graphql/connectors/selectors.js b/src/graphql/connectors/selectors.js
index 9cde12e5625bc99a05d960142b131c300b24633d..1807f7ce457b28645a899e8aa76ffa076d2fdd8f 100644
--- a/src/graphql/connectors/selectors.js
+++ b/src/graphql/connectors/selectors.js
@@ -15,11 +15,11 @@
  * @rights user
  */
 export async function visibleGroups(user){
-    let group_ids = await user.ldap_access.listGroups(user.uid);
+    let group_ids = await user.ldap_access.listerGroupes(user.uid);
     return function (global_query_builder){
         if (typeof group_ids == "undefined")
             throw "invalid user";
-        var membered_groups = qb => qb.select('uid').from('simple_groups').whereIn('uid', group_ids.concat(['kes']));
+        var membered_groups = qb => qb.select('simple_groups.uid').from('simple_groups').whereIn('uid', group_ids.concat(['kes']));
         var directly_visible_simple_groups = qb =>  qb.with('membered_groups', membered_groups)
             .select('simple_groups.uid').from('simple_groups').distinct()
             .innerJoin('membered_groups',
diff --git a/src/graphql/resolvers.js b/src/graphql/resolvers.js
index 6256bc69e4d420eb78f72a09fcddd1fce8edeeac..471cb3d07140b6d6eac94ef54e2ccb6e15bec092 100644
--- a/src/graphql/resolvers.js
+++ b/src/graphql/resolvers.js
@@ -205,15 +205,12 @@ export const resolvers = {
 
         __resolveType: function(obj) {
             return obj.type;
-        }
-
-    },
+        },
 
-    Post: {
         authors: (obj, args, context) => {
-            console.log(obj);
             return knex.select().from('groups').whereIn('uid', obj.authors);
         }
+
     },
 
     Announcement: {
@@ -249,20 +246,21 @@ export const resolvers = {
 
     // @rights viewer(obj.uid)
     Group: {
-        __resolveType: async (obj) => {
+        __resolveType: (obj) => {
+            console.log(obj);
             
-            switch(obj.type) {
-            case "simple":
-                return "SimpleGroup";
-            case "meta":
-                return "MetaGroup";
-            }
+            let isSimple = knex.select().from("groups").where("uid", obj.uid)
+                .then(res => {
+                    console.log(res);
+                    return res;
+                });
+            
+            return undefined;
         }
     },
 
     // @rights viewer(obj.uid)
     SimpleGroup: {
-        
         members: (obj, args, context) => {
             return connectors.utilisateur.listMembers(context.user,obj.uid);
         }
diff --git a/src/ldap/ldap_data.js b/src/ldap/ldap_data.js
index 1d98ab680a03079c9ccd9f26954f1dff134563f4..27d0c56b14383b5da6ea2c644b167b6674a4fa56 100644
--- a/src/ldap/ldap_data.js
+++ b/src/ldap/ldap_data.js
@@ -29,400 +29,328 @@ var config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
 var client = ldap.createClient({ url: config.ldap.server});
 
 //------------------------------------------------------------------------------------------------------------------------
-// Fonctions de base agissant sur le LDAP
+// Fonctions de base
 //------------------------------------------------------------------------------------------------------------------------
 
-class LDAP {
-    /**
-     * @class Cette classe est la brique de base du fichier tout entier puisqu'elle contient les functions qui agisse directement sur le LDAP.
-     * @summary Constructeur vide.
-     * @author hawkspar
-    */
-    constructor() {}
-    
-    /**
-     * @summary Fonction qui sert à s'identifier sur le LDAP. Ne renvoie rien.
-     * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès. Méthode ldapjs 
-     * (voir [`Client API`](http://ldapjs.org/client.html) méthode bind).
-     * @arg {Object} user - Utilisateur de la forme suivante :
-     * @arg {string} user[uid] - User identifier
-     * @arg {string} user[password] - Mot de passe
-     * @static
-    */
-    static connecter(user) { client.bind(connect.dn, connect.passwd, (err, res) => {}); } // TBM utiliser user 
-
-    /**
-     * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et renvoit les valeurs trouvées.
-     * @desc Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Il faut l'appeler suivant un schéma
-     * `rechercher(...).then((res) => { truc avec res });`. Cette fonction fait une demande au LDAP qu'elle filtre selon un schéma prédéfini dans `dic`
-     * et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
-     * @arg {string} base - DN de l'emplacement de la requête
-     * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape
-     * @arg {string} filter_dic[key] - Vraie valeur pertinente de la recherche
-     * @arg {string[]} attributes - Liste des attributs qui figureront dans le résultat final ; peut aussi être un seul élément
-     * @return {Promise(Object[])} Résultats de la recherche ; soit une liste de valeurs d'attributs, 
-     * soit une liste de dictionnaires si on veut plus d'un attribut (les clés du dictionnaire sont celles du LDAP)
-     * @static
-     */
-    static rechercher(base, attributes, filter="(objectClass=*)") {
-        return new Promise((resolve, reject) => {
-            let vals=[];
-            // Interrogation LDAP selon configuration fournie en argument
-            client.search(base, {
-                "scope": "sub",
-                "filter": filter,
-                "attributes": attributes
-            }, function(err, res) {
-                // Gestion erreur
-                if (err) {
-                    reject(err);
-                } else {
-                    // Dès que la recherche renvoit une entrée, on stocke les attributs qui nous intéresse
-                    res.on('searchEntry', function(entry) {
-                        // Cas un seul attribut où le résultat est une liste directement
-                        if (!Array.isArray(attributes)) { vals.push(entry.object[attributes]); }
-                        else if (attributes.length == 1) { vals.push(entry.object[attributes[0]]); }
-                        // Cas plusieurs attributs donc résultat dictionnaire
-                        else {
-                            vals.push({});
-                            attributes.forEach((attribute) => {
-                                vals.slice(-1)[0][attribute]=entry.object[attribute];
-                            });
-                        }
-                    });
-                    // Si la recherche est finie on se déconnecte et on renvoit la liste
-                    res.on('end', function(res) { resolve(vals); });
-                }
-            });
-        });
-    }
-
-    //TBT
-    /**
-     * @summary Fonction qui permet de modifier un élément sur le LDAP. Gestion intelligente de l'appartenance à un binet.
-     * @desc Cette fonction utilise une Promise pour être asynchrone ; elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs
-     * (voir [`Client API`](http://ldapjs.org/client.html) méthode modify). Il faut l'appeler suivant un schéma `LDAP.modifier(...).then((res) => { truc avec res });`.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.connecter}
-     * @arg {string} name - DN de l'endroit à modifier
-     * @arg {string} op - Operation à réaliser sur le LDAP. Trois opération sont possibles ; "add", qui rajoute des attributs et qui peut créer des doublons,
-     * "del" qui en supprime, et "replace" qui remplace du contenu par un autre. 
-     * @arg {Object} mod - Dictionnaire contenant les attributs à modifier et les nouvelles valeurs des attributs. Une nouvelle valeur vide ("") est équivalent à la suppression
-     * de cet attribut.
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon.
-     * @static
-     */
-    static modifier(name, op, mod) {
-        return new Promise((resolve, reject) => {
-            // Modification LDAP selon configuration en argument (pourrait prendre une liste de Changes)
-            client.modify(name, new ldap.Change({
-                operation: op,
-                modification: mod,
-            }), err => {
-                reject(err);
-            });
-            client.bind("", "", (err, res) => {});
-            resolve(true);
-        });
-    }
-
-    //TBT
-    /**
-     * @summary Fonction qui permet de rajouter un élément sur le LDAP.
-     * @desc Cette fonction appelle {@link LDAP.connecter} pour authentifier l'utilisateur puis rompts la connexion. Cette fonction utilise une Promise pour être asynchrone ;
-     * elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add).
-     * Il faut l'appeler suivant un schéma `LDAP.ajouter(...).then((res) => { truc avec res });`.
-     * @arg {Object} user - Utilisateur de la forme nécessaire au {@linkoperationsLDAP. connecterLDAP}
-     * @arg {string} dn - Adresse du parent
-     * @arg {Object} vals - Dictionnaire contenant les valeurs à créer
-     * @arg {string} vals[key] - Nouvelle valeur pour le champ key
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon.
-     * @static
-     */
-    static ajouter(dn, vals) {
-        return new Promise((resolve, reject) => {
-            // Ajout LDAP selon la configuration en argument
-            client.add(config.key_id+"="+vals[config.key_id]+","+dn, vals, function(err) {
-                reject(err);
-            });
-            client.bind("", "", (err, res) => {});
-            resolve(true);
-        });
-    }
+/**
+ * @summary Fonction qui sert à s'identifier sur le LDAP. Ne renvoie rien.
+ * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès. Méthode ldapjs 
+ * (voir [`Client API`](http://ldapjs.org/client.html) méthode bind).
+ * @arg {Object} user - Utilisateur de la forme suivante :
+ * @arg {string} user[uid] - User identifier
+ * @arg {string} user[password] - Mot de passe
+*/
+function connecterLDAP(bind_user) { client.bind(bind_user.dn, bind_user.passwd, (err, res) => {}); } 
 
-    //TBT
-    /**
-     * @summary Fonction qui permet de supprimer une feuille du LDAP.
-     * @desc Cette fonction appelle {@link LDAP.connecter} pour authentifier l'utilisateur puis rompts la connexion. Cette fonction utilise une Promise pour être asynchrone ;
-     * elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode del).
-     * Il faut l'appeler suivant un schéma `LDAP.supprimer(...).then((res) => { truc avec res });`. Cette fonction fait une demande au LDAP qu'elle filtre selon un
-     * schéma prédéfini dans `dic` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
-     * Elle est différente de modify avec "del" car elle affecte directement une feuille et pas un attribut.
-     * @arg {Object} user - Utilisateur de la forme nécessaire au {@link LDAP.connecter}
-     * @arg {string} dn - Adresse de la cible
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @static
-     */
-    static supprimer(dn) {
-        return new Promise((resolve, reject) => {
-            // Suppression LDAP
-            client.del(dn, function(err) {
+/**
+ * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et renvoit les valeurs trouvées.
+ * @desc Cette fonction appelle {@link bind} pour authentifier l'utilisateur pour authentifier l'utilisateur puis rompts la connexion.
+ * Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Il faut l'appeler suivant un schéma
+ * `rechercherLDAP(...).then((res) => { truc avec res });`. Cette fonction fait une demande au LDAP qu'elle filtre selon un schéma prédéfini dans `dic`
+ * et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
+ * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
+ * @arg {string} base - DN de l'emplacement de la requête
+ * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape
+ * @arg {string} filter_dic[key] - Vraie valeur pertinente de la recherche
+ * @arg {string[]} attributes - Liste des attributs qui figureront dans le résultat final ; peut aussi être un seul élément
+ * @return {Promise(Object[])} Résultats de la recherche ; soit une liste de valeurs d'attributs, 
+ * soit une liste de dictionnaires si on veut plus d'un attribut (les clés du dictionnaire sont celles du LDAP) 
+ */
+function rechercherLDAP(base, attributes, filter="(objectClass=*)") {
+    return new Promise((resolve, reject) => {
+        let vals=[];
+        // Interrogation LDAP selon la configuration fournie en argument
+        client.search(base, {
+            "scope": "sub",
+            "filter": filter,
+            "attributes": attributes
+        }, 
+        function(err, res) {
+            // Gestion erreur
+            if (err) {
                 reject(err);
-            });
-            client.bind("", "", (err, res) => {});
-            resolve(true);
+            } else {
+                // Dès que la recherche renvoie une entrée, on stocke les attributs qui nous intéressent
+                res.on('searchEntry', function(entry) {
+                    // Cas un seul attribut où le résultat est une liste directement
+                    if (!Array.isArray(attributes)) { vals.push(entry.object[attributes]); }
+                    else if (attributes.length == 1) { vals.push(entry.object[attributes[0]]); }
+                    // Plusieurs attributs: le résultat est un dictionnaire
+                    else {
+                        vals.push({});
+                        attributes.forEach((attribute) => {
+                            vals.slice(-1)[0][attribute]=entry.object[attribute];
+                        });
+                    }
+                });
+                // Si la recherche est finie on se déconnecte et on renvoie la liste
+                res.on('end', function(res) { resolve(vals); });
+            }
         });
-    }
+    });
 }
 
-//------------------------------------------------------------------------------------------------------------------------
-// Fonctions de recherche
-//------------------------------------------------------------------------------------------------------------------------
-
-class rechercheModulable {
-    /**
-     * @class Cette classe contient des fonctions de recherche génériques trop puissantes pour être exportées tel quel.
-     * @summary Constructeur vide.
-     * @author hawkspar
-    */
-    constructor() {}
-
-    /**
-     * @summary Fonction qui interroge le LDAP et retrouve les groupes (voir LDAP) qui ressemblent
-     *  à l'entrée. Etape 0 vers un vrai TOL (Trombino On Line).
-     * @desc Cette fonction utilise {@link LDAP.rechercher} mais avec un filtre généré à la volée. 
-     * Accepte des champs exacts ou incomplets mais pas approximatifs
-     * et ne gère pas l'auto-complete. Cette fonction utilise aussi config.json. MEF Timeout pour
-     * des recherches trop vagues. Renvoit une liste d'uid.
-     * Elle utilise LDAPEscape pour éviter les injections.
-     * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
-     * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final
-     * @return {Promise(string[])} Liste des uid de groupes dont le nom ressemble à l'input
-     * @static
-     */
-    static trouverGroupes(input, return_attributes) {
-        return new Promise((resolve, reject) => {
-            // Escape de l'input utilisateur par sécurité
-            let str=ldapEscape.filter("${txt}", { txt: input});
-
-            // Construction du filtre custom
-            let filter= "(|("+config.key_id+"="+str+")"+      // On cherche la valeur exacte
-                        "(|("+config.key_id+"=*"+str+")"+     // La valeur finale avec des trucs avant ; wildcard *
-                        "(|("+config.key_id+"=*"+str+"*)"+    // La valeur du milieu avec des trucs avant et après
-                        "("+config.key_id+"="+str+"*))))";   // La valeur du début avec des trucs après
-
-            // Appel rechercheLDAP avec filtre de l'espace 
-            LDAP.rechercher(config.dn_groups, return_attributes, filter).then(res => resolve(res));
+//TBT
+/**
+ * @summary Fonction qui permet de modifier un élément sur le LDAP. Gestion intelligente de l'appartenance à un binet.
+ * @desc Cette fonction appelle {@link bind} pour authentifier l'utilisateur pour authentifier l'utilisateur puis rompts la connexion.
+ * Cette fonction utilise une Promise pour être asynchrone ; elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs
+ * (voir [`Client API`](http://ldapjs.org/client.html) méthode modify). Il faut l'appeler suivant un schéma `modifierLDAP(...).then((res) => { truc avec res });`.
+ * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
+ * @arg {string} name - DN de l'endroit à modifier
+ * @arg {string} op - Operation à réaliser sur le LDAP. Trois opération sont possibles ; "add", qui rajoute des attributs et qui peut créer des doublons,
+ * "del" qui en supprime, et "replace" qui remplace du contenu par un autre. 
+ * @arg {Object} mod - Dictionnaire contenant les attributs à modifier et les nouvelles valeurs des attributs. Une nouvelle valeur vide ("") est équivalent à la suppression
+ * de cet attribut.
+ * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+ */
+function modifierLDAP(bind_user, name, op, mod) {
+    return new Promise((resolve, reject) => {
+        connecterLDAP(bind_user);
+        // Modification LDAP selon configuration en argument (pourrait prendre une liste de Changes)
+        client.modify(name, new ldap.Change({
+            operation: op,
+            modification: mod,
+        }), err => {
+            reject(err);
         });
-    }
+        client.bind("", "", (err, res) => {});
+        resolve(true);
+    });
+}
 
-    /**
-     * @summary Fonction qui renvoit les attributs demandés des paxs validant les critères de recherche. Première étape vers vrai TOL (Trombino On Line).
-     * @desc Cette fonction utilise {@link LDAP.rechercher} mais avec un filtre généré à la volée. Accepte des champs exacts ou incomplets pour la plupart des champs
-     * mais pas approximatifs et ne gère pas l'auto-complete. MEF Timeout pour des recherches trop vagues. Elle utilise LDAPEscape pour éviter les injections.
-     * Utiliser trouverGroupesParTypes pour chaque champ relié à groups.
-     * @arg {Object} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse
-     * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exempl pour chercher un membre
-     * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined.
-     * @arg {string} data[givenName] - Prénom 
-     * @arg {string} data[lastName] - Nom
-     * @arg {string} data[nickname] - Surnom
-     * @arg {string} data[nationality] - Nationalité (non implémentée pour l'instant, pas de format spécifique)
-     * @arg {string} data[promotion] - String de l'année de promo
-     * @arg {string} data[phone] - String du numéro de portable
-     * @arg {string} data[mail] - Adresse mail
-     * @arg {string} data[ips] - Une ou des adresses ip
-     * @arg {string} data[school] - Ecole d'appartenance (pour l'instant instable). Doit être exact.
-     * @arg {string} data[groups] - Un ou plusieurs groupes (pas de différence entre membre simple et admin). Doit être exact.
-     * @arg {string} data[studies] - PA ou autre. Doit être exact.
-     * @arg {string} data[sport] - Section sportive ou autre Doit être exact.
-     * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final
-     * @return {Promise(Object[])} Liste de dictionnaires de profils en cohérence avec l'input avec pour clés les attributs des profils.
-     * @static
-     */
-    static trouverUtilisateurs(data, return_attributes) {
-        return new Promise((resolve, reject) => {
-            let filter="";
-            // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans config encore
-            for (var key in data) {
-                if ((data[key]!= undefined) & (data[key] != '')) {                    // Si il y a qque chose à chercher pour ce filtre
-                    if (!Array.isArray(data[key])) { data[key]=[data[key]]; }        // Gestion d'une liste de valeurs à rechercher
-                    // Iteration pour chaque valeur fournie par l'utilisateur
-                    data[key].forEach(val => {
-                        // Escape de l'input utilisateur
-                        let str=ldapEscape.filter("${input}", { input: val});
-                        // Traduction en language LDAP
-                        let attribute = config.user[key];
-                        // Creation du filtre étape par étape
-                        filter="(&"+filter+ "(|("+attribute+"="+str+")"+      // On cherche la valeur exacte
-                                            "(|("+attribute+"=*"+str+")"+     // La valeur finale avec des trucs avant ; wildcard * (MEF la wildcart ne marche pas pour tous les attributs)
-                                            "(|("+attribute+"=*"+str+"*)"+    // La valeur du milieu avec des trucs avant et après
-                                            "("+attribute+"="+str+"*)))))";   // La valeur du début avec des trucs après
-                    });
-                }
-            }
-            // Appel rechercheLDAP avec filtre de l'espace 
-            LDAP.rechercher(config.dn_users, return_attributes, filter).then(res => resolve(res));
+//TBT
+/**
+ * @summary Fonction qui permet de rajouter un élément sur le LDAP.
+ * @desc Cette fonction appelle {@link connecterLDAP} pour authentifier l'utilisateur puis rompts la connexion. Cette fonction utilise une Promise pour être asynchrone ;
+ * elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add).
+ * Il faut l'appeler suivant un schéma `modifierLDAP(...).then((res) => { truc avec res });`.
+ * @arg {Object} user - Utilisateur de la forme nécessaire au {@link connecterLDAP}
+ * @arg {string} dn - Adresse du parent
+ * @arg {Object} vals - Dictionnaire contenant les valeurs à créer
+ * @arg {string} vals[key] - Nouvelle valeur pour le champ key
+ * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+ */
+function ajouterLDAP(user, dn, vals) {
+    return new Promise((resolve, reject) => {
+        connecterLDAP(user);
+        // Ajout LDAP selon la configuration en argument
+        client.add(config.key_id+"="+vals[config.key_id]+","+dn, vals, function(err) {
+            reject(err);
         });
-    }
+        client.bind("", "", (err, res) => {});
+        resolve(true);
+    });
+}
 
-    /**
-     * @summary Fonction qui retrouve les paxs validant les critères de recherche. Bien mais vite inutilisable car demande trop au LDAP et renvoie des erreurs de type size limit.
-     * Préférer {@link repliquerTOLdesIds} puis {@link renseignerSurUtilisateur} au cas par cas.
-     * @desc Cette fonction utilise {@link rechercheModulable.trouverUtilisateurs} avec un filtre généré à la volée. Accepte des champs incomplets mais pas approximatifs et ne gère pa
-     * l'auto-complete.
-     * @arg {Object} data - Dictionnaire contenant les données nécessaires à {@link repliquerTOLModulable}
-     * @return {Promise(Object[])} Liste de dictionnaires de profils en cohérence avec l'input avec pour clés tous les attributs disponibles ou presque (voir config).
-     * @static
-     */
-    static repliquerTOL(data) {
-        return new Promise((resolve, reject) => {
-            repliquerTOLModulable(data, config.user.profil).then(res => resolve(res));
+//TBT
+/**
+ * @summary Fonction qui permet de supprimer une feuille du LDAP.
+ * @desc Cette fonction appelle {@link connecterLDAP} pour authentifier l'utilisateur puis rompts la connexion. Cette fonction utilise une Promise pour être asynchrone ;
+ * elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode del).
+ * Il faut l'appeler suivant un schéma `modifierLDAP(...).then((res) => { truc avec res });`. Cette fonction fait une demande au LDAP qu'elle filtre selon un
+ * schéma prédéfini dans `dic` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
+ * Elle est différente de modify avec "del" car elle affecte directement une feuille et pas un attribut.
+ * @arg {Object} user - Utilisateur de la forme nécessaire au {@link connecterLDAP}
+ * @arg {string} dn - Adresse de la cible
+ * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+ */
+function supprimerLDAP(user, dn) {
+    return new Promise((resolve, reject) => {
+        connecterLDAP(user);
+        // Suppression LDAP
+        client.del(dn, function(err) {
+            reject(err);
         });
-    }
+        client.bind("", "", (err, res) => {});
+        resolve(true);
+    });
 }
 
 //------------------------------------------------------------------------------------------------------------------------
-// Fonctions intermédiaires TBT
+// Fonctions de recherche
 //------------------------------------------------------------------------------------------------------------------------
 
-class test {
-    /**
-     * @class Cette classe contient des fonctions intermédiaires de calcul utiles mais non exportables. La plupart sont des tests contre le LDAP
-     * @summary Constructeur vide.
-     * @author hawkspar
-    */
-    constructor() {}
+/**
+ * @summary Fonction qui interroge le LDAP et retrouve les groupes (voir LDAP) qui ressemblent
+ *  à l'entrée. Etape 0 vers un vrai TOL (Trombino On Line).
+ * @desc Cette fonction utilise {@link rechercherLDAP} mais avec un filtre généré à la volée. 
+ * Accepte des champs exacts ou incomplets mais pas approximatifs
+ * et ne gère pas l'auto-complete. Cette fonction utilise aussi config.json. MEF Timeout pour
+ * des recherches trop vagues. Renvoit une liste d'uid.
+ * Elle utilise LDAPEscape pour éviter les injections.
+ * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
+ * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final
+ * @return {Promise(string[])} Liste des uid de groupes dont le nom ressemble à l'input
+ */
+function trouverGroupesModulable(input, return_attributes) {
+    return new Promise((resolve, reject) => {
+        // Escape de l'input utilisateur par sécurité
+        let str=ldapEscape.filter("${txt}", { txt: input});
+
+        // Construction du filtre custom
+        let filter= "(|("+config.key_id+"="+str+")"+      // On cherche la valeur exacte
+                    "(|("+config.key_id+"=*"+str+")"+     // La valeur finale avec des trucs avant ; wildcard *
+                    "(|("+config.key_id+"=*"+str+"*)"+    // La valeur du milieu avec des trucs avant et après
+                    "("+config.key_id+"="+str+"*))))";   // La valeur du début avec des trucs après
+
+        // Appel rechercheLDAP avec filtre de l'espace 
+        rechercherLDAP(config.dn_groups, return_attributes, filter).then(res => resolve(res));
+    });
+}
 
-    /**
-     * @summary Cette fonction teste si un utilisateur est membre d'un groupe.
-     * @desc Utilise les méthodes statiques listerGroupes et listerMembres de {@link utilisateurAnonyme} mais aussi ajouterMembreGroupe de {@link administrateurConnecte}
-     * @param {string} uid - Identifiant de l'utilisateur à tester 
-     * @param {string} gid  - Identification du groupe à tester
-     * @returns {Promise(boolean)} True si l'utilisateur est membre
-     * @static
-     */
-    static etreMembreGroupe(uid, gid) {
-        return new Promise((resolve, reject) => {
-            utilisateurAnonyme.listerGroupes(uid).then(lg => {
-                utilisateurAnonyme.listerMembres(gid).then(lm => {
-                    if (lg.includes(gid) | lm.includes(uid)) {
-                            superAdministrateurConnecte.ajouterMembreGroupe(uid, gid);
-                            resolve(true);
-                    }
+/**
+ * @summary Fonction qui renvoit les attributs demandés des paxs validant les critères de recherche. Première étape vers vrai TOL (Trombino On Line).
+ * @desc Cette fonction utilise {@link rechercherLDAP} mais avec un filtre généré à la volée. Accepte des champs exacts ou incomplets pour la plupart des champs
+ * mais pas approximatifs et ne gère pas l'auto-complete. MEF Timeout pour des recherches trop vagues. Elle utilise LDAPEscape pour éviter les injections.
+ * Utiliser trouverGroupesParTypes pour chaque champ relié à groups.
+ * @arg {Object} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse
+ * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exempl pour chercher un membre
+ * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined.
+ * @arg {string} data[givenName] - Prénom 
+ * @arg {string} data[lastName] - Nom
+ * @arg {string} data[nickname] - Surnom
+ * @arg {string} data[nationality] - Nationalité (non implémentée pour l'instant, pas de format spécifique)
+ * @arg {string} data[promotion] - String de l'année de promo
+ * @arg {string} data[phone] - String du numéro de portable
+ * @arg {string} data[mail] - Adresse mail
+ * @arg {string} data[ips] - Une ou des adresses ip
+ * @arg {string} data[school] - Ecole d'appartenance (pour l'instant instable). Doit être exact.
+ * @arg {string} data[groups] - Un ou plusieurs groupes (pas de différence entre membre simple et admin). Doit être exact.
+ * @arg {string} data[studies] - PA ou autre. Doit être exact.
+ * @arg {string} data[sport] - Section sportive ou autre Doit être exact.
+ * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final
+ * @return {Promise(Object[])} Liste de dictionnaires de profils en cohérence avec l'input avec pour clés les attributs des profils.
+ */
+function repliquerTOLModulable(data, return_attributes) {
+    return new Promise((resolve, reject) => {
+        let filter="";
+        // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans config encore
+        for (var key in data) {
+            if ((data[key]!= undefined) & (data[key] != '')) {                    // Si il y a qque chose à chercher pour ce filtre
+                if (!Array.isArray(data[key])) { data[key]=[data[key]]; }        // Gestion d'une liste de valeurs à rechercher
+                // Iteration pour chaque valeur fournie par l'utilisateur
+                data[key].forEach(val => {
+                    // Escape de l'input utilisateur
+                    let str=ldapEscape.filter("${input}", { input: val});
+                    // Traduction en language LDAP
+                    let attribute = config.user[key];
+                    // Creation du filtre étape par étape
+                    filter="(&"+filter+ "(|("+attribute+"="+str+")"+      // On cherche la valeur exacte
+                                        "(|("+attribute+"=*"+str+")"+     // La valeur finale avec des trucs avant ; wildcard * (MEF la wildcart ne marche pas pour tous les attributs)
+                                        "(|("+attribute+"=*"+str+"*)"+    // La valeur du milieu avec des trucs avant et après
+                                        "("+attribute+"="+str+"*)))))";   // La valeur du début avec des trucs après
                 });
-            });
-        });
-    }
+            }
+        }
+        // Appel rechercheLDAP avec filtre de l'espace 
+        rechercherLDAP(config.dn_users, return_attributes, filter).then(res => resolve(res));
+    });
+}
 
-    /**
-     * @summary Cette fonction teste si un utilisateur est admin d'un groupe.
-     * @desc Utilise les méthodes statiques listerAdministrateurs de {@link utilisateurAnonyme} mais aussi ajouterAdministrateurGroupe de {@link administrateurConnecte}
-     * @param {string} uid - Identifiant de l'utilisateur à tester 
-     * @param {string} gid  - Identification du groupe à tester
-     * @returns {Promise(boolean)} True si l'utilisateur est administrateur
-     * @static
-     */
-    static etreAdministrateurGroupe(uid, gid) {
-        return new Promise((resolve, reject) => {
-            utilisateurAnonyme.listerAdministrateurs(gid).then(la => {
-                if (la.includes(uid)) {
-                    superAdministrateurConnecte.ajouterAdministrateurGroupe(uid, gid);
-                    resolve(true);
-                }
-            });
-        });
-    }
+/**
+ * @summary Fonction qui retrouve les paxs validant les critères de recherche. Bien mais vite inutilisable car demande trop au LDAP et renvoie des erreurs de type size limit.
+ * Préférer {@link repliquerTOLdesIds} puis {@link renseignerSurUtilisateur} au cas par cas.
+ * @desc Cette fonction utilise {@link repliquerTOLModulable} avec un filtre généré à la volée. Accepte des champs incomplets mais pas approximatifs et ne gère pa
+ * l'auto-complete.
+ * @arg {Object} data - Dictionnaire contenant les données nécessaires à {@link repliquerTOLModulable}
+ * @return {Promise(Object[])} Liste de dictionnaires de profils en cohérence avec l'input avec pour clés tous les attributs disponibles ou presque (voir config).
+ */
+function repliquerTOL(data) {
+    return new Promise((resolve, reject) => {
+        repliquerTOLModulable(data, config.user.profil).then(res => resolve(res));
+    });
+}
 
-    /**
-     * @summary Cette fonction teste une valeur d'un attribut (typiquement un identifiant) et le fait évoluer jusqu'à ce qu'il soit unique.
-     * @desc Librement adapté de Stack Overflow. Appelle {@link LDAP.rechercher} pour vérifier 
-     * qu'il n'y a pas d'autres occurences de cette valeur pour cette attribut
-     * dans le dn fourni.
-     * @param {string} valeur - Valeur de l'attribut (le plus souvent un identifiant) à tester à cette itération
-     * @param {string} attribut - Attribut à tester
-     * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
-     * @param {function} evoluerValeur - Fonction qui prend uniquement en argument l'id courant et 
-     * le nombre d'itérations et qui renvoit la prochaine valeur de l'attribut 
-     * @param {int} n [0] - Nombre d'itérations (à initialiser à 0)
-     * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
-     * @static
-     */
-    static assurerUnicite(valeur, attribut, dn, evoluerValeur, n=0) {
-        return new Promise((resolve, reject) => { 
-            // Recherche d'autres occurences de l'id
-            LDAP.rechercher(dn, config.key_id, "("+attribut+"="+valeur+")").then(matches => {
-                // On renvoit la valeur si elle est bien unique
-                if (matches.length==0) { resolve(valeur); }
-                // Sinon, on tente de nouveau notre chance avec la valeur suivante
-                else { resolve(test.assurerUnicite(evoluerValeur(valeur, n+1), dn, evoluerValeur, n+1)); }
-            });
+/**
+ * @summary Cette fonction teste une valeur d'un attribut (typiquement un identifiant) et le fait évoluer jusqu'à ce qu'il soit unique.
+ * @desc Librement adapté de Stack Overflow. Appelle {@link rechercherLDAP} pour vérifier 
+ * qu'il n'y a pas d'autres occurences de cette valeur pour cette attribut
+ * dans le dn fourni.
+ * @param {string} valeur - Valeur de l'attribut (le plus souvent un identifiant) à tester à cette itération
+ * @param {string} attribut - Attribut à tester
+ * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
+ * @param {function} evoluerValeur - Fonction qui prend uniquement en argument l'id courant et 
+ * le nombre d'itérations et qui renvoit la prochaine valeur de l'attribut 
+ * @param {int} n [0] - Nombre d'itérations (à initialiser à 0)
+ * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
+ */
+function assurerUnicite(valeur, attribut, dn, evoluerValeur, n=0) {
+    return new Promise((resolve, reject) => { 
+        // Recherche d'autres occurences de l'id
+        rechercherLDAP(dn, config.key_id, "("+attribut+"="+valeur+")").then(matches => {
+            // On renvoit la valeur si elle est bien unique
+            if (matches.length==0) { resolve(valeur); }
+            // Sinon, on tente de nouveau notre chance avec la valeur suivante
+            else { resolve(assurerUnicite(evoluerValeur(valeur, n+1), dn, evoluerValeur, n+1)); }
         });
-    }
+    });
+}
 
-    /**
-     * @summary Cette fonction génère un uid standard, puis le fait évoluer jusqu'à ce qu'il soit unique.
-     * @desc Limité à un appel à {@link test.assurerUnicite} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation).
-     * @param {string} givenName - Prénom
-     * @param {string} lastName - Nom
-     * @param {string} promotion - Année de promotion
-     * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
-     * @static
-     */
-    static genererUid(givenName, lastName, promotion) {
-        // Le filtrage évite l'injection de code dans le LDAP, le normalize et lowerCase standardisent le format
-        return new Promise((resolve, reject) => {
-            test.assurerUnicite(ldapEscape.filter("${uid}",{uid: givenName+'.'+lastName}).toLowerCase().normalize('UFD'), config.key_id, config.dn_users, (id,n) => {
-                if (n==1) { id+='.'+ldapEscape.filter("${pr}",{pr: promotion}); }   // Si prénom.nom existe déjà, on rajoute la promo
-                else if (n==2) { id+='.'+n-1; }                                     // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1
-                else if (n>2) { id+=+n; }                                           // Ensuite on continue .23, .234, etc...
-                return id;
-            }).then(id => resolve(id));
-        });
-    }
+/**
+ * @summary Cette fonction génère un uid standard, puis le fait évoluer jusqu'à ce qu'il soit unique.
+ * @desc Limité à un appel à {@link assurerUnicite} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation).
+ * @param {string} givenName - Prénom
+ * @param {string} lastName - Nom
+ * @param {string} promotion - Année de promotion
+ * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
+ */
+function genererUid(givenName, lastName, promotion) {
+    // Le filtrage évite l'injection de code dans le LDAP, le normalize et lowerCase standardisent le format
+    return new Promise((resolve, reject) => {
+        assurerUnicite(ldapEscape.filter("${uid}",{uid: givenName+'.'+lastName}).toLowerCase().normalize('UFD'), config.key_id, config.dn_users, (id,n) => {
+            if (n==1) { id+='.'+ldapEscape.filter("${pr}",{pr: promotion}); }   // Si prénom.nom existe déjà, on rajoute la promo
+            else if (n==2) { id+='.'+n-1; }                                     // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1
+            else if (n>2) { id+=+n; }                                           // Ensuite on continue .23, .234, etc...
+            return id;
+        }).then(id => resolve(id));
+    });
+}
 
-    /**
-     * @summary Cette fonction génère un gid standard, puis le fait évoluer jusqu'à ce qu'il soit unique.
-     * @desc Limité à un appel à {@link test.assurerUnicite} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation).
-     * @param {string} name - Nom
-     * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
-     * @static
-     */
-    static genererGid(name) {
-        // Le filtrage évite l'injection de code dans le LDAP, le normalize et lowerCase standardisent le format
-        return new Promise((resolve, reject) => {
-            test.assurerUnicite(ldapEscape.filter("${id}",{id: name}).toLowerCase().normalize('UFD'), config.key_id, config.dn_groups, (id,n) => {
-                if (n==1) { id+='.'+n; }    // Si nom existe déjà, on essaie nom.1
-                else if (n>1) { id+=+n; }   // Ensuite on continue .12, .123, etc...
-                return id;
-            }).then(id => resolve(id));
-        });
-    }
+/**
+ * @summary Cette fonction génère un gid standard, puis le fait évoluer jusqu'à ce qu'il soit unique.
+ * @desc Limité à un appel à {@link assurerUnicite} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation).
+ * @param {string} name - Nom
+ * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
+ */
+function genererGid(name) {
+    // Le filtrage évite l'injection de code dans le LDAP, le normalize et lowerCase standardisent le format
+    return new Promise((resolve, reject) => {
+        assurerUnicite(ldapEscape.filter("${id}",{id: name}).toLowerCase().normalize('UFD'), config.key_id, config.dn_groups, (id,n) => {
+            if (n==1) { id+='.'+n; }    // Si nom existe déjà, on essaie nom.1
+            else if (n>1) { id+=+n; }   // Ensuite on continue .12, .123, etc...
+            return id;
+        }).then(id => resolve(id));
+    });
+}
 
-    /**
-     * @summary Cette fonction teste une valeur dummy (0) pour un identifiant numérique puis le fait évoluer aléatoirement (entre 1 et 100 000) jusqu'à ce qu'il soit unique.
-     * @param {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.connecter}.
-     * @param {string} attribut - Intitulé exact de l'id concerné
-     * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
-     * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
-     * @static
-     */
-    static genererIdNum(attribut, dn) {
-        return new Promise((resolve,reject) => { test.assurerUnicite("0", attribut, dn, (id,n) => { Math.floor((Math.random() * 100000) + 1).toString(); }).then(id => resolve(id)); });
-    }
+/**
+ * @summary Cette fonction teste une valeur dummy (0) pour un identifiant numérique puis le fait évoluer aléatoirement (entre 1 et 100 000) jusqu'à ce qu'il soit unique.
+ * @param {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}.
+ * @param {string} attribut - Intitulé exact de l'id concerné
+ * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
+ * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
+ */
+function genererIdNum(attribut, dn) {
+    return new Promise((resolve,reject) => { assurerUnicite("0", attribut, dn, (id,n) => { Math.floor((Math.random() * 100000) + 1).toString(); }).then(id => resolve(id)); });
 }
 
 //------------------------------------------------------------------------------------------------------------------------
 // Classes à exporter TBT
 //------------------------------------------------------------------------------------------------------------------------
 
-class utilisateurAnonyme {
-    /**
-     * @class Cette classe est la classe exportable de base permettant à un utilisateur non connecté de faire des petites recherches simples.
-     * @summary Constructeur vide.
-     * @author hawkspar
-    */
-   constructor() {}
-
+/**
+ * @summary Cette classe est la classe de base permettant à un utilisateur non connecté de faire des petites recherches simples.
+ * @desc Cette classe contient toutes les fonctions de lecture et de recherche.
+ * @method listerGroupes donne liste de groupes d'un individu
+ * @method listerMembres donne liste de membres d'un groupe
+ * @method listerAdministrateurs donne liste d'administrateurs d'un groupe
+ * @method renseignerSurUtilisateur donne toutes les infos sur une personne (non filtré !)
+ * @method renseignerSurGroupe donne toutes les infos sur un groupe (non filtré !)
+ * @method trouverGroupesParTypes permet de retrouver un groupe à partir d'un type et d'un nom incomplet
+ * @method repliquerTOLdesIds permet de retrouver des ids à partir d'infos parcellaires
+*/
+class UtilisateurAnonyme {
     //------------------------------------------------------------------------------------------------------------------------
     // Fonctions de lecture
     //------------------------------------------------------------------------------------------------------------------------
@@ -472,70 +400,69 @@ class utilisateurAnonyme {
 
     /**
      * @summary Fonction qui retrouve les groupes dont un individu est membre.
-     * @desc Cette fonction utilise {@link LDAP.rechercher} va directement à la feuille de l'utilisateur et n'a donc pas de filtre. Elle utilise ldapEscape pour éviter
+     * @desc Cette fonction utilise {@link rechercherLDAP} va directement à la feuille de l'utilisateur et n'a donc pas de filtre. Elle utilise ldapEscape pour éviter
      * les injections.
      * @arg {string} uid - Identifiant de l'individu à interroger (le plus souvent prenom.nom, parfois l'année, supposé valide)
      * @return {Promise(string[])} Liste des uid de groupes (noms flat des groupes) où l'id fourni est membre
-     * @static
      */
-    static listerGroupes(uid) {
-        return new Promise((resolve, reject) => {
-            LDAP.rechercher(ldapEscape.filter(config.key_id+"=${id},"+config.dn_users, {id : uid}), config.user.groups).then(res => resolve(res[0]));
-        });
+    listGroups(uid) {
+        let filtered_request = ldapEscape.filter(config.key_id + "=${id}," + config.dn_users, { id: uid });
+        console.log(filtered_request);
+        return rechercherLDAP(filtered_request, config.user.groups)
+            .then(res => res[0]);
     }
     
     /**
      * @summary Fonction qui retrouve la liste des membres d'un groupe.
-     * @desc Cette fonction utilise {@link LDAP.rechercher} avec un dictionnaire prédéfini dans config.json. Elle utilise LDAPEscape pour éviter les injections.
-     * @arg {string} gid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
+     * @desc Cette fonction utilise {@link rechercherLDAP} avec un dictionnaire prédéfini dans config.json. Elle utilise LDAPEscape pour éviter les injections.
+     * @arg {string} uid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
      * @return {Promise(String[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
-     * @static
      */
-    static listerMembres(gid) {
-        return new Promise((resolve, reject) => {
-            LDAP.rechercher(ldapEscape.filter(config.key_id+"=${id},"+config.dn_users, {id : gid}), config.group.member).then(res => resolve(res[0]));
-        });
+    listMembers(uid) {
+        let filtered_request = ldapEscape.filter(config.key_id + "=${id}," + config.dn_groups, { id: uid });
+        console.log(filtered_request);
+        return rechercherLDAP(filtered_request, config.group.member)
+            .then(res => res);
     }
     
     /**
      * @summary Fonction qui retrouve la liste des admins d'un groupe.
-     * @desc Cette fonction utilise {@link LDAP.rechercher} avec un dictionnaire prédéfini dans config.json. Elle utilise LDAPEscape pour éviter les injections.
+     * @desc Cette fonction utilise {@link rechercherLDAP} avec un dictionnaire prédéfini dans config.json. Elle utilise LDAPEscape pour éviter les injections.
      * @arg {string} gid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
      * @return {Promise(string[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
-     * @static
      */
-    static listerAdministrateurs(gid) {
+    listAdmins(gid) {
         return new Promise((resolve, reject) => {
-            LDAP.rechercher(dapEscape.filter(config.key_id+"=${id},"+config.dn_users, {id : gid}), config.group.admin).then(res => resolve(res[0]));
+            rechercherLDAP(ldapEscape.filter(
+                config.key_id+"=${id},"+config.dn_users, {id : gid}), config.group.admin).then(res => resolve(res[0])
+            );
         });
     }
      
     /**
      * @summary Fonction qui renvoit toutes les infos relatives à un utilisateur particulier.
-     * @desc Cette fonction utilise {@link LDAP.rechercher} avec des attributs prédéfinis. Elle utilise LDAPEscape pour éviter les injections.
+     * @desc Cette fonction utilise {@link rechercherLDAP} avec des attributs prédéfinis. Elle utilise LDAPEscape pour éviter les injections.
      * @arg {string} uid - Identifiant de l'utilisateur
      * @return {Promise(Object[])} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet de l'utilisateur ;
      * voir `ldap_config.json`(..\..\ldap_config.json) pour les clés exactes.
-     * @static
      */
-    static renseignerSurUtilisateur(uid) {
+    getUser(uid) {
         return new Promise((resolve, reject) => {
-            LDAP.rechercher(dapEscape.filter(config.key_id+"=${id},"+config.dn_users, {id : uid}), config.user.profil).then(res => resolve(res));
+            rechercherLDAP(ldapEscape.filter(config.key_id+"=${id},"+config.dn_users, {id : uid}), config.user.profil).then(res => resolve(res));
         });
     }
      
     /**
      * @summary Fonction qui renvoit toutes les infos relatives à un groupe particulier.
-     * @desc Cette fonction utilise {@link LDAP.rechercher} avec des attributs prédéfinis. Elle utilise LDAPEscape pour éviter les injections.
+     * @desc Cette fonction utilise {@link rechercherLDAP} avec des attributs prédéfinis. Elle utilise LDAPEscape pour éviter les injections.
      * @arg {string} gid - Identifiant du groupe
      * @return {Promise(Object[])} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe ;
-     * voir `ldap_config.json`(..\..\ldap_config.json) pour les clés exactes.
-     * @static
+     * voir `ldap_config.json`(../../ldap_config.json) pour les clés exactes.
      */
-    static renseignerSurGroupe(gid) {
-        return new Promise((resolve, reject) => {
-            LDAP.rechercher(dapEscape.filter(config.key_id+"=${id},"+config.dn_groups, {id : gid}), config.group.profil).then(res => resolve(res));
-        });
+    getGroup(gid) {
+        let filtered_request = ldapEscape.filter(config.key_id + "=${id}," + config.dn_groups, { id: gid });
+        console.log(filtered_request);
+        return rechercherLDAP(filtered_request, config.group.profil).then(res => res);
     }
 
     //------------------------------------------------------------------------------------------------------------------------
@@ -544,16 +471,15 @@ class utilisateurAnonyme {
 
     /**
      * @summary Fonction qui retrouve le groupe qui ressemblent à l'input et qui correspond au type fourni. Etape 0 vers un vrai TOL (Trombino On Line).
-     * @desc Cette fonction utilise {@link rechercheModulable.trouverGroupes}.
+     * @desc Cette fonction utilise {@link trouverGroupesModulable}.
      * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
      * @arg {string} type - String aux valeurs prédéfinies dans ldap_config.
-     * @return {Promise(string[])} Liste des uid de groupes dont le nom ressemble à l'input.
-     * @static
+     * @return {Promise(string[])} Liste des uid de groupes dont le nom ressemble à l'input
     */
-    static trouverGroupesParTypes(input, type) {
+    trouverGroupesParTypes(input, type) {
         return new Promise((resolve, reject) => {
             // Simple appel à la fonction précédente
-            rechercheModulable.trouverGroupes(input, [config.key_id, config.group.type]).then(gList => {
+            trouverGroupesModulable(input, [config.key_id, config.group.type]).then(gList => {
                 let gidtyList = [];
                 gList.forEach(g => {
                     // Si le groupe est du bon type on rajoute son gid
@@ -570,23 +496,26 @@ class utilisateurAnonyme {
      * @desc Cette fonction utilise {@link repliquerTOLModulable}.
      * @arg {Object} data - Dictionnaire contenant les données nécessaires à {@link repliquerTOLModulable}
      * @return {Promise(string[])} uids des profils qui "match" les critères proposés.
-     * @static
      */
-    static repliquerTOLdesIds(data) {
+    repliquerTOLdesIds(data) {
         return new Promise((resolve, reject) => {
             repliquerTOLModulable(data, config.key_id).then(res => resolve(res));
         });
     }
 }
 
-class utilisateurConnecte extends utilisateurAnonyme {
-    /**
-     * @class Cette classe est la classe de l'utilisateur connecté qui peut déjà créer un groupe et changer son profil.
-     * @summary Ce constructeur appelle simplement {@link LDAP.connecter}.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.connecter}.
-     * @author hawkspar
-    */
-    constructor(user) { connecterLDAP(user); }
+/**
+ * @summary Cette classe est la classe de l'utilisateur connecté de base qui lui permet de créer un nouveau groupe ou éditer son profil.
+ * @desc Cette classe contient toutes les fonctions de lecture et de recherche.
+ * @constructor Un appel à {@link connecterLDAP}
+ * @method creerGroupes permet à n'importe qui de créer son groupe
+ * @method editerUtilisateur permet à n'importe qui de changer son profil
+*/
+class UtilisateurConnecte extends UtilisateurAnonyme {
+    constructor(bind_user) {
+        super(bind_user);
+        connecterLDAP(bind_user);
+    }
 
     //------------------------------------------------------------------------------------------------------------------------
     // Fonction de création TBT
@@ -595,8 +524,9 @@ class utilisateurConnecte extends utilisateurAnonyme {
     /**
      * @summary Fonction qui créé un nouveau groupe dans le LDAP.
      * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ; c'est mal et cela suppose que beaucoup de soins ont été pris lors de
-     * l'escape de ses paramètres. Appelle {@link LDAP.ajouter} et {@link LDAP.modifier}, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe}
-     * pour gérer les groupes du nouvel utilisateur. Attention une manip FOIREUSE est cachée dedans.
+     * l'escape de ses paramètres. Appelle {@link ajouterLDAP} et {@link modifierLDAP}, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe}
+     * pour gérer les groupes du nouvel utilisateur. Attention une manip FOIREUSE est cachée dedans. 
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {Object} data - Dictionnaire des informations utilisateurs (voir détail des champs dans config.json)
      * @arg {string} data[name] - Nom du groupe
      * @arg {string} data[ns] - Statut du groupe ; 'binet' ou 'free', càd ouvert à tous
@@ -604,19 +534,19 @@ class utilisateurConnecte extends utilisateurAnonyme {
      * @arg {string[]} data[admins] - Liste des admins du groupe ; supposée être une sous-liste de la précédente
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    creerGroupe(data) {
+    createGroup(user, data) {
         return new Promise((resolve, reject) => {
             // Calcul d'un dictionnaire d'ajout
             let vals = {};
     
             // uid de base généré à partir du nom standardisé
-            test.genererGid(data['name']).then(id => { vals[config.group['name']]=id; });
+            genererGid(user, data['name']).then(id => { vals[config.group['name']]=id; });
     
             // Ecriture de toutes les valeurs directement inscrites dans le LDAP (in pour input)
             config.group.direct_input.forEach(key_att => vals[config.group[key_att]]=data[key_att]);
     
             // Appel à la fonction de base
-            LDAP.ajouter(config.key_id+"="+vals[config.group['name']]+","+config.dn_groups, vals).then( res => {
+            ajouterLDAP(user, config.key_id+"="+vals[config.group['name']]+","+config.dn_groups, vals).then( res => {
                 // Certains champs nécessitent de petits calculs
                 let vals2={};
     
@@ -627,8 +557,8 @@ class utilisateurConnecte extends utilisateurAnonyme {
                 vals2[config.user['password']] =  '';
     
                 // Génération id aléatoire et test contre le LDAP
-                test.genererIdNum(config.groups["idNumber"], config.dn_groups).then(id => { vals2[config.group['idNumber']]=id; });
-                // FOIREUX : Hypothèse sur la structure du reste des données mais évite un test.assurerUnicite à deux variables
+                genererIdNum(user, config.groups["idNumber"], config.dn_groups).then(id => { vals2[config.group['idNumber']]=id; });
+                // FOIREUX : Hypothèse sur la structure du reste des données mais évite un assurerUnicite à deux variables
                 vals2[config.group['idNumber2']]=vals2[config.group['idNumber']];
                 
                 // Stockage machine ; dépend du prénom
@@ -645,21 +575,21 @@ class utilisateurConnecte extends utilisateurAnonyme {
                 vals2[config.group['writePerm']] = '!*';
     
                 // Inscription des valeurs calculées
-                LDAP.modifier(config.key_id+"="+vals[config.key_id]+","+config.dn_groups, "add", vals2).then(res => {
+                modifierLDAP(user, config.key_id+"="+vals[config.key_id]+","+config.dn_groups, "add", vals2).then(res => {
                     if (!res) { reject(false); }
                 });
     
                 ["posixAccount", "posixGroup", "brAccount"].forEach(cst => {
                     let vals3={};
                     vals3[config.group['class']]=cst;
-                    LDAP.modifier(config.key_id+"="+vals[config.key_id]+","+config.dn_groups, "add", vals3).then(res => {
+                    modifierLDAP(user, config.key_id+"="+vals[config.key_id]+","+config.dn_groups, "add", vals3).then(res => {
                         if (!res) { reject(false); }
                     });
                 });
     
                 // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
-                data['members'].forEach(uid => { this.ajouterMembreGroupe(uid, vals[config.key_att]); });
-                data['admins'].forEach(uid => { this.ajouterAdministrateurGroupe(uid, vals[config.key_att]); });
+                data['members'].forEach(uid => { this.ajouterMembreGroupe(user, uid, vals[config.key_att]); });
+                data['admins'].forEach(uid => { this.ajouterAdministrateurGroupe(user, uid, vals[config.key_att]); });
     
                 resolve(true);
             });
@@ -673,18 +603,19 @@ class utilisateurConnecte extends utilisateurAnonyme {
     
     /**
      * @summary Fonction qui édite un utilisateur existant dans le LDAP. Très similaire à {@link creerUtilisateur}
-     * @desc Appelle simplement {@link creerUtilisateur} et {@link supprimerUtilisateur} en godmode, plus {@link renseignerSurUtilisateur} pour les champs non fournis.
+     * @desc Appelle simplement {@link creerUtilisateur} et {@link supprimerUtilisateur}, plus {@link renseignerSurUtilisateur} pour les champs non fournis.
      * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_config est important. A modifier car donne trop de pouvoir à l'utilisateur.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} uid - Utilisateur à modifier (le plus souvent le même, mais root possible)
      * @arg {Object} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerUtilisateur} avec tous les champs optionnels ;
      * MEF ces valeurs vont écraser les précédentes.
      * attention toutes les clés de cette entrée seront modifiées dans le LDAP
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    editerUtilisateur(uid, data) {
+    editerUtilisateur(user, uid, data) {
         return new Promise((resolve, reject) => {
             // Récupération des anciennes données
-            super.renseignerSurUtilisateur(uid).then(profil => {
+            this.getUser(user, uid).then(profil => {
                 // Reecriture de profil avec les bons champs
                 Object.keys(profil).forEach(keyLDAP => {
                     Object.keys(config.user).forEach(keyAlias => {
@@ -693,21 +624,19 @@ class utilisateurConnecte extends utilisateurAnonyme {
                     });
                 });
                 // Régénération du champ manquant dans profil
-                super.listerGroupes(user, uid).then(lg => {
+                this.listGroups(user, uid).then(lg => {
                     profil['groupsIsAdmin']=[];
                     lg.forEach(gid =>{
-                        test.etreAdministrateurGroupe(uid, gid).then(res =>{
+                        this.isGroupAdmin(this, uid, gid).then(res =>{
                             if (res) { profil['groupsIsAdmin'].push(gid); }
                         }).then(res => {
                             // Surcharge des champs à modifier selon data
                             Object.keys(data).forEach(key => {
                                 profil[key]=data[key];
                             });
-                            // Passage en godmode
-                            var god = superAdministrateurConnecte({"uid":"", "password":""});
                             // Modification propre
-                            god.supprimerUtilisateur(uid).then(r => {
-                                god.creerUtilisateur(profil).then(res => { if (!res) {reject(false); }});
+                            this.supprimerUtilisateur(user, uid).then(r => {
+                                this.creerUtilisateur(user, profil).then(res => { if (!res) {reject(false); }});
                             }).then (res => { resolve(true); });
                         });
                     });
@@ -719,15 +648,18 @@ class utilisateurConnecte extends utilisateurAnonyme {
     deconnecterLDAP() { client.bind("", "", (err, res) => {}); }
 }
 
-class administrateurConnecte extends utilisateurConnecte {
-    /**
-     * @class Cette classe est la classe de l'administrateur d'un groupe qui lui permet de rajouter des membres, en supprimer, idem pour des admins,
-     * ou éditer, voir supprimer le groupe.
-     * @summary Ce constructeur appelle simplement le constructeur de sa classe mère.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.connecter}.
-     * @author hawkspar
-    */
-    constructor(user) { super(user); }
+/**
+ * @summary Cette classe est la classe de l'administrateur d'un groupe qui lui permet de rajouter des membres, en supprimer, idem pour des admins,
+ * ou éditer, voir supprimer le groupe.
+ * @desc Cette classe contient les première fonctions de relation.
+ * @method ajouterMembreGroupe permet un admin de rajouter un membre (pas de demande d'accord)
+ * @method supprimerMembreGroupe inverse de la précédente
+ * @method ajouterAdministrateurGroupe rajoute un administrateur
+ * @method supprimerAdministrateurGroupe inverse de la précédente
+ * @method editerGroupe permet de changer les informations (statut, nom...) du groupe
+ * @method supprimerGroupe supprime le groupe du LDAP (beaucoup de pouvoir)
+*/
+class AdministrateurConnecte extends UtilisateurConnecte {
     
     //------------------------------------------------------------------------------------------------------------------------
     // Fonctions de relation TBT
@@ -735,30 +667,31 @@ class administrateurConnecte extends utilisateurConnecte {
     
     /**
      * @summary Fonction qui permet de rajouter un membre déjà créé à un groupe.
-     * @desc Cette fonction fait essentiellement appel à {@link LDAP.modifier} et {@link listerGroupes}. Elle n'autorise pas les doublons et opère dans les deux dns users
+     * @desc Cette fonction fait essentiellement appel à {@link modifierLDAP} et {@link listerGroupes}. Elle n'autorise pas les doublons et opère dans les deux dns users
      * et groups.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} uid - Identifiant du futur membre
      * @arg {string} gid - Identifiant du groupe
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    ajouterMembreGroupe(uid, gid) {
+    ajouterMembreGroupe(user, uid, gid) {
         return new Promise((resolve, reject) => {
             // Vérifie que l'utilisateur est pas déjà membre pour groupes
-            super.listerMembres(gid).then(lm => {
+            this.listMembers(user,gid).then(lm => {
                 if (!lm.includes(uid)) {
                     let vals = {};
                     vals[config.groups.member] = uid;
-                    LDAP.modifier(ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "add", vals).then(res => {
+                    modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "add", vals).then(res => {
                         // Erreur si pb lors de la modification
                         if (!res) { reject(false); }
                     });
                 }
             // Vérifie que l'utilisateur est pas déjà membre pour users
-            }).then(res => super.listerGroupes(uid)).then( lg => {
+            }).then(res => this.listGroups(user,uid)).then( lg => {
                 if (!lg.includes(gid)) {
                     let vals2 = {};
                     vals2[config.users.groups] = gid;
-                    LDAP.modifier(ldapEscape(config.key_id+"=${id},"+config.dn_users, { id: uid }), "add", vals2).then(res => {
+                    modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_users, { id: uid }), "add", vals2).then(res => {
                         // Erreur si pb lors de la modification
                         if (!res) { reject(false); }
                     });
@@ -770,32 +703,33 @@ class administrateurConnecte extends utilisateurConnecte {
 
     /**
      * @summary Fonction qui permet de supprimer un membre existant d'un groupe.
-     * @desc Cette fonction fait essentiellement appel à {@link LDAP.rechercher}, {@link operationsLDAP.LDAP.modifier}, {@link listerGroupes} et {@link listerMembres}.
+     * @desc Cette fonction fait essentiellement appel à {@link rechercherLDAP}, {@link modifierLDAP}, {@link listerGroupes} et {@link listerMembres}.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} uid - Identifiant de l'ex-membre
      * @arg {string} gid - Identifiant du groupe
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    supprimerMembreGroupe(uid, gid) {
+    removeGroupMember(user, uid, gid) {
         return new Promise((resolve, reject) => {
             // Vérifie que l'utilisateur est pas déjà viré pour groupes
-            super.listerMembres(gid).then(lm => {
+            this.listMembers(user,gid).then(lm => {
                 if (lm.includes(uid)) {
                     // Supprime tous les utilisateurs
-                    LDAP.modifier(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "del", config.group.member).then(res => {
+                    modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "del", config.group.member).then(res => {
                         // Les rajoute un par un, sauf pour le supprimé
                         lm.forEach(id => {
-                            if (id!=uid) { this.ajouterMembreGroupe(id, gid); }
+                            if (id!=uid) { this.ajouterMembreGroupe(user,id, gid); }
                         });
                     });
                 }
-            }).then(res => super.listerGroupes(uid)).then(lg => {
+            }).then(res => this.listGroups(user,uid)).then(lg => {
                 // Vérifie que l'utilisateur est pas déjà viré pour users
                 if (lg.includes(gid)) {
                     // Supprime tous les groupes
-                    LDAP.modifier(ldapEscape(config.key_id+"=${id},"+config.dn_users, { id: uid }), "del", config.group.admin).then(res => {
+                    modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_users, { id: uid }), "del", config.group.admin).then(res => {
                         // Les rajoute un par un, sauf pour le supprimé
                         lg.forEach(id => {
-                            if (id!=gid) { this.ajouterMembreGroupe(uid, id); }
+                            if (id!=gid) { this.ajouterMembreGroupe(user,uid, id); }
                         });
                     });
                 }
@@ -806,22 +740,23 @@ class administrateurConnecte extends utilisateurConnecte {
 
     /**
      * @summary Fonction qui permet de promouvoir membre au stade d'administrateur d'un groupe.
-     * @desc Cette fonction fait essentiellement appel à {@link ajouterMembreGroupe} {@link LDAP.modifier} et {@link listerAdministrateurs}. Elle n'autorise pas
+     * @desc Cette fonction fait essentiellement appel à {@link ajouterMembreGroupe} {@link modifierLDAP} et {@link listerAdministrateurs}. Elle n'autorise pas
      * les doublons et opère dans les deux dns users et groups.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} uid - Identifiant du futur membre
      * @arg {string} gid - Identifiant du groupe
      * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
      */
-    ajouterAdministrateurGroupe(uid, gid){
+    ajouterAdministrateurGroupe(user, uid, gid){
         return new Promise((resolve, reject) => {
             // ajouter
-            this.ajouterMembreGroupe(uid,gid).then(res => {
-                super.listerAdministrateurs(user,gid).includes(uid).then(la => {
+            this.ajouterMembreGroupe(user,uid,gid).then(res => {
+                this.listAdmins(user,gid).includes(uid).then(la => {
                     if (!la.includes(uid)) {
                         // Finalement modification, uniquement dans groups
                         let vals = {};
                         vals[config.groups.admin] = uid;
-                        LDAP.modifier(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "add", vals).then(res => {
+                        modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "add", vals).then(res => {
                             // Gestion d'erreur
                             if (!res) { reject(false); }
                         });
@@ -834,23 +769,24 @@ class administrateurConnecte extends utilisateurConnecte {
 
     /**
      * @summary Fonction qui permet de rétrograder un membre du stade d'administrateur d'un groupe au stade d'utilisateur.
-     * @desc Cette fonction fait essentiellement appel à {@link LDAP.modifier}.
+     * @desc Cette fonction fait essentiellement appel à {@link modifierLDAP}.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} uid - Identifiant du futur membre
      * @arg {string} gid - Identifiant du groupe
      * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
      */
-    supprimerAdministrateurGroupe(uid, gid) {
+    supprimerAdministrateurGroupe(user, uid, gid) {
         return new Promise((resolve, reject) => {
             // Peut paraître absurde mais permet de s'assurer que le membre est bien présent et que ses champs sont comme il faut
-            this.supprimerMembreGroupe(uid, gid).then( res => { this.ajouterMembreGroupe(uid,gid); });
+            this.removeGroupMember(user, uid, gid).then( res => { this.ajouterMembreGroupe(user,uid,gid); });
             // Vérifie que l'utilisateur est bien admins (comme dans supprimerMembreGroupe)
-            super.listerAdministrateurs(gid).then(la => {
+            this.listAdmins(user,gid).then(la => {
                 if (la.includes(uid)) {
                     // Supprime tous les administrateurs
-                    LDAP.modifier(ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "del", config.group.admin).then(res => {
+                    modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "del", config.group.admin).then(res => {
                         // Les rajoute un par un, sauf pour le supprimé
                         la.forEach(id => {
-                            if (id!=uid) { this.ajouterAdministrateurGroupe(id, gid); }
+                            if (id!=uid) { this.ajouterAdministrateurGroupe(user, id, gid); }
                         });
                     });
                 }
@@ -864,15 +800,16 @@ class administrateurConnecte extends utilisateurConnecte {
     
     /**
      * @summary Fonction qui édite un groupe existant dans le LDAP. Très similaire à {@link creerGroupe}
-     * @desc Appelle {@link LDAP.ajouter} bien sûr, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe} en godmode pour gérer les groupes du nouvel utilisateur.
+     * @desc Appelle {@link ajouterLDAP} bien sûr, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe} pour gérer les groupes du nouvel utilisateur.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} gid - Identifiant du groupe à modifier
      * @arg {Object} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerGroupe} avec tous les champs optionnels.
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    editerGroupe(gid, data) {
+    editGroup(user, gid, data) {
         return new Promise((resolve, reject) => {
             // Récupération des anciennes données
-            super.renseignerSurGroupe(gid).then(profil => {
+            this.getGroup(user, gid).then(profil => {
                 // Reecriture de profil avec les bons champs
                 Object.keys(profil).forEach(keyLDAP => {
                     Object.keys(config.group).forEach(keyAlias => {
@@ -885,8 +822,8 @@ class administrateurConnecte extends utilisateurConnecte {
                     profil[key]=data[key];
                 });
                 // Modification propre
-                this.supprimerGroupe(gid).then(r => {
-                    this.creerGroupe(profil).then(res => { if (!res) { reject(false); }});
+                this.deleteGroup(user, gid).then(r => {
+                    this.createGroup(user, profil).then(res => { if (!res) { reject(false); }});
                 }).then(res => { resolve(true); });
             });
         });
@@ -899,41 +836,41 @@ class administrateurConnecte extends utilisateurConnecte {
     /**
      * @summary Fonction qui supprime un groupe du LDAP.
      * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement.
-     * Appelle {@link LDAP.supprimer} bien sûr, mais aussi {@link supprimerMembreGroupe} et {@link supprimerAdministrateurGroupe} pour gérer les groupes de l'utilisateur sortant.
+     * Appelle {@link supprimerLDAP} bien sûr, mais aussi {@link supprimerMembreGroupe} et {@link supprimerAdministrateurGroupe} pour gérer les groupes de l'utilisateur sortant.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} gid - gid de la victime
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    supprimerGroupe(gid) {
+    deleteGroup(user, gid) {
         return new Promise(function(resolve, reject) {
             // Gestion des membres et administrateurs d'abord
-            this.constructor.renseignerSurGroupe(gid).then(profil => {
+            this.getGroup(user, gid).then(profil => {
                 // Ordre important
-                profil[config.group['admin']].forEach(id => { this.supprimerAdministrateurGroupe(user, id, gid); });
-                profil[config.group['member']].forEach(id => { this.supprimerMembreGroupe(user, id, gid); });
+                profil[config.group['admin']].forEach(id => { this.removeGroupAdmin(user, id, gid); });
+                profil[config.group['member']].forEach(id => { this.removeGroupMember(user, id, gid); });
             // Elimination
             }).then(res => {
-                LDAP.supprimer(user, config.key_id+"="+gid+","+config.dn_groups);
+                supprimerLDAP(user, config.key_id+"="+gid+","+config.dn_groups);
             }).then(res => { if (res) {resolve(true); }});
         });
     }
 }
 
-class superAdministrateurConnecte extends administrateurConnecte {
-    /**
-     * @class Cette classe est la classe du super administrateur qui créé et supprime des membres.
-     * @summary Bête appel au constructeur de la classe mère.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.connecter}.
-     * @author hawkspar
-     */
-    constructor(user) { super(user); }
-
+/**
+ * @summary Cette classe est la classe du super administrateur dieu sur terre.
+ * @desc Cette classe contient les fonctions de suppression et de création utilisateurs.
+ * @method creerUtilisateur créé un nouveau compte sur le LDAP
+ * @method supprimerUtilisateur inverse de la précédente
+*/
+class SuperAdministrateurConnecte extends AdministrateurConnecte {
     //------------------------------------------------------------------------------------------------------------------------
     // Fonctions de création TBT
     //------------------------------------------------------------------------------------------------------------------------
     
     /**
      * @summary Fonction qui créé un nouvel utilisateur dans le LDAP.
-     * @desc Appelle {@link LDAP.ajouter} bien sûr, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe} pour gérer les groupes du nouvel utilisateur.
+     * @desc Appelle {@link ajouterLDAP} bien sûr, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe} pour gérer les groupes du nouvel utilisateur.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}.
      * @arg {Object} data - Dictionnaire des informations utilisateurs. Des erreurs peuvent apparaître si tous les champs ne sont pas remplis.
      * @arg {string} data[givenName] - Prénom
      * @arg {string} data[lastName] - Nom
@@ -953,28 +890,28 @@ class superAdministrateurConnecte extends administrateurConnecte {
      * @arg {string[]} data[groupsIsAdmin] [] - Liste des gid dont le pax est admin ; supposé sous-liste du précédent
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    creerUtilisateur(data) {
+    creerUtilisateur(user, data) {
         return new Promise((resolve, reject) => {
             // Calcul d'un dictionnaire d'ajout
             let vals = {};
     
             // uid de base généré à partir de nom et prénom, plus potentiellement promo et un offset
             // MEF mélange de Promise et de fonction standard
-            test.genererUid(data['givenName'],data['lastName'],data['promotion']).then(id => { vals[config.key_id]=id; } );
+            genererUid(user, data['givenName'],data['lastName'],data['promotion']).then(id => { vals[config.key_id]=id; } );
     
             // Ecriture de toutes les valeurs directement inscrites dans le LDAP (in pour input)
             // Génère une erreur si un champ n'est pas rempli
             config.user.direct_input.forEach(key_att => vals[config.user[key_att]]=data[key_att]);
     
             // Appel à la fonction de base
-            LDAP.ajouter(config.key_id+"="+vals[config.key_id]+","+config.dn_users, vals).then( res => {
+            ajouterLDAP(user, config.key_id+"="+vals[config.key_id]+","+config.dn_users, vals).then( res => {
                 // Modifications multiples pour avoir plusieurs champs de même type ; boucle sur les attributs multiples (d'où mul)
                 config.user.muliple_input.forEach(key_att => {
                     // On rajoute chaque valeur en entrée
                     data[key_att].forEach(val => {
                         let vals2 = {};
                         vals2[config.user[key_att]]=val;
-                        LDAP.modifier(config.key_id+"="+vals[config.key_id]+","+config.dn_users, "add", vals2).then(res => {
+                        modifierLDAP(user, config.key_id+"="+vals[config.key_id]+","+config.dn_users, "add", vals2).then(res => {
                             if (!res) { reject(false); }
                         });
                     });
@@ -992,7 +929,7 @@ class superAdministrateurConnecte extends administrateurConnecte {
                     vals3[config.user['nickname']]=data['nickname'];
                 }
                 // Génération id aléatoire unique
-                test.genererIdNum(config.user['id'], config.dn_users).then(id => { vals3[config.user['id']]=id; });
+                genererIdNum(user, config.user['id'], config.dn_users).then(id => { vals3[config.user['id']]=id; });
                 
                 // Stockage machine ; dépend du prénom
                 vals3[config.user['directory']] = '/hosting/users/' + data['givenName'][0];
@@ -1014,21 +951,21 @@ class superAdministrateurConnecte extends administrateurConnecte {
                 vals3[config.user['idNum']] ='5000';
     
                 // Inscription des valeurs calculées
-                LDAP.modifier(config.key_id+"="+vals[config.user['hruid']]+","+config.dn_users, "add", vals3).then(res => {
+                modifierLDAP(user, config.key_id+"="+vals[config.user['hruid']]+","+config.dn_users, "add", vals3).then(res => {
                     if (!res) { reject(false); }
                 });
     
                 ["posixAccount", "shadowAccount", "inetOrgPerson", "brAccount"].forEach(cst => {
                     let val3={};
                     vals3[config.user['class']]=cst;
-                    LDAP.modifier(config.key_id+"="+vals[config.user['hruid']]+","+config.dn_users, "add", vals3).then(res => {
+                    modifierLDAP(user, config.key_id+"="+vals[config.user['hruid']]+","+config.dn_users, "add", vals3).then(res => {
                         if (!res) { reject(false); }
                     });
                 });
     
                 // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
-                data['groupsIsMember'].forEach(gid => { this.ajouterMembreGroupe(vals[config.key_id], gid); });
-                data['groupsIsAdmin'].forEach(gid => { this.ajouterAdministrateurGroupe(vals[config.key_id], gid); });
+                data['groupsIsMember'].forEach(gid => { this.ajouterMembreGroupe(user, vals[config.key_id], gid); });
+                data['groupsIsAdmin'].forEach(gid => { this.ajouterAdministrateurGroupe(user, vals[config.key_id], gid); });
     
                 resolve(true);
             });
@@ -1043,26 +980,28 @@ class superAdministrateurConnecte extends administrateurConnecte {
     /**
      * @summary Fonction qui supprime un utilisateur du LDAP.
      * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement.
-     * Appelle {@link LDAP.supprimer} bien sûr, mais aussi {@link supprimerMembreGroupe} et {@link supprimerAdministrateurGroupe} pour gérer les groupes de l'utilisateur sortant.
+     * Appelle {@link supprimerLDAP} bien sûr, mais aussi {@link supprimerMembreGroupe} et {@link supprimerAdministrateurGroupe} pour gérer les groupes de l'utilisateur sortant.
+     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
      * @arg {string} uid - uid de la victime
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      */
-    supprimerUtilisateur(uid) {
+    supprimerUtilisateur(user, uid) {
         return new Promise((resolve, reject) => {
             // Gestion des groupes d'abord
-            super.renseignerSurUtilisateur(uid).then(profil => {
+            this.getUser(user, uid).then(profil => {
                 profil[config.user['groups']].forEach(gid => {
-                    test.etreAdministrateurGroupe(gid).then(res => {
-                        if (la.includes(res)) { this.supprimerAdministrateurGroupe(uid, gid); }
-                    }).then(res => { this.supprimerMembreGroupe(uid, gid); });
+                    this.isGroupAdmin(user, uid, gid).then(res => {
+                        if (this.la.includes(res)) { this.supprimerAdministrateurGroupe(user, uid, gid); }
+                    }).then(res => { this.removeGroupMember(user, uid, gid); });
                 });
             // Elimination
-            }).then(res => { this.LDAP.supprimer(config.key_id+"="+uid+","+config.dn_users); });
+            }).then(res => { supprimerLDAP(user, config.key_id+"="+uid+","+config.dn_users); });
         });
     }
 }
 
-//utilisateurAnonyme.trouverGroupesParTypes("faerix","binet").then(res => console.log(res));
+//var u =new utilisateurAnonyme();
+//u.trouverGroupesParTypes("faerix","binet").then(res => console.log(res));
 //repliquerTOL({"givenName":"almy"}).then(res => { console.log(res); });
 
 /* Partage pour le reste du monde ; même remarque syntaxe que pour l'import