Browse Source

LDAP authentication

pull/33/head
NGPixel 7 years ago
parent
commit
80aa30009b
13 changed files with 112 additions and 53 deletions
  1. 2
      app/data.yml
  2. 4
      assets/js/app.js
  3. 67
      assets/js/libs.js
  4. 1
      config.sample.yml
  5. 50
      controllers/auth.js
  6. 3
      locales/en/auth.json
  7. 7
      locales/fr/auth.json
  8. 18
      models/user.js
  9. 2
      npm/install.js
  10. 4
      views/auth/login.pug
  11. 1
      views/pages/admin/profile.pug
  12. 3
      views/pages/admin/users-edit.pug
  13. 3
      views/pages/admin/users.pug

2
app/data.yml

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

4
assets/js/app.js
File diff suppressed because it is too large
View File

67
assets/js/libs.js
File diff suppressed because it is too large
View File

1
config.sample.yml

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

50
controllers/auth.js

@ -1,5 +1,6 @@
'use strict'
const Promise = require('bluebird')
const express = require('express')
const router = express.Router()
const passport = require('passport')
@ -37,24 +38,51 @@ router.get('/login', function (req, res, next) {
})
router.post('/login', bruteforce.prevent, function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
if (err) { return next(err) }
if (!user) {
req.flash('alert', {
title: 'Invalid login',
message: 'The email or password is invalid.'
new Promise((resolve, reject) => {
// [1] LOCAL AUTHENTICATION
passport.authenticate('local', function (err, user, info) {
if (err) { return reject(err) }
if (!user) { return reject(new Error('INVALID_LOGIN')) }
resolve(user)
})(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
}
req.logIn(user, function (err) {
}).then((user) => {
// LOGIN SUCCESS
return req.logIn(user, function (err) {
if (err) { return next(err) }
req.brute.reset(function () {
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')
}
})
})
/**

3
locales/en/auth.json

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

7
locales/fr/auth.json

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

18
models/user.js

@ -71,6 +71,24 @@ userSchema.statics.processProfile = (profile) => {
}, {
new: true
}).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.'))
})
}

2
npm/install.js

@ -56,7 +56,7 @@ pm2.connectAsync().then(() => {
}).then(() => {
return new Promise((resolve, reject) => {
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
})
npmInstallProc.stdout.pipe(process.stdout)

4
views/auth/login.pug

@ -34,12 +34,12 @@ html
h2 Login required
if appflash.length > 0
h3
i.fa.fa-warning
i.icon-warning-outline
= appflash[0].title
h4= appflash[0].message
if appconfig.auth.local.enabled
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')
button(type='submit') Log In
if appconfig.authStrategies.socialEnabled

1
views/pages/admin/profile.pug

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

3
views/pages/admin/users-edit.pug

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

3
views/pages/admin/users.pug

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

Loading…
Cancel
Save