From 1f08eafc3dbe49815477e93a344c2b36f3e64780 Mon Sep 17 00:00:00 2001 From: Nicolas Jaremek Date: Tue, 17 Mar 2015 11:45:46 +0100 Subject: [PATCH 1/7] Added fixtures script to add users to DB --- package.json | 3 +- scripts/add_users.js | 100 +++++++++++++++++++++++++++++++++++++++ tests/fixtures/User.json | 23 +++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 scripts/add_users.js create mode 100644 tests/fixtures/User.json diff --git a/package.json b/package.json index fc4eec5..0423d5a 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "int": "DEBUG=cipherlayer* node main.js", "pro": "DEBUG=cipherlayer* node main.js", "lint": "./node_modules/.bin/gulp jshint", - "lint-go": "./node_modules/.bin/gulp jshint-go" + "lint-go": "./node_modules/.bin/gulp jshint-go", + "fixtures": "node scripts/add_users.js" }, "repository": { "type": "git", diff --git a/scripts/add_users.js b/scripts/add_users.js new file mode 100644 index 0000000..daf65da --- /dev/null +++ b/scripts/add_users.js @@ -0,0 +1,100 @@ +var async = require('async'), + fs = require('fs'), + nock = require('nock'), + userMng = require('../src/managers/user'), + config = require('../config.json'), + userDao = require('../src/managers/dao.js'); +/* + * Objects for `async.eachSeries` + */ + +// Function to apply to each fixture +var addFixture = function(fixture, callback) { + + var data = fixture; + + // Define user object to be passed to userMng + var pin = null; + var profileBody = { + id: data._id.$oid || data._id, + email: data.email, + password: data.password, + phone: data.phone || '111111', + country: data.country || 'US' + }; + + if(!profileBody.id || !profileBody.email || !profileBody.password) { + console.log("Missing mandatory parameter(s)"); + return callback(); + } + // Nock the createUser URL + nock('http://' + config.private_host + ':' + config.private_port + config.passThroughEndpoint.path, { reqheaders: { + 'Content-Type': 'application/json; charset=utf-8' + }}) + .post(config.passThroughEndpoint.path) + .reply(201,profileBody); + + // Save user data to database + userMng().createUser(profileBody, pin, function(err) { + if(err) { + + if (err.err === 'auth_proxy_user_error') { + console.log(profileBody.email + " " + err.des); + return callback(); + } + return callback(err); + } + console.log(profileBody.email + " added"); + return callback(); + }); + +}; + +/* + * Main part of the script: + * - Exports the function, or + * - Executes the function if running from CLI + */ +var runLoadFixtures = module.exports = function(fixtureFile, callback) { + + console.log("running Load Fixtures"); + + + async.eachSeries(fixtureFile, addFixture, callback); + +}; + +if (!module.parent) { // Run as CLI command exec + async.series([ + + // Start cipherLayer components (mongodb, redis...) + function connect(done) { + userDao.connect(done); + }, + + function drop(done) { + if(!process.env.DROP_DB) return done(); + console.log("Dropping database"); + userDao.deleteAllUsers(done); + }, + + function load(done) { + fixtureFile = require(__dirname + '/' + '../tests/fixtures/' + 'User.json'); + runLoadFixtures(fixtureFile,done); + }, + + function disconnect(done) { + userDao.disconnect(done); + } + + ], function(err) { + if (err) { + console.error(err); + process.exit(1); + } + + console.info('Fixtures loaded'); + process.exit(); + }); + +} diff --git a/tests/fixtures/User.json b/tests/fixtures/User.json new file mode 100644 index 0000000..b2631f3 --- /dev/null +++ b/tests/fixtures/User.json @@ -0,0 +1,23 @@ +[ + { + "_id": {"$oid": "01f0000000000000003f0004"}, + "phone": "555-7891-2365", + "email": "nick@intelygenz.com", + "password": "1234", + "country": "PL" + }, + { + "_id": {"$oid": "01f0000000000000003f0002"}, + "phone": "555-8899-1324", + "email": "gustavo@intelygenz.com", + "password": "asdf", + "country": "AR" + }, + { + "_id": {"$oid": "01f0000000000000003f0003"}, + "phone": "555-0012-7453", + "email": "josemanuel@intelygenz.com", + "password": "abcd", + "country": "ES" + } +] \ No newline at end of file From 01f6def22b26a4b314668d9a7f583f005d557a20 Mon Sep 17 00:00:00 2001 From: Nicolas Jaremek Date: Tue, 17 Mar 2015 13:03:42 +0100 Subject: [PATCH 2/7] Added env var for default password. Added default password for users. --- scripts/add_users.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/add_users.js b/scripts/add_users.js index daf65da..984aebe 100644 --- a/scripts/add_users.js +++ b/scripts/add_users.js @@ -18,9 +18,7 @@ var addFixture = function(fixture, callback) { var profileBody = { id: data._id.$oid || data._id, email: data.email, - password: data.password, - phone: data.phone || '111111', - country: data.country || 'US' + password: data.password || (process.env.DEFAULT_PASS ? process.env.DEFAULT_PASS : "qwerty") }; if(!profileBody.id || !profileBody.email || !profileBody.password) { From 2fdd81e3ee9a328bc48881cb8433501a7d756edc Mon Sep 17 00:00:00 2001 From: "gustavo.marin" Date: Wed, 8 Apr 2015 13:23:09 +0200 Subject: [PATCH 3/7] added x-user-id header on directproxy request --- src/middlewares/propagateRequest.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/middlewares/propagateRequest.js b/src/middlewares/propagateRequest.js index af335cd..522645f 100644 --- a/src/middlewares/propagateRequest.js +++ b/src/middlewares/propagateRequest.js @@ -32,6 +32,8 @@ function propagateRequest(req, res, next){ // if url is a direct proxy request, use http-proxy if (useDirectProxy) { + // add user id to proxy request headers + req.headers['x-user-id'] = req.options.headers['x-user-id']; proxy.web(req, res, { target: 'http://'+ config.private_host + ':' + config.private_port }); From 50918ce4ed24b1692ec11baf8b3fc630d77f09ae Mon Sep 17 00:00:00 2001 From: "gustavo.marin" Date: Tue, 21 Apr 2015 13:32:08 +0200 Subject: [PATCH 4/7] added verify old password functionality --- config_sample.json | 1 + src/managers/user.js | 25 ++++++++++++++++++++++++- src/routes/user.js | 44 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/config_sample.json b/config_sample.json index a784791..b11bf89 100644 --- a/config_sample.json +++ b/config_sample.json @@ -104,6 +104,7 @@ "*@a.com" ], "password":{ + "validateOldPassword": false, "regexValidation": "(?=.*\\d)(?=.*[A-Z])(?=.*[a-z]).{8}", "message": "Your password must be at least 8 characters and must contain at least one capital, one lower and one number.", "generatedRegex": "([a-z][\\d][A-Z]){3,4}", diff --git a/src/managers/user.js b/src/managers/user.js index 380a32c..779cea6 100644 --- a/src/managers/user.js +++ b/src/managers/user.js @@ -312,6 +312,28 @@ function setPassword(id, body, cbk){ } } +function validateOldPassword(username, oldPassword, cbk) { + + userDao.getAllUserFields(username, function(err, user) { + if (err) { + res.send(401, err); + return next(); + } + + cryptoMng.encrypt(oldPassword, function(encrypted){ + if (user.password !== encrypted) { + return cbk({ + err: 'invalid_old_password', + des: 'invalid password', + code: 401 + }); + } + + return cbk(); + }); + }); +} + //Aux functions function random (howMany, chars) { chars = chars || "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789"; @@ -357,6 +379,7 @@ module.exports = function(settings) { setPlatformData : setPlatformData, createUser : createUser, createUserByToken : createUserByToken, - setPassword: setPassword + setPassword: setPassword, + validateOldPassword: validateOldPassword }; }; diff --git a/src/routes/user.js b/src/routes/user.js index d92ecb8..2bb1639 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -138,15 +138,49 @@ function createUserByToken(req, res, next) { }); } -function setPassword(req, res, next){ - if(!req.body){ - res.send(400, { +function checkBody(req, res, next) { + var err; + if (!req.body){ + err = { err: 'invalid_body', des: 'The call to this url must have body.' - } ); + }; + res.send(400, err); + return next(false); + } + + return next(); +} + +function validateOldPassword(req, res, next) { + var err; + if (!config.password.validateOldPassword) { return next(); } + if (!req.body.oldPassword) { + err = { + err: 'missing_password', + des: 'Missing old password validation' + }; + res.send(400, err); + return next(false); + } + + debug('validating old password', req.user.password, req.body); + + userMng().validateOldPassword(req.user.username, req.body.oldPassword, function(err){ + if (err) { + res.send(401, err); + return next(false); + } + return next(); + }); + +} + +function setPassword(req, res, next){ + userMng().setPassword(req.user._id, req.body, function(err, modified){ if (err) { if (!err.code ) { @@ -170,7 +204,7 @@ function addRoutes(service){ service.post(config.passThroughEndpoint.path, createUserEndpoint); service.get('/user/activate', createUserByToken); - service.put('/user/me/password', checkAccessTokenParam, checkAuthHeader, decodeToken, findUser, setPassword); + service.put('/user/me/password', checkAccessTokenParam, checkAuthHeader, decodeToken, checkBody, findUser, validateOldPassword, setPassword); debug('User routes added'); } From 1aca4bb589f33d9bd06f476a418108686fdbf116 Mon Sep 17 00:00:00 2001 From: "gustavo.marin" Date: Tue, 21 Apr 2015 16:13:33 +0200 Subject: [PATCH 5/7] temporally skipped tests userAppVersion --- tests/userAppVersion.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/userAppVersion.js b/tests/userAppVersion.js index 413325d..6817ecb 100644 --- a/tests/userAppVersion.js +++ b/tests/userAppVersion.js @@ -44,7 +44,7 @@ describe('middleware userAppVersion', function(){ ], done); }); - it('update (user has no appVersion)', function(done){ + it.skip('update (user has no appVersion)', function(done){ userDao.addUser()(baseUser, function(err, createdUser) { var req = { headers: {}, @@ -70,7 +70,7 @@ describe('middleware userAppVersion', function(){ }); }); - it('update (different appVersion)', function(done){ + it.skip('update (different appVersion)', function(done){ baseUser.appVersion = 'version 1.0.0'; userDao.addUser()(baseUser, function(err, createdUser) { var req = { @@ -141,4 +141,4 @@ describe('middleware userAppVersion', function(){ userAppVersion(settings)(req, res, next); }); -}); \ No newline at end of file +}); From 9ca1c3e86b606110a1f1e56536cac97f75274eb6 Mon Sep 17 00:00:00 2001 From: "gustavo.marin" Date: Tue, 21 Apr 2015 17:03:42 +0200 Subject: [PATCH 6/7] Revert "Added middleware "userAppVersion" (update user info with his app version)" This reverts commit fdcc89d76f3edda9a8baf17d8b2bbed1044c561f. Conflicts: src/cipherlayer.js src/middlewares/userAppVersion.js tests/userAppVersion.js --- src/cipherlayer.js | 11 ++- src/middlewares/userAppVersion.js | 36 -------- tests/userAppVersion.js | 144 ------------------------------ 3 files changed, 5 insertions(+), 186 deletions(-) delete mode 100644 src/middlewares/userAppVersion.js delete mode 100644 tests/userAppVersion.js diff --git a/src/cipherlayer.js b/src/cipherlayer.js index dc546f5..bb67970 100644 --- a/src/cipherlayer.js +++ b/src/cipherlayer.js @@ -23,8 +23,7 @@ var bodyParserWrapper = require('./middlewares/bodyParserWrapper.js'); var versionControl = require('version-control'); -var pinValidation = require('./middlewares/pinValidation.js')(); -var userAppVersion = require('./middlewares/userAppVersion.js')(); +var pinValidation = require('./middlewares/pinValidation.js'); var jsonValidator = require('./managers/json_validator'); var configSchema = require('../config_schema.json'); @@ -100,10 +99,10 @@ function startListener(publicPort, privatePort, cbk){ require(platformsPath + filename).addRoutes(server, passport); }); - server.get(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, pinValidation, userAppVersion, prepareOptions, platformsSetUp, printTraces, propagateRequest); - server.post(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, pinValidation, userAppVersion, prepareOptions, platformsSetUp, printTraces, propagateRequest); - server.del(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, pinValidation, userAppVersion, prepareOptions, platformsSetUp, printTraces, propagateRequest); - server.put(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, pinValidation, userAppVersion, prepareOptions, platformsSetUp, printTraces, propagateRequest); + server.get(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, prepareOptions, platformsSetUp, printTraces, propagateRequest, pinValidation); + server.post(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, prepareOptions, platformsSetUp, printTraces, propagateRequest, pinValidation); + server.del(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser,prepareOptions, platformsSetUp, printTraces, propagateRequest, pinValidation); + server.put(/(.*)/, checkAccessTokenParam, checkAuthHeader, decodeToken, permissions, findUser, prepareOptions, platformsSetUp, printTraces, propagateRequest, pinValidation); server.use(function(req, res, next){ debug('< ' + res.statusCode); diff --git a/src/middlewares/userAppVersion.js b/src/middlewares/userAppVersion.js deleted file mode 100644 index 926205e..0000000 --- a/src/middlewares/userAppVersion.js +++ /dev/null @@ -1,36 +0,0 @@ -var debug = require('debug')('cipherlayer:userAppVersion'); -var userDao = require('../managers/dao'); -var _ = require('lodash'); - -var config = require('../../config.json'); - -var updatingUserError = { - err:'proxy_error', - des:'error updating user appVersion' -}; - -var defaultSettings = config; -var _settings = {}; - -function storeUserAppVersion(req, res, next){ - if(!req.headers[_settings.version.header] || req.user.appVersion === req.headers[_settings.version.header]) { - return next(); - } else { - debug('appVersion [' + req.headers[_settings.version.header] + '] must be updated for the user [' + req.user._id + ']'); - userDao.updateField(req.user._id, 'appVersion', req.headers[_settings.version.header], function(err, updatedUsers){ - if(err){ - debug('error updating user appVersion ', err); - res.send(500, updatingUserError); - return next(false); - } else { - next(); - } - }); - } -} - -module.exports = function(settings){ - _.extend(_settings, defaultSettings, settings); - - return storeUserAppVersion; -}; diff --git a/tests/userAppVersion.js b/tests/userAppVersion.js deleted file mode 100644 index 6817ecb..0000000 --- a/tests/userAppVersion.js +++ /dev/null @@ -1,144 +0,0 @@ -var assert = require('assert'); -var async = require('async'); - -var userAppVersion = require('../src/middlewares/userAppVersion.js'); -var userDao = require('../src/managers/dao'); - -var config = require('../config.json'); - -describe('middleware userAppVersion', function(){ - var settings = { - "version" : { - "header" : "x-mycomms-version", - "platforms" : { - "test" : { - "link" : "http://testLink", - "1" : true - } - }, - "installPath" : "/install" - } - }; - - var baseUser = { - id:'a1b2c3d4e5f6', - username: 'username' + (config.allowedDomains[0] ? config.allowedDomains[0] : ''), - password: '12345678' - }; - - beforeEach(function(done){ - async.series([ - function(done){ - userDao.connect(function(){ - userDao.deleteAllUsers( done ); - }); - } - ], done); - }); - - afterEach(function(done){ - async.series([ - function(done){ - userDao.disconnect(done); - } - ], done); - }); - - it.skip('update (user has no appVersion)', function(done){ - userDao.addUser()(baseUser, function(err, createdUser) { - var req = { - headers: {}, - url: "/api/me", - method: "GET", - user: createdUser - }; - - req.headers[config.version.header] = 'version 1.0.0'; - - var res = {}; - var next = function(canContinue) { - if (canContinue === undefined || canContinue === true){ - userDao.getFromId(createdUser._id, function(err, foundUser){ - assert.equal(err, null); - assert.equal(foundUser.appVersion, 'version 1.0.0'); - done(); - }); - } - }; - - userAppVersion(settings)(req, res, next); - }); - }); - - it.skip('update (different appVersion)', function(done){ - baseUser.appVersion = 'version 1.0.0'; - userDao.addUser()(baseUser, function(err, createdUser) { - var req = { - headers: {}, - url: "/api/me", - method: "GET", - user: createdUser - }; - - req.headers[config.version.header] = 'version 2.0.0'; - - var res = {}; - var next = function(canContinue) { - if (canContinue === undefined || canContinue === true){ - userDao.getFromId(createdUser._id, function(err, foundUser){ - assert.equal(err, null); - assert.equal(foundUser.appVersion, 'version 2.0.0'); - done(); - }); - } - }; - - userAppVersion(settings)(req, res, next); - }); - }); - - it('continue (same appVersion)', function(done){ - baseUser.appVersion = 'version 1.0.0'; - userDao.addUser()(baseUser, function(err, createdUser) { - var req = { - headers: {}, - url: "/api/me", - method: "GET", - user: createdUser - }; - - req.headers[config.version.header] = 'version 1.0.0'; - - var res = {}; - var next = function(canContinue) { - if (canContinue === undefined || canContinue === true){ - userDao.getFromId(createdUser._id, function(err, foundUser){ - assert.equal(err, null); - assert.equal(foundUser.appVersion, 'version 1.0.0'); - done(); - }); - } - }; - - userAppVersion(settings)(req, res, next); - }); - }); - - it('continue (no version header)', function(done){ - var req = { - headers: {}, - url: "/api/me", - method: "GET", - user: baseUser - }; - - var res = {}; - var next = function(canContinue) { - if (canContinue === undefined || canContinue === true){ - done(); - } - }; - - userAppVersion(settings)(req, res, next); - }); -}); From fef9adf4e76a394efbb7259b5e2b09a585dc744c Mon Sep 17 00:00:00 2001 From: "gustavo.marin" Date: Wed, 9 Sep 2015 15:53:04 +0200 Subject: [PATCH 7/7] fixed package and removed log --- package.json | 2 +- src/cipherlayer.js | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index 69f56e6..7fa36c3 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "redis": "^0.12.1", "request": "^2.47.0", "restify": "^2.8.3", - "version-control": "^1.2.1" + "version-control": "^1.2.4" }, "devDependencies": { "assert": "^1.1.2", diff --git a/src/cipherlayer.js b/src/cipherlayer.js index 27dab9f..d79b71d 100644 --- a/src/cipherlayer.js +++ b/src/cipherlayer.js @@ -88,11 +88,6 @@ function startListener(publicPort, privatePort, cbk){ server.use(restify.queryParser()); server.use(bodyParserWrapper(restify.bodyParser({maxBodySize: 1024 * 1024 * 3}))); - server.use(function(req,res,next){ - debug('> ' + req.method + ' ' + req.url); - next(); - }); - var versionControlOptions = clone(config.version); versionControlOptions.public = [ "/auth/sf",