638eae0dfb
This check is needed at there are tons of LDAP implementations out there and none has at least one guaranteed unique field. As we currently check three fields and added an option to select one yourself, it's still not said that any of these fields is set. This will now create an error and fail the authentication instead of letting people may get access to other people's notes which are stored under a this way deterministic wrong userid named `LDAP-undefined`. Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
91 lines
2.9 KiB
JavaScript
91 lines
2.9 KiB
JavaScript
'use strict'
|
|
|
|
const Router = require('express').Router
|
|
const passport = require('passport')
|
|
const LDAPStrategy = require('passport-ldapauth')
|
|
const config = require('../../../config')
|
|
const models = require('../../../models')
|
|
const logger = require('../../../logger')
|
|
const {setReturnToFromReferer} = require('../utils')
|
|
const {urlencodedParser} = require('../../utils')
|
|
const response = require('../../../response')
|
|
|
|
let ldapAuth = module.exports = Router()
|
|
|
|
passport.use(new LDAPStrategy({
|
|
server: {
|
|
url: config.ldap.url || null,
|
|
bindDn: config.ldap.bindDn || null,
|
|
bindCredentials: config.ldap.bindCredentials || null,
|
|
searchBase: config.ldap.searchBase || null,
|
|
searchFilter: config.ldap.searchFilter || null,
|
|
searchAttributes: config.ldap.searchAttributes || null,
|
|
tlsOptions: config.ldap.tlsOptions || null
|
|
}
|
|
}, function (user, done) {
|
|
var uuid = user.uidNumber || user.uid || user.sAMAccountName || undefined
|
|
if (config.ldap.useridField && user[config.ldap.useridField]) {
|
|
uuid = user[config.ldap.useridField]
|
|
}
|
|
|
|
if (typeof uuid === 'undefined') {
|
|
throw new Error('Could not determine UUID for LDAP user. Check that ' +
|
|
'either uidNumber, uid or sAMAccountName is set in your LDAP directory ' +
|
|
'or use another unique attribute and configure it using the ' +
|
|
'"useridField" option in ldap settings.')
|
|
}
|
|
|
|
var username = uuid
|
|
if (config.ldap.usernameField && user[config.ldap.usernameField]) {
|
|
username = user[config.ldap.usernameField]
|
|
}
|
|
|
|
var profile = {
|
|
id: 'LDAP-' + uuid,
|
|
username: username,
|
|
displayName: user.displayName,
|
|
emails: user.mail ? Array.isArray(user.mail) ? user.mail : [user.mail] : [],
|
|
avatarUrl: null,
|
|
profileUrl: null,
|
|
provider: 'ldap'
|
|
}
|
|
var stringifiedProfile = JSON.stringify(profile)
|
|
models.User.findOrCreate({
|
|
where: {
|
|
profileid: profile.id.toString()
|
|
},
|
|
defaults: {
|
|
profile: stringifiedProfile
|
|
}
|
|
}).spread(function (user, created) {
|
|
if (user) {
|
|
var needSave = false
|
|
if (user.profile !== stringifiedProfile) {
|
|
user.profile = stringifiedProfile
|
|
needSave = true
|
|
}
|
|
if (needSave) {
|
|
user.save().then(function () {
|
|
if (config.debug) { logger.debug('user login: ' + user.id) }
|
|
return done(null, user)
|
|
})
|
|
} else {
|
|
if (config.debug) { logger.debug('user login: ' + user.id) }
|
|
return done(null, user)
|
|
}
|
|
}
|
|
}).catch(function (err) {
|
|
logger.error('ldap auth failed: ' + err)
|
|
return done(err, null)
|
|
})
|
|
}))
|
|
|
|
ldapAuth.post('/auth/ldap', urlencodedParser, function (req, res, next) {
|
|
if (!req.body.username || !req.body.password) return response.errorBadRequest(res)
|
|
setReturnToFromReferer(req)
|
|
passport.authenticate('ldapauth', {
|
|
successReturnToOrRedirect: config.serverurl + '/',
|
|
failureRedirect: config.serverurl + '/',
|
|
failureFlash: true
|
|
})(req, res, next)
|
|
})
|