mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #2479 from node-red-hitachi/dev-admin-api-auth
Add admin api authentication function
This commit is contained in:
commit
6912dec166
@ -36,6 +36,7 @@ var log = require("@node-red/util").log; // TODO: separate module
|
||||
passport.use(strategies.bearerStrategy.BearerStrategy);
|
||||
passport.use(strategies.clientPasswordStrategy.ClientPasswordStrategy);
|
||||
passport.use(strategies.anonymousStrategy);
|
||||
passport.use(strategies.tokensStrategy);
|
||||
|
||||
var server = oauth2orize.createServer();
|
||||
|
||||
@ -60,7 +61,7 @@ function init(_settings,storage) {
|
||||
function needsPermission(permission) {
|
||||
return function(req,res,next) {
|
||||
if (settings && settings.adminAuth) {
|
||||
return passport.authenticate(['bearer','anon'],{ session: false })(req,res,function() {
|
||||
return passport.authenticate(['bearer','tokens','anon'],{ session: false })(req,res,function() {
|
||||
if (!req.user) {
|
||||
return next();
|
||||
}
|
||||
|
@ -123,9 +123,38 @@ AnonymousStrategy.prototype.authenticate = function(req) {
|
||||
});
|
||||
}
|
||||
|
||||
function TokensStrategy() {
|
||||
passport.Strategy.call(this);
|
||||
this.name = 'tokens';
|
||||
}
|
||||
util.inherits(TokensStrategy, passport.Strategy);
|
||||
TokensStrategy.prototype.authenticate = function(req) {
|
||||
var self = this;
|
||||
var token = null;
|
||||
if (Users.tokenHeader() === 'authorization') {
|
||||
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
|
||||
token = req.headers.authorization.split(' ')[1];
|
||||
}
|
||||
} else {
|
||||
token = req.headers[Users.tokenHeader()];
|
||||
}
|
||||
if (token) {
|
||||
Users.tokens(token).then(function(admin) {
|
||||
if (admin) {
|
||||
self.success(admin,{scope:admin.permissions});
|
||||
} else {
|
||||
self.fail(401);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
self.fail(401);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
bearerStrategy: bearerStrategy,
|
||||
clientPasswordStrategy: clientPasswordStrategy,
|
||||
passwordTokenExchange: passwordTokenExchange,
|
||||
anonymousStrategy: new AnonymousStrategy()
|
||||
anonymousStrategy: new AnonymousStrategy(),
|
||||
tokensStrategy: new TokensStrategy()
|
||||
}
|
||||
|
@ -59,7 +59,9 @@ function getDefaultUser() {
|
||||
var api = {
|
||||
get: get,
|
||||
authenticate: authenticate,
|
||||
default: getDefaultUser
|
||||
default: getDefaultUser,
|
||||
tokens: getDefaultUser,
|
||||
tokenHeader: "authorization"
|
||||
}
|
||||
|
||||
function init(config) {
|
||||
@ -105,6 +107,12 @@ function init(config) {
|
||||
} else {
|
||||
api.default = getDefaultUser;
|
||||
}
|
||||
if (config.tokens && typeof config.tokens === "function") {
|
||||
api.tokens = config.tokens;
|
||||
if (config.tokenHeader && typeof config.tokenHeader === "string") {
|
||||
api.tokenHeader = config.tokenHeader.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
function cleanUser(user) {
|
||||
if (user && user.hasOwnProperty('password')) {
|
||||
@ -118,5 +126,7 @@ module.exports = {
|
||||
init: init,
|
||||
get: function(username) { return api.get(username).then(cleanUser)},
|
||||
authenticate: function() { return api.authenticate.apply(null, arguments) },
|
||||
default: function() { return api.default(); }
|
||||
default: function() { return api.default(); },
|
||||
tokens: function(token) { return api.tokens(token); },
|
||||
tokenHeader: function() { return api.tokenHeader }
|
||||
};
|
||||
|
@ -129,6 +129,61 @@ describe("api/auth/strategies", function() {
|
||||
})
|
||||
});
|
||||
|
||||
describe("Tokens Strategy", function() {
|
||||
it('Succeeds if tokens user enabled custom header',function(done) {
|
||||
var userTokens = sinon.stub(Users,"tokens",function(token) {
|
||||
return when.resolve("tokens-"+token);
|
||||
});
|
||||
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
|
||||
return "x-test-token";
|
||||
});
|
||||
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
|
||||
strategies.tokensStrategy.success = function(user) {
|
||||
user.should.equal("tokens-1234");
|
||||
strategies.tokensStrategy.success = strategies.tokensStrategy._success;
|
||||
delete strategies.tokensStrategy._success;
|
||||
done();
|
||||
};
|
||||
strategies.tokensStrategy.authenticate({headers:{"x-test-token":"1234"}});
|
||||
});
|
||||
it('Succeeds if tokens user enabled default header',function(done) {
|
||||
var userTokens = sinon.stub(Users,"tokens",function(token) {
|
||||
return when.resolve("tokens-"+token);
|
||||
});
|
||||
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
|
||||
return "authorization";
|
||||
});
|
||||
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
|
||||
strategies.tokensStrategy.success = function(user) {
|
||||
user.should.equal("tokens-1234");
|
||||
strategies.tokensStrategy.success = strategies.tokensStrategy._success;
|
||||
delete strategies.tokensStrategy._success;
|
||||
done();
|
||||
};
|
||||
strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
|
||||
});
|
||||
it('Fails if tokens user not enabled',function(done) {
|
||||
var userTokens = sinon.stub(Users,"tokens",function() {
|
||||
return when.resolve(null);
|
||||
});
|
||||
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
|
||||
return "authorization";
|
||||
});
|
||||
strategies.tokensStrategy._fail = strategies.tokensStrategy.fail;
|
||||
strategies.tokensStrategy.fail = function(err) {
|
||||
err.should.equal(401);
|
||||
strategies.tokensStrategy.fail = strategies.tokensStrategy._fail;
|
||||
delete strategies.tokensStrategy._fail;
|
||||
done();
|
||||
};
|
||||
strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
|
||||
});
|
||||
afterEach(function() {
|
||||
Users.tokens.restore();
|
||||
Users.tokenHeader.restore();
|
||||
})
|
||||
});
|
||||
|
||||
describe("Bearer Strategy", function() {
|
||||
it('Rejects invalid token',function(done) {
|
||||
var getToken = sinon.stub(Tokens,"get",function(token) {
|
||||
|
@ -227,4 +227,47 @@ describe("api/auth/users", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Initialised with tokens set as function',function() {
|
||||
before(function() {
|
||||
Users.init({
|
||||
type:"strategy",
|
||||
tokens: function(token) { return("Done-"+token); }
|
||||
});
|
||||
});
|
||||
after(function() {
|
||||
Users.init({});
|
||||
});
|
||||
describe('#tokens',function() {
|
||||
it('handles api.tokens being a function',function(done) {
|
||||
Users.should.have.property('tokens').which.is.a.Function();
|
||||
(Users.tokens("1234")).should.equal("Done-1234");
|
||||
(Users.tokenHeader()).should.equal("authorization");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Initialised with tokens set as function and tokenHeader set as token header name',function() {
|
||||
before(function() {
|
||||
Users.init({
|
||||
type:"strategy",
|
||||
tokens: function(token) { return("Done-"+token); },
|
||||
tokenHeader: "X-TEST-TOKEN"
|
||||
});
|
||||
});
|
||||
after(function() {
|
||||
Users.init({});
|
||||
});
|
||||
describe('#tokens',function() {
|
||||
it('handles api.tokens being a function and api.tokenHeader being a header name',function(done) {
|
||||
Users.should.have.property('tokens').which.is.a.Function();
|
||||
(Users.tokens("1234")).should.equal("Done-1234");
|
||||
Users.should.have.property('tokenHeader').which.is.a.Function();
|
||||
(Users.tokenHeader()).should.equal("x-test-token");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user