From 2ef23194df4681da02423364800f72c0f0ff0e5d Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 20 Sep 2018 14:59:30 +0100 Subject: [PATCH] WIP: trying to get acceptance tests to pass --- .../AuthenticationController.coffee | 12 +++++---- .../Features/SudoMode/SudoModeHandler.coffee | 11 +++++++- .../SudoMode/SudoModeMiddlewear.coffee | 1 + .../app/coffee/Features/V1/V1Handler.coffee | 27 +++++++++++++++++++ .../acceptance/coffee/SessionTests.coffee | 21 +++++++++++++-- .../acceptance/coffee/SettingsTests.coffee | 15 ++++++++++- .../coffee/helpers/MockV1Api.coffee | 13 +++++++++ .../AuthenticationControllerTests.coffee | 1 + .../SudoMode/SudoModeControllerTests.coffee | 1 + .../SudoMode/SudoModeHandlerTests.coffee | 3 +++ .../SudoMode/SudoModeMiddlewearTests.coffee | 1 + 11 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 services/web/app/coffee/Features/V1/V1Handler.coffee diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee index d301ddabbc..1505af5dcb 100644 --- a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee +++ b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee @@ -12,6 +12,7 @@ UserSessionsManager = require("../User/UserSessionsManager") Analytics = require "../Analytics/AnalyticsManager" passport = require 'passport' NotificationsBuilder = require("../Notifications/NotificationsBuilder") +SudoModeHandler = require '../SudoMode/SudoModeHandler' module.exports = AuthenticationController = @@ -76,11 +77,12 @@ module.exports = AuthenticationController = AuthenticationController.afterLoginSessionSetup req, user, (err) -> if err? return next(err) - AuthenticationController._clearRedirectFromSession(req) - if req.headers?['accept']?.match(/^application\/json.*$/) - res.json {redir: redir} - else - res.redirect(redir) + SudoModeHandler.activateSudoMode user._id, () -> + AuthenticationController._clearRedirectFromSession(req) + if req.headers?['accept']?.match(/^application\/json.*$/) + res.json {redir: redir} + else + res.redirect(redir) doPassportLogin: (req, username, password, done) -> email = username.toLowerCase() diff --git a/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee b/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee index e145f3cc5b..18e7bfd74f 100644 --- a/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee +++ b/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee @@ -2,6 +2,9 @@ RedisWrapper = require('../../infrastructure/RedisWrapper') rclient = RedisWrapper.client('sudomode') logger = require('logger-sharelatex') AuthenticationManager = require '../Authentication/AuthenticationManager' +Settings = require 'settings-sharelatex' +V1Handler = require '../V1/V1Handler' +UserGetter = require '../User/UserGetter' TIMEOUT_IN_SECONDS = 60 * 60 @@ -13,7 +16,13 @@ module.exports = SudoModeHandler = "SudoMode:{#{userId}}" authenticate: (email, password, callback=(err, user)->) -> - AuthenticationManager.authenticate {email}, password, callback + if Settings.overleaf? + V1Handler.authWithV1 email, password, (err, isValid, v1Profile) -> + if !isValid + return callback(null, null) + UserGetter.getUser {'overleaf.id': v1Profile.id}, callback + else + AuthenticationManager.authenticate {email}, password, callback activateSudoMode: (userId, callback=(err)->) -> if !userId? diff --git a/services/web/app/coffee/Features/SudoMode/SudoModeMiddlewear.coffee b/services/web/app/coffee/Features/SudoMode/SudoModeMiddlewear.coffee index 64d238b543..e677ab38bb 100644 --- a/services/web/app/coffee/Features/SudoMode/SudoModeMiddlewear.coffee +++ b/services/web/app/coffee/Features/SudoMode/SudoModeMiddlewear.coffee @@ -7,6 +7,7 @@ Settings = require 'settings-sharelatex' module.exports = SudoModeMiddlewear = protectPage: (req, res, next) -> + console.log ">>>>>> Settings", Settings.overleaf if req.externalAuthenticationSystemUsed() and !Settings.overleaf? logger.log {userId}, "[SudoMode] using external auth, skipping sudo-mode check" return next() diff --git a/services/web/app/coffee/Features/V1/V1Handler.coffee b/services/web/app/coffee/Features/V1/V1Handler.coffee new file mode 100644 index 0000000000..d4f4286f32 --- /dev/null +++ b/services/web/app/coffee/Features/V1/V1Handler.coffee @@ -0,0 +1,27 @@ +V1Api = require './V1Api' +Settings = require 'settings-sharelatex' +logger = require 'logger-sharelatex' + + +module.exports = V1Handler = + + authWithV1: (email, password, callback=(err, isValid, v1Profile)->) -> + V1Api.request { + method: 'POST', + url: '/api/v1/sharelatex/login', + json: {email, password}, + expectedStatusCodes: [403] + }, (err, response, body) -> + if err? + logger.err {email, err}, + "[V1Handler] error while talking to v1 login api" + return callback(err) + if response.statusCode in [200, 403] + isValid = body.valid + userProfile = body.user_profile + logger.log {email, isValid, v1UserId: body?.user_profile?.id}, + "[V1Handler] got response from v1 login api" + callback(null, isValid, userProfile) + else + err = new Error("Unexpected status from v1 login api: #{response.statusCode}") + callback(err) diff --git a/services/web/test/acceptance/coffee/SessionTests.coffee b/services/web/test/acceptance/coffee/SessionTests.coffee index 07a431a229..dff0832836 100644 --- a/services/web/test/acceptance/coffee/SessionTests.coffee +++ b/services/web/test/acceptance/coffee/SessionTests.coffee @@ -4,6 +4,7 @@ User = require "./helpers/User" request = require "./helpers/request" settings = require "settings-sharelatex" redis = require "./helpers/redis" +MockV1Api = require './helpers/MockV1Api' describe "Sessions", -> before (done) -> @@ -254,7 +255,7 @@ describe "Sessions", -> describe 'three sessions, sessions page', -> - before -> + before (done) -> # set up second session for this user @user2 = new User() @user2.email = @user1.email @@ -262,7 +263,23 @@ describe "Sessions", -> @user3 = new User() @user3.email = @user1.email @user3.password = @user1.password - + v1Id = 2345 + v1User2 = { + id: v1Id, + email: @user2.email, + password: @user2.password, + profile: + id: v1Id, + email: @user2.email + } + async.series [ + @user2.login.bind(@user2) + (cb) => @user2.mongoUpdate {$set: {'overleaf.id': v1Id}}, cb + (cb) => + MockV1Api.setUser v1Id, v1User2 + cb() + @user2.activateSudoMode.bind(@user2) + ], done it "should allow the user to erase the other two sessions", (done) -> async.series( diff --git a/services/web/test/acceptance/coffee/SettingsTests.coffee b/services/web/test/acceptance/coffee/SettingsTests.coffee index bd2942e072..78349b0952 100644 --- a/services/web/test/acceptance/coffee/SettingsTests.coffee +++ b/services/web/test/acceptance/coffee/SettingsTests.coffee @@ -1,18 +1,31 @@ should = require('chai').should() async = require("async") User = require "./helpers/User" +MockV1Api = require './helpers/MockV1Api' describe 'SettingsPage', -> before (done) -> @user = new User() + @v1Id = 1234 + @v1User = + id: @v1Id + email: @user.email + password: @user.password + profile: + id: @v1Id + email: @user.email async.series [ @user.ensureUserExists.bind(@user) @user.login.bind(@user) + (cb) => @user.mongoUpdate {$set: {'overleaf.id': @v1Id}}, cb + (cb) => + MockV1Api.setUser @v1Id, @v1User + cb() @user.activateSudoMode.bind(@user) ], done - it 'load settigns page', (done) -> + it 'load settings page', (done) -> @user.getUserSettingsPage (err, statusCode) -> statusCode.should.equal 200 done() diff --git a/services/web/test/acceptance/coffee/helpers/MockV1Api.coffee b/services/web/test/acceptance/coffee/helpers/MockV1Api.coffee index 14177dfbb4..5d98ff73b7 100644 --- a/services/web/test/acceptance/coffee/helpers/MockV1Api.coffee +++ b/services/web/test/acceptance/coffee/helpers/MockV1Api.coffee @@ -76,6 +76,19 @@ module.exports = MockV1Api = @updateEmail parseInt(req.params.id), email return res.sendStatus 200 + app.post "/api/v1/sharelatex/login", (req, res, next) => + for id, user of @users + if user.email == req.body.email && user.password == req.body.password + return res.json { + email: user.email, + valid: true, + user_profile: user.profile + } + return res.status(403).json { + email: user.email, + valid: false + } + app.listen 5000, (error) -> throw error if error? .on "error", (error) -> diff --git a/services/web/test/unit/coffee/Authentication/AuthenticationControllerTests.coffee b/services/web/test/unit/coffee/Authentication/AuthenticationControllerTests.coffee index 300a4663e7..78f7b288f6 100644 --- a/services/web/test/unit/coffee/Authentication/AuthenticationControllerTests.coffee +++ b/services/web/test/unit/coffee/Authentication/AuthenticationControllerTests.coffee @@ -29,6 +29,7 @@ describe "AuthenticationController", -> untrackSession: sinon.stub() revokeAllUserSessions: sinon.stub().callsArgWith(1, null) "../../infrastructure/Modules": @Modules = {hooks: {fire: sinon.stub().callsArgWith(2, null, [])}} + "../SudoMode/SudoModeHandler": @SudoModeHandler = {activateSudoMode: sinon.stub().callsArgWith(1, null)} @user = _id: ObjectId() email: @email = "USER@example.com" diff --git a/services/web/test/unit/coffee/SudoMode/SudoModeControllerTests.coffee b/services/web/test/unit/coffee/SudoMode/SudoModeControllerTests.coffee index 6b6c747034..2532a40898 100644 --- a/services/web/test/unit/coffee/SudoMode/SudoModeControllerTests.coffee +++ b/services/web/test/unit/coffee/SudoMode/SudoModeControllerTests.coffee @@ -28,6 +28,7 @@ describe 'SudoModeController', -> '../Authentication/AuthenticationController': @AuthenticationController '../../infrastructure/Mongoose': {mongo: {ObjectId: () -> 'some_object_id'}} '../User/UserGetter': @UserGetter + 'settings-sharelatex': @Settings = {} describe 'sudoModePrompt', -> beforeEach -> diff --git a/services/web/test/unit/coffee/SudoMode/SudoModeHandlerTests.coffee b/services/web/test/unit/coffee/SudoMode/SudoModeHandlerTests.coffee index 17684f4a68..e23797087f 100644 --- a/services/web/test/unit/coffee/SudoMode/SudoModeHandlerTests.coffee +++ b/services/web/test/unit/coffee/SudoMode/SudoModeHandlerTests.coffee @@ -20,6 +20,9 @@ describe 'SudoModeHandler', -> '../../infrastructure/RedisWrapper': @RedisWrapper 'logger-sharelatex': @logger = {log: sinon.stub(), err: sinon.stub()} '../Authentication/AuthenticationManager': @AuthenticationManager = {} + 'settings-sharelatex': @Settings = {} + '../V1/V1Handler': @V1Handler = {authWithV1: sinon.stub()} + '../User/UserGetter': @UserGetter = {getUser: sinon.stub()} describe '_buildKey', -> diff --git a/services/web/test/unit/coffee/SudoMode/SudoModeMiddlewearTests.coffee b/services/web/test/unit/coffee/SudoMode/SudoModeMiddlewearTests.coffee index d17c397d3c..cc4f859ab2 100644 --- a/services/web/test/unit/coffee/SudoMode/SudoModeMiddlewearTests.coffee +++ b/services/web/test/unit/coffee/SudoMode/SudoModeMiddlewearTests.coffee @@ -18,6 +18,7 @@ describe 'SudoModeMiddlewear', -> './SudoModeHandler': @SudoModeHandler '../Authentication/AuthenticationController': @AuthenticationController 'logger-sharelatex': {log: sinon.stub(), err: sinon.stub()} + 'settings-sharelatex': @Settings = {} describe 'protectPage', -> beforeEach ->