Эх сурвалжийг харах

On logout, clear sudo mode

Shane Kilkelly 9 жил өмнө
parent
commit
c864288c4e

+ 6 - 0
services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee

@@ -18,6 +18,12 @@ module.exports = SudoModeHandler =
 		logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
 		logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
 		rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback
 		rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback
 
 
+	clearSudoMode: (userId, callback=(err)->) ->
+		if !userId?
+			return callback(new Error('[SudoMode] user must be supplied'))
+		logger.log {userId}, "[SudoMode] clearing sudo mode for user"
+		rclient.del SudoModeHandler._buildKey(userId), callback
+
 	isSudoModeActive: (userId, callback=(err, isActive)->) ->
 	isSudoModeActive: (userId, callback=(err, isActive)->) ->
 		if !userId?
 		if !userId?
 			return callback(new Error('[SudoMode] user must be supplied'))
 			return callback(new Error('[SudoMode] user must be supplied'))

+ 2 - 0
services/web/app/coffee/Features/User/UserController.coffee

@@ -11,6 +11,7 @@ AuthenticationManager = require("../Authentication/AuthenticationManager")
 AuthenticationController = require('../Authentication/AuthenticationController')
 AuthenticationController = require('../Authentication/AuthenticationController')
 UserSessionsManager = require("./UserSessionsManager")
 UserSessionsManager = require("./UserSessionsManager")
 UserUpdater = require("./UserUpdater")
 UserUpdater = require("./UserUpdater")
+SudoModeHandler = require('../SudoMode/SudoModeHandler')
 settings = require "settings-sharelatex"
 settings = require "settings-sharelatex"
 
 
 module.exports = UserController =
 module.exports = UserController =
@@ -118,6 +119,7 @@ module.exports = UserController =
 			if err
 			if err
 				logger.err err: err, 'error destorying session'
 				logger.err err: err, 'error destorying session'
 			UserSessionsManager.untrackSession(user, sessionId)
 			UserSessionsManager.untrackSession(user, sessionId)
+			SudoModeHandler.clearSudoMode(user._id)
 			res.redirect '/login'
 			res.redirect '/login'
 
 
 	register : (req, res, next = (error) ->)->
 	register : (req, res, next = (error) ->)->

+ 78 - 0
services/web/test/UnitTests/coffee/SudoMode/SudoModeHandlerTests.coffee

@@ -30,6 +30,7 @@ describe 'SudoModeHandler', ->
 			beforeEach ->
 			beforeEach ->
 				@rclient.set = sinon.stub().callsArgWith(4, null)
 				@rclient.set = sinon.stub().callsArgWith(4, null)
 
 
+
 			it 'should not produce an error', (done) ->
 			it 'should not produce an error', (done) ->
 				@call (err) =>
 				@call (err) =>
 					expect(err).to.equal null
 					expect(err).to.equal null
@@ -43,6 +44,22 @@ describe 'SudoModeHandler', ->
 					)).to.equal true
 					)).to.equal true
 					done()
 					done()
 
 
+		describe 'when user id is not supplied', ->
+			beforeEach ->
+				@call = (cb) =>
+					@SudoModeHandler.activateSudoMode null, cb
+
+			it 'should produce an error', (done) ->
+				@call (err) =>
+					expect(err).to.not.equal null
+					expect(err).to.be.instanceof Error
+					done()
+
+			it 'should not set value in redis', (done) ->
+				@call (err) =>
+					expect(@rclient.set.callCount).to.equal 0
+					done()
+
 		describe 'when rclient.set produces an error', ->
 		describe 'when rclient.set produces an error', ->
 			beforeEach ->
 			beforeEach ->
 				@rclient.set = sinon.stub().callsArgWith(4, new Error('woops'))
 				@rclient.set = sinon.stub().callsArgWith(4, new Error('woops'))
@@ -53,6 +70,51 @@ describe 'SudoModeHandler', ->
 					expect(err).to.be.instanceof Error
 					expect(err).to.be.instanceof Error
 					done()
 					done()
 
 
