From d7de03f50ed88b6cf4bf9f854fc132f0e97ae375 Mon Sep 17 00:00:00 2001 From: hawkspar <quentin.chevalier@polytechnique.edu> Date: Sat, 13 Oct 2018 11:36:47 +0200 Subject: [PATCH] fix ts --- src/graphql/connectors/authentifiers.js | 4 +- src/graphql/connectors/connectors.js | 2 +- src/graphql/typeDefs/actions_wish_list.gql | 6 +- src/graphql/typeDefs/objects.graphql | 2 +- src/ldap/admins.ts | 84 +++++++++++----------- src/ldap/basics.ts | 16 ++--- src/ldap/config.ts | 6 +- src/ldap/users.ts | 80 ++++++++++----------- src/ldap/utilities.ts | 48 ++++++------- tsconfig.json | 3 +- 10 files changed, 124 insertions(+), 127 deletions(-) diff --git a/src/graphql/connectors/authentifiers.js b/src/graphql/connectors/authentifiers.js index 9f9271f..4ad92cd 100644 --- a/src/graphql/connectors/authentifiers.js +++ b/src/graphql/connectors/authentifiers.js @@ -7,8 +7,8 @@ import knex from '../../../db/knex_router.js'; import * as connectors from './connectors.js'; import * as selectors from './selectors.js'; import * as list_selectors from './list_selectors.js'; -import {Open as LDAPOpen, User as LDAPUser} from '../../ldap/users.js'; -import {Admin as LDAPAdmin, Supervisor as LDAPSupervisor} from '../../ldap/admins.js'; +import {Open as LDAPOpen, User as LDAPUser} from '../../ldap/users'; +import {Admin as LDAPAdmin, Supervisor as LDAPSupervisor} from '../../ldap/admins'; /** * @summary Place-holder permettant de concaténer utilisateur et permissions dans un seul objet diff --git a/src/graphql/connectors/connectors.js b/src/graphql/connectors/connectors.js index 69f4d08..f1d017e 100644 --- a/src/graphql/connectors/connectors.js +++ b/src/graphql/connectors/connectors.js @@ -5,7 +5,7 @@ import knex from '../../../db/knex_router'; import * as selectors from './selectors'; import * as list_selectors from './list_selectors'; -import {Open as LDAPOpen, User as LDAPUser} from '../../ldap/users.js'; +import {Open as LDAPOpen, User as LDAPUser} from '../../ldap/users'; const utilisateur = new LDAPOpen(); diff --git a/src/graphql/typeDefs/actions_wish_list.gql b/src/graphql/typeDefs/actions_wish_list.gql index 30e560e..1204069 100644 --- a/src/graphql/typeDefs/actions_wish_list.gql +++ b/src/graphql/typeDefs/actions_wish_list.gql @@ -1,12 +1,12 @@ -// ce fichier en .gql sert juste a forcer VSCode a colorier correctement le langage graphQL. -// son contenu sera copie dans actions.js tout simplement +# ce fichier en .gql sert juste a forcer VSCode a colorier correctement le langage graphQL. +# son contenu sera copie dans actions.js tout simplement /** * @file définit les types query et mutation, points d'entree du schéma graphQL. ce fichier est la wish list de kadabra (qui veut avoir un schema clair pour travailler sereinement sur le front) * @author akka vodol, kadabra */ -// hawkspar->akka ; pas clair +# hawkspar->akka ; pas clair const RootQuery = ` # Requêtes diff --git a/src/graphql/typeDefs/objects.graphql b/src/graphql/typeDefs/objects.graphql index 8064102..47ba8ea 100644 --- a/src/graphql/typeDefs/objects.graphql +++ b/src/graphql/typeDefs/objects.graphql @@ -1,4 +1,4 @@ -// hawkspar->all ; doc ? +# hawkspar->all ; doc ? # Utilisateurs type User { diff --git a/src/ldap/admins.ts b/src/ldap/admins.ts index 6c4c441..0fc7b87 100644 --- a/src/ldap/admins.ts +++ b/src/ldap/admins.ts @@ -4,7 +4,7 @@ * @author hawkspar */ -import {config} from './config'; +import {ldapConfig} from './config'; import {LDAP} from './basics'; import {Tests} from './utilities'; import { Open, User, userData, groupData } from './users'; @@ -54,9 +54,9 @@ export class Admin extends User { let lm = await Open.getMembers(gid); if (!lm.includes(uid)) { let vals = {}; - vals[config.groups.member] = uid; + vals[ldapConfig.groups.member] = uid; // Erreur si pb lors de la modification - if (!await LDAP.change(config.key_id+gid+config.dn_groups, "add", vals)) { + if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "add", vals)) { throw "Erreur lors de la modification dans l'arbre des groupes pour ajouter un membre."; } } @@ -69,9 +69,9 @@ export class Admin extends User { let lg = await Open.getGroups(uid); if (!lg.includes(gid)) { let vals2 = {}; - vals2[config.users.groups] = gid; + vals2[ldapConfig.users.groups] = gid; // Erreur si pb lors de la modification - if (!await LDAP.change(config.key_id+uid+config.dn_users, "add", vals2)) { + if (!await LDAP.change(ldapConfig.key_id+uid+ldapConfig.dn_users, "add", vals2)) { throw "Erreur lors de la modification dans l'arbre des utilisateurs pour ajouter un membre."; } } @@ -97,7 +97,7 @@ export class Admin extends User { let lm = await Open.getMembers(gid); if (lm.includes(uid)) { // Supprime tous les utilisateurs - if (!await LDAP.change(config.key_id+gid+config.dn_groups, "del", config.group.member)) { + if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "del", ldapConfig.group.member)) { throw "Erreur lors de la suppression de tous les membres du groupe."; } // Les rajoute un par un, sauf pour le supprimé @@ -118,7 +118,7 @@ export class Admin extends User { // Vérifie que l'utilisateur est pas déjà viré pour users if (lg.includes(gid)) { // Supprime tous les groupes - if (!await LDAP.change(config.key_id+uid+config.dn_users, "del", config.member.groups)) { + if (!await LDAP.change(ldapConfig.key_id+uid+ldapConfig.dn_users, "del", ldapConfig.member.groups)) { throw "Erreur lors de la suppression de tous les groupes du membre."; } // Les rajoute un par un, sauf pour le supprimé @@ -155,8 +155,8 @@ export class Admin extends User { if (!la.includes(uid)) { // Finalement modification, uniquement dans groups let vals = {}; - vals[config.groups.admin] = uid; - if (!await LDAP.change(config.key_id+gid+config.dn_groups, "add", vals)) { + vals[ldapConfig.groups.admin] = uid; + if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "add", vals)) { throw "Erreur lors de l'ajout de l'admin dans l'arbre des groupes."; } } @@ -184,7 +184,7 @@ export class Admin extends User { let la = await Open.getAdmins(gid); if (la.includes(uid)) { // Supprime tous les administrateurs - if (!await LDAP.change(config.key_id+gid+config.dn_groups, "del", config.group.admin)) { throw "Erreur dans la suppression de tous les admins pour en supprimer un."; } + if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "del", ldapConfig.group.admin)) { throw "Erreur dans la suppression de tous les admins pour en supprimer un."; } // Les rajoute un par un, sauf pour le supprimé la.forEach(id => { if (id!=uid) { Admin.addGroupAdmin(id, gid).then(res => { @@ -218,8 +218,8 @@ export class Admin extends User { let profil = await Open.peekGroup(gid); // Reecriture de profil avec les bons champs Object.keys(profil).forEach(keyLDAP => { - Object.keys(config.group).forEach(keyAlias => { - config.group[keyAlias]=keyLDAP; + Object.keys(ldapConfig.group).forEach(keyAlias => { + ldapConfig.group[keyAlias]=keyLDAP; profil[keyAlias]=profil[keyLDAP]; }); }); @@ -254,14 +254,14 @@ export class Admin extends User { // Gestion des membres et administrateurs d'abord let profil = await Open.peekGroup(gid); // Ordre important - profil[config.group['admin']].forEach( id => { + profil[ldapConfig.group['admin']].forEach( id => { this.delGroupAdmin( id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un admin d'un groupe en cours de suppression."; } }); }); - profil[config.group['member']].forEach(id => { + profil[ldapConfig.group['member']].forEach(id => { this.delGroupMember(id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un membre."; } }); }); // Elimination - if (!await LDAP.clear(config.key_id+"="+gid+","+config.dn_groups)) { throw "Erreur lors de la suppression de la feuille dans l'arbre des groupes."; } + if (!await LDAP.clear(ldapConfig.key_id+"="+gid+","+ldapConfig.dn_groups)) { throw "Erreur lors de la suppression de la feuille dans l'arbre des groupes."; } return true; } catch(err) { @@ -297,7 +297,7 @@ export class Supervisor extends Admin { // 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 { - Tests.generateUid(data['givenName'],data['lastName'],data['promotion']).then(id => { vals[config.key_id]=id; } ); + Tests.generateUid(data['givenName'],data['lastName'],data['promotion']).then(id => { vals[ldapConfig.key_id]=id; } ); } catch(err) { throw "Erreur lors de la génération d'un hruid pour un nouvel utilisateur."; @@ -305,18 +305,18 @@ export class Supervisor extends Admin { // 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]); + ldapConfig.user.direct_input.forEach(key_att => vals[ldapConfig.user[key_att]]=data[key_att]); // Appel à la fonction de base - if (!await LDAP.add(config.key_id+"="+vals[config.key_id]+","+config.dn_users, vals)) { throw "Erreur de l'ajout de la feuille à l'arbre utilisateur."; } + if (!await LDAP.add(ldapConfig.key_id+"="+vals[ldapConfig.key_id]+","+ldapConfig.dn_users, vals)) { throw "Erreur de l'ajout de la feuille à l'arbre utilisateur."; } // Modifications multiples pour avoir plusieurs champs de même type ; boucle sur les attributs multiples - config.user.multiple_input.forEach(key_att => { + ldapConfig.user.multiple_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.change(config.key_id+"="+vals[config.key_id]+","+config.dn_users, "add", vals2).then(res => { + vals2[ldapConfig.user[key_att]]=val; + LDAP.change(ldapConfig.key_id+"="+vals[ldapConfig.key_id]+","+ldapConfig.dn_users, "add", vals2).then(res => { if (!res) { throw "Erreur lors de l'ajout d'une valeur pour un champ à valeurs multiples à la feuille du nouvel utilisateur."; } }); }); @@ -326,64 +326,64 @@ export class Supervisor extends Admin { let vals3={}; // Création d'un nom complet lisible - vals3[config.user['fullName']]=data['givenName']+' '+data['lastName'].toUpperCase(); + vals3[ldapConfig.user['fullName']]=data['givenName']+' '+data['lastName'].toUpperCase(); - // Configuration du mot de passe utilisateur + // ldapConfiguration du mot de passe utilisateur // Le préfixe {CRYPT} signifie que le mdp est hashé dans OpenLDAP voir : https://www.openldap.org/doc/admin24/security.html - vals3[config.user['password']] = "{CRYPT}"+data['password']; + vals3[ldapConfig.user['password']] = "{CRYPT}"+data['password']; // Ecriture d'un surnom s'il y a lieu if ((data['nickname']!=undefined) && (data['nickname']!='')) { - vals3[config.user['nickname']]=data['nickname']; + vals3[ldapConfig.user['nickname']]=data['nickname']; } try { // Génération id aléatoire unique - vals3[config.user['id']]= await Tests.generateId(config.user['id'], config.dn_users); + vals3[ldapConfig.user['id']]= await Tests.generateId(ldapConfig.user['id'], ldapConfig.dn_users); } catch(err) { throw "Erreur lors de la génération d'un id numérique pour un nouvel utilisateur."; } // Stockage machine ; dépend du prénom - vals3[config.user['directory']] = '/hosting/users/' + data['givenName'][0]; + vals3[ldapConfig.user['directory']] = '/hosting/users/' + data['givenName'][0]; // Code root - vals3[config.user['cleanFullName']]=data['fullName'].replace(':', ';').toLowerCase().normalize('UFD'); + vals3[ldapConfig.user['cleanFullName']]=data['fullName'].replace(':', ';').toLowerCase().normalize('UFD'); // Adressage root - if (data['groups'].includes("on_platal")) { vals3[config.user['login']] = "/bin/bash"; } - else { vals3[config.user['login']] = "/sbin/nologin"; } + if (data['groups'].includes("on_platal")) { vals3[ldapConfig.user['login']] = "/bin/bash"; } + else { vals3[ldapConfig.user['login']] = "/sbin/nologin"; } // Permissions BR - vals3[config.user['readPerm']] = 'br.*,public.*'; - if (data['readPerm'].length>0) { vals3[config.user['readPerm']] += ',' + data['readPerm']; } - vals3[config.user['writePerm']] = 'br.*,!br.blague-du-jour,public.*,!br.campagnekes'; - if (data['writePerm'].length>0) { vals3[config.user['readPerm']] += ',' + data['writePerm']; } + vals3[ldapConfig.user['readPerm']] = 'br.*,public.*'; + if (data['readPerm'].length>0) { vals3[ldapConfig.user['readPerm']] += ',' + data['readPerm']; } + vals3[ldapConfig.user['writePerm']] = 'br.*,!br.blague-du-jour,public.*,!br.campagnekes'; + if (data['writePerm'].length>0) { vals3[ldapConfig.user['readPerm']] += ',' + data['writePerm']; } // Valeur nécessaire ASKIP mais inutile - vals3[config.user['idNum']] ='5000'; + vals3[ldapConfig.user['idNum']] ='5000'; // Inscription des valeurs calculées - if (!await LDAP.change(config.key_id+"="+vals[config.user['hruid']]+","+config.dn_users, "add", vals3)) { + if (!await LDAP.change(ldapConfig.key_id+"="+vals[ldapConfig.user['hruid']]+","+ldapConfig.dn_users, "add", vals3)) { throw "Erreur lors de l'ajout des valeurs calculées à la feuille du nouvel utilisateur."; } ["posixAccount", "shadowAccount", "inetOrgPerson", "brAccount"].forEach(cst => { let val3={}; - vals3[config.user['class']]=cst; - LDAP.change(config.key_id+"="+vals[config.user['hruid']]+","+config.dn_users, "add", vals3).then(res => { + vals3[ldapConfig.user['class']]=cst; + LDAP.change(ldapConfig.key_id+"="+vals[ldapConfig.user['hruid']]+","+ldapConfig.dn_users, "add", vals3).then(res => { if (!res) { throw "Erreur lors de l'ajout d'une valeur constante à la feuille du nouvel utilisateur."; } }); }); // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble data['groupsIsMember'].forEach(gid => { - Admin.addGroupMember(vals[config.key_id], gid).then(res => { + Admin.addGroupMember(vals[ldapConfig.key_id], gid).then(res => { if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe."; } }); }); data['groupsIsAdmin'].forEach(gid => { - Admin.addGroupAdmin( vals[config.key_id], gid).then(res => { + Admin.addGroupAdmin( vals[ldapConfig.key_id], gid).then(res => { if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe en tant qu'admin."; } }); }); @@ -408,7 +408,7 @@ export class Supervisor extends Admin { try { // Gestion des groupes d'abord let profil = await Open.peekUser(uid); - profil[config.user['groups']].forEach(gid => { + profil[ldapConfig.user['groups']].forEach(gid => { if (Open.isGroupAdmin(uid,gid)) { if (!Admin.delGroupAdmin(uid, gid)) { throw "Erreur lors de la suppression des droits d'admin de l'utilisateur."; } } @@ -419,6 +419,6 @@ export class Supervisor extends Admin { throw "Erreur lors de l'obtention des informations de l'utilisateur à supprimer."; } // Elimination - if (!LDAP.clear(config.key_id+"="+uid+","+config.dn_users)) { throw "Erreur lors de la suppression de l'utilisateur."; } + if (!LDAP.clear(ldapConfig.key_id+"="+uid+","+ldapConfig.dn_users)) { throw "Erreur lors de la suppression de l'utilisateur."; } } } \ No newline at end of file diff --git a/src/ldap/basics.ts b/src/ldap/basics.ts index 5607e68..6098b32 100644 --- a/src/ldap/basics.ts +++ b/src/ldap/basics.ts @@ -10,14 +10,14 @@ import ldap from 'ldapjs'; // Toutes les entrées utilisateur sont escapées par sécurité import ldapEscape from 'ldap-escape'; -// Fichier de config du ldap -import {config, credentialsConfig} from './config'; +// Fichier de ldapConfig du ldap +import {ldapConfig, credentialsLdapConfig} from './config'; // Important ; permet de vérifier que l'utilisateur reste connecté. //var ensureLoggedin = require('connect-ensure-login').ensureLoggedIn; //hawkspar->manifold : est-ce encore utile ? je ne crois pas // Connection au serveur LDAP avec des temps de timeout arbitraires -var client = ldap.createClient({ url: config.server}); +var client = ldap.createClient({ url: ldapConfig.server}); //------------------------------------------------------------------------------------------------------------------------ // Fonctions de base agissant sur le LDAP @@ -63,7 +63,7 @@ export class LDAP { * @static * @async */ - static async adminBind() { return this.bind(credentialsConfig.dn, credentialsConfig.password); } + static async adminBind() { return this.bind(credentialsLdapConfig.dn, credentialsLdapConfig.password); } /** * @summary Fonction qui sert à se déconnecter du LDAP. @@ -91,7 +91,7 @@ export class LDAP { this.adminBind(); return new Promise((resolve, reject) => { let vals=[]; - // Interrogation LDAP selon configuration fournie en argument + // Interrogation LDAP selon ldapConfiguration fournie en argument client.search(ldapEscape.dn("${txt}", { txt: dn}), { "scope": "sub", "filter": ldapEscape.filter("${txt}", { txt: filter}), @@ -143,7 +143,7 @@ export class LDAP { static async change(dn: string, op: string, mod) { this.adminBind(); return new Promise((resolve, reject) => { - // Modification LDAP selon configuration en argument (pourrait prendre une liste de Changes) + // Modification LDAP selon ldapConfiguration en argument (pourrait prendre une liste de Changes) client.modify(ldapEscape.dn("${txt}", {txt: dn}), new ldap.Change({ operation: ldapEscape.dn("${txt}", {txt: op}), modification: mod, @@ -171,8 +171,8 @@ export class LDAP { static async add(dn: string, vals) { this.adminBind(); return new Promise((resolve, reject) => { - // Ajout LDAP selon la configuration en argument - client.add(ldapEscape.dn(config.key_id+"="+vals[config.key_id]+",${txt}", { txt: dn}), vals, err => { + // Ajout LDAP selon la ldapConfiguration en argument + client.add(ldapEscape.dn(ldapConfig.key_id+"="+vals[ldapConfig.key_id]+",${txt}", { txt: dn}), vals, err => { reject(err); throw "Erreur lors d'une opération d'ajout sur le LDAP."; }); diff --git a/src/ldap/config.ts b/src/ldap/config.ts index 38368e8..b5f4a02 100644 --- a/src/ldap/config.ts +++ b/src/ldap/config.ts @@ -8,9 +8,9 @@ import colors from 'colors'; // Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement console.log(colors.cyan("Loading LDAP config file from config.json")); console.log(colors.cyan("Loading LDAP credentials from connexion_config.json")); -export const config = JSON.parse(fs.readFileSync('config.json').toString()); -export const credentialsConfig = JSON.parse(fs.readFileSync('connexion_config.json').toString()); +export const ldapConfig = JSON.parse(fs.readFileSync('config.json').toString()); +export const credentialsLdapConfig = JSON.parse(fs.readFileSync('connexion_config.json').toString()); // Override config server from environment if (process.env.LDAP_URI != null) { - config.ldap.server = process.env.LDAP_URI; + ldapConfig.ldap.server = process.env.LDAP_URI; } \ No newline at end of file diff --git a/src/ldap/users.ts b/src/ldap/users.ts index 1924ef0..da18234 100644 --- a/src/ldap/users.ts +++ b/src/ldap/users.ts @@ -4,7 +4,7 @@ * @author hawkspar */ -import {config} from './config'; +import {ldapConfig} from './config'; import {LDAP} from './basics'; import {searchUserFields, SmartSearch, Tests} from './utilities.js'; import {Admin, Supervisor} from './admins.js'; @@ -76,7 +76,7 @@ export class Open { */ static async getGroups(uid: string) { try { - return LDAP.search(config.key_id+uid+config.dn_users, config.user.groups)[0]; + return LDAP.search(ldapConfig.key_id+uid+ldapConfig.dn_users, ldapConfig.user.groups)[0]; } catch(err) { throw "Erreur lors de la recherche des groupes d'un individu."; @@ -85,7 +85,7 @@ export class Open { /** * @summary Fonction qui retrouve la liste des membres d'un groupe. - * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans config.json. + * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans ldapConfig.json. * @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 @@ -93,7 +93,7 @@ export class Open { */ static async getMembers(gid: string) { try { - return LDAP.search(config.key_id+gid+config.dn_users, config.group.member)[0]; + return LDAP.search(ldapConfig.key_id+gid+ldapConfig.dn_users, ldapConfig.group.member)[0]; } catch(err) { throw "Erreur lors de la recherche des membres d'un groupe."; @@ -102,7 +102,7 @@ export class Open { /** * @summary Fonction qui retrouve la liste des admins d'un groupe. - * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans config.json. + * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans ldapConfig.json. * @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 @@ -110,7 +110,7 @@ export class Open { */ static async getAdmins(gid: string) { try { - return LDAP.search(config.key_id+gid+config.dn_users, config.group.admin)[0]; + return LDAP.search(ldapConfig.key_id+gid+ldapConfig.dn_users, ldapConfig.group.admin)[0]; } catch(err) { throw "Erreur lors de la recherche des admins d'un groupe."; @@ -165,13 +165,13 @@ export class Open { * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis. * @arg {string} uid - Identifiant de l'utilisateur * @return {Promise(userData)} 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. + * voir `ldap_ldapConfig.json`(..\..\ldap_ldapConfig.json) pour les clés exactes. * @static * @async */ static async peekUser(uid: string) { try { - return LDAP.search(config.key_id+uid+config.dn_users, config.user.profil); + return LDAP.search(ldapConfig.key_id+uid+ldapConfig.dn_users, ldapConfig.user.profil); } catch(err) { throw "Erreur lors d'une recherche d'informations sur un individu."; @@ -183,18 +183,18 @@ export class Open { * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis. * @arg {string} gid - Identifiant du groupe * @return {Promise(groupData)} 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. + * voir `ldap_ldapConfig.json`(..\..\ldap_ldapConfig.json) pour les clés exactes. * @static * @async */ static async peekGroup(gid: string) { try { - let groupData = await LDAP.search(config.key_id+gid+config.dn_groups, config.group.profil); + let groupData = await LDAP.search(ldapConfig.key_id+gid+ldapConfig.dn_groups, ldapConfig.group.profil); let outGroupData={} // Rename output for (var uncleanKey in groupData) { - for (var cleanKey in config.group) { - if (uncleanKey==config.group.cleanKey) { outGroupData[cleanKey] = groupData[uncleanKey]; } + for (var cleanKey in ldapConfig.group) { + if (uncleanKey==ldapConfig.group.cleanKey) { outGroupData[cleanKey] = groupData[uncleanKey]; } } } return outGroupData; @@ -219,7 +219,7 @@ export class Open { static async findGroups(input: string) { try { // Trucs intelligents faits dans ./utilities - return SmartSearch.groups(input, [config.key_id, config.group.type]); + return SmartSearch.groups(input, [ldapConfig.key_id, ldapConfig.group.type]); } catch(err) { throw "Erreur lors de la recherche approximative d'un groupe."; @@ -237,7 +237,7 @@ export class Open { */ static async findUsers(data: searchUserFields) { try { - return SmartSearch.users(data, config.key_id); + return SmartSearch.users(data, ldapConfig.key_id); } catch(err) { throw "Erreur lors de la recherche approximative d'un utilisateur."; @@ -263,7 +263,7 @@ export class User extends Open { * @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.add} et {@link LDAP.change}, mais aussi {@link Admin.addMemberGroup} et {@link Admin.addAdminGroup} * pour gérer les groupes du nouvel utilisateur. Attention une manip FOIREUSE est cachée dedans. - * @arg {groupData} data - Dictionnaire des informations utilisateurs (voir détail des champs dans config.json) + * @arg {groupData} data - Dictionnaire des informations utilisateurs (voir détail des champs dans ldapConfig.json) * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon * @async * @static @@ -274,72 +274,72 @@ export class User extends Open { // uid de base généré à partir du nom standardisé try { - Tests.generateReadableId(data['name']).then(id => { vals[config.group['name']]=id; }); + Tests.generateReadableId(data['name']).then(id => { vals[ldapConfig.group['name']]=id; }); } catch(err) { throw "Erreur lors de la génération d'un hruid pour créer un nouveau groupe."; } // 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]); + ldapConfig.group.direct_input.forEach(key_att => vals[ldapConfig.group[key_att]]=data[key_att]); // Appel à la fonction de base - if (!await LDAP.add(config.key_id+"="+vals[config.group['name']]+","+config.dn_groups, vals)) { + if (!await LDAP.add(ldapConfig.key_id+"="+vals[ldapConfig.group['name']]+","+ldapConfig.dn_groups, vals)) { throw "Erreur lors de la création d'une nouvelle feuille dans l'arbre des groupes."; } // Certains champs nécessitent de petits calculs let vals2={}; // Sauvegarde du nom (pour le cas où gid != data['name']) - vals2[config.group["name"]]=data['name']; + vals2[ldapConfig.group["name"]]=data['name']; // ?! - vals2[config.user['password']] = ''; + vals2[ldapConfig.user['password']] = ''; // Génération id aléatoire et test contre le LDAP try { - Tests.generateId(config.groups["idNumber"], config.dn_groups).then(id => { vals2[config.group['idNumber']]=id; }); + Tests.generateId(ldapConfig.groups["idNumber"], ldapConfig.dn_groups).then(id => { vals2[ldapConfig.group['idNumber']]=id; }); } catch(err) { throw "Erreur lors de la génération d'un id numérique pour créer un nouveau groupe."; } // FOIREUX : Hypothèse sur la structure du reste des données mais évite un test.assurerUnicite à deux variables - vals2[config.group['idNumber2']]=vals2[config.group['idNumber']]; + vals2[ldapConfig.group['idNumber2']]=vals2[ldapConfig.group['idNumber']]; // Stockage machine ; dépend du prénom - vals2[config.group['directory']] = '/hosting/groups/'+vals[config.key_id]; + vals2[ldapConfig.group['directory']] = '/hosting/groups/'+vals[ldapConfig.key_id]; // Code root - vals2[config.group['cleanFullName']]=data['name'].replace(':', ';').toLowerCase().normalize('UFD'); + vals2[ldapConfig.group['cleanFullName']]=data['name'].replace(':', ';').toLowerCase().normalize('UFD'); // Adressage root - vals2[config.group['login']] = "/sbin/nologin"; + vals2[ldapConfig.group['login']] = "/sbin/nologin"; // Permissions BR - vals2[config.group['readPerm']] = '!*'; - vals2[config.group['writePerm']] = '!*'; + vals2[ldapConfig.group['readPerm']] = '!*'; + vals2[ldapConfig.group['writePerm']] = '!*'; // Inscription des valeurs calculées par effet de bord - if (!await LDAP.change(config.key_id+"="+vals[config.key_id]+","+config.dn_groups, "add", vals2)) { + if (!await LDAP.change(ldapConfig.key_id+"="+vals[ldapConfig.key_id]+","+ldapConfig.dn_groups, "add", vals2)) { throw "Erreur lors de l'ajout des valeurs intelligentes du nouveau groupe."; } ["posixAccount", "posixGroup", "brAccount"].forEach(cst => { let vals3={}; - vals3[config.group['class']]=cst; - LDAP.change(config.key_id+"="+vals[config.key_id]+","+config.dn_groups, "add", vals3).then(res => { + vals3[ldapConfig.group['class']]=cst; + LDAP.change(ldapConfig.key_id+"="+vals[ldapConfig.key_id]+","+ldapConfig.dn_groups, "add", vals3).then(res => { if (!res) { throw "Erreur lors de l'ajout des valeurs constantes du nouveau groupe."; } }); }); // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble data['members'].forEach(uid => { - Admin.addGroupMember(uid, vals[config.key_att]).then(res => { + Admin.addGroupMember(uid, vals[ldapConfig.key_att]).then(res => { if (!res) { throw "Erreur de l'ajout d'un membre au groupe."; } }); }); data['admins'].forEach(uid => { - Admin.addGroupAdmin( uid, vals[config.key_att]).then(res => { + Admin.addGroupAdmin( uid, vals[ldapConfig.key_att]).then(res => { if (!res) { throw "Erreur de l'ajout d'un admin au groupe."; } }); }); @@ -354,7 +354,7 @@ export class User extends Open { /** * @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. - * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_config est important. + * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_ldapConfig est important. * Une version "nerfée" de cette fonction est envisageable ; elle donne bcp de pouvoir à l'utilisateur. * @arg {string} uid - Utilisateur à modifier (le plus souvent le même, mais root possible) * @arg {userData} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerUtilisateur} avec tous les champs optionnels ; @@ -369,8 +369,8 @@ export class User extends Open { let profil = await Open.peekUser(uid); // Reecriture de profil avec les bons champs Object.keys(profil).forEach(keyLDAP => { - Object.keys(config.user).forEach(keyAlias => { - config.user[keyAlias]=keyLDAP; + Object.keys(ldapConfig.user).forEach(keyAlias => { + ldapConfig.user[keyAlias]=keyLDAP; profil[keyAlias]=profil[keyLDAP]; }); }); @@ -384,10 +384,9 @@ export class User extends Open { }); }); // Surcharge des champs à modifier selon data - Object.keys(data).forEach(key => { + let unchangeables = ['readPerm','writePerm','forlifes','ips','groups','groupsIsAdmin']; + Object.keys(data).forEach(function(key: string) { // Some fields the user cannot change (groups and groupsIsAdmin must be changed through addGroupMember and addGroupAdmin in Admin) - let unchangeables = ['readPerm','writePerm','forlifes','ips','groups','groupsIsAdmin']; - if (!unchangeables.includes(key)) { profil[key]=data[key]; } }); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -406,7 +405,4 @@ export class User extends Open { } destr() { LDAP.unbind(); } -} - -var unchangeables = ['readPerm','writePerm','forlifes','ips','groups','groupsIsAdmin']; -unchangeables.includes(key); \ No newline at end of file +} \ No newline at end of file diff --git a/src/ldap/utilities.ts b/src/ldap/utilities.ts index 7bda931..133b830 100644 --- a/src/ldap/utilities.ts +++ b/src/ldap/utilities.ts @@ -4,24 +4,24 @@ * @author hawkspar */ -import {config} from './config'; +import {ldapConfig} from './config'; import {LDAP} from './basics.js'; /** * @interface searchUserFields * @desc Interface permettant la recherche d'un utilisateur avec des champs incomplets. Plusieurs valeurs sont possibles pour le même champ. * Aucun de ces champs n'est obligatoire, mais certains de ces champs doivent être exacts pour obtenir un bon résultat. - * @var {string|Array.string} givenName - Prénom(s) - * @var {string|Array.string} lastName - Nom(s) - * @var {string|Array.string} nickname - Surnom(s) - * @var {string|Array.string} nationality - Nationalité(s) (à implémenter) - * @var {string|Array.string} promotion - Année(s) de promo - * @var {string|Array.string} phone - Numéro(s) de téléphone - * @var {string|Array.string} mail - Adresse(s) courriel - * @var {string|Array.string} ip - Adresse(s) ip - * @var {string|Array.string} adress - Adresse(s) + * @var {string|string[]} givenName - Prénom(s) + * @var {string|string[]} lastName - Nom(s) + * @var {string|string[]} nickname - Surnom(s) + * @var {string|string[]} nationality - Nationalité(s) (à implémenter) + * @var {string|string[]} promotion - Année(s) de promo + * @var {string|string[]} phone - Numéro(s) de téléphone + * @var {string|string[]} mail - Adresse(s) courriel + * @var {string|string[]} ip - Adresse(s) ip + * @var {string|string[]} adress - Adresse(s) * @var {string} school - Ecole d'appartenance (instable, doit être exact) - * @var {string|Array.string} groups - Un ou plusieurs groupes dont l'utilisateur est membre (doit être exact). + * @var {string|string[]} groups - Un ou plusieurs groupes dont l'utilisateur est membre (doit être exact). * @var {string} course - PA ou autre. Doit être exact. */ export interface searchUserFields { @@ -35,7 +35,7 @@ export interface searchUserFields { ip: string, adress: string, school: string, - groups: string, + groups: string[], studies: string, sport: string } @@ -57,7 +57,7 @@ export class SmartSearch { * à l'entrée. Etape 0 vers un vrai TOL (Trombino On Line). * @desc Cette fonction utilise {@link LDAP.search} 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 + * et ne gère pas l'auto-complete. Cette fonction utilise aussi ldapConfig.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. @@ -68,14 +68,14 @@ export class SmartSearch { */ static async groups(input: string, return_attributes: string[]) { // Construction du filtre custom - let filter= "(|("+config.key_id+"="+ input+")" + // On cherche la valeur exacte - "(|("+config.key_id+"=*"+input+")" + // La valeur finale avec des trucs avant ; wildcard * - "(|("+config.key_id+"=*"+input+"*)"+ // La valeur du milieu avec des trucs avant et après - "("+ config.key_id+"="+ input+"*))))"; // La valeur du début avec des trucs après + let filter= "(|("+ldapConfig.key_id+"="+ input+")" + // On cherche la valeur exacte + "(|("+ldapConfig.key_id+"=*"+input+")" + // La valeur finale avec des trucs avant ; wildcard * + "(|("+ldapConfig.key_id+"=*"+input+"*)"+ // La valeur du milieu avec des trucs avant et après + "("+ ldapConfig.key_id+"="+ input+"*))))"; // La valeur du début avec des trucs après // Appel rechercheLDAP avec filtre de l'espace try { - return LDAP.search(config.dn_groups, return_attributes, filter); + return LDAP.search(ldapConfig.dn_groups, return_attributes, filter); } catch(err) { throw "Erreur lors de la recherche intelligente d'un groupe."; @@ -97,14 +97,14 @@ export class SmartSearch { */ static async users(data: searchUserFields, return_attributes: string[]) { let filter=""; - // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans config encore + // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans ldapConfig 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 => { // Traduction en language LDAP - let attribute = config.user[key]; + let attribute = ldapConfig.user[key]; // Creation incrémentale du filtre filter="(&"+filter+ "(|("+attribute+"="+ val+")"+ // On cherche la valeur exacte "(|("+attribute+"=*"+val+")"+ // La valeur finale avec des trucs avant ; wildcard * (MEF la wildcart ne marche pas pour tous les attributs) @@ -115,7 +115,7 @@ export class SmartSearch { } // Appel avec filtre de l'espace try { - return LDAP.search(config.dn_users, return_attributes, filter); + return LDAP.search(ldapConfig.dn_users, return_attributes, filter); } catch(err) { throw "Erreur lors de la recherche intelligente d'un utilisateur."; @@ -159,7 +159,7 @@ export class Tests { static async ensureUnique(value: string, attribute: string, dn: string, changeValue: (string, number) => string, n=0) { // Recherche d'autres occurences de l'id try { - return LDAP.search(dn, config.key_id, "("+attribute+"="+value+")").then(function (matches: string[]) { + return LDAP.search(dn, ldapConfig.key_id, "("+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; } @@ -185,7 +185,7 @@ export class Tests { static async generateUid(givenName: string, lastName: string, promotion: string) { try { // normalize et lowerCase standardisent le format - return this.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), config.key_id, config.dn_users, (id: string, n: number) => { + return this.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), ldapConfig.key_id, ldapConfig.dn_users, (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... @@ -208,7 +208,7 @@ export class Tests { static async generateReadableId(name: string) { try { // normalize et lowerCase standardisent le format - return this.ensureUnique(name.toLowerCase().normalize('UFD'), config.key_id, config.dn_groups, (id: string, n: number) => { + return this.ensureUnique(name.toLowerCase().normalize('UFD'), ldapConfig.key_id, ldapConfig.dn_groups, (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; diff --git a/tsconfig.json b/tsconfig.json index bacbcfd..7284a43 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,8 @@ "sourceMap": true, "outDir": "build", "resolveJsonModule": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "lib": ["es7"] }, "include": [ "src/**/*", -- GitLab