From 2dac3d22925938cf381a45d586f74c59071d191f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 22 Feb 2017 14:53:44 +0300 Subject: [PATCH] closes #5465, blacklist tests --- src/meta/blacklist.js | 40 +++++++++++-------- src/pubsub.js | 8 ++-- src/socket.io/blacklist.js | 3 -- test/blacklist.js | 79 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 test/blacklist.js diff --git a/src/meta/blacklist.js b/src/meta/blacklist.js index 679dc3cec9..c02f6fb198 100644 --- a/src/meta/blacklist.js +++ b/src/meta/blacklist.js @@ -3,15 +3,18 @@ var ip = require('ip'); var winston = require('winston'); var async = require('async'); + var db = require('../database'); +var pubsub = require('../pubsub'); var Blacklist = { - _rules: [] - }; + _rules: [] +}; Blacklist.load = function (callback) { + callback = callback || function () {}; async.waterfall([ - async.apply(db.get, 'ip-blacklist-rules'), + async.apply(Blacklist.get), async.apply(Blacklist.validate) ], function (err, rules) { if (err) { @@ -33,13 +36,18 @@ Blacklist.load = function (callback) { }); }; +pubsub.on('blacklist:reload', Blacklist.load); + Blacklist.save = function (rules, callback) { - db.set('ip-blacklist-rules', rules, function (err) { - if (err) { - return callback(err); + async.waterfall([ + function (next) { + db.set('ip-blacklist-rules', rules, next); + }, + function (next) { + pubsub.publish('blacklist:reload'); + next(); } - Blacklist.load(callback); - }); + ], callback); }; Blacklist.get = function (callback) { @@ -48,14 +56,14 @@ Blacklist.get = function (callback) { Blacklist.test = function (clientIp, callback) { if ( - Blacklist._rules.ipv4.indexOf(clientIp) === -1 // not explicitly specified in ipv4 list - && Blacklist._rules.ipv6.indexOf(clientIp) === -1 // not explicitly specified in ipv6 list - && !Blacklist._rules.cidr.some(function (subnet) { + Blacklist._rules.ipv4.indexOf(clientIp) === -1 &&// not explicitly specified in ipv4 list + Blacklist._rules.ipv6.indexOf(clientIp) === -1 &&// not explicitly specified in ipv6 list + !Blacklist._rules.cidr.some(function (subnet) { return ip.cidrSubnet(subnet).contains(clientIp); }) // not in a blacklisted cidr range ) { if (typeof callback === 'function') { - callback(); + setImmediate(callback); } else { return false; } @@ -64,7 +72,7 @@ Blacklist.test = function (clientIp, callback) { err.code = 'blacklisted-ip'; if (typeof callback === 'function') { - callback(err); + setImmediate(callback, err); } else { return true; } @@ -78,9 +86,9 @@ Blacklist.validate = function (rules, callback) { var cidr = []; var invalid = []; - var isCidrSubnet = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/, - inlineCommentMatch = /#.*$/, - whitelist = ['127.0.0.1', '::1', '::ffff:0:127.0.0.1']; + var isCidrSubnet = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/; + var inlineCommentMatch = /#.*$/; + var whitelist = ['127.0.0.1', '::1', '::ffff:0:127.0.0.1']; // Filter out blank lines and lines starting with the hash character (comments) // Also trim inputs and remove inline comments diff --git a/src/pubsub.js b/src/pubsub.js index a2e11746e1..f5c6c2f0ed 100644 --- a/src/pubsub.js +++ b/src/pubsub.js @@ -1,10 +1,10 @@ 'use strict'; -var nconf = require('nconf'), - util = require('util'), - winston = require('winston'), - EventEmitter = require('events').EventEmitter; +var nconf = require('nconf'); +var util = require('util'); +var winston = require('winston'); +var EventEmitter = require('events').EventEmitter; var channelName; diff --git a/src/socket.io/blacklist.js b/src/socket.io/blacklist.js index a05d632f3f..8592a8b901 100644 --- a/src/socket.io/blacklist.js +++ b/src/socket.io/blacklist.js @@ -1,9 +1,6 @@ 'use strict'; -var async = require('async'); -var winston = require('winston'); - var user = require('../user'); var meta = require('../meta'); diff --git a/test/blacklist.js b/test/blacklist.js new file mode 100644 index 0000000000..0ffc0f78a1 --- /dev/null +++ b/test/blacklist.js @@ -0,0 +1,79 @@ +'use strict'; +/*global require, after, before*/ + + +var async = require('async'); +var assert = require('assert'); + +var db = require('./mocks/databasemock'); +var groups = require('../src/groups'); +var user = require('../src/user'); +var blacklist = require('../src/meta/blacklist'); + +describe('blacklist', function () { + + var adminUid; + + before(function (done) { + groups.resetCache(); + user.create({username: 'admin'}, function (err, uid) { + assert.ifError(err); + adminUid = uid; + groups.join('administrators', adminUid, done); + }); + }); + + var socketBlacklist = require('../src/socket.io/blacklist'); + var rules = '1.1.1.1\n2.2.2.2\n::ffff:0:2.2.2.2\n127.0.0.1\n192.168.100.0/22'; + + it('should validate blacklist', function (done) { + socketBlacklist.validate({uid: adminUid}, { + rules: rules + }, function (err, data) { + assert.ifError(err); + done(); + }); + }); + + it('should error if not admin', function (done) { + socketBlacklist.save({uid: 0}, rules, function (err) { + assert.equal(err.message, '[[error:no-privileges]]'); + done(); + }); + }); + + it('should save blacklist', function (done) { + socketBlacklist.save({uid: adminUid}, rules, function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should pass ip test against blacklist async', function (done) { + blacklist.test('3.3.3.3', function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should pass ip test against blacklist sync', function (done) { + assert(!blacklist.test('3.3.3.3')); + done(); + }); + + it('should fail ip test against blacklist async', function (done) { + blacklist.test('1.1.1.1', function (err) { + assert.equal(err.message, '[[error:blacklisted-ip]]'); + done(); + }); + }); + + it('should fail ip test against blacklist sync', function (done) { + assert(blacklist.test('1.1.1.1')); + done(); + }); + + after(function (done) { + db.emptydb(done); + }); +});