+	describe 'clearSudoMode', ->
+		beforeEach ->
+			@rclient.del = sinon.stub().callsArgWith(1, null)
+			@call = (cb) =>
+				@SudoModeHandler.clearSudoMode @userId, cb
+
+		it 'should not produce an error', (done) ->
+			@call (err) =>
+				expect(err).to.equal null
+				done()
+
+		it 'should delete key from redis', (done) ->
+			@call (err) =>
+				expect(@rclient.del.callCount).to.equal 1
+				expect(@rclient.del.calledWith(
+					'SudoMode:{some_user_id}'
+				)).to.equal true
+				done()
+
+		describe 'when rclient.del produces an error', ->
+			beforeEach ->
+				@rclient.del = sinon.stub().callsArgWith(1, new Error('woops'))
+
+			it 'should produce an error', (done) ->
+				@call (err) =>
+					expect(err).to.not.equal null
+					expect(err).to.be.instanceof Error
+					done()
+
+		describe 'when user id is not supplied', ->
+			beforeEach ->
+				@call = (cb) =>
+					@SudoModeHandler.clearSudoMode null, cb
+
+			it 'should produce an error', (done) ->
+				@call (err) =>
+					expect(err).to.not.equal null
+					expect(err).to.be.instanceof Error
+					done()
+
+			it 'should not delete value in redis', (done) ->
+				@call (err) =>
+					expect(@rclient.del.callCount).to.equal 0
+					done()
+
 	describe 'isSudoModeActive', ->
 	describe 'isSudoModeActive', ->
 		beforeEach ->
 		beforeEach ->
 			@call = (cb) =>
 			@call = (cb) =>
@@ -108,3 +170,19 @@ describe 'SudoModeHandler', ->
 					expect(err).to.be.instanceof Error
 					expect(err).to.be.instanceof Error
 					expect(isActive).to.be.oneOf [null, undefined]
 					expect(isActive).to.be.oneOf [null, undefined]
 					done()
 					done()
+
+		describe 'when user id is not supplied', ->
+			beforeEach ->
+				@call = (cb) =>
+					@SudoModeHandler.isSudoModeActive null, cb
+
+			it 'should produce an error', (done) ->
+				@call (err) =>
+					expect(err).to.not.equal null
+					expect(err).to.be.instanceof Error
+					done()
+
+			it 'should not get value in redis', (done) ->
+				@call (err) =>
+					expect(@rclient.get.callCount).to.equal 0
+					done()

+ 14 - 0
services/web/test/UnitTests/coffee/User/UserControllerTests.coffee

@@ -60,6 +60,8 @@ describe "UserController", ->
 			trackSession: sinon.stub()
 			trackSession: sinon.stub()
 			untrackSession: sinon.stub()
 			untrackSession: sinon.stub()
 			revokeAllUserSessions: sinon.stub().callsArgWith(2, null)
 			revokeAllUserSessions: sinon.stub().callsArgWith(2, null)
+		@SudoModeHandler =
+			clearSudoMode: sinon.stub()
 		@UserController = SandboxedModule.require modulePath, requires:
 		@UserController = SandboxedModule.require modulePath, requires:
 			"./UserLocator": @UserLocator
 			"./UserLocator": @UserLocator
 			"./UserDeleter": @UserDeleter
 			"./UserDeleter": @UserDeleter
@@ -73,6 +75,7 @@ describe "UserController", ->
 			"../Subscription/SubscriptionDomainHandler":@SubscriptionDomainHandler
 			"../Subscription/SubscriptionDomainHandler":@SubscriptionDomainHandler
 			"./UserHandler":@UserHandler
 			"./UserHandler":@UserHandler
 			"./UserSessionsManager": @UserSessionsManager
 			"./UserSessionsManager": @UserSessionsManager
+			"../SudoMode/SudoModeHandler": @SudoModeHandler
 			"settings-sharelatex": @settings
 			"settings-sharelatex": @settings
 			"logger-sharelatex":
 			"logger-sharelatex":
 				log:->
 				log:->
@@ -302,6 +305,17 @@ describe "UserController", ->
 
 
 			@UserController.logout @req, @res
 			@UserController.logout @req, @res
 
 
+		it 'should clear sudo-mode', (done) ->
+			@req.session.destroy = sinon.stub().callsArgWith(0)
+			@SudoModeHandler.clearSudoMode = sinon.stub()
+			@res.redirect = (url)=>
+				url.should.equal "/login"
+				@SudoModeHandler.clearSudoMode.callCount.should.equal 1
+				@SudoModeHandler.clearSudoMode.calledWith(@user._id).should.equal true
+				done()
+
+			@UserController.logout @req, @res
+
 
 
 	describe "register", ->
 	describe "register", ->
 		beforeEach ->
 		beforeEach ->