From 9d13e5051142f4d16cfc68b719080960470892ce Mon Sep 17 00:00:00 2001 From: ManifoldFR <wilson.jallet@gmail.com> Date: Tue, 20 Mar 2018 23:08:16 +0100 Subject: [PATCH] Corrections diverses. --- src/graphql/connectors/authentifiers.js | 18 +-- src/graphql/connectors/connectors.js | 16 ++- src/graphql/resolvers.js | 5 +- src/ldap/ldap_data.js | 181 ++++++++++++------------ 4 files changed, 112 insertions(+), 108 deletions(-) diff --git a/src/graphql/connectors/authentifiers.js b/src/graphql/connectors/authentifiers.js index 68346c6..e7ace7a 100644 --- a/src/graphql/connectors/authentifiers.js +++ b/src/graphql/connectors/authentifiers.js @@ -7,8 +7,8 @@ import knex from '../../../db/knex_router'; import * as connectors from './connectors.js'; import * as selectors from './selectors'; import * as list_selectors from './list_selectors'; -import { utilisateurAnonyme, utilisateurConnecte, - administrateurConnecte, superAdministrateurConnecte +import { UtilisateurAnonyme, UtilisateurConnecte, + AdministrateurConnecte, SuperAdministrateurConnecte } from '../../ldap/ldap_data'; @@ -25,8 +25,8 @@ function user_object(user, ldap_access){ * @return {Promise(Boolean)} L'utilisateur possède-t-il les droits indiqués ici ? * @rights user */ -export async function anonymous(user){ - return new user_object(user, new utilisateurAnonyme()); +export function anonymous(user){ + return new user_object(user, new UtilisateurAnonyme()); } /** @@ -35,8 +35,8 @@ export async function anonymous(user){ * @return {Promise(Boolean)} L'utilisateur possède-t-il les droits indiqués ici ? * @rights user */ -export async function loggedIn(user, groupUID){ - return new user_object(user, new utilisateurConnecte(user)); +export function loggedIn(user, groupUID){ + return new user_object(user, new UtilisateurConnecte(user)); } /** @@ -45,7 +45,7 @@ export async function loggedIn(user, groupUID){ * @return {Promise(Boolean)} L'utilisateur possède-t-il les droits indiqués ici ? * @rights user */ -export async function viewer(user, groupUID){ +export function viewer(user, groupUID){ return null; } @@ -59,7 +59,7 @@ export async function member(user, groupUID){ let group_list = await selectors.groupsWithMember(user); let test = await knex.with('group_list', group_list).select().from('group_list').where('uid', groupUID); if(test[0]) - return new user_object(user, new utilisateurConnecte(user)); + return new user_object(user, new UtilisateurConnecte(user)); return admin(user, groupUID); } @@ -69,7 +69,7 @@ export async function member(user, groupUID){ * @return {Promise(Boolean)} L'utilisateur possède-t-il les droits indiqués ici ? * @rights user */ -export async function speaker(user, groupUID){ +export function speaker(user, groupUID){ return admin(user, groupUID); } diff --git a/src/graphql/connectors/connectors.js b/src/graphql/connectors/connectors.js index 04fa0d0..73d2178 100644 --- a/src/graphql/connectors/connectors.js +++ b/src/graphql/connectors/connectors.js @@ -10,8 +10,14 @@ import ldap from '../../ldap/ldap_data'; // dn et mot de passe du bind user du LDAP import ldap_bind_user from '../../../ldap_connexion_config.json'; -const utilisateur = ldap.UtilisateurAnonyme(); -utilisateur.repliquerTOLdesIds(); +const utilisateur = new ldap.UtilisateurAnonyme(); + +let result = utilisateur.listMembers("br").then(res => { + console.log("Got it"); + return res; +}); + +export { utilisateur }; /* Le tag @rights est la gestion des autorisations. @@ -23,7 +29,7 @@ utilisateur.repliquerTOLdesIds(); Commençons par un rappel sur le fonctionnement des droits. Chaque utilisateur a un certain niveau de droit sur chaque groupe. Ce niveau de droit indique - ce qu'il a le droit de savoir et de faire. Chaque niveau est inclu dans les niveaus supérieur. + ce qu'il a le droit de savoir et de faire. Chaque niveau est inclus dans les niveaus supérieur. Les différends niveaux sont : none - aucun droit viewer : l'utilisateur a visibilité sur le groupe. Il sait que le groupe existe, et a accès à un certain nombre d'infos. @@ -328,7 +334,7 @@ export const getUser = (user, userUID) => { }; }; - const result = utilisateur.renseignerSurUtilisateur(user, userUID).then(res => { + const result = utilisateur.getUser(user, userUID).then(res => { console.log(res[0]); return refactorer(res[0]); }); @@ -531,7 +537,7 @@ export async function getGroupMemberUsers(user, GroupUID){ let type = await list_selectors.getGroupType(user, GroupUID); switch( type ){ case "SimpleGroup": - return user.ldap_access.listerMembres(GroupUID); + return utilisateur.listMembers(GroupUID); // return ["anatole.romon"]; case "MetaGroup": return getMetaGroupMemberUsers(user, GroupUID); diff --git a/src/graphql/resolvers.js b/src/graphql/resolvers.js index bde1530..fd02164 100644 --- a/src/graphql/resolvers.js +++ b/src/graphql/resolvers.js @@ -7,10 +7,9 @@ import _ from 'lodash'; import { assertBinaryExpression } from 'babel-types'; import knex from '../../db/knex_router'; -import * as connectors from './connectors/connectors.js'; +import * as connectors from './connectors/connectors'; import * as list_selectors from './connectors/list_selectors'; import * as authenthifiers from './connectors/authentifiers'; -import { connect } from 'http2'; /** * @description Résolveurs des différentes requêtes GraphQL @@ -246,7 +245,7 @@ export const resolvers = { // @rights viewer(obj.uid) SimpleGroup: { members: (obj, args, context) => { - return connectors.listerMembres(context.user,obj.uid); + return connectors.utilisateur.listMembers(context.user,obj.uid); } }, diff --git a/src/ldap/ldap_data.js b/src/ldap/ldap_data.js index 4964613..27d0c56 100644 --- a/src/ldap/ldap_data.js +++ b/src/ldap/ldap_data.js @@ -59,22 +59,23 @@ function connecterLDAP(bind_user) { client.bind(bind_user.dn, bind_user.passwd, function rechercherLDAP(base, attributes, filter="(objectClass=*)") { return new Promise((resolve, reject) => { let vals=[]; - // Interrogation LDAP selon configuration fournie en argument + // Interrogation LDAP selon la configuration fournie en argument client.search(base, { "scope": "sub", "filter": filter, "attributes": attributes - }, function(err, res) { + }, + 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 + // 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]]); } - // Cas plusieurs attributs donc résultat dictionnaire + // Plusieurs attributs: le résultat est un dictionnaire else { vals.push({}); attributes.forEach((attribute) => { @@ -82,7 +83,7 @@ function rechercherLDAP(base, attributes, filter="(objectClass=*)") { }); } }); - // Si la recherche est finie on se déconnecte et on renvoit la liste + // Si la recherche est finie on se déconnecte et on renvoie la liste res.on('end', function(res) { resolve(vals); }); } }); @@ -261,48 +262,6 @@ function repliquerTOL(data) { }); } -//------------------------------------------------------------------------------------------------------------------------ -// Fonctions intermédiaires TBT -//------------------------------------------------------------------------------------------------------------------------ - -/** - * @summary Cette fonction teste si un utilisateur est membre d'un groupe. - * @desc Au passage on appelle {@link ajouterMembreGroupe} au cas où il ne soit pas membre. - * @param {string} uid - Identifiant de l'utilisateur à tester - * @param {string} gid - Identification du groupe à - * @param {Object} utilisateur - Objet utilisateur à passer - * @returns {Promise(boolean)} True si l'utilisateur est membre - */ -function 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)) { - resolve(true); - } - }); - }); - }); -} - -/** - * @summary Cette fonction teste si un utilisateur est admin d'un groupe. - * @desc Au passage on appelle {@link ajouterAdministrateurGroupe} au cas où il ne soit pas membre. - * @param {string} uid - Identifiant de l'utilisateur à tester - * @param {string} gid - Identification du groupe à tester - * @param {Object} utilisateur - Objet utilisateur pour l'authentification. - * @returns {Promise(boolean)} True si l'utilisateur est administrateur - */ -function etreAdministrateurGroupe(user, uid, gid) { - return new Promise((resolve, reject) => { - user.listerAdministrateurs(gid).then(la => { - if (la.includes(uid)) { - resolve(true); - } - }); - }); -} - /** * @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 @@ -395,10 +354,50 @@ class UtilisateurAnonyme { //------------------------------------------------------------------------------------------------------------------------ // Fonctions de lecture //------------------------------------------------------------------------------------------------------------------------ - - constructor() { + + //------------------------------------------------------------------------------------------------------------------------ + // Fonctions intermédiaires TBT + //------------------------------------------------------------------------------------------------------------------------ + + /** + * @summary Cette fonction teste si un utilisateur est membre d'un groupe. + * @desc Au passage on appelle {@link ajouterMembreGroupe} au cas où il ne soit pas membre. + * @param {string} uid - Identifiant de l'utilisateur à tester + * @param {string} gid - Identification du groupe à + * @param {Object} utilisateur - Objet utilisateur à passer + * @returns {Promise(boolean)} True si l'utilisateur est membre + */ + isGroupMember(uid, gid) { + return new Promise((resolve, reject) => { + this.listGroups(uid).then(lg => { + this.listMembers(gid).then(lm => { + if (lg.includes(gid) | lm.includes(uid)) { + resolve(true); + } + }); + }); + }); + } + + /** + * @summary Cette fonction teste si un utilisateur est admin d'un groupe. + * @desc Au passage on appelle {@link ajouterAdministrateurGroupe} au cas où il ne soit pas membre. + * @param {string} uid - Identifiant de l'utilisateur à tester + * @param {string} gid - Identification du groupe à tester + * @param {Object} utilisateur - Objet utilisateur pour l'authentification. + * @returns {Promise(boolean)} True si l'utilisateur est administrateur + */ + isGroupAdmin(user, uid, gid) { + return new Promise((resolve, reject) => { + this.listAdmins(gid).then(la => { + if (la.includes(uid)) { + resolve(true); + } + }); + }); } + /** * @summary Fonction qui retrouve les groupes dont un individu est membre. * @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 @@ -406,22 +405,24 @@ class UtilisateurAnonyme { * @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 */ - listerGroupes(uid) { - return new Promise((resolve, reject) => { - rechercherLDAP(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 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) + * @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) */ - listerMembres(gid) { - return new Promise((resolve, reject) => { - rechercherLDAP(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); } /** @@ -430,7 +431,7 @@ class UtilisateurAnonyme { * @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) */ - listerAdministrateurs(gid) { + listAdmins(gid) { return new Promise((resolve, reject) => { rechercherLDAP(ldapEscape.filter( config.key_id+"=${id},"+config.dn_users, {id : gid}), config.group.admin).then(res => resolve(res[0]) @@ -445,7 +446,7 @@ class UtilisateurAnonyme { * @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. */ - renseignerSurUtilisateur(uid) { + getUser(uid) { return new Promise((resolve, reject) => { rechercherLDAP(ldapEscape.filter(config.key_id+"=${id},"+config.dn_users, {id : uid}), config.user.profil).then(res => resolve(res)); }); @@ -456,12 +457,12 @@ class UtilisateurAnonyme { * @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. + * voir `ldap_config.json`(../../ldap_config.json) pour les clés exactes. */ - renseignerSurGroupe(gid) { - return new Promise((resolve, reject) => { - rechercherLDAP(ldapEscape.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); } //------------------------------------------------------------------------------------------------------------------------ @@ -533,7 +534,7 @@ 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(user, data) { + createGroup(user, data) { return new Promise((resolve, reject) => { // Calcul d'un dictionnaire d'ajout let vals = {}; @@ -614,7 +615,7 @@ class UtilisateurConnecte extends UtilisateurAnonyme { editerUtilisateur(user, uid, data) { return new Promise((resolve, reject) => { // Récupération des anciennes données - this.renseignerSurUtilisateur(user, 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 => { @@ -623,10 +624,10 @@ class UtilisateurConnecte extends UtilisateurAnonyme { }); }); // Régénération du champ manquant dans profil - this.listerGroupes(user, uid).then(lg => { + this.listGroups(user, uid).then(lg => { profil['groupsIsAdmin']=[]; lg.forEach(gid =>{ - etreAdministrateurGroupe(this, 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 @@ -676,7 +677,7 @@ class AdministrateurConnecte extends UtilisateurConnecte { ajouterMembreGroupe(user, uid, gid) { return new Promise((resolve, reject) => { // Vérifie que l'utilisateur est pas déjà membre pour groupes - this.listerMembres(user,gid).then(lm => { + this.listMembers(user,gid).then(lm => { if (!lm.includes(uid)) { let vals = {}; vals[config.groups.member] = uid; @@ -686,7 +687,7 @@ class AdministrateurConnecte extends UtilisateurConnecte { }); } // Vérifie que l'utilisateur est pas déjà membre pour users - }).then(res => this.listerGroupes(user,uid)).then( lg => { + }).then(res => this.listGroups(user,uid)).then( lg => { if (!lg.includes(gid)) { let vals2 = {}; vals2[config.users.groups] = gid; @@ -708,10 +709,10 @@ class AdministrateurConnecte extends UtilisateurConnecte { * @arg {string} gid - Identifiant du groupe * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon */ - supprimerMembreGroupe(user, uid, gid) { + removeGroupMember(user, uid, gid) { return new Promise((resolve, reject) => { // Vérifie que l'utilisateur est pas déjà viré pour groupes - this.listerMembres(user,gid).then(lm => { + this.listMembers(user,gid).then(lm => { if (lm.includes(uid)) { // Supprime tous les utilisateurs modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "del", config.group.member).then(res => { @@ -721,7 +722,7 @@ class AdministrateurConnecte extends UtilisateurConnecte { }); }); } - }).then(res => this.listerGroupes(user,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 @@ -750,7 +751,7 @@ class AdministrateurConnecte extends UtilisateurConnecte { return new Promise((resolve, reject) => { // ajouter this.ajouterMembreGroupe(user,uid,gid).then(res => { - this.listerAdministrateurs(user,gid).includes(uid).then(la => { + this.listAdmins(user,gid).includes(uid).then(la => { if (!la.includes(uid)) { // Finalement modification, uniquement dans groups let vals = {}; @@ -777,9 +778,9 @@ class AdministrateurConnecte extends UtilisateurConnecte { 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(user, uid, gid).then( res => { this.ajouterMembreGroupe(user,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) - this.listerAdministrateurs(user,gid).then(la => { + this.listAdmins(user,gid).then(la => { if (la.includes(uid)) { // Supprime tous les administrateurs modifierLDAP(user, ldapEscape(config.key_id+"=${id},"+config.dn_groups, { id: gid }), "del", config.group.admin).then(res => { @@ -805,10 +806,10 @@ class AdministrateurConnecte extends UtilisateurConnecte { * @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(user, gid, data) { + editGroup(user, gid, data) { return new Promise((resolve, reject) => { // Récupération des anciennes données - this.renseignerSurGroupe(user, 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 => { @@ -821,8 +822,8 @@ class AdministrateurConnecte extends UtilisateurConnecte { profil[key]=data[key]; }); // Modification propre - this.supprimerGroupe(user, gid).then(r => { - this.creerGroupe(user, 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); }); }); }); @@ -840,13 +841,13 @@ class AdministrateurConnecte extends UtilisateurConnecte { * @arg {string} gid - gid de la victime * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon */ - supprimerGroupe(user, gid) { + deleteGroup(user, gid) { return new Promise(function(resolve, reject) { // Gestion des membres et administrateurs d'abord - this.renseignerSurGroupe(user, 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 => { supprimerLDAP(user, config.key_id+"="+gid+","+config.dn_groups); @@ -987,11 +988,11 @@ class SuperAdministrateurConnecte extends AdministrateurConnecte { supprimerUtilisateur(user, uid) { return new Promise((resolve, reject) => { // Gestion des groupes d'abord - this.renseignerSurUtilisateur(user, uid).then(profil => { + this.getUser(user, uid).then(profil => { profil[config.user['groups']].forEach(gid => { - etreAdministrateurGroupe(user, uid, gid).then(res => { + this.isGroupAdmin(user, uid, gid).then(res => { if (this.la.includes(res)) { this.supprimerAdministrateurGroupe(user, uid, gid); } - }).then(res => { this.supprimerMembreGroupe(user, uid, gid); }); + }).then(res => { this.removeGroupMember(user, uid, gid); }); }); // Elimination }).then(res => { supprimerLDAP(user, config.key_id+"="+uid+","+config.dn_users); }); @@ -1010,7 +1011,5 @@ module.exports = { UtilisateurAnonyme, UtilisateurConnecte, AdministrateurConnecte, - SuperAdministrateurConnecte, - etreAdministrateurGroupe, - etreMembreGroupe + SuperAdministrateurConnecte }; -- GitLab