Ver código fonte

If a token-based project not found, check private overleaf project

Shane Kilkelly 9 anos atrás
pai
commit
ad999a72b6

+ 22 - 10
services/web/app/coffee/Features/TokenAccess/TokenAccessController.coffee

@@ -19,16 +19,28 @@ module.exports = TokenAccessController =
 			if !project?
 				logger.log {token, userId},
 					"no project found for readAndWrite token"
-				return next(new Errors.NotFoundError())
-			logger.log {userId, projectId: project._id},
-				"adding user to project with readAndWrite token"
-			TokenAccessHandler.addReadAndWriteUserToProject userId, project._id, (err) ->
-				if err?
-					logger.err {err, token, userId, projectId: project._id},
-						"error adding user to project with readAndWrite token"
-					return next(err)
-				req.params.Project_id = project._id.toString()
-				return ProjectController.loadEditor(req, res, next)
+				TokenAccessHandler
+					.findPrivateOverleafProjectWithReadAndWriteToken token, (err, project) ->
+						if err?
+							logger.err {err, token, userId},
+								"error getting project by readAndWrite token"
+							return next(err)
+						if !project?
+							logger.log {token, userId},
+								"no private-overleaf project found with readAndWriteToken"
+							return next(new Errors.NotFoundError())
+						logger.log {token, projectId: project._id}, "redirecting user to project"
+						res.redirect(302, "/project/#{project._id}")
+			else
+				logger.log {userId, projectId: project._id},
+					"adding user to project with readAndWrite token"
+				TokenAccessHandler.addReadAndWriteUserToProject userId, project._id, (err) ->
+					if err?
+						logger.err {err, token, userId, projectId: project._id},
+							"error adding user to project with readAndWrite token"
+						return next(err)
+					req.params.Project_id = project._id.toString()
+					return ProjectController.loadEditor(req, res, next)
 
 	readOnlyToken: (req, res, next) ->
 		userId = AuthenticationController.getLoggedInUserId(req)

+ 7 - 0
services/web/app/coffee/Features/TokenAccess/TokenAccessHandler.coffee

@@ -16,6 +16,13 @@ module.exports = TokenAccessHandler =
 			'publicAccesLevel': PublicAccessLevels.TOKEN_BASED
 		}, {_id: 1, publicAccesLevel: 1}, callback
 
+	findPrivateOverleafProjectWithReadAndWriteToken: (token, callback=(err, project)->) ->
+		Project.findOne {
+			'tokens.readAndWrite': token,
+			'publicAccesLevel': PublicAccessLevels.PRIVATE,
+			'overleaf.id': {'$exists': true}
+		}, {_id: 1, publicAccesLevel: 1, owner_ref: 1}, callback
+
 	addReadOnlyUserToProject: (userId, projectId, callback=(err)->) ->
 		userId = ObjectId(userId.toString())
 		projectId = ObjectId(projectId.toString())

+ 89 - 28
services/web/test/UnitTests/coffee/TokenAccess/TokenAccessControllerTests.coffee

@@ -107,38 +107,99 @@ describe "TokenAccessController", ->
 
 		describe 'when findProject does not find a project', ->
 			beforeEach ->
-				@req = new MockRequest()
-				@res = new MockResponse()
-				@next = sinon.stub()
-				@req.params['read_and_write_token'] = @readAndWriteToken
-				@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
-					.callsArgWith(1, null, null)
-				@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
-					.callsArgWith(2, null)
-				@ProjectController.loadEditor = sinon.stub()
-				@TokenAccessController.readAndWriteToken @req, @res, @next
 
-			it 'should try to find a project with this token', (done) ->
-				expect(@TokenAccessHandler.findProjectWithReadAndWriteToken.callCount)
-					.to.equal 1
-				expect(@TokenAccessHandler.findProjectWithReadAndWriteToken.calledWith(@readAndWriteToken))
-					.to.equal true
-				done()
+			describe 'when it is a private overleaf project', ->
+				beforeEach ->
+					@req = new MockRequest()
+					@res = new MockResponse()
+					@res.redirect = sinon.stub()
+					@next = sinon.stub()
+					@req.params['read_and_write_token'] = @readAndWriteToken
+					@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
+						.callsArgWith(1, null, null)
+					@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken =
+						sinon.stub()
+						.callsArgWith(1, null, @project)
+					@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
+						.callsArgWith(2, null)
+					@ProjectController.loadEditor = sinon.stub()
+					@TokenAccessController.readAndWriteToken @req, @res, @next
 
