diff --git a/lib/conditions/index.js b/lib/conditions/index.js index 28469bc12..b5eae019f 100644 --- a/lib/conditions/index.js +++ b/lib/conditions/index.js @@ -1,4 +1,3 @@ -const express = require('express'); const chalk = require('chalk'); const logger = require('../logger').policy; const schemas = require('../schemas'); @@ -25,20 +24,6 @@ function register({ name, handler, schema }) { function init() { predefined.forEach(register); - - // extending express.request - express.request.matchEGCondition = function (conditionConfig) { - logger.debug(`matchEGCondition for ${conditionConfig.name}`); - const func = conditions[conditionConfig.name]; - - if (!func) { - logger.warn(`Condition not found for ${conditionConfig.name}`); - return null; - } - - return func(conditionConfig)(this); - }; - return { register }; } diff --git a/lib/config/config.js b/lib/config/config.js index e66d1f715..bd4d1438f 100644 --- a/lib/config/config.js +++ b/lib/config/config.js @@ -10,7 +10,7 @@ const eventBus = require('../eventBus'); const schemas = require('../schemas'); class Config { - constructor () { + constructor() { this.models = {}; this.configTypes = { @@ -29,7 +29,7 @@ class Config { }; } - loadConfig (type) { + loadConfig(type) { const configType = this.configTypes[type]; let configPath = this[configType.pathProperty] || path.join(process.env.EG_CONFIG_DIR, `${configType.baseFilename}.yml`); let config; @@ -59,9 +59,9 @@ class Config { log.debug(`ConfigPath: ${configPath}`); } - loadGatewayConfig () { this.loadConfig('gateway'); } + loadGatewayConfig() { this.loadConfig('gateway'); } - loadModels () { + loadModels() { ['users.json', 'credentials.json', 'applications.json'].forEach(model => { const module = path.resolve(process.env.EG_CONFIG_DIR, 'models', model); const name = path.basename(module, '.json'); @@ -71,7 +71,9 @@ class Config { }); } - watch () { + watch() { + if (typeof this.systemConfigPath !== 'string' || typeof this.gatewayConfigPath !== 'string') { return; } + const watchEvents = ['add', 'change']; const watchOptions = { @@ -96,15 +98,15 @@ class Config { }); } - unwatch () { + unwatch() { this.watcher && this.watcher.close(); } - updateGatewayConfig (modifier) { + updateGatewayConfig(modifier) { return this._updateConfigFile('gateway', modifier); } - _updateConfigFile (type, modifier) { + _updateConfigFile(type, modifier) { const configType = this.configTypes[type]; const path = this[configType.pathProperty]; @@ -166,7 +168,7 @@ class Config { // Kindly borrowed from https://github.com/macbre/optimist-config-file/blob/master/lib/envvar-replace.js // Thanks a lot guys 🙌 -function envReplace (str, vars) { +function envReplace(str, vars) { return str.replace(/\$?\$\{([A-Za-z0-9_]+)(:-(.*?))?\}/g, function (varStr, varName, _, defValue) { // Handle escaping: if (varStr.indexOf('$$') === 0) { diff --git a/test/conditions.test.js b/test/conditions.test.js index 0bc0b89dd..6c198c139 100644 --- a/test/conditions.test.js +++ b/test/conditions.test.js @@ -1,197 +1,164 @@ const EgContextBase = require('../lib/gateway/context'); -require('../lib/conditions').init(); +const { init, conditions } = require('../lib/conditions'); const express = require('express'); const should = require('should'); -describe('always', function () { - const req = Object.create(express.request); - it('should always return true', function () { - should(req.matchEGCondition({ name: 'always' })).be.true(); - }); -}); +describe('conditions', () => { + before(init); -describe('never', function () { - const req = Object.create(express.request); - it('should always return false', function () { - should(req.matchEGCondition({ name: 'never' })).be.false(); + describe('always', function () { + const req = Object.create(express.request); + it('should always return true', function () { + should(conditions['always']()(req)).be.true(); + }); }); -}); -describe('allOf', function () { - const req = Object.create(express.request); - it('should return true if all of the arguments is true', function () { - should(req.matchEGCondition({ - name: 'allOf', - conditions: [{ name: 'always' }, { name: 'always' }] - })).be.true(); - }); - it('should return false if one of the arguments is false', function () { - should(req.matchEGCondition({ - name: 'allOf', - conditions: [{ name: 'always' }, { name: 'never' }] - })).be.false(); + describe('never', function () { + const req = Object.create(express.request); + it('should always return false', function () { + should(conditions['never']()(req)).be.false(); + }); }); -}); -describe('oneOf', function () { - const req = Object.create(express.request); - it('should return true if one of the arguments is true', function () { - should(req.matchEGCondition({ - name: 'oneOf', - conditions: [{ name: 'never' }, { name: 'always' }] - })).be.true(); - }); - it('should return true if more than one of the arguments is true', - function () { - should(req.matchEGCondition({ - name: 'oneOf', - conditions: [{ name: 'always' }, { name: 'always' }] - })).be.true(); - }); - it('should return false if none of the arguments are true', function () { - should(req.matchEGCondition({ - name: 'oneOf', - conditions: [{ name: 'never' }, { name: 'never' }] - })).be.false(); + describe('allOf', function () { + const req = Object.create(express.request); + it('should return true if all of the arguments is true', function () { + should(conditions['allOf']({ conditions: [{ name: 'always' }, { name: 'always' }] })(req)).be.true(); + }); + it('should return false if one of the arguments is false', function () { + should(conditions['allOf']({ conditions: [{ name: 'always' }, { name: 'never' }] })(req)).be.false(); + }); }); -}); -describe('not', function () { - const req = Object.create(express.request); - it('should return true if the argument is false', function () { - should(req.matchEGCondition({ name: 'not', condition: { name: 'never' } })).be.true(); - }); - it('should return false if the argument is true', function () { - should(req.matchEGCondition({ name: 'not', condition: { name: 'always' } })).be.false(); + describe('oneOf', function () { + const req = Object.create(express.request); + it('should return true if one of the arguments is true', function () { + should(conditions['oneOf']({ conditions: [{ name: 'never' }, { name: 'always' }] })(req)).be.true(); + }); + it('should return true if more than one of the arguments is true', + function () { + should(conditions['oneOf']({ conditions: [{ name: 'always' }, { name: 'always' }] })(req)).be.true(); + }); + it('should return false if none of the arguments are true', function () { + should(conditions['oneOf']({ conditions: [{ name: 'never' }, { name: 'never' }] })(req)).be.false(); + }); }); -}); -describe('pathExact', function () { - const req = Object.create(express.request); - it('should return true if request url is the same', function () { - req.url = '/foo/bar/baz'; - should(req.matchEGCondition({ name: 'pathExact', path: '/foo/bar/baz' })).be.true(); - }); - it('should return false if request url is not the same', function () { - req.url = '/foo/bar'; - should(req.matchEGCondition({ name: 'pathExact', path: '/foo/bar/baz' })).be.false(); + describe('not', function () { + const req = Object.create(express.request); + it('should return true if the argument is false', function () { + should(conditions['not']({ condition: { name: 'never' } })(req)).be.true(); + }); + it('should return false if the argument is true', function () { + should(conditions['not']({ condition: { name: 'always' } })(req)).be.false(); + }); }); -}); -describe('pathMatch', function () { - const req = Object.create(express.request); - it('should return true if request url matches', function () { - req.url = '/foo/bar'; - should(req.matchEGCondition({ name: 'pathMatch', pattern: '(/(foo|bar|baz))+/?' })).be.true(); - }); - it('should return false if request url does not match', function () { - req.url = '/froo/brar'; - should(req.matchEGCondition({ name: 'pathMatch', pattern: '(/(foo|bar|baz))/?' })).be.false(); - }); -}); - -describe('expression', () => { - const req = Object.create(express.request); - req.egContext = Object.create(new EgContextBase()); - req.egContext.req = req; - it('should return false if expression does not match', function () { - req.url = 'test'; - should(req.matchEGCondition({ - name: 'expression', - expression: 'req.url.length>5' - })).be.false(); - }); - it('should pass if expression match', function () { - req.url = 'test_123'; - should(req.matchEGCondition({ - name: 'expression', - expression: 'req.url.length>5' - })).be.true(); + describe('pathExact', function () { + const req = Object.create(express.request); + it('should return true if request url is the same', function () { + req.url = '/foo/bar/baz'; + should(conditions['pathExact']({ path: '/foo/bar/baz' })(req)).be.true(); + }); + it('should return false if request url is not the same', function () { + req.url = '/foo/bar'; + should(conditions['pathExact']({ path: '/foo/bar/baz' })(req)).be.false(); + }); }); -}); -describe('method', function () { - const req = Object.create(express.request); - it('should return true if methods param is string and matches', function () { - req.method = 'GET'; - should(req.matchEGCondition({ - name: 'method', - methods: 'GET' - })).be.true(); + describe('pathMatch', function () { + const req = Object.create(express.request); + it('should return true if request url matches', function () { + req.url = '/foo/bar'; + should(conditions['pathMatch']({ pattern: '(/(foo|bar|baz))+/?' })(req)).be.true(); + }); + it('should return false if request url does not match', function () { + req.url = '/froo/brar'; + should(conditions['pathMatch']({ pattern: '(/(foo|bar|baz))/?' })(req)).be.false(); + }); }); - it('should return true if methods param is list and method is member', function () { - req.method = 'POST'; - should(req.matchEGCondition({ - name: 'method', - methods: ['GET', 'POST', 'PUT'] - })).be.true(); + describe('expression', () => { + const req = Object.create(express.request); + req.egContext = Object.create(new EgContextBase()); + req.egContext.req = req; + it('should return false if expression does not match', function () { + req.url = 'test'; + should(conditions['expression']({ expression: 'req.url.length>5' })(req)).be.false(); + }); + it('should pass if expression match', function () { + req.url = 'test_123'; + should(conditions['expression']({ expression: 'req.url.length>5' })(req)).be.true(); + }); }); - it('should return false if methods param is string and does not match', function () { - req.method = 'POST'; - should(req.matchEGCondition({ - name: 'method', - methods: 'GET' - })).be.false(); - }); + describe('method', function () { + const req = Object.create(express.request); + it('should return true if methods param is string and matches', function () { + req.method = 'GET'; + should(conditions['method']({ methods: 'GET' })(req)).be.true(); + }); - it('should return false if param is list and method is not member', - function () { - req.method = 'HEAD'; - should(req.matchEGCondition({ - name: 'method', - methods: ['GET', 'POST', 'PUT'] - })).be.false(); + it('should return true if methods param is list and method is member', function () { + req.method = 'POST'; + should(conditions['method']({ methods: ['GET', 'POST', 'PUT'] })(req)).be.true(); }); -}); -describe('tlsClientAuthenticated', function () { - const req = Object.create(express.request); + it('should return false if methods param is string and does not match', function () { + req.method = 'POST'; + should(conditions['method']({ methods: 'GET' })(req)).be.false(); + }); - it('should return true if request is client authenticated', function () { - req.client = { authorized: true }; - should(req.matchEGCondition({ - name: 'tlsClientAuthenticated' - })).be.true(); + it('should return false if param is list and method is not member', + function () { + req.method = 'HEAD'; + should(conditions['method']({ methods: ['GET', 'POST', 'PUT'] })(req)).be.false(); + }); }); - it('should return false if request is client authenticated', function () { - req.client.authorized = false; - should(req.matchEGCondition({ - name: 'tlsClientAuthenticated' - })).be.false(); + describe('tlsClientAuthenticated', function () { + const req = Object.create(express.request); + + it('should return true if request is client authenticated', function () { + req.client = { authorized: true }; + should(conditions['tlsClientAuthenticated']()(req)).be.true(); + }); + + it('should return false if request is client authenticated', function () { + req.client.authorized = false; + should(conditions['tlsClientAuthenticated']()(req)).be.false(); + }); }); -}); -describe('req.matchEGCondition', function () { - const req = Object.create(express.request); - it('correctly handles complex conditional rule', function () { - const control = { name: 'never' }; - const rule = { - name: 'allOf', - conditions: [{ - name: 'oneOf', - conditions: [ - { name: 'pathExact', path: '/foo/bar' }, - { name: 'not', condition: { name: 'always' } } - ] - }, - { - name: 'not', - condition: { + describe('req.matchEGCondition', function () { + const req = Object.create(express.request); + it('correctly handles complex conditional rule', function () { + const control = { name: 'never' }; + const rule = { + name: 'allOf', + conditions: [{ name: 'oneOf', conditions: [ - control, - { name: 'pathExact', path: '/path/path/path' } + { name: 'pathExact', path: '/foo/bar' }, + { name: 'not', condition: { name: 'always' } } ] + }, + { + name: 'not', + condition: { + name: 'oneOf', + conditions: [ + control, + { name: 'pathExact', path: '/path/path/path' } + ] + } } - } - ] - }; - req.url = '/foo/bar'; - should(req.matchEGCondition(rule)).be.true(); - control.name = 'always'; - should(req.matchEGCondition(rule)).be.false(); + ] + }; + req.url = '/foo/bar'; + should(conditions['allOf'](rule)(req)).be.true(); + control.name = 'always'; + should(conditions['allOf'](rule)(req)).be.false(); + }); }); }); diff --git a/test/plugins/condition.test.js b/test/plugins/condition.test.js index 3e5f431da..19d556232 100644 --- a/test/plugins/condition.test.js +++ b/test/plugins/condition.test.js @@ -1,4 +1,6 @@ const should = require('should'); + +const { conditions, init } = require('../../lib/conditions'); const gateway = require('../../lib/gateway'); const Config = require('../../lib/config/config'); const express = require('express'); @@ -34,6 +36,8 @@ config.gatewayConfig = { }; describe('gateway condition with plugins', () => { + before(init); + let gatewaySrv; before('fires up a new gateway instance', function () { return gateway({ @@ -57,13 +61,13 @@ describe('gateway condition with plugins', () => { it('should return false for param1 not matching url', function () { const req = Object.create(express.request); req.url = '/test'; - should(req.matchEGCondition({ name: 'test-condition', param1: true })).be.false(); + should(conditions['test-condition']({ param1: true })(req)).be.false(); }); it('should return true for param1 matching url', function () { const req = Object.create(express.request); req.url = '/test'; - should(req.matchEGCondition({ name: 'test-condition', param1: '/test' })).be.ok(); + should(conditions['test-condition']({ param1: '/test' })(req)).be.ok(); }); after('close gateway srv', () => { @@ -103,7 +107,7 @@ describe('gateway condition schema with plugins', () => { gatewaySrv = srv.app; const req = Object.create(express.request); req.url = '/test'; - should(req.matchEGCondition({ name: 'test-condition-1', param1: true })).be.false(); + should(conditions['test-condition-1']({ param1: true })(req)).be.false(); }); }); @@ -120,7 +124,7 @@ describe('gateway condition schema with plugins', () => { }, required: ['param2'] }, - handler: function () { + handler: function (req, config) { should.fail(); } }] @@ -130,7 +134,7 @@ describe('gateway condition schema with plugins', () => { gatewaySrv = srv.app; const req = Object.create(express.request); req.url = '/test'; - should.throws(() => req.matchEGCondition({ name: 'test-condition-2', param1: true })); + should.throws(() => conditions['test-condition-2']({ param1: true })(req)); }); }); });