var http = require('http') var express = require('express') var validator = require('express-validator') var cookieSession = require('cookie-session') var bodyParser = require('body-parser') var serveStatic = require('serve-static') var csrf = require('csurf') var Promise = require('bluebird') var logger = require('../../util/logger') var requtil = require('../../util/requtil') var ldaputil = require('../../util/ldaputil') var jwtutil = require('../../util/jwtutil') var pathutil = require('../../util/pathutil') var urlutil = require('../../util/urlutil') var lifecycle = require('../../util/lifecycle') module.exports = function(options) { var log = logger.createLogger('auth-ldap') , app = express() , server = Promise.promisifyAll(http.createServer(app)) lifecycle.observe(function() { log.info('Waiting for client connections to end') return server.closeAsync() .catch(function() { // Okay }) }) app.set('view engine', 'jade') app.set('views', pathutil.resource('auth/ldap/views')) app.set('strict routing', true) app.set('case sensitive routing', true) app.use(cookieSession({ name: options.ssid , keys: [options.secret] })) app.use(bodyParser.json()) app.use(csrf()) app.use(validator()) app.use('/static/bower_components', serveStatic(pathutil.resource('bower_components'))) app.use('/static/auth/ldap', serveStatic(pathutil.resource('auth/ldap'))) app.use(function(req, res, next) { res.cookie('XSRF-TOKEN', req.csrfToken()); next() }) app.get('/partials/:name', function(req, res) { var whitelist = { 'signin': true } if (whitelist[req.params.name]) { res.render('partials/' + req.params.name) } else { res.send(404) } }) app.get('/', function(req, res) { res.render('index') }) app.post('/api/v1/auth/ldap', function(req, res) { var log = logger.createLogger('auth-ldap') log.setLocalIdentifier(req.ip) switch (req.accepts(['json'])) { case 'json': requtil.validate(req, function() { req.checkBody('username').notEmpty() req.checkBody('password').notEmpty() }) .then(function() { return ldaputil.login( options.ldap , req.body.username , req.body.password ) }) .then(function(user) { log.info('Authenticated "%s"', ldaputil.email(user)) var token = jwtutil.encode({ payload: { email: ldaputil.email(user) , name: user.cn } , secret: options.secret }) res.status(200) .json({ success: true , redirect: urlutil.addParams(options.appUrl, { jwt: token }) }) }) .catch(requtil.ValidationError, function(err) { res.status(400) .json({ success: false , error: 'ValidationError' , validationErrors: err.errors }) }) .catch(ldaputil.InvalidCredentialsError, function(err) { log.warn('Authentication failure for "%s"', err.user) res.status(400) .json({ success: false , error: 'InvalidCredentialsError' }) }) .catch(function(err) { log.error('Unexpected error', err.stack) res.status(500) .json({ success: false , error: 'ServerError' }) }) break default: res.send(406) break } }) server.listen(options.port) log.info('Listening on port %d', options.port) }