1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 10:19:30 +02:00
OpenSTF/lib/roles/auth.js
2014-01-23 22:51:46 +09:00

102 lines
2.9 KiB
JavaScript

var url = require('url')
var express = require('express')
var validator = require('express-validator')
var logger = require('../util/logger')
var requtil = require('../util/requtil')
var ldaputil = require('../util/ldaputil')
var jwtutil = require('../util/jwtutil')
module.exports = function(options) {
var log = logger.createLogger('app')
, app = express()
app.use(express.cookieParser())
app.use(express.cookieSession({
secret: options.secret
, key: options.ssid
}))
app.use(express.json())
app.use(express.urlencoded())
app.use(validator())
app.get('/auth', function(req, res) {
res.locals.csrf = req.csrfToken()
})
app.post('/auth', function(req, res) {
var log = logger.createLogger('auth')
log.setLocalIdentifier(req.ip)
switch (req.accepts(['json'])) {
case 'json':
requtil.validate(req, function() {
req.checkBody('username').notEmpty()
req.checkBody('password').notEmpty()
// This is a security risk. Someone might forward the user
// to the login page with their own redirect set, and they'd
// then be able to steal the token. Some kind of a whitelist
// or a fixed redirect URL is needed.
req.checkBody('redirect').isUrl()
})
.then(function() {
return ldaputil.login(
options.ldap
, req.body.username
, req.body.password
)
})
.then(function(user) {
log.info('Authenticated "%s"', user.userPrincipalName)
var token = jwtutil.encode({
payload: {
email: user.userPrincipalName
, name: user.cn
}
, secret: options.secret
})
var target = url.parse(req.body.redirect)
target.query = {
jwt: token
}
res.status(200)
.json({
success: true
, redirect: url.format(target)
})
})
.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
}
})
app.listen(options.port)
log.info('Listening on port %d', options.port)
}