diff --git a/src/app.ts b/src/app.ts index ee42104abb0dbd68a1efb71c984cd83125c783d3..8a5a743e6153550f42d2bddff0ee2d1336e0ebad 100644 --- a/src/app.ts +++ b/src/app.ts @@ -182,6 +182,7 @@ app.post('/login', (req, res, next) => { import { Context } from './graphql/typeDefs/queries'; import { AuthorisationModel } from './graphql/connectors/authorisationModel'; import { UserModel } from './graphql/connectors/userModel'; +import { GroupModel } from './graphql/connectors/groupModel'; 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 @@ -203,15 +204,14 @@ const context = async ({ req }): Promise<Context> => { console.log(err); } } - - let authModule = await AuthorisationModel.create(uid); return { request: req, user: { uid: uid }, models: { - auth: authModule, - user: new UserModel(authModule) + auth: await AuthorisationModel.create(uid), + user: new UserModel(uid), + group: new GroupModel(uid) } }; }; diff --git a/src/graphql/connectors/authorisationModel.ts b/src/graphql/connectors/authorisationModel.ts index 47ab2c5e8fae6443c817f879e5d44aa83d16f5a6..7e13d67fc7a79fbf4a673a2cecbfa239db933bfc 100644 --- a/src/graphql/connectors/authorisationModel.ts +++ b/src/graphql/connectors/authorisationModel.ts @@ -35,7 +35,7 @@ export class AuthorisationModel { * @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 + * @returns {Promise(AuthorisationModel)} Renvoie un nouveau AuthorisationModel avec cet utilisateur * @async * @static */ @@ -185,7 +185,12 @@ export class AuthorisationModel { //ensure uid is valid !!!!!!!! if (this.isAuthenticated()) { let groups = this.adminOf; - return (groups.simpleGroups.has(gid) || groups.metaGroups.has(gid)); + let is_admin = groups.simpleGroups.has(gid) || groups.metaGroups.has(gid); + + //TODO : Vérifier s'il a pris les droits d'admin en étant supervisor + let took_admin_rights = false; + + return (is_admin || took_admin_rights); } return false; } diff --git a/src/graphql/connectors/groupModel.ts b/src/graphql/connectors/groupModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..3ace9eda118c76d59ed49540dce237cfd4bc474d --- /dev/null +++ b/src/graphql/connectors/groupModel.ts @@ -0,0 +1,359 @@ +/** + * @file Fonctions qui implémentent les requetes relatives aux groupes + * @author ofacklam + * @memberof GraphQL + */ + +import { Group, SimpleGroup, MetaGroup } from "../resolvers/groups"; +import { Request } from "../resolvers/requests"; +import { User } from "../resolvers/users"; +import knex from "../../../db/knex_router" +import { GroupCollection, GroupSet } from "./tools"; +import { createSubgroupArgs, editGroupArgs } from "../typeDefs/queries"; + +export class GroupModel { + + /** + * @memberof GraphQL + * @class GroupModel + * @summary Requetes relatives aux groupes. + * @classdesc Cette classe contient les méthodes implémentant les requetes relatives aux groupes. + * @arg {string} contextUser - L'identifiant de l'utilisateur du 'context' + */ + constructor(contextUser: string) { + this.contextUser = contextUser; + } + + protected contextUser: string; + + /** + * @memberof GraphQL.GroupModel# + * @function getGroup + * @summary Fonction qui renvoie un groupe donné. + * @arg {string} gid - Identifiant demandé. + * @return {Promise(Group)} Renvoie le groupe dont l'identifiant est 'gid' + * @async + * @rights connectedOrOnplatal + */ + async getGroup(gid: string): Promise<Group> { + let data = await knex.select('type').from('groups').where('gid', gid); + + if(data.length > 0) { + let type = data[0].type; + switch(type) { + case 'simple': + return new SimpleGroup(gid); + case 'meta': + return new MetaGroup(gid); + default: + return null; + } + } + return null; + } + + /** + * @memberof GraphQL.GroupModel# + * @function getSimpleGroup + * @summary Fonction qui renvoie un groupe simple donné. + * @arg {string} gid - Identifiant demandé. + * @return {Promise(SimpleGroup)} Renvoie le groupe dont l'identifiant est 'gid' + * @async + * @rights connectedOrOnplatal + */ + async getSimpleGroup(gid: string): Promise<SimpleGroup> { + return SimpleGroup.tryCreate(gid); + } + + /** + * @memberof GraphQL.GroupModel# + * @function getMetaGroup + * @summary Fonction qui renvoie un méta-groupe donné. + * @arg {string} gid - Identifiant demandé. + * @return {Promise(MetaGroup)} Renvoie le groupe dont l'identifiant est 'gid' + * @async + * @rights connectedOrOnplatal + */ + async getMetaGroup(gid: string): Promise<MetaGroup> { + return MetaGroup.tryCreate(gid); + } + + /** + * @memberof GraphQL.GroupModel# + * @function getAllGroupsByCollection + * @summary Fonction qui renvoie tous les groupes donnés en argument. + * @arg {GroupCollection} groups - Collection d'identifiants, supposés valides. + * @return {Group[]} Renvoie le tableau de groupes correspondant + * @rights connectedOrOnplatal + */ + getAllGroupsByCollection(groups: GroupCollection): Group[] { + let res: Group[] + + for(let s of groups.simpleGroups) { + res.push(new SimpleGroup(s)); + } + for(let m of groups.metaGroups) { + res.push(new MetaGroup(m)); + } + + return res; + } + + /** + * @memberof GraphQL.GroupModel# + * @function getAllGroupsBySet + * @summary Fonction qui renvoie tous les groupes donnés en argument. + * @arg {GroupSet} groups - Ensemble d'identifiants, supposés valides. + * @return {Promise(Group[])} Renvoie le tableau de groupes correspondant + * @async + * @rights connectedOrOnplatal + */ + async getAllGroupsBySet(groups: GroupSet): Promise<Group[]> { + let res: Group[] + + for(let g of groups) { + res.push(await this.getGroup(g)); + } + + return res; + } + + /** + * @memberof GraphQL.GroupModel# + * @function getAllSimpleGroups + * @summary Fonction qui renvoie tous les groupes simples donnés en argument. + * @arg {GroupSet} groups - Ensemble d'identifiants, supposés valides. + * @return {Group[]} Renvoie le tableau de groupes correspondant + * @rights connectedOrOnplatal + */ + getAllSimpleGroups(groups: GroupSet): Group[] { + let res: Group[] + + for (let g of groups) { + res.push(new SimpleGroup(g)); + } + + return res; + } + + /** + * @memberof GraphQL.GroupModel# + * @function likeGroup + * @summary Fonction pour devenir sympathisant + * @arg {string} gid - Identifiant du groupe. + * @return {Promise(boolean)} Renvoie true si modification réussie. + * @async + * @rights viewer du groupe + */ + async likeGroup(gid: string): Promise<boolean> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function unlikeGroup + * @summary Fonction pour devenir non-sympathisant + * @arg {string} gid - Identifiant du groupe. + * @return {Promise(boolean)} Renvoie true si modification réussie. + * @async + * @rights viewer du groupe + */ + async unlikeGroup(gid: string): Promise<boolean> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function userRequestJoinGroup + * @summary Fonction pour demander a devenir membre + * @arg {string} gid - Identifiant du groupe. + * @arg {string} comment - Commentaire supplémentaire + * @return {Promise(Request)} Renvoie la requete créée. + * @async + * @rights viewer du groupe + */ + async userRequestJoinGroup(gid: string, comment: string): Promise<Request> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function userLeaveGroup + * @summary Fonction pour quitter un groupe + * @arg {string} gid - Identifiant du groupe. + * @return {Promise(boolean)} Renvoie true si modification réussie. + * @async + * @rights member du groupe + */ + async userLeaveGroup(gid: string): Promise<boolean> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function writePostsSummary + * @summary Fonction pour écrire le résumé des posts. + * @arg {string} gid - Identifiant du groupe. + * @arg {string} content - Contenu du résumé. + * @return {Promise(boolean)} Renvoie true si modification réussie. + * @async + * @rights speaker du groupe + */ + async writePostsSummary(gid: string, content: string): Promise<boolean> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function createSubgroup + * @summary Fonction pour créer un sous-groupe + * @arg {createSubgroupArgs} args - Les arguments pour la création. + * @return {Promise(Group)} Renvoie le groupe créé. + * @async + * @rights admin du groupe + */ + async createSubgroup(args: createSubgroupArgs): Promise<Group> { + throw "Not implemented"; + // TODO : finish + + /*if (typeof args.fromGroup != 'string') + throw "Illegal argument : parent_uid must be a non null string"; + if (typeof args.subName != 'string') + throw "Illegal argument : name must be a non null string"; + + let rasGID = await getAvailableGID(args.subGid); + + // TODO : appeller une fonction de LDAPUser pour y créer un groupe. + await knex('simple_groups').insert({ + uid: rasGID, + parent_uid: args.parent_uid, + createdAt: knex.fn.now(), + updatedAt: this.createdAt, + name: args.name, + website: args.website, + description: args.description, + school: args.school, + type: "simple" + }); + + return getGroup(rasGID);*/ + } + + /** + * @memberof GraphQL.GroupModel# + * @function makeAdmin + * @summary Fonction pour rendre un membre admin + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur. + * @return {Promise(User)} Renvoie l'utilisateur promu. + * @async + * @rights admin du groupe + */ + async makeAdmin(gid: string, uid: string): Promise<User> { + //TODO : vérifier que l'utilisateur est bien déja membre !! + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function unmakeAdmin + * @summary Fonction pour rendre un membre non-admin + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur. + * @return {Promise(User)} Renvoie l'utilisateur dé-promu. + * @async + * @rights admin du groupe + */ + async unmakeAdmin(gid: string, uid: string): Promise<User> { + //TODO : vérifier que l'utilisateur est bien déja membre !! + //TODO : relacher les droits admin (des groupes enfants) pris en étant admin. + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function makeSpeaker + * @summary Fonction pour rendre un membre speaker + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur. + * @return {Promise(User)} Renvoie l'utilisateur promu. + * @async + * @rights admin du groupe + */ + async makeSpeaker(gid: string, uid: string): Promise<User> { + //TODO : vérifier que l'utilisateur est bien déja membre !! + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function unmakeSpeaker + * @summary Fonction pour rendre un membre non-speaker + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur. + * @return {Promise(User)} Renvoie l'utilisateur dé-promu. + * @async + * @rights admin du groupe + */ + async unmakeSpeaker(gid: string, uid: string): Promise<User> { + //TODO : vérifier que l'utilisateur est bien déja membre !! + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function editGroup + * @summary Fonction pour modifier un groupe. + * @arg {editGroupArgs} args - Les arguments de la modification. + * @return {Promise(Group)} Renvoie le groupe modifié. + * @async + * @rights admin du groupe + */ + async editGroup(args: editGroupArgs): Promise<Group> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function removeUser + * @summary Fonction pour enlever un membre du groupe. + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur. + * @return {Promise(User)} Renvoie l'utilisateur. + * @async + * @rights admin du groupe + */ + async removeUser(gid: string, uid: string): Promise<User> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function takeAdminRights + * @summary Fonction pour prendre les droits admin du groupe. + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur qui prend les droits. + * @return {Promise(boolean)} Renvoie true si modification réussie. + * @async + * @rights supervisor du groupe + */ + async takeAdminRights(gid: string, uid: string): Promise<boolean> { + throw "Not implemented"; + } + + /** + * @memberof GraphQL.GroupModel# + * @function releaseAdminRights + * @summary Fonction pour relacher les droits admin du groupe. + * @arg {string} gid - Identifiant du groupe. + * @arg {string} uid - Identifiant de l'utilisateur qui relache les droits. + * @return {Promise(boolean)} Renvoie true si modification réussie. + * @async + * @rights supervisor du groupe + */ + async releaseAdminRights(gid: string, uid: string): Promise<boolean> { + //TODO : relacher récursivement + throw "Not implemented"; + } + +} \ No newline at end of file diff --git a/src/graphql/connectors/tools.ts b/src/graphql/connectors/tools.ts index 5455700abbe8ca019c4de1db095ba0a7a0f0ed51..895964ed64755e7e7fe2ac9371846cf7489a4714 100644 --- a/src/graphql/connectors/tools.ts +++ b/src/graphql/connectors/tools.ts @@ -34,6 +34,17 @@ export class Tools { */ constructor() { } + /** + * @memberof GraphQL + * @summary Fonction qui escape l'id donné en argument + * @arg {string} id - L'identifiant a escape. + * @return {Promise(Group)} Renvoie l'identifiant escapé. + * @static + */ + static escapeID(id: string) { + return String(id).replace(' ', '_').replace(/\W/g, '').toLowerCase(); //the REGEXP matches all non-word characters (\W) in a global search (/../g) + } + /** * @memberof GraphQL * @summary Fonction qui renvoit l'union de deux ensembles diff --git a/src/graphql/connectors/userModel.ts b/src/graphql/connectors/userModel.ts index 5906c6cfcebddfc50b74c4279b92a48ef7de52f4..c3446bdc79cff8f66649b6a026b7bef00bf2c75c 100644 --- a/src/graphql/connectors/userModel.ts +++ b/src/graphql/connectors/userModel.ts @@ -29,7 +29,7 @@ export class UserModel { * @function getUser * @summary Fonction qui renvoit un utilisateur donné. * @arg {string} uid - Identifiant demandé. - * @return {Promise<User>} Renvoie l'utilisateur dont l'identifiant est 'uid' + * @return {Promise(User)} Renvoie l'utilisateur dont l'identifiant est 'uid' * @async * @rights connectedOrOnplatal */ @@ -42,7 +42,7 @@ export class UserModel { * @function searchTOL * @summary Fonction qui recherche dans le TOL * @arg {searchTOLArgs} args - les données de recherche - * @return {Promise<User[]>} Renvoie une liste d'utilisateurs + * @return {Promise(User[])} Renvoie une liste d'utilisateurs * @async * @rights connectedOrOnplatal */ @@ -69,7 +69,7 @@ export class UserModel { * @function editProfile * @summary Fonction qui modifie le profil et renvoie l'utilisateur * @arg {editProfileArgs} args - les données a modifier - * @return {Promise<User>} Renvoie l'utilisateur mis a jour + * @return {Promise(User)} Renvoie l'utilisateur mis a jour * @async * @rights authentified */ diff --git a/src/graphql/typeDefs/queries.d.ts b/src/graphql/typeDefs/queries.d.ts index 1f6f3307b0ab6155de7f95f951835b403d86bfed..2c495783a9d3a327f15a721040ce19e90a148a12 100644 --- a/src/graphql/typeDefs/queries.d.ts +++ b/src/graphql/typeDefs/queries.d.ts @@ -1,12 +1,14 @@ import { AuthorisationModel } from "../connectors/authorisationModel"; import { UserModel } from "../connectors/userModel"; +import { GroupModel } from "../connectors/groupModel"; interface Context { request, user: { uid: string }, models: { auth: AuthorisationModel, - user: UserModel + user: UserModel, + group: GroupModel } } @@ -31,3 +33,22 @@ interface editProfileArgs { mail: string, phone: string } + +interface createSubgroupArgs { + fromGroup: string, + subGid: string, + subName: string, + subDescription: string, + subMail: string, + subWebsite: string, + subSchool: string +} + +interface editGroupArgs { + forGroup: string, + name: string, + description: string, + mail: string, + website: string, + school: string +} \ No newline at end of file