diff --git a/src/app.ts b/src/app.ts
index d90da204975279980098166f0fe3398889e9ed4f..7694423c3a0890689dc6086ac54e11895a58e571 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -179,8 +179,9 @@ app.post('/login', (req, res, next) => {
 
 // Define GraphQL request's context object, through a callback, with authorization.
 // See: https://www.apollographql.com/docs/apollo-server/features/authentication.html
-
-const context = async ({ req }) => {
+import { Context } from './graphql/typeDefs/queries';
+import { AuthorisationModel } from './graphql/connectors/authorisationModel';
+const context = async ({ req }): Promise<Context> => {
     // set a special uid for non-authenticated requests
     // /!\ FOR DEVELOPMENT ONLY: use the one in the ldap config .json file
     // for production, replace with a "publicUser" or "notLoggedInUser" or something.
@@ -204,7 +205,10 @@ const context = async ({ req }) => {
     
     return {
         request: req,
-        user: { uid: uid }
+        user: { uid: uid },
+        models: {
+            auth: await AuthorisationModel.create(uid)
+        }
     };
 };
 
diff --git a/src/graphql/connectors/authorisation.ts b/src/graphql/connectors/authorisation.ts
deleted file mode 100644
index 60ef61c410e77e88e23f37804c22221f2b3a727e..0000000000000000000000000000000000000000
--- a/src/graphql/connectors/authorisation.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file Fonctions qui gerent l'autorisation des utilisateurs
- * @author ofacklam
- * @memberof GraphQL
- */
-
- import {Tools} from './tools'
-
-/*
- * There are 7 levels of authorisation
- *  none : doesn't know the group / the user exists
- *  connectedOrOnplatal : knows the group exists, can use TOL
- *  viewer : can see the group
- *  member : part of the group
- *  speaker : allowed to speak for the group
- *  admin : admin of the group
- *  supervisor : allowed to take control of the group
- */
-
-// These functions test if the given user has the right privileges for the given group
-
-export class Authorisation {
-
-    /**
-     * @memberof GraphQL
-     * @class Authorisation
-     * @summary Autorisation des utilisateurs.
-     * @classdesc Cette classe contient les fonctions d'autorisation des utilisateurs.
-     */
-    constructor() { }
-
-    static PUBLICUSER = "public_user";
-    static ONPLATALUSER = "public_onplatal_user";
-
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est connecté ou on-platal
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est connecté ou on-platal
-     * @static
-     */
-    static isConnectedOrOnplatal(uid: string): boolean {
-        return (uid != this.PUBLICUSER);
-    }
-    
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est authentifié
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est authentifié
-     * @static
-     */
-    static isAuthenticated(uid: string): boolean {
-        return(uid != this.PUBLICUSER && uid != this.ONPLATALUSER);
-    }
-
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est viewer du groupe.
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @arg {string} gid - Identifiant du groupe.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est viewer du groupe.
-     * @static
-     * @async
-     */
-    static async isViewer(uid: string, gid: string): Promise<boolean> {
-        //ensure uid is valid !!!!!!!!
-        if(Authorisation.isAuthenticated(uid)) {
-            let groups = await Tools.viewerOf(uid);
-            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
-        }
-        return false;
-    }
-
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est membre du groupe.
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @arg {string} gid - Identifiant du groupe.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est membre du groupe.
-     * @static
-     * @async
-     */
-    static async isMember(uid: string, gid: string): Promise<boolean> {
-        //ensure uid is valid !!!!!!!!
-        if(Authorisation.isAuthenticated(uid)) {
-            let groups = await Tools.memberOf(uid);
-            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
-        }
-        return false;
-    }
-
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est speaker du groupe.
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @arg {string} gid - Identifiant du groupe.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est speaker du groupe.
-     * @static
-     * @async
-     */
-    static async isSpeaker(uid: string, gid: string): Promise<boolean> {
-        //ensure uid is valid !!!!!!!!
-        if(Authorisation.isAuthenticated(uid)) {
-            let groups = await Tools.speakerOf(uid);
-            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
-        }
-        return false;
-    }
-
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est admin du groupe.
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @arg {string} gid - Identifiant du groupe.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est admin du groupe.
-     * @static
-     * @async
-     */
-    static async isAdmin(uid: string, gid: string): Promise<boolean> {
-        //ensure uid is valid !!!!!!!!
-        if(Authorisation.isAuthenticated(uid)) {
-            let groups = await Tools.adminOf(uid);
-            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
-        }
-        return false;
-    }
-
-    /**
-     * @memberof GraphQL
-     * @summary Fonction qui renvoit si l'utilisateur est supervisor du groupe.
-     * @arg {string} uid - Identifiant de l'utilisateur.
-     * @arg {string} gid - Identifiant du groupe.
-     * @return {Promise(boolean)} Renvoie true si l'utilisateur est supervisor du groupe.
-     * @static
-     * @async
-     */
-    static async isSupervisor(uid: string, gid: string): Promise<boolean> {
-        //ensure uid is valid !!!!!!!!
-        if(Authorisation.isAuthenticated(uid)) {
-            let groups = await Tools.supervisorOf(uid);
-            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
-        }
-        return false;
-    }
-
-}
\ No newline at end of file
diff --git a/src/graphql/connectors/authorisationModel.ts b/src/graphql/connectors/authorisationModel.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8064b9ac2d595826d3cf3c0e832044951e6e0fe4
--- /dev/null
+++ b/src/graphql/connectors/authorisationModel.ts
@@ -0,0 +1,190 @@
+/**
+ * @file Fonctions qui gerent l'autorisation des utilisateurs
+ * @author ofacklam
+ * @memberof GraphQL
+ */
+
+import { Tools, GroupSet, GroupCollection } from "./tools";
+import { User as UT } from '../../ldap/export/user'
+
+/*
+ * There are 7 levels of authorisation
+ *  none : doesn't know the group / the user exists
+ *  connectedOrOnplatal : knows the group exists, can use TOL
+ *  viewer : can see the group
+ *  member : part of the group
+ *  speaker : allowed to speak for the group
+ *  admin : admin of the group
+ *  supervisor : allowed to take control of the group
+ */
+
+export class AuthorisationModel {
+    
+    /**
+     * @memberof GraphQL
+     * @class AuthorisationModel
+     * @summary Autorisation des utilisateurs.
+     * @classdesc Cette classe contient les méthodes d'autorisation de l'utilisateur dans le 'context'.
+     * @arg {string} uid - L'identifiant de l'utilisateur.
+     */
+    constructor(uid: string) {
+        this.uid = uid;
+    }
+
+    /**
+     * @memberof GraphQL
+     * @summary Fonction qui crée une nouvelle instance de AuthorisationModel et charge les données
+     * @arg {string} uid - Identifiant de l'utilisateur.
+     * @returns {Promise<AuthorisationModel>} Renvoie un nouveau AuthorisationModel avec cet utilisateur
+     * @async
+     * @static
+     */
+    static async create(uid: string): Promise<AuthorisationModel> {
+        let model = new AuthorisationModel(uid);
+        
+        if(model.isAuthenticated()) {
+            await model.fetchData();
+        }
+
+        return model;
+    }
+
+    protected uid: string;
+    protected viewerOf: GroupCollection;
+    protected memberOf: GroupCollection;
+    protected speakerOf: GroupCollection;
+    protected adminOf: GroupCollection;
+    protected supervisorOf: GroupCollection;
+
+    static PUBLICUSER = "public_user";
+    static ONPLATALUSER = "public_onplatal_user";
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui recupere toutes les données pour populer les champs a partir de l'uid.
+     * @async
+     */
+    async fetchData(): Promise<void> {
+        let data = await UT.peek(this.uid);
+
+        this.viewerOf = await Tools.viewerOf(data);
+        this.memberOf = await Tools.memberOf(data);
+        this.speakerOf = await Tools.viewerOf(data);
+        this.adminOf = await Tools.adminOf(data);
+        this.supervisorOf = await Tools.supervisorOf(data);
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est connecté ou on-platal
+     * @return {boolean} Renvoie true si l'utilisateur est connecté ou on-platal
+     */
+    isConnectedOrOnplatal(): boolean {
+        return (this.uid != AuthorisationModel.PUBLICUSER);
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est authentifié
+     * @return {boolean} Renvoie true si l'utilisateur est authentifié
+     */
+    isAuthenticated(): boolean {
+        return (this.uid != AuthorisationModel.PUBLICUSER && this.uid != AuthorisationModel.ONPLATALUSER);
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est viewer du groupe.
+     * @arg {string} gid - Identifiant du groupe.
+     * @return {boolean} Renvoie true si l'utilisateur est viewer du groupe.
+     */
+    isViewer(gid: string): boolean {
+        //ensure uid is valid !!!!!!!!
+        if (this.isAuthenticated()) {
+            let groups = this.viewerOf;
+            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
+        }
+        return false;
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est membre du groupe.
+     * @arg {string} gid - Identifiant du groupe.
+     * @return {boolean} Renvoie true si l'utilisateur est membre du groupe.
+     */
+    isMember(gid: string): boolean {
+        //ensure uid is valid !!!!!!!!
+        if (this.isAuthenticated()) {
+            let groups = this.memberOf;
+            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
+        }
+        return false;
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est membre d'au moins un de ces groupes.
+     * @arg {GroupSet} groups - Ensemble de groupes.
+     * @return {boolean} Renvoie true si l'utilisateur est membre d'un des groupes
+     */
+    isMemberOr(groups: GroupSet): boolean {
+        //ensure uid is valid !!!!!!!!
+        if (this.isAuthenticated()) {
+            let member = this.memberOf;
+
+            for (let gid of groups) {
+                if (member.simpleGroups.has(gid) || member.metaGroups.has(gid)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est speaker du groupe.
+     * @arg {string} gid - Identifiant du groupe.
+     * @return {boolean} Renvoie true si l'utilisateur est speaker du groupe.
+     */
+    isSpeaker(gid: string): boolean {
+        //ensure uid is valid !!!!!!!!
+        if (this.isAuthenticated()) {
+            let groups = this.speakerOf;
+            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
+        }
+        return false;
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est admin du groupe.
+     * @arg {string} gid - Identifiant du groupe.
+     * @return {boolean} Renvoie true si l'utilisateur est admin du groupe.
+     */
+    isAdmin(gid: string): boolean {
+        //ensure uid is valid !!!!!!!!
+        if (this.isAuthenticated()) {
+            let groups = this.adminOf;
+            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
+        }
+        return false;
+    }
+
+    /**
+     * @memberof GraphQL.AuthorisationModel#
+     * @summary Fonction qui renvoit si l'utilisateur est supervisor du groupe.
+     * @arg {string} gid - Identifiant du groupe.
+     * @return {boolean} Renvoie true si l'utilisateur est supervisor du groupe.
+     */
+    isSupervisor(gid: string): boolean {
+        //ensure uid is valid !!!!!!!!
+        if (this.isAuthenticated()) {
+            let groups = this.supervisorOf;
+            return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid));
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/src/graphql/connectors/tools.ts b/src/graphql/connectors/tools.ts
index 55e45f0c3317c867e48682d2a7730df10373d539..5455700abbe8ca019c4de1db095ba0a7a0f0ed51 100644
--- a/src/graphql/connectors/tools.ts
+++ b/src/graphql/connectors/tools.ts
@@ -53,38 +53,36 @@ export class Tools {
     /**
      * @memberof GraphQL
      * @summary Fonction qui renvoit tous les groupes simples dont le user est membre.
-     * @arg {string} uid - Identifiant de l'utilisateur, supposé valide.
+     * @arg {userData} data - Données de l'utilisateur.
      * @return {Promise(GroupSet)} Renvoie un GroupSet contenant le nom des groupes simples.
      * @static
      * @async
      */
-    static async memberOfSimple(uid: string): Promise<GroupSet> {
-        let data = await UT.peek(uid);
+    static async memberOfSimple(data: userData): Promise<GroupSet> {
         return new GroupSet(data.groups);
     }
 
     /**
      * @memberof GraphQL
      * @summary Fonction qui renvoit tous les groupes simples dont le user est speaker.
-     * @arg {string} uid - Identifiant de l'utilisateur, supposé valide.
+     * @arg {userData} data - Données de l'utilisateur.
      * @return {Promise(GroupSet)} Renvoie un GroupSet contenant le nom des groupes simples.
      * @static
      * @async
      */
-    static async speakerOfSimple(uid: string): Promise<GroupSet> {
+    static async speakerOfSimple(data: userData): Promise<GroupSet> {
         throw "Not implemented";
     }
 
     /**
      * @memberof GraphQL
      * @summary Fonction qui renvoit tous les groupes simples dont le user est administrateur.
-     * @arg {string} uid - Identifiant de l'utilisateur, supposé valide.
+     * @arg {userData} data - Données de l'utilisateur.
      * @return {Promise(GroupSet)} Renvoie un GroupSet contenant le nom des groupes simples.
      * @static
      * @async
      */
-    static async adminOfSimple(uid: string): Promise<GroupSet> {
-        let data = await UT.peek(uid);
+    static async adminOfSimple(data: userData): Promise<GroupSet> {
         return new GroupSet(data.groupsIsAdmin);
     }
 
@@ -106,40 +104,40 @@ export class Tools {
     /**
      * @memberof GraphQL
      * @summary Fonction qui renvoit tous les groupes (simples ou méta) dont le user est membre.
-     * @arg {string} uid - Identifiant de l'utilisateur, supposé valide.
+     * @arg {userData} data - Données de l'utilisateur.
      * @return {Promise(GroupCollection)} Renvoie une GroupCollection contenant le nom des groupes. 
      * @static
      * @async
      */
-    static async memberOf(uid: string): Promise<GroupCollection> {
-        let simple = await Tools.memberOfSimple(uid);
+    static async memberOf(data: userData): Promise<GroupCollection> {
+        let simple = await Tools.memberOfSimple(data);
         return { simpleGroups: simple, metaGroups: await Tools.metaGroupsOfGroups(simple) };
     }
 
     /**
      * @memberof GraphQL
      * @summary Fonction qui renvoit tous les groupes (simples ou méta) dont le user est speaker.
-     * @arg {string} uid - Identifiant de l'utilisateur, supposé valide.
+     * @arg {userData} data - Données de l'utilisateur.
      * @return {Promise(GroupCollection)} Renvoie une GroupCollection contenant le nom des groupes. 
      * @static
      * @async
      */
-    static async speakerOf(uid: string): Promise<GroupCollection> {
-        let speaker = await Tools.speakerOfSimple(uid);
-        let admin = await Tools.adminOfSimple(uid);
+    static async speakerOf(data: userData): Promise<GroupCollection> {
+        let speaker = await Tools.speakerOfSimple(data);
+        let admin = await Tools.adminOfSimple(data);
         return { simpleGroups: speaker, metaGroups: await Tools.metaGroupsOfGroups(admin) };
     }
 
     /**
      * @memberof GraphQL
      * @summary Fonction qui renvoit tous les groupes (simples ou méta) dont le user est administrateur.
-     * @arg {string} uid - Identifiant de l'utilisateur, supposé valide.
+     * @arg {userData} data - Données de l'utilisateur.
      * @return {Promise(GroupCollection)} Renvoie une GroupCollection contenant le nom des groupes.
      * @static
      * @async
      */
-    static async adminOf(uid: string): Promise<GroupCollection> {
-        let simple = await Tools.adminOfSimple(uid);
+    static async adminOf(data: userData): Promise<GroupCollection> {
+        let simple = await Tools.adminOfSimple(data);
         return { simpleGroups: simple, metaGroups: await Tools.metaGroupsOfGroups(simple) };
     }
 
@@ -186,13 +184,13 @@ export class Tools {
      * @memberof GraphQL
      * @summary Fonction qui renvoie tous les groupes dont l'utilisateur est supervisor.
      * @desc Utilise {@link Tools.oneDownSearch} pour avoir la profondeur 1 des arbres enracinés en chacun des groupes dont il est admin.
-     * @arg {string} uid - Identifiant du user, supposé valide.
-     * @return {Promise(string[])} Renvoie une liste contenant le nom des groupes.
+     * @arg {userData} data - Données du user.
+     * @return {Promise(GroupCollection)} Renvoie une GroupCollection contenant le nom des groupes.
      * @static
      * @async
      */
-    static async supervisorOf(uid: string): Promise<GroupCollection> {
-        let groups = await Tools.adminOf(uid);
+    static async supervisorOf(data: userData): Promise<GroupCollection> {
+        let groups = await Tools.adminOf(data);
 
         let simple = new GroupSet();
         let meta = new GroupSet();
@@ -211,13 +209,13 @@ export class Tools {
      * @memberof GraphQL
      * @summary Fonction qui renvoie tous les groupes dont l'utilisateur est viewer.
      * @desc Utilise {@link Tools.oneDownSearch} pour avoir la profondeur 1 des arbres enracinés en chacun des groupes dont il est membre.
-     * @arg {string} uid - Identifiant du user, supposé valide.
-     * @return {Promise(string[])} Renvoie une liste contenant le nom des groupes.
+     * @arg {userData} data - Données du user.
+     * @return {Promise(GroupCollection)} Renvoie une GroupCollection contenant le nom des groupes.
      * @static
      * @async
      */
-    static async viewerOf(uid: string): Promise<GroupCollection> {
-        let groups = await Tools.memberOf(uid);
+    static async viewerOf(data: userData): Promise<GroupCollection> {
+        let groups = await Tools.memberOf(data);
 
         let simple = new GroupSet();
         let meta = new GroupSet();
diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts
index c2fc1ccab31f36e9d188b78d7cbdf776342241ae..fcc78cafc0d9a0e609d25979b2368662d4715d44 100644
--- a/src/graphql/resolvers.ts
+++ b/src/graphql/resolvers.ts
@@ -10,8 +10,8 @@ import knex from '../../db/knex_router';
 
 import '../config_passport';
 
-import * as auth from './new_connectors/authorisation';
-import * as conn from './new_connectors/connection';
+import * as auth from './connectors/authorisation';
+import * as conn from './connectors/connection';
 
 import MessageResolvers from './resolvers/messages';
 import GroupResolvers from './resolvers/groups';
diff --git a/src/graphql/resolvers/groups.ts b/src/graphql/resolvers/groups.ts
index bced15a11d592f5946dc26afa3608d7ac40b73a3..5f5dc400f42c467de58b9c8565cc9d0a30e2f022 100644
--- a/src/graphql/resolvers/groups.ts
+++ b/src/graphql/resolvers/groups.ts
@@ -3,11 +3,11 @@
  * @author ofacklam
  */
 
-import {Authorisation} from '../connectors/authorisation';
 import {User} from './users';
 import {Announcement, Event, PrivatePost, Question, Answer} from './messages';
 import {Group as LDAP_Group} from '../../ldap/export/group';
 import knex from '../../../db/knex_router';
+import { Context } from '../typeDefs/queries';
 
 export abstract class Group {
 
@@ -88,7 +88,7 @@ export abstract class Group {
      * @rights connectedOrOnplatal
      * @async
      */
-    async createdAt(args, context, info): Promise<string> {
+    async createdAt(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_createdAt;
     }
@@ -101,7 +101,7 @@ export abstract class Group {
      * @rights connectedOrOnplatal
      * @async
      */
-    async updatedAt(args, context, info): Promise<string> {
+    async updatedAt(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_updatedAt;
     }
@@ -114,7 +114,7 @@ export abstract class Group {
      * @rights connectedOrOnplatal
      * @async
      */
-    async name(args, context, info): Promise<string> {
+    async name(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_name;
     }
@@ -127,8 +127,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async description(args, context, info): Promise<string> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async description(args, context: Context, info): Promise<string> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_description;
         }
@@ -143,8 +143,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async mail(args, context, info): Promise<string> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async mail(args, context: Context, info): Promise<string> {
+        if (context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_mail;
         }
@@ -159,8 +159,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async website(args, context, info): Promise<string> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async website(args, context: Context, info): Promise<string> {
+        if (context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_website;
         }
@@ -176,7 +176,7 @@ export abstract class Group {
      * @async
      * @abstract
      */
-    abstract async admins(args, context, info): Promise<User[]>
+    abstract async admins(args, context: Context, info): Promise<User[]>
 
     /**
      * @memberof GraphQL.Group#
@@ -186,8 +186,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async frontPage(args, context, info): Promise<string> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async frontPage(args, context: Context, info): Promise<string> {
+        if (context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_frontPage;
         }
@@ -202,8 +202,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async questions(args, context, info): Promise<Question[]> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async questions(args, context: Context, info): Promise<Question[]> {
+        if (context.models.auth.isViewer(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a viewer";
@@ -217,8 +217,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async answers(args, context, info): Promise<Answer[]> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async answers(args, context: Context, info): Promise<Answer[]> {
+        if (context.models.auth.isViewer(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a viewer";
@@ -232,8 +232,8 @@ export abstract class Group {
      * @rights member
      * @async
      */
-    async announcementsFromGroup(args, context, info): Promise<Announcement[]> {
-        if(await Authorisation.isMember(context.user.uid, this.gid)) {
+    async announcementsFromGroup(args, context: Context, info): Promise<Announcement[]> {
+        if(context.models.auth.isMember(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a member"
@@ -247,8 +247,8 @@ export abstract class Group {
      * @rights member
      * @async
      */
-    async announcementsToGroup(args, context, info): Promise<Announcement[]> {
-        if (await Authorisation.isMember(context.user.uid, this.gid)) {
+    async announcementsToGroup(args, context: Context, info): Promise<Announcement[]> {
+        if (context.models.auth.isMember(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a member"
@@ -262,8 +262,8 @@ export abstract class Group {
      * @rights member
      * @async
      */
-    async eventsFromGroup(args, context, info): Promise<Event[]> {
-        if (await Authorisation.isMember(context.user.uid, this.gid)) {
+    async eventsFromGroup(args, context: Context, info): Promise<Event[]> {
+        if (context.models.auth.isMember(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a member"
@@ -277,8 +277,8 @@ export abstract class Group {
      * @rights member
      * @async
      */
-    async eventsToGroup(args, context, info): Promise<Event[]> {
-        if (await Authorisation.isMember(context.user.uid, this.gid)) {
+    async eventsToGroup(args, context: Context, info): Promise<Event[]> {
+        if (context.models.auth.isMember(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a member"
@@ -292,8 +292,8 @@ export abstract class Group {
      * @rights member
      * @async
      */
-    async privatePosts(args, context, info): Promise<PrivatePost[]> {
-        if (await Authorisation.isMember(context.user.uid, this.gid)) {
+    async privatePosts(args, context: Context, info): Promise<PrivatePost[]> {
+        if (context.models.auth.isMember(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a member"
@@ -307,8 +307,8 @@ export abstract class Group {
      * @rights member
      * @async
      */
-    async postsSummary(args, context, info): Promise<string> {
-        if (await Authorisation.isMember(context.user.uid, this.gid)) {
+    async postsSummary(args, context: Context, info): Promise<string> {
+        if (context.models.auth.isMember(this.gid)) {
             await this.fetchData();
             return this.m_postsSummary;
         }
@@ -323,8 +323,8 @@ export abstract class Group {
      * @rights viewer
      * @async
      */
-    async visibilityEdges(args, context, info): Promise<Group[]> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async visibilityEdges(args, context: Context, info): Promise<Group[]> {
+        if (context.models.auth.isViewer(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a viewer";
@@ -439,8 +439,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async members(args, context, info): Promise<User[]> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async members(args, context: Context, info): Promise<User[]> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_members.map(uid => {
                 return new User(uid);
@@ -457,8 +457,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async speakers(args, context, info): Promise<User[]> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async speakers(args, context: Context, info): Promise<User[]> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_speakers.map(uid => {
                 return new User(uid);
@@ -475,8 +475,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async admins(args, context, info): Promise<User[]> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async admins(args, context: Context, info): Promise<User[]> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_admins.map(uid => {
                 return new User(uid);
@@ -493,8 +493,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async likers(args, context, info): Promise<User[]> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async likers(args, context: Context, info): Promise<User[]> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_likers.map(uid => {
                 return new User(uid);
@@ -511,8 +511,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async parent(args, context, info): Promise<SimpleGroup> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async parent(args, context: Context, info): Promise<SimpleGroup> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             if(this.m_parent == 'root') {
                 return null;
@@ -532,8 +532,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async children(args, context, info): Promise<SimpleGroup[]> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async children(args, context: Context, info): Promise<SimpleGroup[]> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_children.map(gid => {
                 return new SimpleGroup(gid);
@@ -550,8 +550,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async memberOfMeta(args, context, info): Promise<MetaGroup[]> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async memberOfMeta(args, context: Context, info): Promise<MetaGroup[]> {
+        if(context.models.auth.isViewer(this.gid)) {
             throw "Not implemented";
         }
         throw "Not a viewer";
@@ -565,8 +565,8 @@ export class SimpleGroup extends Group {
      * @rights viewer
      * @async
      */
-    async school(args, context, info): Promise<string> {
-        if(await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async school(args, context: Context, info): Promise<string> {
+        if(context.models.auth.isViewer(this.gid)) {
             await this.fetchData();
             return this.m_school;
         }
@@ -664,8 +664,8 @@ export class MetaGroup extends Group {
      * @rights viewer
      * @async
      */
-    async admins(args, context, info): Promise<User[]> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async admins(args, context: Context, info): Promise<User[]> {
+        if (context.models.auth.isViewer(this.gid)) {
             throw "Not implemented";
         }
         throw "Not a viewer";
@@ -679,8 +679,8 @@ export class MetaGroup extends Group {
      * @rights viewer
      * @async
      */
-    async members(args, context, info): Promise<SimpleGroup[]> {
-        if (await Authorisation.isViewer(context.user.uid, this.gid)) {
+    async members(args, context: Context, info): Promise<SimpleGroup[]> {
+        if (context.models.auth.isViewer(this.gid)) {
             throw "Not implemented"
         }
         throw "Not a viewer";
diff --git a/src/graphql/resolvers/messages.ts b/src/graphql/resolvers/messages.ts
index 7feb59a1bf4dbdc43b6a2457560f7616cf60915b..cde94b5024942edfdaa39cebc9f02b5bd129a651 100644
--- a/src/graphql/resolvers/messages.ts
+++ b/src/graphql/resolvers/messages.ts
@@ -6,6 +6,7 @@
 import {Group, SimpleGroup, MetaGroup} from './groups';
 import {User} from './users';
 import knex from '../../../db/knex_router';
+import { Context } from '../typeDefs/queries';
 
 export abstract class Message {
 
@@ -92,7 +93,7 @@ export abstract class Message {
      * @rights same as message object
      * @async
      */
-    async createdAt(args, context, info): Promise<string> {
+    async createdAt(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_createdAt;
     }
@@ -105,7 +106,7 @@ export abstract class Message {
      * @rights same as message object
      * @async
      */
-    async updatedAt(args, context, info): Promise<string> {
+    async updatedAt(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_updatedAt;
     }
@@ -118,7 +119,7 @@ export abstract class Message {
      * @rights same as message object
      * @async
      */
-    async title(args, context, info): Promise<string> {
+    async title(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_title;
     }
@@ -131,7 +132,7 @@ export abstract class Message {
      * @rights same as message object
      * @async
      */
-    async content(args, context, info): Promise<string> {
+    async content(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_content;
     }
@@ -231,7 +232,7 @@ export class Announcement extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async authors(args, context, info): Promise<Group[]> {
+    async authors(args, context: Context, info): Promise<Group[]> {
         throw "Not implemented";
     }
 
@@ -243,7 +244,7 @@ export class Announcement extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async recipients(args, context, info): Promise<Group[]> {
+    async recipients(args, context: Context, info): Promise<Group[]> {
         throw "Not implemented";
     }
 
@@ -255,7 +256,7 @@ export class Announcement extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async importance(args, context, info): Promise<number> {
+    async importance(args, context: Context, info): Promise<number> {
         await this.fetchData();
         return this.m_importance;
     }
@@ -268,7 +269,7 @@ export class Announcement extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async views(args, context, info): Promise<number> {
+    async views(args, context: Context, info): Promise<number> {
         await this.fetchData();
         return this.m_views;
     }
@@ -281,7 +282,7 @@ export class Announcement extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async forEvent(args, context, info): Promise<Event> {
+    async forEvent(args, context: Context, info): Promise<Event> {
         let data = await knex.select('mid').from('messages_events').where('for_announcement', this.mid);
         if(data.length > 0) {
             return new Event(data[0].mid);
@@ -390,7 +391,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async authors(args, context, info): Promise<Group[]> {
+    async authors(args, context: Context, info): Promise<Group[]> {
         throw "Not implemented";
     }
 
@@ -402,7 +403,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async recipients(args, context, info): Promise<Group[]> {
+    async recipients(args, context: Context, info): Promise<Group[]> {
         throw "Not implemented";
     }
 
@@ -414,7 +415,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async location(args, context, info): Promise<string> {
+    async location(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_location;
     }
@@ -427,7 +428,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async startTime(args, context, info): Promise<string> {
+    async startTime(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_startTime;
     }
@@ -440,7 +441,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async endTime(args, context, info): Promise<string> {
+    async endTime(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_endTime;
     }
@@ -453,7 +454,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async participatingGroups(args, context, info): Promise<Group[]> {
+    async participatingGroups(args, context: Context, info): Promise<Group[]> {
         throw "Not implemented";
     }
 
@@ -465,7 +466,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async participatingUsers(args, context, info): Promise<User[]> {
+    async participatingUsers(args, context: Context, info): Promise<User[]> {
         throw "Not implemented";
     }
 
@@ -477,7 +478,7 @@ export class Event extends Message {
      * @rights membre d'un groupe author ou d'un groupe recipient
      * @async
      */
-    async forAnnouncement(args, context, info): Promise<Announcement> {
+    async forAnnouncement(args, context: Context, info): Promise<Announcement> {
         await this.fetchData();
         if (this.m_forAnnouncement == 0) { //what is the default ?????
             return null;
@@ -575,27 +576,27 @@ export class PrivatePost extends Message {
      */
 
     /**
-     * @memberof GraphQL.Event#
+     * @memberof GraphQL.PrivatePost#
      * @function author
      * @summary Renvoie le user auteur
      * @return {Promise(User)}
      * @rights membre du groupe recipient
      * @async
      */
-    async author(args, context, info): Promise<User> {
+    async author(args, context: Context, info): Promise<User> {
         await this.fetchData();
         return new User(this.m_author);
     }
 
     /**
-     * @memberof GraphQL.Event#
+     * @memberof GraphQL.PrivatePost#
      * @function recipient
      * @summary Renvoie le groupe destinataire
      * @return {Promise(Group)}
      * @rights membre du groupe recipient
      * @async
      */
-    async recipient(args, context, info): Promise<Group> {
+    async recipient(args, context: Context, info): Promise<Group> {
         await this.fetchData();
         throw "Not implemented";
     }
@@ -695,7 +696,7 @@ export class Question extends Message {
      * @rights viewer du groupe recipient
      * @async
      */
-    async author(args, context, info): Promise<User> {
+    async author(args, context: Context, info): Promise<User> {
         await this.fetchData();
         return new User(this.m_author);
     }
@@ -708,7 +709,7 @@ export class Question extends Message {
      * @rights viewer du groupe recipient
      * @async
      */
-    async recipient(args, context, info): Promise<Group> {
+    async recipient(args, context: Context, info): Promise<Group> {
         await this.fetchData();
         throw "Not implemented";
     }
@@ -721,7 +722,7 @@ export class Question extends Message {
      * @rights viewer du groupe recipient
      * @async
      */
-    async forAnswer(args, context, info): Promise<Answer> {
+    async forAnswer(args, context: Context, info): Promise<Answer> {
         let data = await knex.select('mid').from('messages_answers').where('for_question', this.mid);
         if (data.length > 0) {
             return new Answer(data[0].mid);
@@ -824,7 +825,7 @@ export class Answer extends Message {
      * @rights viewer du groupe author
      * @async
      */
-    async author(args, context, info): Promise<Group> {
+    async author(args, context: Context, info): Promise<Group> {
         await this.fetchData();
         throw "Not implemented";
     }
@@ -837,7 +838,7 @@ export class Answer extends Message {
      * @rights viewer du groupe author
      * @async
      */
-    async forQuestion(args, context, info): Promise<Question> {
+    async forQuestion(args, context: Context, info): Promise<Question> {
         await this.fetchData();
         return new Question(this.m_forQuestion);
     }
diff --git a/src/graphql/resolvers/requests.ts b/src/graphql/resolvers/requests.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3f5cc0574848184a2baceef5085dcd0193ed0686
--- /dev/null
+++ b/src/graphql/resolvers/requests.ts
@@ -0,0 +1,433 @@
+/**
+ * @file Resolvers pour tous les types de messages
+ * @author akka, ofacklam
+ */
+
+import { Group, SimpleGroup, MetaGroup } from "./groups";
+import { User } from './users';
+import { Event } from "./messages";
+import knex from '../../../db/knex_router';
+import { Context } from "../typeDefs/queries";
+
+export abstract class Request {
+
+    /**
+     * @memberof GraphQL
+     * @class Request
+     * @summary Resolvers des requetes
+     * @classdesc Une classe abstraite représentant l'interface Request du schéma.
+     * Comme Apollo Server, par défaut, appelle la propriété / fonction avec le nom a résoudre, il n'y a pas besoin d'écrire les resolvers explicitement.
+     * @arg {number} rid - Identifiant de la requete, supposé valide.
+     * @rights dépend du type de requete
+     * @abstract
+     */
+    constructor(rid: number) {
+        this.rid = rid;
+        this.m_dataLoaded = false;
+    }
+
+    /**
+     * @memberof GraphQL.Request#
+     * @function fetchData
+     * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait.
+     * @throws {Not_found} Les données n'ont pas pu etre trouvées.
+     * @async
+     * @protected
+     * @abstract
+     */
+    protected abstract async fetchData(): Promise<void>
+
+    /**
+     * Protected properties.
+     * Ce sont tous les champs triviaux, ie qui peuvent etre récupérés en une seule requete a la BDD,
+     * ce qui permet d'etre plus efficace.
+     * La variable dataLoaded témoigne de si on est déja allés chercher les données.
+     * ATTENTION. Ce ne sont PAS directement les resolvers, il FAUT donc qu'ils aient un nom DIFFÉRENT du nom des champs dans le schéma.
+     */
+    protected m_dataLoaded: boolean
+
+    protected m_comment: string
+    protected m_from: string
+    protected m_to: string
+
+    /**
+     * Ci-dessous les resolvers a proprement parler.
+     */
+
+    /**
+     * @memberof GraphQL.Request#
+     * @function __resolveType
+     * @summary Renvoie quel type de Request c'est
+     * @return {string}
+     * @rights same as request object
+     */
+    __resolveType(): string {
+        if (this instanceof UserJoinGroup) {
+            return "UserJoinGroup";
+        }
+        else if (this instanceof GroupJoinMetagroup) {
+            return "GroupJoinMetagroup";
+        }
+        else if (this instanceof GroupCoauthorEvent) {
+            return "GroupCoauthorEvent";
+        }
+        else {
+            throw "Mauvais type de requete";
+        }
+    }
+
+    /** @rights same as request object */
+    rid: number;
+
+    /**
+     * @memberof GraphQL.Request#
+     * @function comment
+     * @summary Renvoie le commentaire associé
+     * @return {Promise(string)}
+     * @rights same as request object
+     * @async
+     */
+    async comment(args, context: Context, info): Promise<string> {
+        await this.fetchData();
+        return this.m_comment;
+    }
+
+    /**
+     * @memberof GraphQL.Request#
+     * @function from
+     * @summary Renvoie l'émetteur de demande
+     * @return {Promise(Group | User)}
+     * @rights same as request object
+     * @async
+     * @abstract
+     */
+    abstract async from(args, context: Context, info);
+
+    /**
+     * @memberof GraphQL.Request#
+     * @function to
+     * @summary Renvoie le destinataire de la demande
+     * @return {Promise(Group)}
+     * @rights same as request object
+     * @async
+     * @abstract
+     */
+    abstract async to(args, context: Context, info): Promise<Group>;
+}
+
+export class UserJoinGroup extends Request {
+
+    /**
+     * @memberof GraphQL
+     * @class UserJoinGroup
+     * @extends GraphQL.Request
+     * @summary Resolvers des requetes UserJoinGroup
+     * @classdesc Une classe représentant le type UserJoinGroup du schéma.
+     * Comme Apollo Server, par défaut, appelle la propriété / fonction avec le nom a résoudre, il n'y a pas besoin d'écrire les resolvers explicitement.
+     * @arg {number} rid - Identifiant de la requete, supposé valide.
+     * @rights admin du groupe recipient ou le user émetteur
+     */
+    constructor(rid: number) {
+        super(rid);
+    }
+
+    /**
+     * @memberof GraphQL.UserJoinGroup#
+     * @function tryCreate
+     * @summary Fonction qui va essayer de créer la requete correspondante
+     * @arg {number} rid - Identifiant de la requete, sans hypothese sur la validité.
+     * @returns {Promise(UserJoinGroup)} - Renvoie le UserJoinGroup créé, ou null en cas d'erreur.
+     * @rights admin du groupe recipient ou le user émetteur
+     * @async
+     * @static
+     */
+    static async tryCreate(rid: number): Promise<UserJoinGroup> {
+        let r = new UserJoinGroup(rid);
+        try {
+            await r.fetchData();
+            return r;
+        }
+        catch {
+            return null;
+        }
+    }
+
+    /**
+     * @memberof GraphQL.UserJoinGroup#
+     * @function fetchData
+     * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait.
+     * @throws {Not_found} Les données n'ont pas pu etre trouvées.
+     * @async
+     * @protected
+     */
+    protected async fetchData(): Promise<void> {
+        if (!this.m_dataLoaded) {
+            let data = await knex.select('request_comment',
+                'request_from',
+                'request_to').from('requests_user_join_group').where('rid', this.rid);
+
+            if (data.length > 0) {
+                let r = data[0];
+
+                this.m_comment = r.request_comment;
+                this.m_from = r.request_from;
+                this.m_to = r.request_to;
+
+                this.m_dataLoaded = true;
+            }
+            else {
+                throw "Not_found";
+            }
+        }
+    }
+
+    /**
+     * Ci-dessous les resolvers a proprement parler.
+     */
+
+    /**
+     * @memberof GraphQL.UserJoinGroup#
+     * @function from
+     * @summary Renvoie le user émetteur
+     * @return {Promise(User)}
+     * @rights admin du groupe recipient ou le user émetteur
+     * @async
+     */
+    async from(args, context: Context, info): Promise<User> {
+        await this.fetchData();
+        return new User(this.m_from);
+    }
+
+    /**
+     * @memberof GraphQL.UserJoinGroup#
+     * @function to
+     * @summary Renvoie le groupe destinataire
+     * @return {Promise(SimpleGroup)}
+     * @rights admin du groupe recipient ou le user émetteur
+     * @async
+     */
+    async to(args, context: Context, info): Promise<SimpleGroup> {
+        await this.fetchData();
+        return new SimpleGroup(this.m_to);
+    }
+}
+
+export class GroupJoinMetagroup extends Request {
+
+    /**
+     * @memberof GraphQL
+     * @class GroupJoinMetagroup
+     * @extends GraphQL.Request
+     * @summary Resolvers des requetes GroupJoinMetagroup
+     * @classdesc Une classe représentant le type GroupJoinMetagroup du schéma.
+     * Comme Apollo Server, par défaut, appelle la propriété / fonction avec le nom a résoudre, il n'y a pas besoin d'écrire les resolvers explicitement.
+     * @arg {number} rid - Identifiant de la requete, supposé valide.
+     * @rights admin du groupe émetteur ou destinataire
+     */
+    constructor(rid: number) {
+        super(rid);
+    }
+
+    /**
+     * @memberof GraphQL.GroupJoinMetagroup#
+     * @function tryCreate
+     * @summary Fonction qui va essayer de créer la requete correspondante
+     * @arg {number} rid - Identifiant de la requete, sans hypothese sur la validité.
+     * @returns {Promise(GroupJoinMetagroup)} - Renvoie le GroupJoinMetagroup créé, ou null en cas d'erreur.
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     * @static
+     */
+    static async tryCreate(rid: number): Promise<GroupJoinMetagroup> {
+        let r = new GroupJoinMetagroup(rid);
+        try {
+            await r.fetchData();
+            return r;
+        }
+        catch {
+            return null;
+        }
+    }
+
+    /**
+     * @memberof GraphQL.GroupJoinMetagroup#
+     * @function fetchData
+     * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait.
+     * @throws {Not_found} Les données n'ont pas pu etre trouvées.
+     * @async
+     * @protected
+     */
+    protected async fetchData(): Promise<void> {
+        if (!this.m_dataLoaded) {
+            let data = await knex.select('request_comment',
+                'request_from',
+                'request_to').from('requests_group_join_metagroup').where('rid', this.rid);
+
+            if (data.length > 0) {
+                let r = data[0];
+
+                this.m_comment = r.request_comment;
+                this.m_from = r.request_from;
+                this.m_to = r.request_to;
+
+                this.m_dataLoaded = true;
+            }
+            else {
+                throw "Not_found";
+            }
+        }
+    }
+
+    /**
+     * Ci-dessous les resolvers a proprement parler.
+     */
+
+    /**
+     * @memberof GraphQL.GroupJoinMetagroup#
+     * @function from
+     * @summary Renvoie le groupe émetteur
+     * @return {Promise(SimpleGroup)}
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     */
+    async from(args, context: Context, info): Promise<SimpleGroup> {
+        await this.fetchData();
+        return new SimpleGroup(this.m_from);
+    }
+
+    /**
+     * @memberof GraphQL.GroupJoinMetagroup#
+     * @function to
+     * @summary Renvoie le groupe destinataire
+     * @return {Promise(MetaGroup)}
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     */
+    async to(args, context: Context, info): Promise<MetaGroup> {
+        await this.fetchData();
+        return new MetaGroup(this.m_to);
+    }
+}
+
+export class GroupCoauthorEvent extends Request {
+
+    /**
+     * @memberof GraphQL
+     * @class GroupCoauthorEvent
+     * @extends GraphQL.Request
+     * @summary Resolvers des requetes GroupCoauthorEvent
+     * @classdesc Une classe représentant le type GroupCoauthorEvent du schéma.
+     * Comme Apollo Server, par défaut, appelle la propriété / fonction avec le nom a résoudre, il n'y a pas besoin d'écrire les resolvers explicitement.
+     * @arg {number} rid - Identifiant de la requete, supposé valide.
+     * @rights admin du groupe émetteur ou destinataire
+     */
+    constructor(rid: number) {
+        super(rid);
+    }
+
+    /**
+     * @memberof GraphQL.GroupCoauthorEvent#
+     * @function tryCreate
+     * @summary Fonction qui va essayer de créer la requete correspondante
+     * @arg {number} rid - Identifiant de la requete, sans hypothese sur la validité.
+     * @returns {Promise(GroupCoauthorEvent)} - Renvoie le GroupCoauthorEvent créé, ou null en cas d'erreur.
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     * @static
+     */
+    static async tryCreate(rid: number): Promise<GroupCoauthorEvent> {
+        let r = new GroupCoauthorEvent(rid);
+        try {
+            await r.fetchData();
+            return r;
+        }
+        catch {
+            return null;
+        }
+    }
+
+    /**
+     * @memberof GraphQL.GroupCoauthorEvent#
+     * @function fetchData
+     * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait.
+     * @throws {Not_found} Les données n'ont pas pu etre trouvées.
+     * @async
+     * @protected
+     */
+    protected async fetchData(): Promise<void> {
+        if (!this.m_dataLoaded) {
+            let data = await knex.select('request_comment',
+                'request_from',
+                'request_to',
+                'for_event').from('requests_group_coauthor_event').where('rid', this.rid);
+
+            if (data.length > 0) {
+                let r = data[0];
+
+                this.m_comment = r.request_comment;
+                this.m_from = r.request_from;
+                this.m_to = r.request_to;
+                this.m_forEvent = r.for_event;
+
+                this.m_dataLoaded = true;
+            }
+            else {
+                throw "Not_found";
+            }
+        }
+    }
+
+    /**
+     * Protected properties.
+     * Ce sont tous les champs triviaux, ie qui peuvent etre récupérés en une seule requete a la BDD,
+     * ce qui permet d'etre plus efficace.
+     * La variable dataLoaded témoigne de si on est déja allés chercher les données.
+     * ATTENTION. Ce ne sont PAS directement les resolvers, il FAUT donc qu'ils aient un nom DIFFÉRENT du nom des champs dans le schéma.
+     */
+    protected m_forEvent: number;
+
+    /**
+     * Ci-dessous les resolvers a proprement parler.
+     */
+
+    /**
+     * @memberof GraphQL.GroupCoauthorEvent#
+     * @function from
+     * @summary Renvoie le groupe émetteur
+     * @return {Promise(Group)}
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     */
+    async from(args, context: Context, info): Promise<Group> {
+        await this.fetchData();
+        throw "Not implemented";
+    }
+
+    /**
+     * @memberof GraphQL.GroupCoauthorEvent#
+     * @function to
+     * @summary Renvoie le groupe destinataire
+     * @return {Promise(Group)}
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     */
+    async to(args, context: Context, info): Promise<Group> {
+        await this.fetchData();
+        throw "Not implemented";
+    }
+
+    /**
+     * @memberof GraphQL.GroupCoauthorEvent#
+     * @function forEvent
+     * @summary Renvoie l'evenement a co-organiser
+     * @return {Promise(Event)}
+     * @rights admin du groupe émetteur ou destinataire
+     * @async
+     */
+    async forEvent(args, context: Context, info): Promise<Event> {
+        await this.fetchData();
+        throw "Not implemented";
+        //a-t-il le droit de voir ???
+        return new Event(this.m_forEvent);
+    }
+}
\ No newline at end of file
diff --git a/src/graphql/resolvers/users.ts b/src/graphql/resolvers/users.ts
index 2011194980c7c6628380ca7721a3a11760727421..140180011344173b0c03cbfd560838f335d91dcc 100644
--- a/src/graphql/resolvers/users.ts
+++ b/src/graphql/resolvers/users.ts
@@ -7,6 +7,7 @@ import {Group, SimpleGroup, MetaGroup} from './groups';
 import {Question} from './messages';
 import {User as LDAP_User} from '../../ldap/export/user';
 import {Tools, GroupSet} from '../connectors/tools';
+import { Context } from '../typeDefs/queries';
 
 export class User {
 
@@ -125,7 +126,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async givenName(args, context, info): Promise<string> {
+    async givenName(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_givenName;
     }
@@ -138,7 +139,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async lastName(args, context, info): Promise<string> {
+    async lastName(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_lastName;
     }
@@ -151,7 +152,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async nickname(args, context, info): Promise<string> {
+    async nickname(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_nickname;
     }
@@ -164,7 +165,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async nationality(args, context, info): Promise<string> {
+    async nationality(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_nationality;
     }
@@ -177,7 +178,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async birthdate(args, context, info): Promise<string> {
+    async birthdate(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_birthdate;
     }
@@ -190,7 +191,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async promotion(args, context, info): Promise<string> {
+    async promotion(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_promotion;
     }
@@ -203,7 +204,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async mail(args, context, info): Promise<string> {
+    async mail(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_mail;
     }
@@ -216,7 +217,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async phone(args, context, info): Promise<string> {
+    async phone(args, context: Context, info): Promise<string> {
         await this.fetchData();
         return this.m_phone;
     }
@@ -229,7 +230,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async addresses(args, context, info): Promise<string[]> {
+    async addresses(args, context: Context, info): Promise<string[]> {
         await this.fetchData();
         return this.m_addresses;
     }
@@ -242,7 +243,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async memberOf(args, context, info): Promise<Group[]> {
+    async memberOf(args, context: Context, info): Promise<Group[]> {
         await this.fetchData();
         let simple = new GroupSet(this.m_memberOf);
         let meta = await Tools.metaGroupsOfGroups(simple);
@@ -267,7 +268,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async speakerOf(args, context, info): Promise<Group[]> {
+    async speakerOf(args, context: Context, info): Promise<Group[]> {
         await this.fetchData();
         let speaker = new GroupSet(this.m_speakerOf);
         let admin = new GroupSet(this.m_adminOf);
@@ -293,7 +294,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async adminOf(args, context, info): Promise<Group[]> {
+    async adminOf(args, context: Context, info): Promise<Group[]> {
         await this.fetchData();
         let simple = new GroupSet(this.m_adminOf);
         let meta = await Tools.metaGroupsOfGroups(simple);
@@ -318,7 +319,7 @@ export class User {
      * @rights connectedOrOnplatal
      * @async
      */
-    async likes(args, context, info): Promise<Group[]> {
+    async likes(args, context: Context, info): Promise<Group[]> {
         await this.fetchData();
         let simple = new GroupSet(this.m_likes);
         let meta = await Tools.metaGroupsOfGroups(simple);
@@ -343,7 +344,7 @@ export class User {
      * @rights viewer of recipient group
      * @async
      */
-    async questionsFromUser(args, context, info): Promise<Question[]> {
+    async questionsFromUser(args, context: Context, info): Promise<Question[]> {
         throw "Not implemented";
     }
  }
\ No newline at end of file
diff --git a/src/graphql/typeDefs/queries.d.ts b/src/graphql/typeDefs/queries.d.ts
index eb4096b19cb8ca7ab1bd83d439c4fdadcab9dadc..97f96d7b7cf822dd3d8531ee3e6901b47f24dea3 100644
--- a/src/graphql/typeDefs/queries.d.ts
+++ b/src/graphql/typeDefs/queries.d.ts
@@ -1,3 +1,5 @@
+import { AuthorisationModel } from "../connectors/authorisationModel";
+
 interface searchTOLArgs {
     givenName: string,
     lastName: string,
@@ -12,4 +14,12 @@ interface searchTOLArgs {
     mail: string,
     addresses: string[],
     ips: string[]
+}
+
+interface Context {
+    request,
+    user: { uid: string },
+    models: {
+        auth: AuthorisationModel
+    }
 }
\ No newline at end of file