diff --git a/features/login.feature b/features/login.feature index a1de2f6..f7460e0 100644 --- a/features/login.feature +++ b/features/login.feature @@ -13,3 +13,9 @@ Feature: client application logs in into a protected backend When the client app requests log in the protected application with invalid credentials Then the response status code is 409 And the response body contains json attribute "err" + + Scenario: client app logs in with incorrect username + Given a user with valid credentials + When the client app requests log in the protected application with username substring + Then the response status code is 409 + And the response body contains json attribute "err" diff --git a/features/step_definitions/login_invalid_username.js b/features/step_definitions/login_invalid_username.js new file mode 100644 index 0000000..338aac6 --- /dev/null +++ b/features/step_definitions/login_invalid_username.js @@ -0,0 +1,29 @@ +var world = require('../support/world'); +var request = require('request'); +var assert = require('assert'); +var config = require('../../config.json'); + +module.exports = function(){ + this.When(/^the client app requests log in the protected application with username substring/, function (callback) { + var username = world.getUser().username; + world.getUser().username = username.slice(0, username.length / 2); + + var options = { + url: 'http://localhost:'+config.public_port+'/auth/login', + headers: { + 'Content-Type': 'application/json; charset=utf-8' + }, + method:'POST', + body : JSON.stringify(world.getUser()) + }; + + options.headers[config.version.header] = "test/1"; + + request(options, function(err,res,body) { + assert.equal(err,null); + world.getResponse().statusCode = res.statusCode; + world.getResponse().body = JSON.parse(body); + callback(); + }); + }); +}; diff --git a/src/managers/dao.js b/src/managers/dao.js index 3eac2b8..a782be4 100644 --- a/src/managers/dao.js +++ b/src/managers/dao.js @@ -97,7 +97,7 @@ function getFromUsername(username, cbk){ if(!username){ return cbk({err:'invalid_username'}, null); } - username = new RegExp(escapeRegexp(username.toLowerCase()), "i"); + username = new RegExp("^"+escapeRegexp(username.toLowerCase())+"$", "i"); collection.find({username: username}, {password:0}, function(err, users){ if(err) { return cbk(err, null); @@ -116,7 +116,7 @@ function getFromUsername(username, cbk){ } function getFromUsernamePassword(username, password, cbk){ - username = new RegExp(escapeRegexp(username.toLowerCase()), "i"); + username = new RegExp("^"+escapeRegexp(username.toLowerCase())+"$", "i"); collection.find({username: username, password: password}, {password:0}, function(err, users){ if(err) { return cbk(err, null); @@ -138,7 +138,7 @@ function getAllUserFields(username, cbk){ if(!username){ return cbk({err:'invalid_username'}, null); } - username = new RegExp(escapeRegexp(username.toLowerCase()), "i"); + username = new RegExp("^"+escapeRegexp(username.toLowerCase())+"$", "i"); collection.find({username: username}, function(err, users){ if(err) { return cbk(err, null); @@ -280,4 +280,4 @@ module.exports = { ERROR_USERNAME_ALREADY_EXISTS: ERROR_USERNAME_ALREADY_EXISTS, getStatus: getStatus -}; \ No newline at end of file +}; diff --git a/tests/auth/login.js b/tests/auth/login.js index 9516930..e1f3f44 100644 --- a/tests/auth/login.js +++ b/tests/auth/login.js @@ -89,6 +89,29 @@ module.exports = { done(); }); }); + + it('POST 409 username substring', function (done) { + var user = clone(baseUser); + var username = user.username; + user.username = username.slice(0, username.length / 2); + var options = { + url: 'http://localhost:' + config.public_port + '/auth/login', + headers: { + 'Content-Type': 'application/json; charset=utf-8' + }, + method: 'POST', + body: JSON.stringify(user) + }; + options.headers[config.version.header] = "test/1"; + + request(options, function (err, res, body) { + assert.equal(err, null); + assert.equal(res.statusCode, 409); + body = JSON.parse(body); + assert.notEqual(body.err, 'invalid_credentials'); + done(); + }); + }); }); describe('Admin /login', function () {