Merge branch 'cloudron-io-master'
This commit is contained in:
commit
3fcd389db8
8 changed files with 209 additions and 76 deletions
4
app.js
4
app.js
|
@ -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',
|
||||
|
|
|
@ -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=""
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,7 +61,51 @@ module.exports.login = (req, res, next) => {
|
|||
})(req, res, next);
|
||||
};
|
||||
|
||||
passport.use(new LocalStrategy((username, password, done) => {
|
||||
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) {
|
||||
return done(err);
|
||||
|
@ -72,7 +119,8 @@ passport.use(new LocalStrategy((username, password, done) => {
|
|||
|
||||
return done(null, user);
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
passport.serializeUser((user, done) => {
|
||||
done(null, user.id);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -7,7 +7,14 @@
|
|||
|
||||
<hr>
|
||||
|
||||
<form class="form-horizontal" method="post" action="/users/account">
|
||||
{{#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}}">
|
||||
|
||||
|
@ -61,4 +68,5 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</form>
|
||||
{{/if}}
|
||||
|
|
|
@ -8,10 +8,17 @@
|
|||
|
||||
<hr>
|
||||
|
||||
<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>
|
||||
{{#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>
|
||||
|
||||
<form class="form-horizontal" role="login" method="post" action="/users/forgot">
|
||||
<form class="form-horizontal" role="login" method="post" action="/users/forgot">
|
||||
|
||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||
|
||||
|
@ -26,4 +33,5 @@
|
|||
<button type="submit" class="btn btn-primary">Send verification email</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
{{/if}}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue