Source: src/talk_ldap_data.js

var ensureLoggedin =  require('connect-ensure-login').ensureLoggedIn;
var ldapescape = require("ldap-escape");
var Fuse = require("fuse.js");

/**
 * Fonction de Toussaint
 * @arg {int} uid - L'id à tester
 * @arg {int} from - Le groupeà tester
 * @arg {string} client - Le serveur à tester
 *
 */
function checkGroupAdmin(uid, from, client){
    return new Promise(function(resolve, reject) {
        client.search("dc=frankiz,dc=net", {scope: "sub", attributes: ["cn", "uid", "mail", "memberUid", "objectClass"], filter: ldapescape.filter("(uid=${uid})", {uid: from})}, function(err, resldap){
            if (err) {
                reject("LDAP search error");
            } else {
                resldap.on('searchEntry', function(entry) {
                    if (entry.object.objectClass.indexOf("inetOrgPerson") > -1) {
                        if (entry.object.uid == uid) {
                            resolve(entry.object.cn + " <" + entry.object.mail + ">");
                        } else {
                            reject("Cannot send as user which is not you");
                        }
                    } else {
                        if (entry.object.memberUid.indexOf(uid) > -1) {
                            resolve(entry.object.cn + " <" + from + "@eleves.polytechnique.fr>");
                        } else {
                            reject("You are not admin of this group");
                        }
                    }
                });
            }
        });
    });
}

module.exports = function(server, passport, ldap, mailqueue, config) {
    // Create Express API's here

    server.post('/api/auth', passport.authenticate('ldapauth', {failureRedirect: '/'}), function (req, res) {
        req.session.dn = req.user.dn;
        req.session.password = req.body.password;

        if (req.session.returnTo !== undefined) {
            res.redirect(req.session.returnTo);
        } else {
            res.redirect("/send");
        }
    });

    server.get('/api/logout', function(req, res){
        req.logout();
        res.redirect('/');
    });

    server.get('/api/listfrom', ensureLoggedin(), function(req, res){
        var client = ldap.createClient({
            url: config.ldap.server,
        });
        client.bind(req.session.dn, req.session.password, function(err){
            if (err) {
                console.error("Error binding", err);
                res.status(500).end("Unable to bind");
            } else {
                var out = [{name: req.user.cn, mail: req.user.mail, id: req.user.uid}];
                client.search("ou=groups,dc=frankiz,dc=net", {scope: "sub", attributes: ["cn", "uid"], filter: ldapescape.filter("(memberUid=${uid})", {uid: req.user.uid})}, function(err, resldap){
                    if (err) {
                        console.error(err);
                    } else {
                        resldap.on('error', function(err) {
                            console.error('error: ' + err.message);
                        });

                        resldap.on('searchEntry', function(entry) {
                            out.push({name: entry.object.cn, id: entry.object.uid, mail: entry.object.uid + "@eleves.polytechnique.fr"});
                        });

                        resldap.on('end', function(result) {
                            res.json(out);
                        });
                    }
                });
            }
        });

    });

    server.get('/api/autocomplete/:query', ensureLoggedin(), function(req, res){
        var client = ldap.createClient({
            url: config.ldap.server
        });
        client.bind(req.session.dn, req.session.password, function(err){
            if (err) {
                console.error("Error binding", err);
                res.status(500).end("Unable to bind");
            } else {
                var out = [];
                client.search("ou=eleves,dc=frankiz,dc=net", {scope: "sub", attributes: ["cn", "uid", "mail"], filter: ldapescape.filter("(|(uid=*${uid}*)(cn=*${uid}*))", {uid: req.params.query})}, function(err, resldap){
                    if (err) {
                        console.error(err);
                    } else {
                        resldap.on('error', function(err) {
                            console.error('error: ' + err.message);
                        });

                        resldap.on('searchEntry', function(entry) {
                            out.push({label: entry.object.cn, id: entry.object.uid, value: entry.object.mail});
                        });

                        resldap.on('end', function(result) {
                            var options = {
                                shouldSort: true,
                                threshold: 0.6,
                                location: 0,
                                distance: 100,
                                maxPatternLength: 32,
                                minMatchCharLength: 1,
                                keys: ["label", "value"]
                            };

                            var fuse = new Fuse(out, options);

                            res.json(fuse.search(req.params.query));
                        });
                    }
                });
            }
        });
    });

    server.post('/api/send', ensureLoggedin(), function(req, res){
        var client = ldap.createClient({
            url: config.ldap.server 
        });
        client.bind(req.session.dn, req.session.password, function(err){
            if (err) {
                console.error("Error binding", err);
                res.status(500).end("Unable to bind");
            } else {
                checkGroupAdmin(req.user.uid, req.body.from, client).then(function(sender){
                    var to = JSON.parse(req.body.to);
                    console.log(to);
                    for (var i = 0; i < to.length; i++) {
                        message = {
                            from: sender,
                            to: to[i].value,
                            subject: req.body.subject,
                            html: req.body.content
                        };
                        mailqueue.push(message);
                    }

                }, function(error){console.error(error);});
                res.redirect("/send");
            }
        });

    });


};