diff --git a/lib/web/auth/index.ts b/lib/web/auth/index.ts index aae33dd72..d00e84f25 100644 --- a/lib/web/auth/index.ts +++ b/lib/web/auth/index.ts @@ -9,7 +9,7 @@ import { GithubMiddleware } from './github' import { GitlabMiddleware } from './gitlab' import { DropboxMiddleware } from './dropbox' import google from './google' -import ldap from './ldap' +import { LdapMiddleware } from './ldap' import { SamlMiddleware } from './saml' import oauth2 from './oauth2' import { EmailMiddleware } from './email' @@ -49,7 +49,7 @@ if (config.isGitHubEnable) AuthRouter.use(GithubMiddleware.getMiddleware()) if (config.isGitLabEnable) AuthRouter.use(GitlabMiddleware.getMiddleware()) if (config.isDropboxEnable) AuthRouter.use(DropboxMiddleware.getMiddleware()) if (config.isGoogleEnable) AuthRouter.use(google) -if (config.isLDAPEnable) AuthRouter.use(ldap) +if (config.isLDAPEnable) AuthRouter.use(LdapMiddleware.getMiddleware()) if (config.isSAMLEnable) AuthRouter.use(SamlMiddleware.getMiddleware()) if (config.isOAuth2Enable) AuthRouter.use(oauth2) if (config.isEmailEnable) AuthRouter.use(EmailMiddleware.getMiddleware()) diff --git a/lib/web/auth/ldap/index.js b/lib/web/auth/ldap/index.js index 78d82dbf0..e69de29bb 100644 --- a/lib/web/auth/ldap/index.js +++ b/lib/web/auth/ldap/index.js @@ -1,90 +0,0 @@ -'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 { urlencodedParser } = require('../../utils') -const errors = require('../../../errors') - -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, - starttls: config.ldap.starttls || 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 () { - logger.debug(`user login: ${user.id}`) - return done(null, user) - }) - } else { - 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 errors.errorBadRequest(res) - passport.authenticate('ldapauth', { - successReturnToOrRedirect: config.serverURL + '/', - failureRedirect: config.serverURL + '/', - failureFlash: true - })(req, res, next) -}) diff --git a/lib/web/auth/ldap/index.ts b/lib/web/auth/ldap/index.ts new file mode 100644 index 000000000..99b1d8999 --- /dev/null +++ b/lib/web/auth/ldap/index.ts @@ -0,0 +1,96 @@ +import { Router } from 'express' +import passport from 'passport' +import LDAPStrategy from 'passport-ldapauth' + +import { config } from '../../../config' +import { User } from '../../../models' +import { logger } from '../../../logger' +import { urlencodedParser } from '../../utils' +import { errors } from '../../../errors' +import { AuthMiddleware } from '../interface' + +export const LdapMiddleware: AuthMiddleware = { + getMiddleware (): Router { + const LdapAuth = 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, + starttls: config.ldap.starttls || null + } + }, function (user, done) { + let 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.') + } + + let username = uuid + if (config.ldap.usernameField && user[config.ldap.usernameField]) { + username = user[config.ldap.usernameField] + } + + const 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' + } + const stringifiedProfile = JSON.stringify(profile) + User.findOrCreate({ + where: { + profileid: profile.id.toString() + }, + defaults: { + profile: stringifiedProfile + } + }).then(function ([user, _]) { + if (user) { + let needSave = false + if (user.profile !== stringifiedProfile) { + user.profile = stringifiedProfile + needSave = true + } + if (needSave) { + user.save().then(function () { + logger.debug(`user login: ${user.id}`) + return done(null, user) + }) + } else { + 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 errors.errorBadRequest(res) + passport.authenticate('ldapauth', { + successReturnToOrRedirect: config.serverURL + '/', + failureRedirect: config.serverURL + '/', + failureFlash: true + })(req, res, next) + }) + + return LdapAuth + } +}