From 5e8e909574c48ba1f88f46c60baf4e8ebf890f4c Mon Sep 17 00:00:00 2001 From: "gustavo.marin" Date: Mon, 14 Sep 2015 16:41:06 +0200 Subject: [PATCH] added validateOldPassword feature --- config_sample.json | 1 + src/managers/user.js | 25 ++++++++++++++- src/routes/user.js | 53 +++++++++++++++++++++++++++++--- tests/routesUser.js | 73 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 145 insertions(+), 7 deletions(-) diff --git a/config_sample.json b/config_sample.json index e6da2d1..207a1f1 100644 --- a/config_sample.json +++ b/config_sample.json @@ -112,6 +112,7 @@ "*@a.com" ], "password":{ + "validateOldPassword": true, "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 21e2536..6f8f616 100644 --- a/src/managers/user.js +++ b/src/managers/user.js @@ -309,6 +309,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"; @@ -352,6 +374,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 7fdeab3..7e88f7e 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -1,3 +1,4 @@ +var log = require('../logger/service.js'); var RandExp = require('randexp'); var userDao = require('../managers/dao'); @@ -140,15 +141,57 @@ 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); + } + + if (!req.body.password){ + err = { + err: 'auth_proxy_error', + des: 'invalid body request', + }; + 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); + } + + log.info('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){ if (err) { if (!err.code ) { @@ -172,7 +215,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); } module.exports = addRoutes; diff --git a/tests/routesUser.js b/tests/routesUser.js index b75932e..37f9462 100644 --- a/tests/routesUser.js +++ b/tests/routesUser.js @@ -137,7 +137,8 @@ describe('user', function () { describe('Update Password', function () { it('204 Ok', function (done) { var newPassword = { - password: 'n3wPas5W0rd' + password: 'n3wPas5W0rd', + oldPassword: 'validpassword' }; var options = { @@ -218,6 +219,76 @@ describe('user', function () { }); }); + it('400 (no old password)', function (done) { + var newPassword = { + password: 'n3wPas5W0rd' + }; + + if (!config.password.validateOldPassword) { + return done(); + } + + var options = { + url: 'http://localhost:' + config.public_port + '/user/me/password', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': AUTHORIZATION + }, + method: 'PUT', + body : JSON.stringify(newPassword) + }; + options.headers[config.version.header] = "test/1"; + + var expectedResult = { + err: "missing_password", + des: "Missing old password validation" + }; + + request(options, function (err, res, body) { + assert.equal(err, null, body); + assert.equal(res.statusCode, 400, body); + body = JSON.parse(body); + assert.deepEqual(body, expectedResult); + done(); + }); + }); + + it('401 (invalid old password)', function (done) { + var newPassword = { + password: 'n3wPas5W0rd', + oldPassword: 'invalidPassword' + }; + + if (!config.password.validateOldPassword) { + return done(); + } + + var options = { + url: 'http://localhost:' + config.public_port + '/user/me/password', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': AUTHORIZATION + }, + method: 'PUT', + body : JSON.stringify(newPassword) + }; + options.headers[config.version.header] = "test/1"; + + var expectedResult = { + err: "invalid_old_password", + des:"invalid password", + code: 401 + }; + + request(options, function (err, res, body) { + assert.equal(err, null, body); + assert.equal(res.statusCode, 401, body); + body = JSON.parse(body); + assert.deepEqual(body, expectedResult); + done(); + }); + }); + it('400 (no authorization)', function (done) { var newPassword = {};