From 4cddd0113a0fe0f18a6eb2438e7b6a6c48819d2e Mon Sep 17 00:00:00 2001 From: Oliver Facklam <oliver.facklam.lfgeb@gmail.com> Date: Fri, 28 Dec 2018 22:44:54 +0100 Subject: [PATCH] requests.ts et transformation en authorisationModel.ts --- src/app.ts | 10 +- src/graphql/connectors/authorisation.ts | 147 ------- src/graphql/connectors/authorisationModel.ts | 190 ++++++++ src/graphql/connectors/tools.ts | 50 +-- src/graphql/resolvers.ts | 4 +- src/graphql/resolvers/groups.ts | 102 ++--- src/graphql/resolvers/messages.ts | 53 +-- src/graphql/resolvers/requests.ts | 433 +++++++++++++++++++ src/graphql/resolvers/users.ts | 29 +- src/graphql/typeDefs/queries.d.ts | 10 + 10 files changed, 759 insertions(+), 269 deletions(-) delete mode 100644 src/graphql/connectors/authorisation.ts create mode 100644 src/graphql/connectors/authorisationModel.ts create mode 100644 src/graphql/resolvers/requests.ts diff --git a/src/app.ts b/src/app.ts index d90da20..7694423 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 60ef61c..0000000 --- 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 0000000..8064b9a --- /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 55e45f0..5455700 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 c2fc1cc..fcc78ca 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 bced15a..5f5dc40 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 7feb59a..cde94b5 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 0000000..3f5cc05 --- /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 2011194..1401800 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 eb4096b..97f96d7 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 -- GitLab