From 123c0b11a03d0bcb25ac402bfe20697235e9a7b2 Mon Sep 17 00:00:00 2001
From: ManifoldFR <wilson.jallet@gmail.com>
Date: Sun, 4 Mar 2018 21:11:50 +0100
Subject: [PATCH] =?UTF-8?q?User.groups=20a=20d=C3=A9sormais=20un=20resolve?=
 =?UTF-8?q?r=20(non=20filtr=C3=A9)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Ajout de lodash aux dépendances, faites un npm install

Les fonctions getGroup, getSimpleGroup et getMetaGroup sont implémentées

getUser est implémenté correctement

Retours à la ligne dans les docstrings (faites un effort putain)

Modifs noms de types GraphQL ambigus
---
 .../20180303192411_create_metaGroups.js       |  56 +++----
 .../20180304154225_group_type_column.js       |  12 +-
 ldap_config.json                              |   5 +-
 package.json                                  |   1 +
 .../{db_utils.js => connectors/connectors.js} | 145 +++++++++++-------
 src/graphql/resolvers.js                      | 112 +++++---------
 src/graphql/typeDefs.js                       |  25 +--
 src/ldap/ldap_data.js                         |  16 +-
 src/server.js                                 |   2 +-
 9 files changed, 192 insertions(+), 182 deletions(-)
 rename src/graphql/{db_utils.js => connectors/connectors.js} (72%)

diff --git a/db/migrations/20180303192411_create_metaGroups.js b/db/migrations/20180303192411_create_metaGroups.js
index 2063ac9..90df1a8 100644
--- a/db/migrations/20180303192411_create_metaGroups.js
+++ b/db/migrations/20180303192411_create_metaGroups.js
@@ -12,38 +12,38 @@ Après cette mutation, plus rien n'est sensé être mis directement dans la tabl
 
 exports.up = function(knex, Promise) {
     return knex('groups').select().then( groups_content => {
-    return knex('groups').del().then(function () {
-    return knex.schema.table('groups', function (table){
-        table.dropColumn('school');
-        table.dropColumn('parentuid');
-    }).then(()=> {
-    return knex.schema.createTable('simple_groups', function (table){
-        table.inherits('groups');
-        table.string('parentuid');
-        table.enum('school', ['polytechnique', 'ensta', 'supoptique']).notNullable();
-    }).then(() => {
-    return knex.schema.createTable('meta_groups', function (table){
-        table.inherits('groups');
-    }).then(function(){
-    return knex('simple_groups').insert(groups_content);
-    });
-    });
-    });
-    });
+        return knex('groups').del().then(function () {
+            return knex.schema.table('groups', function (table){
+                table.dropColumn('school');
+                table.dropColumn('parentuid');
+            }).then(()=> {
+                return knex.schema.createTable('simple_groups', function (table){
+                    table.inherits('groups');
+                    table.string('parentuid');
+                    table.enum('school', ['polytechnique', 'ensta', 'supoptique']).notNullable();
+                }).then(() => {
+                    return knex.schema.createTable('meta_groups', function (table){
+                        table.inherits('groups');
+                    }).then(function(){
+                        return knex('simple_groups').insert(groups_content);
+                    });
+                });
+            });
+        });
     });
 };
 
 exports.down = function(knex, Promise) {
     return knex('simple_groups').select().then(simple_groups_content => {
-    return knex.schema.dropTable('simple_groups').then(function (){
-    return knex.schema.dropTable('meta_groups').then(function (){
-    return knex.schema.table('groups', function (table){
-        table.string('parentuid');
-        table.enum('school', ['polytechnique', 'ensta', 'supoptique']).notNullable();
-    }).then(function (){
-    return knex('groups').insert(simple_groups_content);
-    });
-    });
-    });
+        return knex.schema.dropTable('simple_groups').then(function (){
+            return knex.schema.dropTable('meta_groups').then(function (){
+                return knex.schema.table('groups', function (table){
+                    table.string('parentuid');
+                    table.enum('school', ['polytechnique', 'ensta', 'supoptique']).notNullable();
+                }).then(function (){
+                    return knex('groups').insert(simple_groups_content);
+                });
+            });
+        });
     });
 };
