Merge pull request #793 from sharelatex/sk-sl-login-v2

If we're creating v1 accounts, don't allow login for users already linked up
This commit is contained in:
James Allen 2018-08-08 15:51:25 +01:00 committed by GitHub
commit 9cbb51bbbc
2 changed files with 41 additions and 17 deletions

View file

@ -1,6 +1,5 @@
AuthenticationManager = require ("./AuthenticationManager")
LoginRateLimiter = require("../Security/LoginRateLimiter")
UserGetter = require "../User/UserGetter"
UserUpdater = require "../User/UserUpdater"
Metrics = require('metrics-sharelatex')
logger = require("logger-sharelatex")
@ -64,7 +63,10 @@ module.exports = AuthenticationController =
if user # `user` is either a user object or false
AuthenticationController.finishLogin(user, req, res, next)
else
res.json message: info
if info.redir?
res.json {redir: info.redir}
else
res.json message: info
)(req, res, next)
finishLogin: (user, req, res, next) ->
@ -81,20 +83,30 @@ module.exports = AuthenticationController =
doPassportLogin: (req, username, password, done) ->
email = username.toLowerCase()
LoginRateLimiter.processLoginRequest email, (err, isAllowed)->
return done(err) if err?
if !isAllowed
logger.log email:email, "too many login requests"
return done(null, null, {text: req.i18n.translate("to_many_login_requests_2_mins"), type: 'error'})
AuthenticationManager.authenticate email: email, password, (error, user) ->
return done(error) if error?
if user?
# async actions
return done(null, user)
else
AuthenticationController._recordFailedLogin()
logger.log email: email, "failed log in"
return done(null, false, {text: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error'})
Modules = require "../../infrastructure/Modules"
Modules.hooks.fire 'preDoPassportLogin', email, (err, infoList) ->
return next(err) if err?
info = infoList.find((i) => i?)
if info?
return done(null, false, info)
LoginRateLimiter.processLoginRequest email, (err, isAllowed)->
return done(err) if err?
if !isAllowed
logger.log email:email, "too many login requests"
return done(null, null, {text: req.i18n.translate("to_many_login_requests_2_mins"), type: 'error'})
AuthenticationManager.authenticate email: email, password, (error, user) ->
return done(error) if error?
if user?
# async actions
return done(null, user)
else
AuthenticationController._recordFailedLogin()
logger.log email: email, "failed log in"
return done(
null,
false,
{text: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error'}
)
_loginAsyncHandlers: (req, user) ->
UserHandler.setupLoginData(user, ()->)

View file

@ -15,7 +15,6 @@ describe "AuthenticationController", ->
tk.freeze(Date.now())
@AuthenticationController = SandboxedModule.require modulePath, requires:
"./AuthenticationManager": @AuthenticationManager = {}
"../User/UserGetter" : @UserGetter = {}
"../User/UserUpdater" : @UserUpdater = {}
"metrics-sharelatex": @Metrics = { inc: sinon.stub() }
"../Security/LoginRateLimiter": @LoginRateLimiter = { processLoginRequest:sinon.stub(), recordSuccessfulLogin:sinon.stub() }
@ -29,6 +28,7 @@ describe "AuthenticationController", ->
trackSession: sinon.stub()
untrackSession: sinon.stub()
revokeAllUserSessions: sinon.stub().callsArgWith(1, null)
"../../infrastructure/Modules": @Modules = {hooks: {fire: sinon.stub().callsArgWith(2, null, [])}}
@user =
_id: ObjectId()
email: @email = "USER@example.com"
@ -214,6 +214,7 @@ describe "AuthenticationController", ->
beforeEach ->
@AuthenticationController._recordFailedLogin = sinon.stub()
@AuthenticationController._recordSuccessfulLogin = sinon.stub()
@Modules.hooks.fire = sinon.stub().callsArgWith(2, null, [])
# @AuthenticationController.establishUserSession = sinon.stub().callsArg(2)
@req.body =
email: @email
@ -222,6 +223,17 @@ describe "AuthenticationController", ->
postLoginRedirect: "/path/to/redir/to"
@cb = sinon.stub()
describe "when the preDoPassportLogin hooks produce an info object", ->
beforeEach ->
@Modules.hooks.fire = sinon.stub().callsArgWith(2, null, [null, {redir: '/somewhere'}, null])
it "should stop early and call done with this info object", (done) ->
@AuthenticationController.doPassportLogin(@req, @req.body.email, @req.body.password, @cb)
@cb.callCount.should.equal 1
@cb.calledWith(null, false, {redir: '/somewhere'}).should.equal true
@LoginRateLimiter.processLoginRequest.callCount.should.equal 0
done()
describe "when the users rate limit", ->
beforeEach ->