From ef376f9101fe0302f97286724db0254e5fb1a7d3 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Thu, 4 Feb 2021 23:07:52 +0200 Subject: [PATCH] Add unit test for socket.io connect (#6845) * Add unit test for socket.io connect * Fix white space --- lib/server/websocket.js | 37 +++++++---- tests/security.test.js | 144 ++++++++++++++++++++++++++++++---------- 2 files changed, 133 insertions(+), 48 deletions(-) diff --git a/lib/server/websocket.js b/lib/server/websocket.js index dbe104cecb1..651e808ea7f 100644 --- a/lib/server/websocket.js +++ b/lib/server/websocket.js @@ -85,8 +85,10 @@ function init (env, ctx, server) { function verifyAuthorization (message, ip, callback) { - if (!message) return; - if (!message.token && !message.secret) return; + if (!message || !message.token && !message.secret) { + callback('Bad request', null); + return; + } ctx.authorization.resolve({ api_secret: message.secret, token: message.token, ip: ip }, function resolved (err, result) { @@ -256,9 +258,7 @@ function init (env, ctx, server) { } var objId = new ObjectID(data._id); - ctx.store.collection(collection).update( - { '_id': objId }, - { $unset: data.data } + ctx.store.collection(collection).update({ '_id': objId }, { $unset: data.data } , function(err, results) { if (!err) { @@ -274,7 +274,7 @@ function init (env, ctx, server) { } }); } - }); + }); if (callback) { callback({ result: 'success' }); @@ -329,7 +329,7 @@ function init (env, ctx, server) { callback([]); return; } - + if (array.length > 0) { console.log(LOG_DEDUP + 'Exact match'); if (callback) { @@ -379,7 +379,7 @@ function init (env, ctx, server) { callback([]); return; } - + if (array.length > 0) { console.log(LOG_DEDUP + 'Found similiar', array[0]); array[0].created_at = data.data.created_at; @@ -433,12 +433,12 @@ function init (env, ctx, server) { if (array.length > 0) { console.log(LOG_DEDUP + 'Devicestatus exact match'); - if (callback) { - callback([array[0]]); - } - return; + if (callback) { + callback([array[0]]); + } + return; } - + }); ctx.store.collection(collection).insert(data.data, function insertResult (err, doc) { @@ -464,7 +464,7 @@ function init (env, ctx, server) { console.log(data.collection + ' insertion error: ', err.message); return; } - + ctx.bus.emit('data-update', { type: data.collection , op: 'update' @@ -526,6 +526,15 @@ function init (env, ctx, server) { socket.on('authorize', function authorize (message, callback) { const remoteIP = socket.request.connection.remoteAddress; verifyAuthorization(message, remoteIP, function verified (err, authorization) { + + if (err) { + console.log('Websocket authorization failed:', err); + socket.disconnect(); + return; + } + + socket.emit('connected'); + socketAuthorization = authorization; clientType = message.client; history = message.history || 48; //default history is 48 hours diff --git a/tests/security.test.js b/tests/security.test.js index c0b8821248b..e056c831527 100644 --- a/tests/security.test.js +++ b/tests/security.test.js @@ -1,13 +1,25 @@ 'use strict'; -var request = require('supertest'); -var should = require('should'); -var language = require('../lib/language')(); +const request = require('supertest'); +const should = require('should'); +const language = require('../lib/language')(); +const io = require('socket.io-client') -describe('API_SECRET', function ( ) { +describe('API_SECRET', function() { var api; var scope = this; - this.timeout(5000); + var websocket; + var app; + var server; + var listener; + + this.timeout(7000); + + afterEach(function() { + if (listener) { + listener.close(); + } + }); function setup_app (env, fn) { api = require('../lib/api/'); @@ -19,19 +31,36 @@ describe('API_SECRET', function ( ) { }); } - it('should fail when unauthorized', function (done) { + function setup_big_app (env, fn) { + api = require('../lib/api/'); + require('../lib/server/bootevent')(env, language).boot(function booted (ctx) { + ctx.app = api(env, ctx); + scope.app = ctx.app; + scope.entries = ctx.entries; + + app = require('../lib/server/app')(env, ctx); + server = require('http').createServer(app); + listener = server.listen(1337, 'localhost'); + websocket = require('../lib/server/websocket')(env, ctx, server); + + fn(ctx); + }); + } + + it('should fail when unauthorized', function(done) { var known = 'b723e97aa97846eb92d5264f084b2823f57c4aa1'; delete process.env.API_SECRET; process.env.API_SECRET = 'this is my long pass phrase'; - var env = require('../lib/server/env')( ); + var env = require('../lib/server/env')(); env.enclave.isApiKey(known).should.equal(true); - setup_app(env, function (ctx) { + setup_app(env, function(ctx) { ctx.app.enabled('api').should.equal(true); ping_status(ctx.app, again); - function again ( ) { + + function again () { ctx.app.api_secret = ''; ping_authorized_endpoint(ctx.app, 401, done); } @@ -39,17 +68,17 @@ describe('API_SECRET', function ( ) { }); - - it('should work fine set', function (done) { + it('should work fine set', function(done) { var known = 'b723e97aa97846eb92d5264f084b2823f57c4aa1'; delete process.env.API_SECRET; process.env.API_SECRET = 'this is my long pass phrase'; - var env = require('../lib/server/env')( ); + var env = require('../lib/server/env')(); env.enclave.isApiKey(known).should.equal(true); - setup_app(env, function (ctx) { + setup_app(env, function(ctx) { ctx.app.enabled('api').should.equal(true); ping_status(ctx.app, again); - function again ( ) { + + function again () { ctx.app.api_secret = known; ping_authorized_endpoint(ctx.app, 200, done); } @@ -57,36 +86,83 @@ describe('API_SECRET', function ( ) { }); - it('should not work short', function ( ) { + it('should not work short', function() { delete process.env.API_SECRET; process.env.API_SECRET = 'tooshort'; - var env = require('../lib/server/env')( ); + var env = require('../lib/server/env')(); should.not.exist(env.api_secret); env.err[0].desc.should.startWith('API_SECRET should be at least'); }); function ping_status (app, fn) { - request(app) - .get('/status.json') - .expect(200) - .end(function (err, res) { - res.body.status.should.equal('ok'); - fn( ); - }); + request(app) + .get('/status.json') + .expect(200) + .end(function(err, res) { + res.body.status.should.equal('ok'); + fn(); + }); } function ping_authorized_endpoint (app, fails, fn) { - request(app) - .get('/experiments/test') - .set('api-secret', app.api_secret || '') - .expect(fails) - .end(function (err, res) { - if (fails < 400) { - res.body.status.should.equal('ok'); - } - fn( ); - }); + request(app) + .get('/experiments/test') + .set('api-secret', app.api_secret || '') + .expect(fails) + .end(function(err, res) { + if (fails < 400) { + res.body.status.should.equal('ok'); + } + fn(); + }); } -}); + it('socket IO should connect', function(done) { + var known = 'b723e97aa97846eb92d5264f084b2823f57c4aa1'; + process.env.API_SECRET = 'this is my long pass phrase'; + var env = require('../lib/server/env')(); + + setup_big_app(env, function(ctx) { + + const socket2 = io.connect('ws://localhost:1337/'); + + socket2.on('connect', function() { + console.log('Socket 2 authorizing'); + socket2.emit("authorize", { + secret: known + }); + }); + + socket2.on('disconnect', function() { + //socket.emit("authorize"); + console.log('Client 2 disconnected'); + done(); + }); + + socket2.on('connected', function(msg) { + console.log('Connected'); + + // Disconnect both client connections + socket2.disconnect(); + + const socket = io.connect('ws://localhost:1337/'); + + socket.on('connect', function() { + console.log('Socket 1 authorizing'); + socket.emit("authorize"); + }); + + socket.on('disconnect', function() { + //socket.emit("authorize"); + console.log('Client 1 disconnected'); + done(); + }); + + }); + + }); + + }); + +});