mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Auth permission should honour the token scope
This commit is contained in:
		| @@ -49,7 +49,7 @@ function needsPermission(permission) { | ||||
|                 if (!req.user) { | ||||
|                     return next(); | ||||
|                 } | ||||
|                 if (permissions.hasPermission(req.user,permission)) { | ||||
|                 if (permissions.hasPermission(req.authInfo.scope,permission)) { | ||||
|                     return next(); | ||||
|                 } | ||||
|                 return res.send(401); | ||||
| @@ -101,7 +101,7 @@ module.exports = { | ||||
|     errorHandler: function(err,req,res,next) { | ||||
|         //TODO: standardize json response | ||||
|         //TODO: audit log statment | ||||
|         //console.log(err.stack); | ||||
|         console.log(err.stack); | ||||
|         //log.log({level:"audit",type:"auth",msg:err.toString()}); | ||||
|         return server.errorHandler()(err,req,res,next); | ||||
|     }, | ||||
|   | ||||
| @@ -19,17 +19,36 @@ var util = require('util'); | ||||
| var readRE = /^((.+)\.)?read$/ | ||||
| var writeRE = /^((.+)\.)?write$/ | ||||
|  | ||||
| function hasPermission(user,permission) { | ||||
|     if (!user.permissions) { | ||||
|         return false; | ||||
|     } | ||||
|     if (user.permissions == "*") { | ||||
| function hasPermission(userScope,permission) { | ||||
|     var i; | ||||
|     if (util.isArray(userScope)) { | ||||
|         if (userScope.length === 0) { | ||||
|             return false; | ||||
|         } | ||||
|         for (i=0;i<userScope.length;i++) { | ||||
|             if (!hasPermission(userScope[i],permission)) { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         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 | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -24,6 +24,7 @@ var util = require("util"); | ||||
| var Tokens = require("./tokens"); | ||||
| var Users = require("./users"); | ||||
| var Clients = require("./clients"); | ||||
| var permissions = require("./permissions"); | ||||
|  | ||||
| var bearerStrategy = function (accessToken, done) { | ||||
|     // is this a valid token? | ||||
| @@ -79,13 +80,17 @@ var passwordTokenExchange = function(client, username, password, scope, done) { | ||||
|  | ||||
|     Users.authenticate(username,password).then(function(user) { | ||||
|         if (user) { | ||||
|             loginAttempts = loginAttempts.filter(function(logEntry) { | ||||
|                 return logEntry.user !== username; | ||||
|             }); | ||||
|             Tokens.create(username,client.id,scope).then(function(tokens) { | ||||
|                 // TODO: audit log | ||||
|                 done(null,tokens.accessToken); | ||||
|             }); | ||||
|             if (permissions.hasPermission(user,scope)) { | ||||
|                 loginAttempts = loginAttempts.filter(function(logEntry) { | ||||
|                     return logEntry.user !== username; | ||||
|                 }); | ||||
|                 Tokens.create(username,client.id,scope).then(function(tokens) { | ||||
|                     // TODO: audit log | ||||
|                     done(null,tokens.accessToken); | ||||
|                 }); | ||||
|             } else { | ||||
|                 done(null,false); | ||||
|             } | ||||
|         } else { | ||||
|             // TODO: audit log | ||||
|             done(null,false); | ||||
|   | ||||
| @@ -71,8 +71,8 @@ function start() { | ||||
|                             handleRemoteSubscription(ws,msg.subscribe); | ||||
|                         } | ||||
|                     } else { | ||||
|                         var completeConnection = function(user,sendAck) { | ||||
|                             if (!user || !Permissions.hasPermission(user,"status.read")) { | ||||
|                         var completeConnection = function(userScope,sendAck) { | ||||
|                             if (!userScope || !Permissions.hasPermission(userScope,"status.read")) { | ||||
|                                 ws.close(); | ||||
|                             } else { | ||||
|                                 pendingAuth = false; | ||||
| @@ -87,7 +87,7 @@ function start() { | ||||
|                             Tokens.get(msg.auth).then(function(client) { | ||||
|                                 if (client) { | ||||
|                                     Users.get(client.user).then(function(user) { | ||||
|                                         completeConnection(user,true); | ||||
|                                         completeConnection(client.scope,true); | ||||
|                                     }); | ||||
|                                 } else { | ||||
|                                     completeConnection(null,false); | ||||
|   | ||||
| @@ -20,20 +20,24 @@ var permissions = require("../../../../red/api/auth/permissions"); | ||||
| describe("Auth permissions", function() { | ||||
|     describe("hasPermission", 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() { | ||||
|             permissions.hasPermission({permissions:"*"},"read").should.be.true; | ||||
|             permissions.hasPermission({permissions:"*"},"write").should.be.true; | ||||
|             permissions.hasPermission("*","read").should.be.true; | ||||
|             permissions.hasPermission(["*"],"write").should.be.true; | ||||
|         }); | ||||
|         it('a user with read permissions',function() { | ||||
|             permissions.hasPermission({permissions:"read"},"read").should.be.true; | ||||
|             permissions.hasPermission({permissions:"read"},"node.read").should.be.true; | ||||
|             permissions.hasPermission({permissions:"read"},"write").should.be.false; | ||||
|             permissions.hasPermission({permissions:"read"},"node.write").should.be.false; | ||||
|             permissions.hasPermission(["read"],"read").should.be.true; | ||||
|             permissions.hasPermission(["read"],"node.read").should.be.true; | ||||
|             permissions.hasPermission(["read"],"write").should.be.false; | ||||
|             permissions.hasPermission(["read"],"node.write").should.be.false; | ||||
|         }); | ||||
|         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; | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user