LDAP authentication

pull/33/head
NGPixel 8 years ago
parent 3f1d946b3d
commit 80aa30009b

@ -33,6 +33,8 @@ defaults:
enabled: false enabled: false
slack: slack:
enabled: false enabled: false
ldap:
enabled: false
db: mongodb://localhost/wiki db: mongodb://localhost/wiki
sessionSecret: null sessionSecret: null
admin: null admin: null

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -82,7 +82,6 @@ auth:
bindDn: cn='root' bindDn: cn='root'
bindCredentials: BIND_PASSWORD bindCredentials: BIND_PASSWORD
searchBase: o=users,o=example.com searchBase: o=users,o=example.com
# searchFilter: {{username}} to use the provided username in search
searchFilter: (uid={{username}}) searchFilter: (uid={{username}})
tlsEnabled: false tlsEnabled: false
tlsCertPath: C:\example\root_ca_cert.crt tlsCertPath: C:\example\root_ca_cert.crt

@ -1,5 +1,6 @@
'use strict' 'use strict'
const Promise = require('bluebird')
const express = require('express') const express = require('express')
const router = express.Router() const router = express.Router()
const passport = require('passport') const passport = require('passport')
@ -37,24 +38,51 @@ router.get('/login', function (req, res, next) {
}) })
router.post('/login', bruteforce.prevent, function (req, res, next) { router.post('/login', bruteforce.prevent, function (req, res, next) {
passport.authenticate('local', function (err, user, info) { new Promise((resolve, reject) => {
if (err) { return next(err) } // [1] LOCAL AUTHENTICATION
passport.authenticate('local', function (err, user, info) {
if (!user) { if (err) { return reject(err) }
req.flash('alert', { if (!user) { return reject(new Error('INVALID_LOGIN')) }
title: 'Invalid login', resolve(user)
message: 'The email or password is invalid.' })(req, res, next)
}).catch({ message: 'INVALID_LOGIN' }, err => {
if (appconfig.auth.ldap && appconfig.auth.ldap.enabled) {
// [2] LDAP AUTHENTICATION
return new Promise((resolve, reject) => {
passport.authenticate('ldapauth', function (err, user, info) {
if (err) { return reject(err) }
if (info && info.message) { return reject(new Error(info.message)) }
if (!user) { return reject(new Error('INVALID_LOGIN')) }
resolve(user)
})(req, res, next)
}) })
return res.redirect('/login') } else {
throw err
} }
}).then((user) => {
req.logIn(user, function (err) { // LOGIN SUCCESS
return req.logIn(user, function (err) {
if (err) { return next(err) } if (err) { return next(err) }
req.brute.reset(function () { req.brute.reset(function () {
return res.redirect('/') return res.redirect('/')
}) })
}) })
})(req, res, next) }).catch(err => {
// LOGIN FAIL
if (err.message === 'INVALID_LOGIN') {
req.flash('alert', {
title: 'Invalid login',
message: 'The email or password is invalid.'
})
return res.redirect('/login')
} else {
req.flash('alert', {
title: 'Login error',
message: err.message
})
return res.redirect('/login')
}
})
}) })
/** /**

@ -5,6 +5,7 @@
"google": "Google ID", "google": "Google ID",
"facebook": "Facebook", "facebook": "Facebook",
"github": "GitHub", "github": "GitHub",
"slack": "Slack" "slack": "Slack",
"ldap": "LDAP / Active Directory"
} }
} }

@ -3,6 +3,9 @@
"local": "Local", "local": "Local",
"windowslive": "Compte Microsoft", "windowslive": "Compte Microsoft",
"google": "Google ID", "google": "Google ID",
"facebook": "Facebook" "facebook": "Facebook",
"github": "GitHub",
"slack": "Slack",
"ldap": "LDAP / Active Directory"
} }
} }

@ -71,6 +71,24 @@ userSchema.statics.processProfile = (profile) => {
}, { }, {
new: true new: true
}).then((user) => { }).then((user) => {
// LDAP - Handle unregistered accounts
// Todo: Allow this behavior for any provider...
if (!user && profile.provider === 'ldap') {
let nUsr = {
email: primaryEmail,
provider: profile.provider,
providerId: profile.id,
password: '',
name: profile.displayName || profile.name || profile.cn,
rights: [{
role: 'read',
path: '/',
exact: false,
deny: false
}]
}
return db.User.create(nUsr)
}
return user || Promise.reject(new Error('You have not been authorized to login to this site yet.')) return user || Promise.reject(new Error('You have not been authorized to login to this site yet.'))
}) })
} }

@ -56,7 +56,7 @@ pm2.connectAsync().then(() => {
}).then(() => { }).then(() => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
ora.text = 'Installing Wiki.js npm dependencies...' ora.text = 'Installing Wiki.js npm dependencies...'
let npmInstallProc = exec('npm install --only=production', { let npmInstallProc = exec('npm install --only=production --no-optional', {
cwd: installDir cwd: installDir
}) })
npmInstallProc.stdout.pipe(process.stdout) npmInstallProc.stdout.pipe(process.stdout)

@ -34,12 +34,12 @@ html
h2 Login required h2 Login required
if appflash.length > 0 if appflash.length > 0
h3 h3
i.fa.fa-warning i.icon-warning-outline
= appflash[0].title = appflash[0].title
h4= appflash[0].message h4= appflash[0].message
if appconfig.auth.local.enabled if appconfig.auth.local.enabled
form(method='post', action='/login') form(method='post', action='/login')
input#login-user(type='text', name='email', placeholder='Email address') input#login-user(type='text', name='email', placeholder='Email / Username')
input#login-pass(type='password', name='password', placeholder='Password') input#login-pass(type='password', name='password', placeholder='Password')
button(type='submit') Log In button(type='submit') Log In
if appconfig.authStrategies.socialEnabled if appconfig.authStrategies.socialEnabled

@ -40,6 +40,7 @@ block adminContent
when 'facebook': i.icon-facebook.is-indigo when 'facebook': i.icon-facebook.is-indigo
when 'github': i.icon-github.is-grey when 'github': i.icon-github.is-grey
when 'slack': i.icon-slack.is-purple when 'slack': i.icon-slack.is-purple
when 'ldap': i.icon-arrow-repeat-outline
default: i.icon-warning default: i.icon-warning
= t('auth:providers.' + user.provider) = t('auth:providers.' + user.provider)
label.label Member since label.label Member since

@ -42,6 +42,9 @@ block adminContent
when 'slack' when 'slack'
i.icon-slack.is-purple i.icon-slack.is-purple
| Slack | Slack
when 'ldap'
i.icon-arrow-repeat-outline
| LDAP / Active Directory
default: i.icon-warning default: i.icon-warning
td.is-centered= userMoment(usr.createdAt).format('lll') td.is-centered= userMoment(usr.createdAt).format('lll')
td.is-centered= userMoment(usr.updatedAt).format('lll') td.is-centered= userMoment(usr.updatedAt).format('lll')

@ -49,6 +49,9 @@ block adminContent
when 'slack' when 'slack'
i.icon-slack.is-purple i.icon-slack.is-purple
| Slack | Slack
when 'ldap'
i.icon-arrow-repeat-outline
| LDAP / Active Directory
default: i.icon-warning default: i.icon-warning
td.is-centered= userMoment(usr.createdAt).format('lll') td.is-centered= userMoment(usr.createdAt).format('lll')
td.is-centered= userMoment(usr.updatedAt).format('lll') td.is-centered= userMoment(usr.updatedAt).format('lll')

Loading…
Cancel
Save