(function(module) { "use strict"; var user = module.parent.require('./user'), meta = module.parent.require('./meta'), db = module.parent.require('../src/database'), passport = module.parent.require('passport'), passportSAML = require('passport-saml').Strategy, fs = module.parent.require('fs'), path = module.parent.require('path'), nconf = module.parent.require('nconf'), async = module.parent.require('async'), winston = require('winston'); var constants = Object.freeze({ 'name': "SAML", 'admin': { 'route': '/plugins/sso-saml', 'icon': 'fa-university' } }); var master_config = {}; var samlObj; class SsoSaml { init(params, callback) { function render(req, res, next) { res.render('admin/plugins/sso-saml', {}); } meta.settings.get('sso_saml', function(err, options) { console.log('[sso-saml] got options', options); master_config = options; }); params.router.get('/admin/plugins/sso-saml', params.middleware.admin.buildHeader, render); params.router.get('/api/admin/plugins/sso-saml', render); console.log("[sso-saml] init done"); callback(); } get_config(options, callback) { meta.settings.get('sso_saml', function(err, settings) { if (err) { return callback(null, options); } master_config = settings; options.sso_saml = settings; callback(null, options); }); } initSaml() { console.log("[sso-saml] initSaml"); //if (master_config.idp_entry_point && master_config.callback_path && master_config.issuer && master_config.metadata) { // console.log("creating samlObj"); // samlObj = new passportSAML({ // path: master_config.callback_path, // entryPoint: master_config.idp_entry_point, // issuer: master_config.issuer, // callbackUrl: nconf.get('url') + master_config.callback_path, // disableRequestedAuthnContext: true, // identifierFormat: null // }, // function(profile, done) { // console.log("[sso-saml] profile, ", profile); // var user = { // nameID: profile.nameID, // nameIDFormat: profile.nameIDFormat, // sn: profile['urn:oid:2.5.4.4'], // sn // //sn: profile.sn, // cn: profile['urn:oid:2.5.4.42'], // givenname // //cn: profile.cn, // //mail: profile.mail, // //eduPersonAffiliation: profile.eduPersonAffiliation, // email: profile.mail, // //email: profile.email, // username: profile['urn:oid:1.3.6.1.4.1.5923.1.1.1.2'], // eduPersonNickname // //username: profile.eduPersonNickname // }; // SAML.login(user,function(err, user) { // if (err) { // return done(err); // } // done(null, user); // }); // } // ); //} //if (samlObj){ // if (master_config.metadata) { // params.router.get(master_config.metadata, function(req, res) { // if (master_config.server_crt){ // var cert = fs.readFileSync(master_config.server_crt, 'utf-8'); // res.header("Content-Type", "application/xml"); // res.send(samlObj.generateServiceProviderMetadata(cert)) // } // else{ // res.send("No servercrt specified. Please enter it at nodebb admin panel."); // } // }); // } // params.router.post(master_config.callback_path, // passport.authenticate('saml'), // function(req, res, next){ // if (master_config.login_redirect_url){ // res.redirect(master_config.login_redirect_url); // } // else{ // res.redirect("/"); // } // } // ); // if (master_config.logout_url) { // params.router.get(master_config.logout_url,function(req,res){ // if (req.user && parseInt(req.user.uid, 10) > 0) { // winston.info('[Auth] Session ' + req.sessionID + ' logout (uid: ' + req.user.uid + ')'); // var ws = module.parent.require('./socket.io'); // ws.logoutUser(req.user.uid); // req.logout(); // if (master_config.logout_redirect_url){ // res.redirect(master_config.logout_redirect_url); // } // else{ // res.redirect("/"); // } // } // }); // } //} //else { // console.log("[sso-saml] Cannot create samlObj"); //} } getStrategy(strategies, callback) { this.initSaml(); if (samlObj){ passport.use(samlObj); strategies.push({ name: 'saml', url: '/auth/saml', callbackURL: master_config.callback_path, icon: constants.admin.icon, scope: '' }); } callback(null, strategies); } login(userdata, callback) { SAML.getUidBySAMLId(userdata.username, function(err, uid) { if(err) { return callback(err); } if (uid !== null) { // Existing User callback(null, { uid: uid }); } else { console.log(userdata); // New User user.create({ username: userdata.username, email: userdata.email, fullname : userdata.first_name + " " + userdata.last_name }, function(err, uid) { if(err) { return callback(err); } user.setUserField(uid, 'samlid', userdata.username); db.setObjectField('samlid:uid', userdata.username, uid); callback(null, { uid: uid }); }); } }); } getUidBySAMLId(samlid, callback) { db.getObjectField('samlid:uid', samlid, function(err, uid) { if (err) { return callback(err); } callback(null, uid); }); } addMenuItem(custom_header, callback) { custom_header.authentication.push({ "route": constants.admin.route, "icon": constants.admin.icon, "name": constants.name }); callback(null, custom_header); } deleteUserData(uid, callback) { async.waterfall([ async.apply(user.getUserField, uid, 'samlid'), function(idToDelete, next) { db.deleteObjectField('samlid:uid', idToDelete, next); } ], function(err) { if (err) { winston.error('[sso-saml] Could not remove user data for uid ' + uid + '. Error: ' + err); return callback(err); } callback(null, uid); }); } }; var SAML = new SsoSaml(); module.exports = SAML; }(module));