Merge branch 'cloudron-io-master'

This commit is contained in:
Andris Reinman 2016-08-29 13:02:20 +03:00
commit 3fcd389db8
8 changed files with 209 additions and 76 deletions

4
app.js
View file

@ -135,6 +135,10 @@ passport.setup(app);
app.use((req, res, next) => {
res.locals.flash = req.flash.bind(req);
res.locals.user = req.user;
res.locals.ldap = {
enabled: config.ldap.enabled,
passwordresetlink: config.ldap.passwordresetlink
};
let menu = [{
title: 'Home',

View file

@ -87,3 +87,12 @@ host="0.0.0.0"
username="testuser"
password="testpass"
logger=false
[ldap]
# enable to use ldap user backend
enabled=false
host="localhost"
port=3002
baseDN="ou=users,dc=company"
filter="(|(username={{username}})(mail={{username}}))"
passwordresetlink=""

View file

@ -61,6 +61,52 @@ module.exports.findByAccessToken = (accessToken, callback) => {
});
};
module.exports.findByUsername = (username, callback) => {
db.getConnection((err, connection) => {
if (err) {
return callback(err);
}
connection.query('SELECT `id`, `username`, `email`, `access_token` FROM `users` WHERE `username`=? LIMIT 1', [username], (err, rows) => {
connection.release();
if (err) {
return callback(err);
}
if (!rows.length) {
return callback(null, false);
}
let user = tools.convertKeys(rows[0]);
return callback(null, user);
});
});
};
module.exports.add = (username, password, email, callback) => {
db.getConnection((err, connection) => {
if (err) {
return callback(err);
}
connection.query('INSERT INTO `users` (`username`, `password`, `email`, `created`) VALUES (?, ?, ?, NOW())', [username, password, email], (err, result) => {
connection.release();
if (err) {
return callback(err);
}
let id = result && result.insertId;
if (!id) {
return callback(new Error('Could not store user row'));
}
return callback(null, id);
});
});
};
/**
* Fetches user by username and password
*
@ -70,6 +116,10 @@ module.exports.findByAccessToken = (accessToken, callback) => {
*/
module.exports.authenticate = (username, password, callback) => {
if (password === '') {
return callback(null, false);
}
let login = (connection, callback) => {
connection.query('SELECT `id`, `password`, `access_token` FROM `users` WHERE `username`=? OR email=? LIMIT 1', [username, username], (err, rows) => {
if (err) {

View file

@ -1,8 +1,11 @@
'use strict';
let config = require('config');
let log = require('npmlog');
let passport = require('passport');
let LocalStrategy = require('passport-local').Strategy;
let LdapStrategy = require('passport-ldapjs').Strategy;
let csrf = require('csurf');
let bodyParser = require('body-parser');
let users = require('./models/users');
@ -30,7 +33,7 @@ module.exports.logout = (req, res) => {
};
module.exports.login = (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
passport.authenticate(config.ldap.enabled ? 'ldap' : 'local', (err, user, info) => {
if (err) {
req.flash('danger', err.message);
return next(err);
@ -58,6 +61,50 @@ module.exports.login = (req, res, next) => {
})(req, res, next);
};
if (config.ldap.enabled) {
log.info('Using LDAP auth');
var opts = {
server: {
url: 'ldap://' + config.ldap.host + ':' + config.ldap.port,
},
base: config.ldap.baseDN,
search: {
filter: config.ldap.filter,
attributes: ['username', 'mail'],
scope: 'sub'
}
};
passport.use(new LdapStrategy(opts, function (profile, done) {
users.findByUsername(profile.username, (err, user) => {
if (err) {
return done(err);
}
if (!user) {
// password is empty for ldap
users.add(profile.username, '', profile.mail, (err, id) => {
if (err) {
return done(err);
}
return done(null, {
id: id,
username: profile.username
});
});
} else {
return done(null, {
id: user.id,
username: user.username
});
}
});
}));
} else {
log.info('Using local auth');
passport.use(new LocalStrategy((username, password, done) => {
users.authenticate(username, password, (err, user) => {
if (err) {
@ -73,6 +120,7 @@ passport.use(new LocalStrategy((username, password, done) => {
return done(null, user);
});
}));
}
passport.serializeUser((user, done) => {
done(null, user.id);

View file

@ -65,6 +65,7 @@
"npmlog": "^4.0.0",
"openpgp": "^2.3.3",
"passport": "^0.3.2",
"passport-ldapjs": "^1.0.2",
"passport-local": "^1.0.0",
"request": "^2.74.0",
"serve-favicon": "^2.3.0",

View file

@ -7,6 +7,13 @@
<hr>
{{#if ldap.enabled}}
<p>
This account is managed through LDAP.<br/>
<br/>
Associated Email Address: <a href="mailto:{{email}}">{{email}}</a>
</p>
{{else}}
<form class="form-horizontal" method="post" action="/users/account">
<input type="hidden" name="_csrf" value="{{csrfToken}}">
@ -62,3 +69,4 @@
</div>
</form>
{{/if}}

View file

@ -8,6 +8,13 @@
<hr>
{{#if ldap.enabled}}
<p>
Accounts are managed through LDAP.<br/>
<br/>
<a href="{{ldap.passwordresetlink}}">Reset Password</a>
</p>
{{else}}
<p>Please provide the username or email address that you used when you signed up for your Mailtrain account.</p>
<p>We will send you an email that will allow you to reset your password.</p>
@ -27,3 +34,4 @@
</div>
</div>
</form>
{{/if}}

View file

@ -32,7 +32,12 @@
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-xs-4">
<button type="submit" class="btn btn-primary">Sign in</button> or <a href="/users/forgot">Forgot password?</a>
<button type="submit" class="btn btn-primary">Sign in</button> or
{{#if ldap.enabled}}
<a href="{{ldap.passwordresetlink}}">Forgot password?</a>
{{else}}
<a href="/users/forgot">Forgot password?</a>
{{/if}}
</div>
</div>
</form>