// Original file created by Prof.Dr. Matthias Hopf /* * Authorization */ var common, Users; const ldap = require ('./ldap_ohm'), crypto = require ('./crypto'), dbs = require ('./dbs'); // deactivated is not used yet const serverVisibleSession = { user: true, name: true, type: true, mail: true, roles: true, gender: true, deactivated: true, host: true }; const clientVisibleSession = { user: true, name: true, type: true, mail: true, roles: true, gender: true }; // Return user role, query from found.mail function getUserRole(found) { var roles = "user:true"; var mail = found.mail; if (!/\d/.test(mail)) { // Mail contains no number roles += ',"author:true"'; } return ('{'+roles+'}'); } // Fill in session object function fillSession (req, user, roles, cb) { if (req.session === undefined) next (common.genError (500, "Error")); // regenerate a new session-id with clean instance if (user !== undefined && roles !== undefined) { req.session.regenerate (function (err) { if (user !== undefined && ! err) { common.shallowCopy (user, serverVisibleSession, {roles: true}, req.session); // console.info(req.session); if (user._id) { req.session.user = user._id; } req.session.roles = roles; console.info(req.session); } return cb (err); }); } else { return cb (); } } // Save found user into DB, if not already exists function saveFoundToDB(found, cb) { // console.info(found); Users.findById(found.user) .exec(function(err, result){ if (err) { console.error("Error: Users collection."); console.error(err); } // User doesn't exist if (found !== undefined && !result) { Users.create({ _id: found.user, name: found.name, mail: found.mail, type: found.type, gender: found.gender, abos: '', bookmarks: '', roles: getUserRole(found), }, function(err, done) { if (err) { console.error("User creation: Failed"); console.error(err); } else { console.info("User created: "+ found.user); } if (done == null) { console.error("Can not create user."); } return cb(err); }); } else { return cb(err); } }); } const authorization = { // Generate Error object suitible for throwing or next()ing genCheckAuthorized: function (group) { return function (req, res, next) { if (req.session === undefined || req.session.user === undefined || req.session.roles === undefined) return next (common.genError (403, "Unauthorized")); if (req.session.roles[group] === undefined) return next (common.genError (403, "Unauthorized")); next (); } }, // Login route: requires .user and .pwd params login: function (req, res, next) { var user = req.body.user || ''; var pwd = req.body.pwd || ''; // Helper: Return valid session Object function returnSession () { // Only export client visible parts of session object var copy = common.shallowCopy (req.session, clientVisibleSession); return res.json (copy); } // Helper: Return error function returnError () { fillSession (req, undefined, undefined, function (err) { next (common.genError (401, "Unauthorized")); }); } // Check whether to just validate current session ID if (user === '' && pwd === '') { console.log ("auth revalidate: " + req.session._id); if (req.session.user === undefined) return returnError(); return returnSession (); } // check local database, then ldap Users.findById (req.body.user) .exec (function (err, entry) { // If there is a local user AND it has a password associated, test against this, and only this if (entry != null && entry.pwd) { console.info(entry); if (crypto.checkLocalAuth (entry, req.body.pwd)) { return fillSession (req, entry, entry.roles, returnSession); } return returnError (); } // check ldap ldap.authorize (user.toLowerCase(), pwd, function (found) { //console.log ("ldap authorize " + user + " returns " + JSON.stringify (found)); // No ldap entry either -> unauthorized if (found == null) { return returnError (); } // If there is an entry w/o password, use it for roles etc. if (entry) { if (! entry.name || entry.name === "") entry.name = found.name; if (! entry.mail || entry.mail === "") entry.mail = found.mail; if (! entry.type || entry.type === "") entry.type = found.type; if (! entry.orclgender || entry.orclgender === "") entry.orclgender = found.orclgender; return fillSession (req, entry, entry.roles.length > 0 ? entry.roles : {user:true}, returnSession); } // Otherwise create standard user entry saveFoundToDB(found, function() { return fillSession (req, found, {user:true}, returnSession); }); }); }); }, logout: function (req, res, next) { fillSession (req, undefined, undefined, function (err) { // Session delete, exists further in db req.session.destroy(function(err) { if (err) { console.error(err); } }); // console.info(req.session); return res.json ({}); }); }, init: function (_common) { common = _common; ldap.init (_common); Users = dbs.models.Users; }, }; module.exports = authorization;