diff --git a/src/ldap/export/group.ts b/src/ldap/export/group.ts index 4796b52eb2af89228f22b05f7fd5d3edf0b6f88e..8ead0ac3d67c215b07093de253fea08d40f51b70 100644 --- a/src/ldap/export/group.ts +++ b/src/ldap/export/group.ts @@ -128,26 +128,7 @@ export class Group { * @async * @static */ - static async remMember(uid: string, gid: string): Promise<boolean> { - return await Tools.remove(uid, gid, "members"); - - // Ce qui suit est une suppression récursive du membre dans tous les groupes fils - let stack = []; - let res = true; - let visited = {}; - stack.push(gid); - while (stack.length>0) { - let cur_id = stack.pop(); - if (visited[cur_id] == undefined) { - visited[cur_id] = true; - res = res && await Tools.remove(uid, cur_id, "admins") && - await Tools.remove(uid, cur_id, "speakers") && - await Tools.remove(uid, cur_id, "members"); - stack.concat(await Basics.searchSingle("group", ldapConfig.group.childs, cur_id)); - } - } - return res; - } + static async remMember(uid: string, gid: string): Promise<boolean> { return await Tools.remove(uid, gid, "members"); } /** * @memberof LDAP @@ -190,8 +171,8 @@ export class Group { // gid de base généré à partir du nom standardisé, pas à partir de l'entrée 'gid' ! try { - Tools.generateReadableId(data['name']).then(id => { - vals[ldapConfig.key_id]=id; + Tools.generateReadableId("group", data['name']).then(id => { + vals[ldapConfig.group.gid]=id; vals[ldapConfig.group['name']]=id; }); } @@ -199,7 +180,7 @@ export class Group { throw "Erreur lors de la génération d'un hruid pour créer un nouveau groupe."; } - let gid: string = vals[ldapConfig.key_id]; + let gid: string = vals[ldapConfig.group.gid]; // Ecriture de toutes les valeurs directement inscrites dans le LDAP for (let key_att in data) { vals[ldapConfig.group[key_att]]=data[key_att] }; diff --git a/src/ldap/export/user.ts b/src/ldap/export/user.ts index 0d192ecc74d850aae2f4de3ef300185bd2cb0f20..cd9c64304e7a143f1af0e6c05cc681b5a10df343 100644 --- a/src/ldap/export/user.ts +++ b/src/ldap/export/user.ts @@ -85,13 +85,13 @@ export class User { // 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 try { - Tools.generateUid(data['givenName'],data['lastName'],data['birthdate']).then(id => { vals[ldapConfig.key_id]=id; } ); + Tools.generateUid("user",data['givenName'],data['lastName'],data['birthdate']).then(id => { vals[ldapConfig.user.uid]=id; } ); } catch(err) { throw "Erreur lors de la génération d'un hruid pour un nouvel utilisateur."; } - let uid = vals[ldapConfig.key_id]; + let uid = vals[ldapConfig.user.uid]; // Génère une erreur si un champ n'est pas rempli for (let key_att in data) { diff --git a/src/ldap/internal/basics.ts b/src/ldap/internal/basics.ts index 942790db170d8ab1edc84477e9117a067b68b324..88a741b15b842a28ef4855d36b2c915aa8170634 100644 --- a/src/ldap/internal/basics.ts +++ b/src/ldap/internal/basics.ts @@ -197,8 +197,10 @@ export class Basics { */ static async change(domain: 'group'|'user', id: string, op: "add"|"del"|"replace", mod: dic) : Promise<boolean> { Basics.adminBind(); - let dn = ldapConfig.key_id+'='+id+',' - dn+=ldapConfig.dn[domain]; + let dn =""; + if (domain == 'group') { dn += ldapConfig.group.gid; } + else { dn += ldapConfig.user.uid; } + dn+='='+id+','+ldapConfig.dn[domain]; // Modification LDAP selon dn fourni en argument (pourrait prendre une liste de Changes) client.modify(ldapEscape.dn("${txt}", {txt: dn}), new ldap.Change({ operation: op, @@ -217,7 +219,7 @@ export class Basics { * @summary Fonction qui permet de rajouter un élément sur le LDAP. * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add). * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) - * @arg {Object.<string, string>} vals - Dictionnaire contenant les valeurs à créer (contient un champ en ldapConfig.key_id) + * @arg {Object.<string, string>} vals - Dictionnaire contenant les valeurs à créer (contient un champ en ldapConfig) * @arg {Object} vals[key] - Nouvelle valeur pour le champ key * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon. * @static @@ -225,7 +227,9 @@ export class Basics { */ static async add(domain: 'group'|'user', vals) : Promise<boolean> { Basics.adminBind(); - let dn = ldapConfig.key_id+"="+vals[ldapConfig.key_id]; + let dn = ""; + if (domain == "group") { dn+=ldapConfig.group.gid+"="+vals[ldapConfig.group.gid]; } + else { dn+=ldapConfig.user.uid+"="+vals[ldapConfig.user.uid]; } dn+=ldapConfig.dn[domain]; // Ajout LDAP selon la ldapConfiguration en argument client.add(ldapEscape.dn("${txt}", { txt: dn}), vals, err => { @@ -249,7 +253,9 @@ export class Basics { */ static async clear(domain: 'group'|'user', id: string) : Promise<boolean> { Basics.adminBind(); - let dn = ldapConfig.key_id+'='+id+',' + let dn = ""; + if (domain == "group") { dn+=ldapConfig.group.gid+"="+id; } + else { dn+=ldapConfig.user.uid+"="+id; } dn+=ldapConfig.dn[domain]; // Suppression LDAP client.del(ldapEscape.dn("${txt}", {txt: dn}), err => { diff --git a/src/ldap/internal/tools.ts b/src/ldap/internal/tools.ts index 1c5a6b2f6ac6551d201c1773301bd6921dddd8b5..1879fbd4e65a1ccd879fd4970feba1cd1725f7ef 100644 --- a/src/ldap/internal/tools.ts +++ b/src/ldap/internal/tools.ts @@ -84,8 +84,10 @@ export class Tools { }); } } - // Appel avec filtre de l'espace - return Basics.searchSingle(domain, ldapConfig.key_id, null, filter); + // Appel avec filtre de l'espace + if (domain == "group") { var att=ldapConfig.group.gid; } + else { var att=ldapConfig.user.uid; } + return Basics.searchSingle(domain, att, null, filter); } /** @@ -241,7 +243,9 @@ export class Tools { static async ensureUnique(value: string, attribute: string, domain: 'group'|'user', changeValue: (string, number) => string, n: number=0) : Promise<string> { // Recherche d'autres occurences de l'id try { - return Basics.searchSingle(domain, ldapConfig.key_id, null, "("+attribute+"="+value+")").then(function (matches: string[]) { + if (domain == "group") { var att=ldapConfig.group.gid; } + else { var att=ldapConfig.user.uid; } + return Basics.searchSingle(domain, att, null, "("+attribute+"="+value+")").then(function (matches: string[]) { if (!matches) { throw ""; } // On renvoit la valeur si elle est bien unique else if (matches.length=0) { return value; } @@ -258,6 +262,7 @@ export class Tools { * @memberof LDAP * @summary Cette fonction génère un uid standard, puis le fait évoluer jusqu'à ce qu'il soit unique. * @desc Limité à un appel à {@link Tools.ensureUnique} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation). + * @param {"group"|"user"} domain - Arbre à parcourir * @param {string} givenName - Prénom * @param {string} lastName - Nom * @param {string} promotion - Année de promotion @@ -265,10 +270,12 @@ export class Tools { * @static * @async */ - static async generateUid(givenName: string, lastName: string, promotion: string) : Promise<string> { + static async generateUid(domain : "group"|"user", givenName: string, lastName: string, promotion: string) : Promise<string> { try { + if (domain == "group") { var att=ldapConfig.group.gid; } + else { var att=ldapConfig.user.uid; } // normalize et lowerCase standardisent le format - return Tools.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), ldapConfig.key_id, "user", (id: string, n: number) => { + return Tools.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), att, "user", (id: string, n: number) => { if (n=1) { id+='.'+promotion; } // Si prénom.nom existe déjà , on rajoute la promo else if (n=2) { id+='.'+(n-1).toString(); } // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1 else if (n>2) { id+=n; } // Ensuite on continue .123, .1234, etc... @@ -284,15 +291,18 @@ export class Tools { * @memberof LDAP * @summary Cette fonction génère un id lisible, puis le fait évoluer jusqu'à ce qu'il soit unique. * @desc Limité à un appel à {@link Tools.ensureUnique} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation). + * @param {"group"|"user"} domain - Arbre à parcourir * @param {string} name - Nom * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié * @static * @async */ - static async generateReadableId(name: string) : Promise<string> { + static async generateReadableId(domain : "group"|"user", name: string) : Promise<string> { try { + if (domain == "group") { var att=ldapConfig.group.gid; } + else { var att=ldapConfig.user.uid; } // normalize et lowerCase standardisent le format - return Tools.ensureUnique(name.toLowerCase().normalize('UFD'), ldapConfig.key_id, "group", (id: string, n: number) => { + return Tools.ensureUnique(name.toLowerCase().normalize('UFD'), att, domain, (id: string, n: number) => { if (n=1) { id+='.'+n.toString(); } // Si nom existe déjà , on essaie nom.1 else if (n>1) { id+=n.toString(); } // Ensuite on continue .12, .123, etc... return id; @@ -306,15 +316,15 @@ export class Tools { /** * @memberof LDAP * @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 {string} attribut - Intitulé exact de l'id concerné + * @param {string} attribute - Intitulé exact de l'id concerné * @param {"gr"|"us"} domain - Domaine dans lequel l'attribut doit être unique * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié * @static * @async */ - static async generateId(attribut: string, domain: "group"|"user") : Promise<string> { + static async generateId(attribute: string, domain: "group"|"user") : Promise<string> { try { - return Tools.ensureUnique("0", attribut, domain, (id,n) => { return Math.floor((Math.random() * 100000) + 1).toString(); }); + return Tools.ensureUnique("0", attribute, domain, (id,n) => { return Math.floor((Math.random() * 100000) + 1).toString(); }); } catch(err) { throw "Erreur lors de l'assurance de l'unicité d'un unique identifier numérique."; @@ -336,28 +346,6 @@ export class Tools { static async get(id : string, domain : "user"|"group", category : string): Promise<string[]> { try { return await Basics.searchSingle(domain, ldapConfig[domain][category], id); - - // Ce qui suit est une récursion qui sera déplacée dans la gestion des autorisations - if (!(category in ["admins","members"]) || domain=="user") { - return await Basics.searchSingle(domain, ldapConfig[domain][category], id); - } - else { - // Clean depth-first search for inherited members and admins - let stack = []; - let res = []; - let visited = {}; - stack.push(id); - while (stack.length>0) { - let cur_id = stack.pop(); - if (visited[cur_id] == undefined) { - visited[cur_id] = true; - res.concat(await Basics.searchSingle("group", ldapConfig.group[category], cur_id)); - // In the end, the precise category only changes the iteration direction - if (category == "members") { stack.concat(await Basics.searchSingle("group", ldapConfig.group.childs, cur_id)); } - else { stack.concat(await Basics.searchSingle("group", ldapConfig.group.parents, cur_id)); } - } - } - } } catch(err) { throw "Erreur lors d'une recherche générique d'un membre d'une certaine catégorie d'un groupe.";