/** * @file Fonctions qui implémentent les requetes relatives aux groupes * @author ofacklam * @memberof GraphQL */ import { Group } from "../object_resolvers/groups/groups"; import { SimpleGroup } from "../object_resolvers/groups/simpleGroups"; import { MetaGroup } from "../object_resolvers/groups/metaGroups"; import { Request } from "../object_resolvers/requests/requests"; import { User } from "../object_resolvers/users"; import knex from "../../../db/knex_router" import { GroupCollection, GroupSet, Tools } from "../../utils/tools"; import { createSubgroupArgs, editGroupArgs } from "../typeDefs/queries"; import {Cache} from "../../utils/cache"; 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; this.cache = new Cache<Promise<Group>, string>(this.newGroup); } protected contextUser: string; protected cache: Cache<Promise<Group>, string>; /** * @memberof GraphQL.GroupModel# * @function newGroup * @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 newGroup(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; } } else { //maybe the simple group isn't buffered yet => check in the LDAP let sg = SimpleGroup.tryCreate(gid); if(sg) { //group found => insert into groups table knex('groups').insert({gid: gid, type: 'simple'}).then(); // <-- .then() necessary for command execution } return sg; } } async getGroup(gid: string): Promise<Group> { console.log("Getgroup called: ", gid); return this.cache.get(gid); } /** * @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 {SimpleGroup[]} Renvoie le tableau de groupes correspondant * @rights connectedOrOnplatal */ getAllSimpleGroups(groups: GroupSet): SimpleGroup[] { let res: SimpleGroup[] for (let g of groups) { res.push(new SimpleGroup(g)); } return res; } /** * @memberof GraphQL.GroupModel# * @function getAllMetaGroups * @summary Fonction qui renvoie tous les groupes metas du groupe simple. * @arg {string} gid - identifiant du groupe en question. * @return {GroupSet} Renvoie le tableau de groupes correspondant * @rights connectedOrOnplatal */ getAllMetaGroupsFromSimple(gid: string): Promise<GroupSet> { let arg=new GroupSet(); arg.add(gid); let res=Tools.metaGroupsOfGroups(arg); return res; } /** * @memberof GraphQL.GroupModel# * @function getAllSimpleGroupsFromMeta * @summary Fonction qui renvoie tous les groupes simples du groupe meta. * @arg {string} gid - identifiant du groupe en question. * @return {GroupSet} Renvoie le tableau de groupes correspondant * @rights connectedOrOnplatal */ getAllSimpleGroupsFromMeta(gid: string): Promise<GroupSet> { let arg=new GroupSet(); arg.add(gid); let res=Tools.simpleGroupsOfGroups(arg); return res; } /** * @memberof GraphQL.GroupModel# * @function getMetaGroupAdmins * @summary Fonction qui renvoie les administrateurs d'un méta-groupe. * @arg {string} gid - identifiant du groupe en question. * @return {Promise(User[])} Renvoie le tableau des admins * @rights viewer */ async getMetaGroupAdmins(gid: string): Promise<User[]> { let admins = new Set<string>(); // <-- needs to be a string set and not a User set in order to avoid duplicates let arg = await this.getAllSimpleGroupsFromMeta(gid); for (let g of arg) { let sg = new SimpleGroup(g); let sg_admins = await sg.getAdmins(); for (let admin of sg_admins) { admins.add(admin.uid); } } return [...admins].map(uid => new User(uid)); } /** * @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> { // Pour l'instant, ce n'est pas a implémenter... 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> { // Pour l'instant, ce n'est pas a implémenter... 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 : Vérifier que 'parent' est un groupe _simple_. // 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 getAvailableGID * @summary Attribue un GID qui n'a pas encore été utilisé à un groupe * @desc Escape le string initialGID si necessaire (ramené à de l'ASCII sans espace), puis si le gid est deja pris rajoute un n a la fin et reteste * @arg {string} initialGID - Le gid initial du groupe, qu'il faut tester pour l'unicité. * @return {Promise(string)} Renvoie le gid unique pour ce groupe. * @rights authentified * remarque : n'importe qui peut tester si un groupe existe en demandant a créer un groupe avec ce nom la et en regardant si * son GID a été modifié. Je ne vois pas comment contourner ce problème, c'est donc une faille permanente (mineure) de sigma. * // ofacklam -> savoir qu'un groupe existe est autorisé pour toute personne connectée ou on-platal et il faut etre connecté pour * // utiliser cette fonction-ci donc il n'y a pas de probleme. */ async getAvailableGID(initialGID: string): Promise<string> { let rasGID = Tools.escapeID(initialGID); const res = knex.from('groups').where('gid', rasGID) if (res.length == 0) { return (rasGID); } else { return (this.getAvailableGID(rasGID + 'n')); } } /** * @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 addVisibilityEdge * @summary Fonction pour ajouter une arete de visibilité. * @arg {string} forGroup - Le groupe a rendre visible. * @arg {string} visibleBy - Le groupe qui pourra voir. * @return {Promise(boolean)} Renvoie true si modification réussie. * @async * @rights admin du groupe 'forGroup' */ async addVisibilityEdge(forGroup: string, visibleBy: string): Promise<boolean> { throw "Not implemented"; } /** * @memberof GraphQL.GroupModel# * @function removeVisibilityEdge * @summary Fonction pour retirer une arete de visibilité. * @arg {string} forGroup - Le groupe a rendre invisible. * @arg {string} visibleBy - Le groupe qui ne pourra plus voir. * @return {Promise(boolean)} Renvoie true si modification réussie. * @async * @rights admin du groupe 'forGroup' */ async removeVisibilityEdge(forGroup: string, visibleBy: string): Promise<boolean> { 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"; } }