Auth permission should honour the token scope

This commit is contained in:
Nick O'Leary 2015-03-29 21:59:48 +01:00
parent 216b5fba7a
commit c8d6dc2531
5 changed files with 56 additions and 28 deletions

View File

@ -49,7 +49,7 @@ function needsPermission(permission) {
if (!req.user) { if (!req.user) {
return next(); return next();
} }
if (permissions.hasPermission(req.user,permission)) { if (permissions.hasPermission(req.authInfo.scope,permission)) {
return next(); return next();
} }
return res.send(401); return res.send(401);
@ -101,7 +101,7 @@ module.exports = {
errorHandler: function(err,req,res,next) { errorHandler: function(err,req,res,next) {
//TODO: standardize json response //TODO: standardize json response
//TODO: audit log statment //TODO: audit log statment
//console.log(err.stack); console.log(err.stack);
//log.log({level:"audit",type:"auth",msg:err.toString()}); //log.log({level:"audit",type:"auth",msg:err.toString()});
return server.errorHandler()(err,req,res,next); return server.errorHandler()(err,req,res,next);
}, },

View File

@ -19,17 +19,36 @@ var util = require('util');
var readRE = /^((.+)\.)?read$/ var readRE = /^((.+)\.)?read$/
var writeRE = /^((.+)\.)?write$/ var writeRE = /^((.+)\.)?write$/
function hasPermission(user,permission) { function hasPermission(userScope,permission) {
if (!user.permissions) { var i;
return false; if (util.isArray(userScope)) {
} if (userScope.length === 0) {
if (user.permissions == "*") { return false;
}
for (i=0;i<userScope.length;i++) {
if (!hasPermission(userScope[i],permission)) {
return false;
}
}
return true; return true;
} }
if (user.permissions == "read") {
return readRE.test(permission); if (userScope == "*") {
return true;
} }
else {
if (util.isArray(permission)) {
for (var i=0;i<permission.length;i++) {
if (!hasPermission(userScope,permission[i])) {
return false;
}
}
return true;
}
if (userScope == "read") {
return readRE.test(permission);
} else {
return false; // anything not allowed is disallowed return false; // anything not allowed is disallowed
} }
} }

View File

@ -24,6 +24,7 @@ var util = require("util");
var Tokens = require("./tokens"); var Tokens = require("./tokens");
var Users = require("./users"); var Users = require("./users");
var Clients = require("./clients"); var Clients = require("./clients");
var permissions = require("./permissions");
var bearerStrategy = function (accessToken, done) { var bearerStrategy = function (accessToken, done) {
// is this a valid token? // is this a valid token?
@ -79,13 +80,17 @@ var passwordTokenExchange = function(client, username, password, scope, done) {
Users.authenticate(username,password).then(function(user) { Users.authenticate(username,password).then(function(user) {
if (user) { if (user) {
loginAttempts = loginAttempts.filter(function(logEntry) { if (permissions.hasPermission(user,scope)) {
return logEntry.user !== username; loginAttempts = loginAttempts.filter(function(logEntry) {
}); return logEntry.user !== username;
Tokens.create(username,client.id,scope).then(function(tokens) { });
// TODO: audit log Tokens.create(username,client.id,scope).then(function(tokens) {
done(null,tokens.accessToken); // TODO: audit log
}); done(null,tokens.accessToken);
});
} else {
done(null,false);
}
} else { } else {
// TODO: audit log // TODO: audit log
done(null,false); done(null,false);

View File

@ -71,8 +71,8 @@ function start() {
handleRemoteSubscription(ws,msg.subscribe); handleRemoteSubscription(ws,msg.subscribe);
} }
} else { } else {
var completeConnection = function(user,sendAck) { var completeConnection = function(userScope,sendAck) {
if (!user || !Permissions.hasPermission(user,"status.read")) { if (!userScope || !Permissions.hasPermission(userScope,"status.read")) {
ws.close(); ws.close();
} else { } else {
pendingAuth = false; pendingAuth = false;
@ -87,7 +87,7 @@ function start() {
Tokens.get(msg.auth).then(function(client) { Tokens.get(msg.auth).then(function(client) {
if (client) { if (client) {
Users.get(client.user).then(function(user) { Users.get(client.user).then(function(user) {
completeConnection(user,true); completeConnection(client.scope,true);
}); });
} else { } else {
completeConnection(null,false); completeConnection(null,false);

View File

@ -20,20 +20,24 @@ var permissions = require("../../../../red/api/auth/permissions");
describe("Auth permissions", function() { describe("Auth permissions", function() {
describe("hasPermission", function() { describe("hasPermission", function() {
it('a user with no permissions',function() { it('a user with no permissions',function() {
permissions.hasPermission({},"*").should.be.false; permissions.hasPermission([],"*").should.be.false;
}); });
it('a user with global permissions',function() { it('a user with global permissions',function() {
permissions.hasPermission({permissions:"*"},"read").should.be.true; permissions.hasPermission("*","read").should.be.true;
permissions.hasPermission({permissions:"*"},"write").should.be.true; permissions.hasPermission(["*"],"write").should.be.true;
}); });
it('a user with read permissions',function() { it('a user with read permissions',function() {
permissions.hasPermission({permissions:"read"},"read").should.be.true; permissions.hasPermission(["read"],"read").should.be.true;
permissions.hasPermission({permissions:"read"},"node.read").should.be.true; permissions.hasPermission(["read"],"node.read").should.be.true;
permissions.hasPermission({permissions:"read"},"write").should.be.false; permissions.hasPermission(["read"],"write").should.be.false;
permissions.hasPermission({permissions:"read"},"node.write").should.be.false; permissions.hasPermission(["read"],"node.write").should.be.false;
}); });
it('a user with foo permissions',function() { it('a user with foo permissions',function() {
permissions.hasPermission({permissions:"foo"},"foo").should.be.false; permissions.hasPermission("foo","foo").should.be.false;
});
it('an array of permissions', function() {
permissions.hasPermission(["*"],["foo.read","foo.write"]).should.be.true;
permissions.hasPermission("read",["foo.read","foo.write"]).should.be.false;
}); });
}); });
}); });