From 57154b2853fc3fe5ba5fc5946d16e7282f86630f Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 6 Jul 2020 20:45:07 +0100 Subject: [PATCH] Authenticate websocket comms using user-provided token if present Fixes #2642 --- .../@node-red/editor-api/lib/editor/comms.js | 12 +++++-- .../editor-api/lib/editor/comms_spec.js | 35 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/comms.js b/packages/node_modules/@node-red/editor-api/lib/editor/comms.js index 0acdcc8fd..2c46f87e8 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/comms.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/comms.js @@ -130,8 +130,16 @@ function CommsConnection(ws) { } }); } else { - log.audit({event: "comms.auth.fail"}); - completeConnection(null,null,false); + Users.tokens(msg.auth).then(function(user) { + if (user) { + self.user = user; + log.audit({event: "comms.auth",user:self.user}); + completeConnection(user.permissions,msg.auth,true); + } else { + log.audit({event: "comms.auth.fail"}); + completeConnection(null,null,false); + } + }); } }); } else { diff --git a/test/unit/@node-red/editor-api/lib/editor/comms_spec.js b/test/unit/@node-red/editor-api/lib/editor/comms_spec.js index 72378508b..8f6f78315 100644 --- a/test/unit/@node-red/editor-api/lib/editor/comms_spec.js +++ b/test/unit/@node-red/editor-api/lib/editor/comms_spec.js @@ -343,6 +343,7 @@ describe("api/editor/comms", function() { var getDefaultUser; var getUser; var getToken; + var getUserToken; before(function(done) { getDefaultUser = sinon.stub(Users,"default",function() { return when.resolve(null);}); getUser = sinon.stub(Users,"get", function(username) { @@ -352,6 +353,13 @@ describe("api/editor/comms", function() { return when.resolve(null); } }); + getUserToken = sinon.stub(Users,"tokens", function(token) { + if (token == "abcde") { + return when.resolve({user:"wilma", permissions:"*"}) + } else { + return when.resolve(null); + } + }); getToken = sinon.stub(Tokens,"get",function(token) { if (token == "1234") { return when.resolve({user:"fred",scope:["*"]}); @@ -377,6 +385,7 @@ describe("api/editor/comms", function() { getDefaultUser.restore(); getUser.restore(); getToken.restore(); + getUserToken.restore(); comms.stop(); server.stop(done); }); @@ -420,7 +429,33 @@ describe("api/editor/comms", function() { } }); }); + it('allows connections that do authenticate - user-provided-token',function(done) { + var ws = new WebSocket(url); + var received = 0; + ws.on('open', function() { + ws.send('{"auth":"abcde"}'); + }); + ws.on('message', function(msg) { + received++; + if (received == 1) { + msg.should.equal('{"auth":"ok"}'); + ws.send('{"subscribe":"foo"}'); + connections[0].send('foo', 'correct'); + } else { + msg.should.equal('[{"topic":"foo","data":"correct"}]'); + ws.close(); + } + }); + ws.on('close', function() { + try { + received.should.equal(2); + done(); + } catch(err) { + done(err); + } + }); + }); it('rejects connections for non-existant token',function(done) { var ws = new WebSocket(url); var received = 0;