-			it 'should not add the user to the project with read-write access', (done) ->
-				expect(@TokenAccessHandler.addReadAndWriteUserToProject.callCount)
-					.to.equal 0
-				done()
+				it 'should try to find a project with this token', (done) ->
+					expect(@TokenAccessHandler.findProjectWithReadAndWriteToken.callCount)
+						.to.equal 1
+					expect(@TokenAccessHandler.findProjectWithReadAndWriteToken.calledWith(@readAndWriteToken))
+						.to.equal true
+					done()
 
-			it 'should not pass control to loadEditor', (done) ->
-				expect(@ProjectController.loadEditor.callCount).to.equal 0
-				expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal false
-				done()
+				it 'should try to find a private overleaf project', (done) ->
+					expect(
+						@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken
+							.callCount
+					).to.equal 1
+					expect(
+						@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken
+							.calledWith(@readAndWriteToken)
+					).to.equal true
+					done()
 
-			it 'should call next with a not-found error', (done) ->
-				expect(@next.callCount).to.equal 1
-				expect(@next.lastCall.args[0]).to.be.instanceof Error
-				done()
+				it 'should not add the user to the project with read-write access', (done) ->
+					expect(@TokenAccessHandler.addReadAndWriteUserToProject.callCount)
+						.to.equal 0
+					done()
+
+				it 'should not pass control to loadEditor', (done) ->
+					expect(@ProjectController.loadEditor.callCount).to.equal 0
+					expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal false
+					done()
+
+				it 'should not call next with a not-found error', (done) ->
+					expect(@next.callCount).to.equal 0
+					done()
+
+				it 'should redirect to the canonical project url', (done) ->
+					expect(@res.redirect.callCount).to.equal 1
+					expect(@res.redirect.calledWith(302, "/project/#{@project._id}")).to.equal true
+					done()
+
+			describe 'when it is not a private overleaf project', ->
+				beforeEach ->
+					@req = new MockRequest()
+					@res = new MockResponse()
+					@next = sinon.stub()
+					@req.params['read_and_write_token'] = @readAndWriteToken
+					@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
+						.callsArgWith(1, null, null)
+					@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken =
+						sinon.stub()
+						.callsArgWith(1, null, null)
+					@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
+						.callsArgWith(2, null)
+					@ProjectController.loadEditor = sinon.stub()
+					@TokenAccessController.readAndWriteToken @req, @res, @next
+
+				it 'should try to find a project with this token', (done) ->
+					expect(@TokenAccessHandler.findProjectWithReadAndWriteToken.callCount)
+						.to.equal 1
+					expect(@TokenAccessHandler.findProjectWithReadAndWriteToken.calledWith(
+						@readAndWriteToken
+					)).to.equal true
+					done()
+
+				it 'should not add the user to the project with read-write access', (done) ->
+					expect(@TokenAccessHandler.addReadAndWriteUserToProject.callCount)
+						.to.equal 0
+					done()
+
+				it 'should not pass control to loadEditor', (done) ->
+					expect(@ProjectController.loadEditor.callCount).to.equal 0
+					expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal false
+					done()
+
+				it 'should call next with a not-found error', (done) ->
+					expect(@next.callCount).to.equal 1
+					expect(@next.lastCall.args[0]).to.be.instanceof Error
+					done()
 
 		describe 'when adding user to project produces an error', ->
 			beforeEach ->

+ 33 - 0
services/web/test/UnitTests/coffee/TokenAccess/TokenAccessHandlerTests.coffee

@@ -84,6 +84,39 @@ describe "TokenAccessHandler", ->
 					done()
 
 
+	describe 'findPrivateOverleafProjectWithReadAndWriteToken', ->
+		beforeEach ->
+			@Project.findOne = sinon.stub().callsArgWith(2, null, @project)
+
+		it 'should call Project.findOne', (done) ->
+			@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken @token, (err, project) =>
+				expect(@Project.findOne.callCount).to.equal 1
+				expect(@Project.findOne.calledWith({
+					'tokens.readAndWrite': @token,
+					'publicAccesLevel': 'private',
+					'overleaf.id': {$exists: true}
+				})).to.equal true
+				done()
+
+		it 'should produce a project object with no error', (done) ->
+			@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken @token, (err, project) =>
+				expect(err).to.not.exist
+				expect(project).to.exist
+				expect(project).to.deep.equal @project
+				done()
+
+		describe 'when Project.findOne produces an error', ->
+			beforeEach ->
+				@Project.findOne = sinon.stub().callsArgWith(2, new Error('woops'))
+
+			it 'should produce an error', (done) ->
+				@TokenAccessHandler.findPrivateOverleafProjectWithReadAndWriteToken @token, (err, project) =>
+					expect(err).to.exist
+					expect(project).to.not.exist
+					expect(err).to.be.instanceof Error
+					done()
+
+
 	describe 'addReadOnlyUserToProject', ->
 		beforeEach ->
 			@Project.update = sinon.stub().callsArgWith(2, null)