1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Allow adminAuth.user to be a Function

Fixes #1461
This commit is contained in:
Nick O'Leary 2018-01-23 23:08:11 +00:00
parent cc9011cd68
commit 3cb5cbd8d5
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
4 changed files with 97 additions and 91 deletions

View File

@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
**/ **/
var when = require("when");
var clients = [ var clients = [
{id:"node-red-editor",secret:"not_available"}, {id:"node-red-editor",secret:"not_available"},
{id:"node-red-admin",secret:"not_available"} {id:"node-red-admin",secret:"not_available"}
@ -25,9 +23,9 @@ module.exports = {
get: function(id) { get: function(id) {
for (var i=0;i<clients.length;i++) { for (var i=0;i<clients.length;i++) {
if (clients[i].id == id) { if (clients[i].id == id) {
return when.resolve(clients[i]); return Promise.resolve(clients[i]);
} }
} }
return when.resolve(null); return Promise.resolve(null);
} }
} }

View File

@ -135,21 +135,8 @@ function completeVerify(profile,done) {
}); });
} }
module.exports = {
init: init, function genericStrategy(adminApp,strategy) {
needsPermission: needsPermission,
ensureClientSecret: ensureClientSecret,
authenticateClient: authenticateClient,
getToken: getToken,
errorHandler: function(err,req,res,next) {
//TODO: audit log statment
//console.log(err.stack);
//log.log({level:"audit",type:"auth",msg:err.toString()});
return server.errorHandler()(err,req,res,next);
},
login: login,
revoke: revoke,
genericStrategy: function(adminApp,strategy) {
var crypto = require("crypto") var crypto = require("crypto")
var session = require('express-session') var session = require('express-session')
var MemoryStore = require('memorystore')(session) var MemoryStore = require('memorystore')(session)
@ -174,7 +161,7 @@ module.exports = {
function() { function() {
var originalDone = arguments[arguments.length-1]; var originalDone = arguments[arguments.length-1];
if (options.verify) { if (options.verify) {
var args = Array.prototype.slice.call(arguments); var args = Array.from(arguments);
args[args.length-1] = function(err,profile) { args[args.length-1] = function(err,profile) {
if (err) { if (err) {
return originalDone(err); return originalDone(err);
@ -191,16 +178,36 @@ module.exports = {
} }
)); ));
adminApp.get('/auth/strategy', passport.authenticate(strategy.name)); adminApp.get('/auth/strategy',
passport.authenticate(strategy.name, {session:false, failureRedirect: settings.httpAdminRoot }),
completeGenerateStrategyAuth
);
adminApp.get('/auth/strategy/callback', adminApp.get('/auth/strategy/callback',
passport.authenticate(strategy.name, {session:false, failureRedirect: settings.httpAdminRoot }), passport.authenticate(strategy.name, {session:false, failureRedirect: settings.httpAdminRoot }),
function(req, res) { completeGenerateStrategyAuth
);
}
function completeGenerateStrategyAuth(req,res) {
var tokens = req.user.tokens; var tokens = req.user.tokens;
delete req.user.tokens; delete req.user.tokens;
// Successful authentication, redirect home. // Successful authentication, redirect home.
res.redirect(settings.httpAdminRoot + '?access_token='+tokens.accessToken); res.redirect(settings.httpAdminRoot + '?access_token='+tokens.accessToken);
} }
);
} module.exports = {
init: init,
needsPermission: needsPermission,
ensureClientSecret: ensureClientSecret,
authenticateClient: authenticateClient,
getToken: getToken,
errorHandler: function(err,req,res,next) {
//TODO: audit log statment
//console.log(err.stack);
//log.log({level:"audit",type:"auth",msg:err.toString()});
return server.errorHandler()(err,req,res,next);
},
login: login,
revoke: revoke,
genericStrategy: genericStrategy
} }

View File

@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
**/ **/
var when = require("when");
function generateToken(length) { function generateToken(length) {
var c = "ABCDEFGHIJKLMNOPQRSTUZWXYZabcdefghijklmnopqrstuvwxyz1234567890"; var c = "ABCDEFGHIJKLMNOPQRSTUZWXYZabcdefghijklmnopqrstuvwxyz1234567890";
var token = []; var token = [];
@ -49,7 +47,7 @@ function expireSessions() {
if (modified) { if (modified) {
return storage.saveSessions(sessions); return storage.saveSessions(sessions);
} else { } else {
return when.resolve(); return Promise.resolve();
} }
} }
function loadSessions() { function loadSessions() {
@ -69,7 +67,7 @@ module.exports = {
// At this point, storage will not have been initialised, so defer loading // At this point, storage will not have been initialised, so defer loading
// the sessions until there's a request for them. // the sessions until there's a request for them.
loadedSessions = null; loadedSessions = null;
return when.resolve(); return Promise.resolve();
}, },
get: function(token) { get: function(token) {
return loadSessions().then(function() { return loadSessions().then(function() {
@ -78,7 +76,7 @@ module.exports = {
return expireSessions().then(function() { return null }); return expireSessions().then(function() { return null });
} }
} }
return when.resolve(sessions[token]); return Promise.resolve(sessions[token]);
}); });
}, },
create: function(user,client,scope) { create: function(user,client,scope) {

View File

@ -14,13 +14,12 @@
* limitations under the License. * limitations under the License.
**/ **/
var when = require("when");
var util = require("util"); var util = require("util");
var clone = require("clone");
var bcrypt; var bcrypt;
try { bcrypt = require('bcrypt'); } try { bcrypt = require('bcrypt'); }
catch(e) { bcrypt = require('bcryptjs'); } catch(e) { bcrypt = require('bcryptjs'); }
var users = {}; var users = {};
var passwords = {};
var defaultUser = null; var defaultUser = null;
function authenticate() { function authenticate() {
@ -28,31 +27,33 @@ function authenticate() {
if (typeof username !== 'string') { if (typeof username !== 'string') {
username = username.username; username = username.username;
} }
var user = users[username]; const args = Array.from(arguments);
return api.get(username).then(function(user) {
if (user) { if (user) {
if (arguments.length === 2) { if (args.length === 2) {
// Username/password authentication // Username/password authentication
var password = arguments[1]; var password = args[1];
return when.promise(function(resolve,reject) { return new Promise(function(resolve,reject) {
bcrypt.compare(password, passwords[username], function(err, res) { bcrypt.compare(password, user.password, function(err, res) {
resolve(res?user:null); resolve(res?cleanUser(user):null);
}); });
}); });
} else { } else {
// Try to extract common profile information // Try to extract common profile information
if (arguments[0].hasOwnProperty('photos') && arguments[0].photos.length > 0) { if (args[0].hasOwnProperty('photos') && args[0].photos.length > 0) {
user.image = arguments[0].photos[0].value; user.image = args[0].photos[0].value;
} }
return when.resolve(user); return cleanUser(user);
} }
} }
return when.resolve(null); return null;
});
} }
function get(username) { function get(username) {
return when.resolve(users[username]); return Promise.resolve(users[username]);
} }
function getDefaultUser() { function getDefaultUser() {
return when.resolve(null); return Promise.resolve(null);
} }
var api = { var api = {
@ -63,7 +64,6 @@ var api = {
function init(config) { function init(config) {
users = {}; users = {};
passwords = {};
defaultUser = null; defaultUser = null;
if (config.type == "credentials" || config.type == "strategy") { if (config.type == "credentials" || config.type == "strategy") {
if (config.users) { if (config.users) {
@ -77,11 +77,7 @@ function init(config) {
} }
for (var i=0;i<us.length;i++) { for (var i=0;i<us.length;i++) {
var u = us[i]; var u = us[i];
users[u.username] = { users[u.username] = clone(u);
"username":u.username,
"permissions":u.permissions
};
passwords[u.username] = u.password;
} }
} }
} }
@ -96,7 +92,7 @@ function init(config) {
api.default = config.default; api.default = config.default;
} else { } else {
api.default = function() { api.default = function() {
return when.resolve({ return Promise.resolve({
"anonymous": true, "anonymous": true,
"permissions":config.default.permissions "permissions":config.default.permissions
}); });
@ -106,10 +102,17 @@ function init(config) {
api.default = getDefaultUser; api.default = getDefaultUser;
} }
} }
function cleanUser(user) {
if (user && user.hasOwnProperty('password')) {
user = clone(user);
delete user.password;
}
return user;
}
module.exports = { module.exports = {
init: init, init: init,
get: function(username) { return api.get(username) }, get: function(username) { return api.get(username).then(cleanUser)},
authenticate: function() { return api.authenticate.apply(null, arguments) }, authenticate: function() { return api.authenticate.apply(null, arguments) },
default: function() { return api.default(); } default: function() { return api.default(); }
}; };