diff --git a/db/migrations/20180304154225_group_type_column.js b/db/migrations/20180304154225_group_type_column.js
index 61f2aaa..f178a0a 100644
--- a/db/migrations/20180304154225_group_type_column.js
+++ b/db/migrations/20180304154225_group_type_column.js
@@ -3,15 +3,15 @@ exports.up = function(knex, Promise) {
     return knex.schema.table('groups', function(table) {
         table.enum('type', ['simple', 'meta', 'error']).notNullable().defaultTo('error');
     }).then( () => {
-    return knex('simple_groups').update({type : "simple"}).then(() => {
-    return knex('meta_groups').update({type : "meta"});
-    });
+        return knex('simple_groups').update({type : "simple"}).then(() => {
+            return knex('meta_groups').update({type : "meta"});
+        });
     });
   
 };
 
 exports.down = function(knex, Promise) {
-  return knex.schema.table('groups', function(table) {
-      table.dropColumn('type');
-  });
+    return knex.schema.table('groups', function(table) {
+        table.dropColumn('type');
+    });
 };
diff --git a/ldap_config.json b/ldap_config.json
index 9962671..94aee8d 100644
--- a/ldap_config.json
+++ b/ldap_config.json
@@ -36,7 +36,10 @@
 			"mail": "mail",
 			"adress": "brRoom",
 			"ip": "brIP", 
