Skip to content
Snippets Groups Projects
groupModel.ts 15.2 KiB
Newer Older
Olivér FACKLAM's avatar
Olivér FACKLAM committed
/**
 * @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";
Olivér FACKLAM's avatar
Olivér FACKLAM committed
import knex from "../../../db/knex_router"
Hadrien RENAUD's avatar
Hadrien RENAUD committed
import { GroupCollection, GroupSet, Tools } from "../../utils/tools";
Olivér FACKLAM's avatar
Olivér FACKLAM committed
import { createSubgroupArgs, editGroupArgs } from "../typeDefs/queries";
Hadrien RENAUD's avatar
Hadrien RENAUD committed
import {Cache} from "../../utils/cache";
Olivér FACKLAM's avatar
Olivér FACKLAM committed

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;
Hadrien RENAUD's avatar
Hadrien RENAUD committed
        this.cache = new Cache<Promise<Group>, string>(this.newGroup);
Olivér FACKLAM's avatar
Olivér FACKLAM committed
    }

    protected contextUser: string;

Hadrien RENAUD's avatar
Hadrien RENAUD committed
    protected cache: Cache<Promise<Group>, string>;
Hadrien RENAUD's avatar
Hadrien RENAUD committed

Olivér FACKLAM's avatar
Olivér FACKLAM committed
    /**
     * @memberof GraphQL.GroupModel#
Hadrien RENAUD's avatar
Hadrien RENAUD committed
     * @function newGroup
Olivér FACKLAM's avatar
Olivér FACKLAM committed
     * @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
     */
Hadrien RENAUD's avatar
Hadrien RENAUD committed
    async newGroup(gid: string): Promise<Group> {
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        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;
        }
Olivér FACKLAM's avatar
Olivér FACKLAM committed
    }

Hadrien RENAUD's avatar
Hadrien RENAUD committed
    async getGroup(gid: string): Promise<Group> {
        console.log("Getgroup called: ", gid);
        return this.cache.get(gid);
    }

Olivér FACKLAM's avatar
Olivér FACKLAM committed
    /**
     * @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.
Olivér FACKLAM's avatar
Olivér FACKLAM committed
     * @return {SimpleGroup[]} Renvoie le tableau de groupes correspondant
Olivér FACKLAM's avatar
Olivér FACKLAM committed
     * @rights connectedOrOnplatal
     */
Olivér FACKLAM's avatar
Olivér FACKLAM committed
    getAllSimpleGroups(groups: GroupSet): SimpleGroup[] {
        let res: SimpleGroup[]
Olivér FACKLAM's avatar
Olivér FACKLAM committed

        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));
    }

Olivér FACKLAM's avatar
Olivér FACKLAM committed
    /**
     * @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> {
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        // Pour l'instant, ce n'est pas a implémenter...
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        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> {
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        // Pour l'instant, ce n'est pas a implémenter...
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        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";
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        //TODO : Vérifier que 'parent' est un groupe _simple_.
Olivér FACKLAM's avatar
Olivér FACKLAM committed
        // 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'));
        }
    }

Olivér FACKLAM's avatar
Olivér FACKLAM committed
    /**
     * @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";
    }

Olivér FACKLAM's avatar
Olivér FACKLAM committed
    /**
     * @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";
    }

Olivér FACKLAM's avatar
Olivér FACKLAM committed
    /**
     * @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";
    }

Hadrien RENAUD's avatar
Hadrien RENAUD committed
}