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