-			"school": "brMemberOf", "groups": "brMemberOf", "studies": "brMemberOf", "sport": "brMemberOf"
+			"school": "brMemberOf", 
+			"groups": "brMemberOf", 
+			"studies": "brMemberOf", 
+			"sport": "brMemberOf"
 		}
 	},
 	"tol": {
diff --git a/package.json b/package.json
index cd95995..3fb5e24 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
     "knex": "^0.14.4",
     "ldap-escape": "^1.1.5",
     "ldapjs": "^1.0.2",
+    "lodash": "^4.17.5",
     "morgan": "^1.9.0",
     "passport": "^0.4.0",
     "passport-ldapauth": "^2.0.0",
diff --git a/src/graphql/db_utils.js b/src/graphql/connectors/connectors.js
similarity index 72%
rename from src/graphql/db_utils.js
rename to src/graphql/connectors/connectors.js
index e550585..6d2fdf1 100644
--- a/src/graphql/db_utils.js
+++ b/src/graphql/connectors/connectors.js
@@ -2,8 +2,10 @@
  * @file Fonctions pour interagir avec la BDD sigma et le LDAP.
  * @author akka vodol
  */
-import knex from '../../db/knex_router';
-import { renseignerSurUtilisateur, repliquerTOLdesIds, listerGroupes, listerMembres, listerAdministrateurs } from '../ldap/ldap_data';
+import knex from '../../../db/knex_router';
+import { renseignerSurUtilisateur, repliquerTOLdesIds, 
+    listerGroupes, listerMembres, listerAdministrateurs 
+} from '../../ldap/ldap_data';
 import { exportAllDeclaration } from 'babel-types';
 
 export { renseignerSurUtilisateur, repliquerTOLdesIds, listerMembres };
@@ -12,7 +14,8 @@ export { renseignerSurUtilisateur, repliquerTOLdesIds, listerMembres };
  * @summary Génère une promise.
  * @function
  * @desc Les fonctions ici sont toutes supposées renvoyer une promise. 
- * Si on veut renvoyer une valeur directement, cette fonction permet de construire une promise qui renvoie cette valeur facilement.
+ * Si on veut renvoyer une valeur directement, cette fonction permet de construire 
+ * une Promise qui renvoie cette valeur facilement.
  * @arg {Object} val - La valeur qu'on veut renvoyer.
  * @return {Promise(Object)} Une promise qui renvoi val
  */
@@ -26,11 +29,14 @@ const quickPromise = (val) => {
  * @summary Renvoie le type d'un groupe.
  * @function
  * @desc Parcours les BDD pour savoir dans laquelle se trouve le groupe ayant l'UID donné. 
- * Cette opération nécéssite un parcours de base de donnée, et il est préférable de ne pas sans servir si on a un autre moyend de connaitre le typed d'un groupe
+ * Cette opération nécéssite un parcours de base de donnée, et il est préférable de ne pas 
+ * sans servir si on a un autre moyend de connaitre le typed d'un groupe
  * (Par exemple, si on dispose d'un retour de BDD pour ce groupe. Le champ 'type' indique alors son type.)
- * @arg {Object} user - Objet contenant un attribut *uid* de type *string*. User représente l'utilisateur qui a effectué la requête. 
+ * @arg {Object} user - Objet contenant un attribut `uid` de type `string`. 
+ * User représente l'utilisateur qui a effectué la requête. 
  * @arg {Object} groupUID - L'id du groupe dont on veut connaître le type.
- * @return {Promise(String)} Un string représentant le type du groupe. Peut être "SimpleGroup" ou "MetaGroup". Renvoie *Undefined* si le groupe 'existe pas
+ * @return {Promise(String)} Un string représentant le type du groupe.
+ * Peut être "SimpleGroup" ou "MetaGroup". Renvoie `Undefined` si le groupe n'existe pas
  */
 export const getGroupType = (user, groupUID) => {
     return knex('simple_groups').select('uid').where('uid', groupUID).then( sg_res => {
@@ -52,7 +58,8 @@ export const getGroupType = (user, groupUID) => {
  * Les utilisateurs ayant droit d'admin sur un meta-groupe sont les utilisateurs 
  * ayant droit d'admin sur un des groupes membres
  * @arg {String} uid - L'uid du groupe dont on veut les administrateurs. 
- * @return {Promise} Retour de requête knex. Promise qui renvera une liste de tous les utilisateurs ayant droit d'admin sur le groupe
+ * @return {Promise} Retour de requête knex. Promise qui renvera une liste 
+ * de tous les utilisateurs ayant droit d'admin sur le groupe
  */
 export const getUsersWithAdminRights = (user, groupUID) => {
     return getGroupType(user, groupUID).then( groupType => {
@@ -68,7 +75,8 @@ export const getUsersWithAdminRights = (user, groupUID) => {
                                 return adminList.concat(parentAdmins);
                             });
                         else
-                            return adminList.concat(['anatole.romon']); // pour les besoins des tests, anatole romon a tout les droits
+                            // pour les besoins des tests, anatole romon a tout les droits
+                            return adminList.concat(['anatole.romon']); 
                     });
             });
         }else{
@@ -87,7 +95,8 @@ export const getUsersWithAdminRights = (user, groupUID) => {
 /**
  * @summary teste si un utilisateur a des droits
  * @desc Cette fonction effectue une requête knex. Elle gère l'arête de parenté.
- * @arg {Object} user - Objet contenant un attribut *uid* de type *string*. User représente l'utilisateur qui a effectué la requête. 
+ * @arg {Object} user - Objet contenant un attribut `uid` de type `string`. 
+ * User représente l'utilisateur qui a effectué la requête. 
  * @return {Promise} Retour de requête knex. Liste de tous les groupes que l'utilisateur a le droit de voire.
  */
 export const hasAdminRights = (user, groupUID) => {
@@ -102,7 +111,8 @@ export const hasAdminRights = (user, groupUID) => {
 /**
  * @summary Renvoie une liste des id de tous les groupes visibles par l'utilisateur
  * @desc Cette fonction génère un callback qui créé une table contenant les uid de tous les groupes visibles
- * @arg {Object} user - Objet contenant un attribut *uid* de type *string*. User représente l'utilisateur qui a effectué la requête. 
+ * @arg {Object} user - Objet contenant un attribut `uid` de type `string`. 
+ * User représente l'utilisateur qui a effectué la requête. 
  * @return {Promise(Callback)} callback contruisant une requête knex pour une table de tous les id visibles.
  */
 export const getVisibleGroupCallback = (user) => {
@@ -114,7 +124,8 @@ export const getVisibleGroupCallback = (user) => {
             var directly_visible_simple_groups = qb =>  qb.with('membered_groups', membered_groups).select('simple_groups.uid').from('simple_groups').distinct()
                 .innerJoin('membered_groups',
                     function () {
-                        this.on('simple_groups.uid', '=', 'membered_groups.uid').orOn('simple_groups.parentuid', '=', 'membered_groups.uid');
+                        this.on('simple_groups.uid', '=', 'membered_groups.uid')
+                            .orOn('simple_groups.parentuid', '=', 'membered_groups.uid');
                     }
                 );
             return directly_visible_simple_groups(global_query_builder);
@@ -126,15 +137,19 @@ export const getVisibleGroupCallback = (user) => {
 /**
  * @summary Renvoie le nom de la table dans laquelle il faut chercher en fonction de ce qu'on veut
  * @desc a remplir
- * @arg {String} wantedType - Un string indiquant le type de groupe qu'on veut. Peut être *"simple"*, *"meta"* ou *"all"*. 
+ * @arg {String} wantedType - Un string indiquant le type de groupe qu'on veut. Peut être `"simple"`, `"meta"` ou `"all"`. 
  * @return {String} Le nom de la table dans laquelle la requète doit être effectuée.
  */
 function getGroupTableName(wantedType){
     switch(wantedType){
     case "simple":
         return "simple_groups";
+    case "SimpleGroup":
+        return "simple_groups";
     case "meta":
         return "meta_groups";
+    case "MetaGroup":
+        return "meta_groups";
     case "all":
         return "groups";
     default:
@@ -144,29 +159,33 @@ function getGroupTableName(wantedType){
 
 /**
  * @summary Renvoie un unique groupe, ssi ce groupe est visible par l'utilisateur
- * @desc Actuellement, la fonction effectue la même requête que *getAllVisibleGroups* et restreint au groupe demandé. Cette fonction peut être implémentée de manière plus efficace et plus chiante.
- * @arg {Object} user - Objet contenant un attribut *uid* de type *string*. User représente l'utilisateur qui a effectué la requête. 
- * @arg {String} uid - uid du groupe que l'on veut voire. 
- * @arg {String} wantedType - Un string indiquant le type de groupe qu'on veut. Peut être *"simple"*, *"meta"* ou *"all"*. 
+ * @desc Pour l'instant, la fonction effectue la même requête que `getAllVisibleGroups` 
+ * et restreint au groupe demandé. Cette fonction peut être implémentée de manière 
+ * plus efficace et plus chiante.
+ * @arg {Object} user - Utilisateur effectuant la requête. 
+ * @arg {String} uid - Identifiant du groupe voulu.
+ * @arg {String} type - Type de groupe voulu. `"simple"`, `"meta"` ou `"all"`.
  * @return {Promise(group)} Retour de requête knex. Le groupe demandé, si l'utilisateur a le droit de la voire.
  */
-export const getGroupIfVisible = (user, groupUID, wantedType="all") => {
-    var group_table_name = getGroupTableName(wantedType);
+export const getGroupIfVisible = (user, groupUID, type="all") => {
+    var group_table_name = getGroupTableName(type);
     return getVisibleGroupCallback(user).then(visible_groups => {
-        return knex.with('visible_groups', visible_groups).select().from(group_table_name).innerJoin('visible_groups', function (){
-            this.on('visible_groups.uid', '=', group_table_name + '.uid');
-        }).where(group_table_name + '.uid', groupUID).then(res => {
-            return res[0];
-        });
+        return knex.with('visible_groups', visible_groups).select()
+            .from(group_table_name).innerJoin('visible_groups', function (){
+                this.on('visible_groups.uid', '=', group_table_name + '.uid');
+            }).where(group_table_name + '.uid', groupUID).then(res => {
+                return res[0];
+            });
     });
 };
 
 
+
 /**
  * @summary Renvoie tous les groupes visibles par l'utilisateur user
  * @desc Cette fonction effectue une requête knex. Elle gère l'arête de parenté.
- * @arg {Object} user - Objet contenant un attribut *uid* de type *string*. User représente l'utilisateur qui a effectué la requête. 
- * @arg {String} wantedType - Un string indiquant le type de groupe qu'on veut. Peut être *"simple"*, *"meta"* ou *"all"*. 
+ * @arg {Object} user - Représente l'utilisateur qui a effectué la requête. 
+ * @arg {String} wantedType - Type de groupe voulu : `"simple"`, `"meta"` ou `"all"`. 
  * @return {Promise} Retour de requête knex. Liste de tous les groupes que l'utilisateur a le droit de voire.
  */
 export const getAllVisibleGroups = (user, wantedType="all") => {
@@ -178,9 +197,12 @@ export const getAllVisibleGroups = (user, wantedType="all") => {
     });
 };
 
+export const getAllVisibleSimpleGroups = (user) => getAllVisibleGroups(user,"simple");
+export const getAllVisibleMetaGroups = (user) => getAllVisibleGroups(user,"meta");
+
 /**
  * @summary Teste si un utilisateur est membre d'un groupe
- * @arg {Object} user - Objet contenant un attribut *uid* de type *string*. User représente l'utilisateur qui a effectué la requête. 
+ * @arg {Object} user - Représente l'utilisateur qui a effectué la requête. 
  * @arg {Object} groupUID - L'id du groupe dont on veu savoir si l'utilisateur est membre. 
  * @return {Promise(Boolean)} Boolean indiquant si l'utilisateur est membre du groupe.
  */
@@ -209,7 +231,8 @@ export const getAvailablegroupUID = (initialUID) => {
  * @summary Créé un groupe si les arguments sont tous valides
  * @desc Les arguments doivent être valides, sauf pour uid. Une clé uid valide sera générée dans tous les cas. 
  * Les authorisations de l'utilisateur ne sont pas vérifiées
- * On teste si l'utilisateur qui envoie la requête a des droits d'admin sur le parent du groupe qui doit être créé, avec la fonction *getUsersWithAdminRights*
+ * On teste si l'utilisateur qui envoie la requête a des droits d'admin sur le parent du groupe qui doit être créé, avec la fonction
+ * `getUsersWithAdminRights`.
  * Si un argument est invalide ou si l'utilisateur n'a pas les droits, la fonction renvoie une erreur
  * @arg {Object} user - L'utilisateur qui effectue la requête. 
  * @arg {Object} args - Les arguments envoyés à la mutation. Cf le schéma GraphQL 
@@ -241,7 +264,7 @@ export const createSubgroup = (user, args) => {
 /**
  * @summary Créé un groupe si les arguments sont tous valides et l'utilisateur est authorisé
  * @desc Les arguments doivent être valides, sauf pour uid. Une clé uid valide sera générée dans tous les cas. 
- * On teste si l'utilisateur qui envoie la requête a des droits d'admin sur le parent du groupe qui doit être créé, avec la fonction *getUsersWithAdminRights*
+ * On teste si l'utilisateur qui envoie la requête a des droits d'admin sur le parent du groupe qui doit être créé, avec la fonction `getUsersWithAdminRights`
  * Si un argument est invalide ou si l'utilisateur n'a pas les droits, la fonction renvoie une erreur
  * @arg {Object} user - L'utilisateur qui effectue la requête. 
  * @arg {Object} args - Les arguments envoyés à la mutation. Cf le schéma GraphQL 
@@ -259,50 +282,60 @@ export const getUserJoinGroupRequests = (user, recipientUID) => {
     return knex('user_join_group').select(/*'id', 'useruid', 'message'*/)/*.where('recipient', recipientUID)*/;
 };
 
-//Don't forget the argument user is the guy who makes the request, not the user we want
+/**
+ * @function Obtient un utilisateur dont on donne l'identifiant.
+ * @param {Object} user - Utilisateur émettant la requête. 
+ * @param {String} userUID - Utilisateur demandé.
+ */
 export const getUser = (user, userUID) => { 
-    return new Promise( (resolve, reject) => {
-        resolve({
-            givenName : "Jean-Michel",
-            lastName : "Samarchepas",
-            uid : "jm",
-            birthdate : "dans le turfu",
-            mail : "email.email@email.com",
-            phone : "06 60 06 60 06",
-            groups : [],
-            likes : [],
-            address : "aussi dans le turfu"
-        });
-    });
-    /*return renseignerSurUtilisateur(user, userUID).then(res => {
+    const refactorer = (data) => {
         return {
-            givenName : res[0].givenName,
-            lastName : res[0].lastName,
-            uid : userUID,
-            birthdate : res[0].brBirthdate,
-            mail : res[0].mail,
-            phone : res[0].telephoneNumber,
-            groups : [],
-            likes : [],
-            address : res[0].brRoom
+            uid: userUID,
+            lastName: data.sn,
+            givenName: data.givenName,
+            birthdate: data.brBirthdate,
+            groups: data.brMemberOf,
+            mail: data.mail,
+            phone: data.telephoneNumber,
+            room: data.brRoom
         };
-    });*/
+    };
+
+    const result = renseignerSurUtilisateur(user, userUID).then(res => {
+        return refactorer(res[0]);
+    });
+
+    return result;
 };
 
+/**
+ * @function Renvoie un événement en fonction de son identifiant.
+ * @param {*} user - Utilisateur effectuant la requête.
+ * @param {*} eventID - Identifiant unique de l'événement.
+ */
 export const getEvent = (user, eventID) => {
     return quickPromise(null);
 };
 
+/**
+ * @function Renvoie simplement un groupe en fonction de son identifiant.
+ * @param {Object} user - Utilisateur effectuant la requête.
+ * @param {String} groupUID - Identifiant unique du groupe.
+ * @author manifold 
+ */
 export const getGroup = (user, groupUID) => {
-    return quickPromise(null);
+    // Une sélection sur une table renvoie un tableau.
+    // Knex renvoie une promesse, qui se résout en le tableau sélectionné.
+    // On récupère son unique valeur, puisqu'on filtre sur l'identifiant unique.
+    return knex.select().from('groups').where('uid',groupUID).then(results => results [0]);
 };
 
 export const getSimpleGroup = (user, groupUID) => {
-    return quickPromise(null);
+    return knex.select().from('simple_groups').where('uid',groupUID).then(results => results [0]);
 };
 
 export const getMetaGroup = (user, groupUID) => {
-    return quickPromise(null);
+    return knex.select().from('meta_groups').where('uid',groupUID).then(results => results [0]);
 };
 
 export const getMetaGroupAdminMembers = (user, metaGroupUID) => {
diff --git a/src/graphql/resolvers.js b/src/graphql/resolvers.js
index aee354d..df5d4c9 100644
--- a/src/graphql/resolvers.js
+++ b/src/graphql/resolvers.js
@@ -1,13 +1,13 @@
 /**
- * @file Ce fichier construit les resolvers GraphQL.
+ * @file Implémentation des requêtes GraphQL.
  * @author akka vodol
 */
-
 import { request } from 'https';
+import _ from 'lodash';
 import { assertBinaryExpression } from 'babel-types';
 import knex from '../../db/knex_router';
 
-import * as db_utils from './db_utils';
+import * as connectors from './connectors/connectors.js';
 
 /** 
  * @description Résolveurs des différentes requêtes GraphQL
@@ -16,7 +16,7 @@ export const resolvers = {
     Query: {
 
         asAdmin: (obj, args, context) => {
-            return db_utils.hasAdminRights(context.user, args.groupUID).then(res => {
+            return connectors.hasAdminRights(context.user, args.groupUID).then(res => {
                 if(res)
                     return {groupUID : args.groupUID};
                 else
@@ -39,20 +39,20 @@ export const resolvers = {
 
     GroupQuery : {
         allGroups: (obj, args, context) => {
-            return db_utils.getAllVisibleGroups(context.user);
+            return connectors.getAllVisibleGroups(context.user);
         },
         group: (obj, args, context) => {
-            return db_utils.getGroupIfVisible(context.user, args.uid);
+            return connectors.getGroupIfVisible(context.user, args.uid);
         },
         simpleGroup: (obj, args, context) => {
-            return db_utils.getGroupIfVisible(context.user, args.uid, "simple");
+            return connectors.getGroupIfVisible(context.user, args.uid, "simple");
         },
         metaGroup: (obj, args, context) => {
-            return db_utils.getGroupIfVisible(context.user, args.uid, "meta");
+            return connectors.getGroupIfVisible(context.user, args.uid, "meta");
         }
     },
 
-    PostQuery : {
+    MessageQuery : {
         allPosts: (obj, args, context) => {
             return knex.select().from('posts');
         },
@@ -64,29 +64,13 @@ export const resolvers = {
 
     UserQuery: {
         user: (obj, args, context) => {
-            const refactorer = (data) => {
-                return {
-                    uid: args.uid,
-                    lastName: data.sn,
-                    givenName: data.givenName,
-                    birthdate: data.brBirthdate,
-                    groups: data.brMemberOf,
-                    mail: data.mail,
-                    phone: data.telephoneNumber,
-                    room: data.brRoom
-                };
-            };
-
-            const result = db_utils.renseignerSurUtilisateur(context.user, args.uid).then(res => {
-                return refactorer(res[0]);
-            });
-
-            return result;
+            
+            return connectors.getUser(context.user,args.uid);
         },
 
         searchTOL: (obj, args, context) => {
             console.log(args);
-            return db_utils.repliquerTOLdesIds(context.user, {
+            return connectors.repliquerTOLdesIds(context.user, {
                 givenName: args.givenName,
                 lastName: args.lastName,
                 nickname: args.nickname,
@@ -117,13 +101,13 @@ export const resolvers = {
 
     AllRequests: {
         userJoinGroup : (obj, args, context) => {
-            return db_utils.getUserJoinGroupRequests(context.user, args.groupUID);
+            return connectors.getUserJoinGroupRequests(context.user, args.groupUID);
         },
     },
 
     UserJoinGroup: {
         user : (obj, args, context) => {
-            return db_utils.getUser(context.user, obj.useruid);
+            return connectors.getUser(context.user, obj.useruid);
             /*return db_utils.getUser(context.user, "quentin.gendre");
             if(obj.useruid === "anatole.romon"){
                 return db_utils.getUser(context.user, "anatole.romon").then(res => {
@@ -139,66 +123,38 @@ export const resolvers = {
 
     GroupJoinEvent : {
         event: (obj, args, context) => {
-            return db_utils.getEvent(context.user, obj.eventuid);
+            return connectors.getEvent(context.user, obj.eventuid);
         },
         groupWantingToJoin: (obj, args, context) => {
-            return db_utils.getGroup(context.user, obj.senderuid);
+            return connectors.getGroup(context.user, obj.senderuid);
         }
     },
 
     YourGroupHostEvent : {
         event: (obj, args, context) => {
-            return db_utils.getEvent(context.user, obj.eventuid);
+            return connectors.getEvent(context.user, obj.eventuid);
         },
         sender: (obj, args, context) => {
-            return db_utils.getGroup(context.user, obj.senderuid);
+            return connectors.getGroup(context.user, obj.senderuid);
         }
     },
 
-    /*User : {
-
-        givenName : (obj, args, context) => {
-            console.log("I got this")
-            return null;
-        },
-
-        lastName : (obj, args, context) => {
-            return null;
-        },
-
-        uid : (obj, args, context) => {
-            return null;
-        },
-
-        birthdate : (obj, args, context) => {
-            return null;
-        },
-
-        mail : (obj, args, context) => {
-            return null;
-        },
-
-        phone : (obj, args, context) => {
-            return null;
-        },
-
+    User : {
         groups : (obj, args, context) => {
-            return null;
-        },
+            let result = Promise.all(obj.groups.map((grid) => {
+                return connectors.getSimpleGroup(context.user,grid);
+            }));
 
-        likes : (obj, args, context) => {
-            return null;
+            return result.then(groups => {
+                return _.filter(groups,(o) => !_.isUndefined(o));
+            });
         },
 
-        address : (obj, args, context) => {
-            return null;
-        }
-
-    },*/
+    },
 
     Mutation: {
         asAdmin: (obj, args, context) => {
-            return db_utils.hasAdminRights(context.user, args.groupUID).then(res => {
+            return connectors.hasAdminRights(context.user, args.groupUID).then(res => {
                 if(res)
                     return {groupUID : args.groupUID};
                 else
@@ -207,7 +163,7 @@ export const resolvers = {
         },
 
         asSpeaker: (obj, args, context) => {
-            return db_utils.hasAdminRights(context.user, args.groupUID).then(res => {
+            return connectors.hasAdminRights(context.user, args.groupUID).then(res => {
                 if(res)
                     return {groupUID : args.groupUID};
                 else
@@ -216,7 +172,7 @@ export const resolvers = {
         },
 
         asMember: (obj, args, context) => {
-            return db_utils.isMember(context.user, args.groupUID).then(res => {
+            return connectors.isMember(context.user, args.groupUID).then(res => {
                 if(res)
                     return {groupUID : args.groupUID};
                 else
@@ -224,7 +180,7 @@ export const resolvers = {
             });
         },
         asViewer: (obj, args, context) => {
-            return db_utils.getGroupIfVisible(context.user, args.groupUID).then(res => {
+            return connectors.getGroupIfVisible(context.user, args.groupUID).then(res => {
                 if(res)
                     return {groupUID : args.groupUID};
                 else
@@ -240,7 +196,7 @@ export const resolvers = {
         },
         createSubgroup: (obj, args, context) => {
             args.parentuid = obj.groupUID;
-            return db_utils.createSubgroup(context.user, args);
+            return connectors.createSubgroup(context.user, args);
         },
 
         editGroup: (obj, args, context) => {
@@ -280,10 +236,14 @@ export const resolvers = {
         members: (obj, args, context) => {
             console.log("Current group is",obj.uid);
             console.log("\tMembers of the group are:",obj);
-            return db_utils.listerMembres(context.user,obj.uid);
+            return connectors.listerMembres(context.user,obj.uid);
         }
     },
 
     MetaGroup: {
+
+        members: (obj, args, context) => {
+        }
+
     }
 };
diff --git a/src/graphql/typeDefs.js b/src/graphql/typeDefs.js
index d239876..b77e9ea 100644
--- a/src/graphql/typeDefs.js
+++ b/src/graphql/typeDefs.js
@@ -2,7 +2,7 @@ const RootTypes = `
     # Requêtes
     type Query {
         accessGroups : GroupQuery
-        accessPosts : PostQuery
+        accessPosts : MessageQuery
         accessUsers : UserQuery
 
         asAdmin(groupUID: ID): AdminQuery
@@ -67,6 +67,9 @@ const subMutations = `
 
 const subQueries = `
 
+    """
+    Requête pour obtenir un groupe.
+    """
     type GroupQuery{
         allGroups: [Group]
         group(uid: ID) : Group
@@ -75,7 +78,10 @@ const subQueries = `
 
     }
 
-    type PostQuery{
+    """
+    Requête pour obtenir un message.
+    """
+    type MessageQuery{
         allMessages: [Message]
         allEvents: [Event]
         allPosts: [Post]
@@ -135,7 +141,7 @@ const User = `
         mail: String
         phone: String
         # Groupes dont l'utilisateur est membre.
-        groups: [Group]
+        groups: [SimpleGroup]
         # Groupes que l'utilisateur aime.
         likes: [Group]
         address: String
@@ -145,10 +151,11 @@ const User = `
 const Group = `
     # Groupes associatifs
 
-    # L'interface Group implemente les deux types de groupes possibles:
-    # Les groupes constitués directement de gens et les groupes constitués de d'autres groupes
-    # En dehors des opérations sur les membres, ces deux types de groupes se comportent pareil
-    # Et ils peuvent tous les deux êtres manipulés par l'interface Group 
+    """
+    L'interface Group représente les deux types de groupes implémentés dans Sigma : les groupes
+    simples, dont les membres sont des utilisateurs, et les métagroupes, dont les membres sont
+    des groupes simples (tel que Federez, dont les membres incluent le BR et DaTA). 
+    """
     interface Group {
         # Identifiant unique de l'union
         uid: ID
@@ -189,8 +196,8 @@ const Group = `
         createdAt: String!
         updatedAt: String!
 
-        # Les membres sont des groupes
-        groupMembers: [Group]!
+        # Les groupes constitutifs du méta-groupe.
+        members: [Group]!
     }
 
 `;
diff --git a/src/ldap/ldap_data.js b/src/ldap/ldap_data.js
index 16e8867..2d8922c 100644
--- a/src/ldap/ldap_data.js
+++ b/src/ldap/ldap_data.js
@@ -32,7 +32,7 @@ var client = ldap.createClient({ url: config.ldap.server});
 //------------------------------------------------------------------------------------------------------------------------
 
 /**
- * @summary Fonction qui sert à s'identifier sur le LDAP. Renvoit rien.
+ * @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 :
@@ -164,7 +164,7 @@ function listerGroupes(user, uid) {
  * @desc Cette fonction utilise {@link rechercherLDAP} avec un dictionnaire prédéfini dans config.json. Elle utilise LDAPEscape pour éviter les injections.
  * @arg {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
  * @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)
+ * @return {Promise(String[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
  */
 function listerMembres(user, gid) {
     return new Promise(function(resolve, reject) {
@@ -203,7 +203,8 @@ function renseignerSurUtilisateur(user, uid) {
 //------------------------------------------------------------------------------------------------------------------------
 
 /**
- * @summary Fonction qui interroge le LDAP et retrouve les groupes (voir LDAP) qui ressemblent à l'input. Etape 0 vers un vrai TOL (Trombino On Line).
+ * @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 {Object} user - Utilisateur de la forme nécessaire à {@link connecterLDAP}
  * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
@@ -685,7 +686,9 @@ function editerGroupe(user, data) {
 //TBC
 /**
  * @summary Fonction qui supprime un utilisateur du LDAP.
- * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ; voir ldap_config.json pour le détail de la génération des champs finaux. Appelle {@link ajouterLDAP} bien sûr, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe} pour gérer les groupes du nouvel utilisateur.
+ * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ;
+ * voir ldap_config.json pour le détail de la génération des champs finaux. 
+ * 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} uid - uid de la victime
  * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
@@ -720,7 +723,10 @@ function supprimerUtilisateur(user, data) {
 //TBC
 /**
  * @summary Fonction qui supprime un 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 ajouterLDAP} et {@link modifierLDAP}, mais aussi {@link ajouterMembreGroupe} et {@link ajouterAdministrateurGroupe} pour gérer les groupes du nouvel utilisateur.
+ * @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 ajouterLDAP} 
+ * et {@link modifierLDAP}, 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 à supprimer
  * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
diff --git a/src/server.js b/src/server.js
index 9a54338..af64a85 100644
--- a/src/server.js
+++ b/src/server.js
@@ -113,7 +113,7 @@ server.use('/graphql', bodyParser.json(),
     }));
 
 // GraphiQL est une console interactive pour faire des requêtes au schéma GraphQL
-server.use('/graphiql', ensureLoggedIn('/login'), graphiqlExpress({endpointURL: '/graphql'}));
+server.use('/graphiql', /*ensureLoggedIn('/login'),*/ graphiqlExpress({endpointURL: '/graphql'}));
 
 // GraphQL voyager
 server.use('/voyager', graphqlVoyager({ endpointUrl: '/graphql' }));
-- 
GitLab