From ec12c7742212d025ed7380dfc6869e6bf22fff01 Mon Sep 17 00:00:00 2001 From: Oliver Facklam <oliver.facklam.lfgeb@gmail.com> Date: Mon, 14 Jan 2019 23:21:34 +0100 Subject: [PATCH] Tentative. ATTENTION DANGER INJECTION Ne fonctionne tjrs pas --- src/config_passport.js | 6 ++--- src/ldap/export/group.ts | 16 ++++++------- src/ldap/export/user.ts | 46 ++++++++++++++++++------------------ src/ldap/internal/basics.ts | 47 ++++++++++++++++++++++--------------- src/ldap/internal/tools.ts | 18 ++++++++------ 5 files changed, 73 insertions(+), 60 deletions(-) diff --git a/src/config_passport.js b/src/config_passport.js index 33a86aa..ea19c80 100644 --- a/src/config_passport.js +++ b/src/config_passport.js @@ -40,8 +40,8 @@ passport.use(new LdapStrategy({ url: ldapConfig.server, //bindDn: '.............', //bindCredentials: '..........', - // searchBase: ldapConfig.searchBase, TODO: this cannot be left empty. - // searchFilter: ldapConfig.searchFilter, TODO: this cannot be left empty. + searchBase: "ou=eleves,dc=frankiz,dc=net",//ldapConfig.searchBase, TODO: this cannot be left empty. + searchFilter: "(uid={{username}})"//ldapConfig.searchFilter, TODO: this cannot be left empty. //searchAttributes: ['givenName', 'sn'], //tlsOptions: '..........', }, @@ -85,6 +85,6 @@ passport.serializeUser(function (user, done) { * > This user object is attached to the request as req.user making it accessible in our request handling. (available in all subsequent middleware) */ passport.deserializeUser(function (userUid, done) { - // console.log(`passport.deserializeUser(): deserializing user ${userUid}`); // DEBUG + console.log(`passport.deserializeUser(): deserializing user ${userUid}`); // DEBUG done(null, { uid: userUid }); }); diff --git a/src/ldap/export/group.ts b/src/ldap/export/group.ts index 7f9f11f..2c2bb8a 100644 --- a/src/ldap/export/group.ts +++ b/src/ldap/export/group.ts @@ -16,13 +16,13 @@ import {Tools} from '../internal/tools'; * @var {string[]} admins - Liste des admins du groupe ; supposée être une sous-liste de la précédente * @var {string} description - Description du groupe (facultatif) */ -export interface groupData { - "gid": string, - "name": string, - "type": string, - "members": string[], - "admins": string[], - "description"?: string +export class groupData { + "gid": string; + "name": string; + "type": string; + "members": string[]; + "admins": string[]; + "description"?: string; } //------------------------------------------------------------------------------------------------------------------------ @@ -49,7 +49,7 @@ export class Group { */ static async peek(gid: string) : Promise<groupData> { try { - return Tools.peek<groupData>("gr", gid); + return Tools.peek<groupData>("gr", gid, groupData); } catch(err) { throw "Erreur lors d'une recherche d'informations sur un groupe."; diff --git a/src/ldap/export/user.ts b/src/ldap/export/user.ts index b50f668..8eb37d2 100644 --- a/src/ldap/export/user.ts +++ b/src/ldap/export/user.ts @@ -33,28 +33,28 @@ import {Group} from './group'; * @var {string[]} admins - Liste des gid dont l'utilisateur est admin ; supposé sous-liste de groups * TBA @var {string[]} likes - Liste des gid dont l'utilisateur est sympathisant */ -export interface userData { - uid?: string, - groups?: string[], - groupsIsAdmin?: string[], - password?: string, - givenName?: string, - lastName?: string, - nickname?: string, - promotion?: string, - photo?: string, - birthdate?: string, - nationality?: string, - phone?: string, - address?: string, - mail?: string, - ips?: string[], - directory?: string, - login?: string, - readPerm?: string, - writePerm?: string, - forlifes?: string[], - sport?: string +export class userData { + uid?: string; + groups?: string[]; + groupsIsAdmin?: string[]; + password?: string; + givenName?: string; + lastName?: string; + nickname?: string; + promotion?: string; + photo?: string; + birthdate?: string; + nationality?: string; + phone?: string; + address?: string; + mail?: string; + ips?: string[]; + directory?: string; + login?: string; + readPerm?: string; + writePerm?: string; + forlifes?: string[]; + sport?: string; //"likes"?: string[] } @@ -82,7 +82,7 @@ export class User { */ static async peek(uid: string) : Promise<userData> { try { - return Tools.peek<userData>("us", uid); + return Tools.peek<userData>("us", uid, userData); } catch(err) { throw "Error while peeking a user."; diff --git a/src/ldap/internal/basics.ts b/src/ldap/internal/basics.ts index b96736d..c14dbb9 100644 --- a/src/ldap/internal/basics.ts +++ b/src/ldap/internal/basics.ts @@ -98,30 +98,38 @@ export class Basics { * @static * @async */ - static search(domain: 'gr'|'us', attributes: string[], id: string, filter: string, handler : (entry: any) => void) : void { + static search(domain: 'gr'|'us', attributes: string[], id: string, filter: string, handler : (entry: any) => void) : Promise<void> { Basics.adminBind(); let dn =""; - if (id != null) { dn+=ldapConfig.key_id+'='+id+','; } + if (id != null) { dn+=ldapConfig.key_id+'='+ ldapEscape.dn("${txt}", { txt: id}) +','; } if (domain == "gr") { dn+=ldapConfig.dn_groups; } else { dn+=ldapConfig.dn_users; } // Interrogation LDAP selon filter - client.search(ldapEscape.dn("${txt}", { txt: dn}), { // Must be escaped in case of a malignious false id - "scope": "sub", - "filter": ldapEscape.filter("${txt}", { txt: filter}), // Must be escaped in case of a malignious search arg - "attributes": attributes - }, (err, res) => { - // Gestion erreur ; pb car pas simple true / autre en sortie - if (err) { - throw "Erreur lors de la recherche sur le LDAP."; - } else { - // Dès que la recherche renvoit une entrée, on stocke les attributs qui nous intéresse - res.on('searchEntry', entry => { handler(entry); }); - // Si la recherche renvoie une erreur, on renvoit - res.on('error', resErr => { throw resErr; }); - // Quand la recherche est finie on se déconnecte - res.on('end', _ => { Basics.unbind(); }); - } + console.log(dn); + //filter = ldapEscape.filter("${txt}", { txt: filter }); + console.log(filter); + + let promise = new Promise<void>(function(resolve, reject) { + client.search(dn, { // Must be escaped in case of a malignious false id + "scope": "sub", + "filter": filter, // Must be escaped in case of a malignious search arg + "attributes": attributes + }, (err, res) => { + // Gestion erreur ; pb car pas simple true / autre en sortie + if (err) { + throw "Erreur lors de la recherche sur le LDAP."; + } else { + // Dès que la recherche renvoit une entrée, on stocke les attributs qui nous intéresse + res.on('searchEntry', entry => { handler(entry); }); + // Si la recherche renvoie une erreur, on renvoit + res.on('error', resErr => { throw resErr; }); + // Quand la recherche est finie on se déconnecte + res.on('end', _ => { Basics.unbind(); resolve(); }); + } + }); }); + + return promise; } /** @@ -162,8 +170,9 @@ export class Basics { */ static async searchMultiple(domain: 'gr'|'us', attributes: string[], id: string=null, filter: string="(objectClass=*)") : Promise<Array<dic>> { let vals=[]; - Basics.search(domain, attributes, id, filter, entry => { + await Basics.search(domain, attributes, id, filter, entry => { // Cas plusieurs attributs donc résultat dictionnaire + console.log("Found entry!!"); vals.push({}); attributes.forEach(attribute => { vals.slice(-1)[0][attribute]=entry.object[attribute]; diff --git a/src/ldap/internal/tools.ts b/src/ldap/internal/tools.ts index cb79122..d22325a 100644 --- a/src/ldap/internal/tools.ts +++ b/src/ldap/internal/tools.ts @@ -32,19 +32,23 @@ export class Tools { * @static * @async */ - static async peek<T>(domain: 'us'|'gr', id: string) : Promise<T> { - if (domain='gr') { + static async peek<T>(domain: 'us'|'gr', id: string, type: new () => T) : Promise<T> { + if (domain=='gr') { var dirtyKeys = ldapConfig.group; } else { var dirtyKeys = ldapConfig.user; } - let cleanData : T; - let dirtyData = await Basics.searchMultiple(domain, dirtyKeys.values(), id)[0]; + let cleanData : T = new type(); + let attr = Object.keys(dirtyKeys).map(key => dirtyKeys[key]); + //console.log(attr); + let dirtyData = await Basics.searchMultiple(domain, attr, id); + //console.log(dirtyData[0]); // Rename output - for (let uncleanKey in dirtyData) { - for (let cleanKey in cleanData) { - if (uncleanKey=dirtyKeys[cleanKey]) { cleanData[cleanKey] = dirtyData[uncleanKey]; } + for (let uncleanKey in dirtyData[0]) { + for (let cleanKey of Object.keys(cleanData)) { + //console.log(cleanKey); + if (uncleanKey==dirtyKeys[cleanKey]) { cleanData[cleanKey] = dirtyData[uncleanKey]; } } } return cleanData; -- GitLab