/** * @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 { Group as LDAP_Group, groupData } from "../../ldap/export/group"; 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.cacheSimple = new Cache<SimpleGroup, string>(); this.cacheMeta = new Cache<MetaGroup, string>(); } protected contextUser: string; protected cacheSimple: Cache<SimpleGroup, string>; protected cacheMeta: Cache<MetaGroup, 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 sg = await this.getSimpleGroup(gid); if(sg) return sg; let mg = await this.getMetaGroup(gid); if(mg) return mg; return null; } /** * @memberof GraphQL.GroupModel# * @function getSimpleGroup * @summary Fonction qui renvoie un groupe simple donné. * @arg {string} gid - Identifiant demandé. * @arg {boolean} load - Si load vaut false, les données ne seront pas chargées * @return {Promise(SimpleGroup)} Renvoie le groupe dont l'identifiant est 'gid' * @async * @rights connectedOrOnplatal */ async getSimpleGroup(gid: string, load: boolean = true): Promise<SimpleGroup> { return this.cacheSimple.get(gid, (id) => SimpleGroup.tryCreate(id, load)); } /** * @memberof GraphQL.GroupModel# * @function getMetaGroup * @summary Fonction qui renvoie un méta-groupe donné. * @arg {string} gid - Identifiant demandé. * @arg {boolean} load - Si load vaut false, les données ne seront pas chargées * @return {Promise(MetaGroup)} Renvoie le groupe dont l'identifiant est 'gid' * @async * @rights connectedOrOnplatal */ async getMetaGroup(gid: string, load: boolean = true): Promise<MetaGroup> { return this.cacheMeta.get(gid, (id) => MetaGroup.tryCreate(id, load)); } /** * @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 */ async getAllGroupsByCollection(groups: GroupCollection): Promise<Group[]> { let res = new Array<Group>(); for(let s of groups.simpleGroups) { res.push(await this.getSimpleGroup(s, false)); } for(let m of groups.metaGroups) { res.push(await this.getMetaGroup(m, false)); } 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 = new Array<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 */ async getAllSimpleGroups(groups: GroupSet): Promise<SimpleGroup[]> { let res = new Array<SimpleGroup>(); for (let g of groups) { res.push(await this.getSimpleGroup(g, false)); } return res; } /** * @memberof GraphQL.GroupModel# * @function getAllMetaGroups * @summary Fonction qui renvoie tous les méta-groupes donnés en argument. * @arg {GroupSet} groups - Ensemble d'identifiants, supposés valides. * @return {MetaGroup[]} Renvoie le tableau de groupes correspondant * @rights connectedOrOnplatal */ async getAllMetaGroups(groups: GroupSet): Promise<MetaGroup[]> { let res = new Array<MetaGroup>(); for (let g of groups) { res.push(await this.getMetaGroup(g, false)); } 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(string[])} Renvoie le tableau des admins * @rights viewer */ async getMetaGroupAdmins(gid: string): Promise<string[]> { 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 = await this.getSimpleGroup(g); let sg_admins = await sg.getAdmins(); for (let admin of sg_admins) { admins.add(admin); } } return [...admins]; } /** * @memberof GraphQL.GroupModel# * @function getSimpleGroupFrontPage * @summary Fonction qui renvoie la frontpage d'un groupe simple. * @arg {string} gid - identifiant du groupe en question. * @return {Promise(string)} Renvoie la frontpage. * @rights viewer */ async getSimpleGroupFrontPage(gid: string): Promise<string> { let data = await knex.select('frontPage').from('simplegroups').where('gid', gid); if(data.length > 0) { return data[0].frontPage; } return null; } /** * @memberof GraphQL.GroupModel# * @function getSimpleGroupChildren * @summary Fonction qui renvoie les enfants d'un groupe simple. * @arg {string} gid - identifiant du groupe en question. * @return {Promise(GroupSet)} Renvoie la frontpage. * @rights viewer */ async getSimpleGroupChildren(gid: string): Promise<GroupSet> { let gd = new groupData(); gd.parents = [gid]; let gids = await LDAP_Group.search(gd); return new GroupSet(gids); } /** * @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"; } }