If no project found for read/write token, redirect to v1

This commit is contained in:
Alasdair Smith
2018-09-24 18:16:30 +01:00
parent 237810509a
commit 99dec02266
4 changed files with 53 additions and 45 deletions

View File

@@ -34,11 +34,15 @@ module.exports = TokenAccessController =
userId = AuthenticationController.getLoggedInUserId(req)
token = req.params['read_and_write_token']
logger.log {userId, token}, "[TokenAccess] requesting read-and-write token access"
TokenAccessHandler.findProjectWithReadAndWriteToken token, (err, project) ->
TokenAccessHandler.findProjectWithReadAndWriteToken token, (err, project, projectExists) ->
if err?
logger.err {err, token, userId},
"[TokenAccess] error getting project by readAndWrite token"
return next(err)
if !projectExists and settings.overleaf
logger.log {token, userId},
"[TokenAccess] no project found for this token"
return res.redirect(302, settings.overleaf.host + '/' + token)
if !project?
logger.log {token, userId},
"[TokenAccess] no token-based project found for readAndWrite token"

View File

@@ -22,11 +22,17 @@ module.exports = TokenAccessHandler =
return callback(null, null, true)
return callback(null, project, true)
findProjectWithReadAndWriteToken: (token, callback=(err, project)->) ->
findProjectWithReadAndWriteToken: (token, callback=(err, project, projectExists)->) ->
Project.findOne {
'tokens.readAndWrite': token,
'publicAccesLevel': PublicAccessLevels.TOKEN_BASED
}, {_id: 1, publicAccesLevel: 1, owner_ref: 1}, callback
'tokens.readAndWrite': token
}, {_id: 1, publicAccesLevel: 1, owner_ref: 1}, (err, project) ->
if err?
return callback(err)
if !project?
return callback(null, null, false)
if project.publicAccesLevel != PublicAccessLevels.TOKEN_BASED
return callback(null, null, true)
return callback(null, project, true)
findProjectWithHigherAccess: (token, userId, callback=(err, project, projectExists)->) ->
Project.findOne {

View File

@@ -48,7 +48,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, @project)
.callsArgWith(1, null, @project, true)
@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
.callsArgWith(2, null)
@ProjectController.loadEditor = sinon.stub()
@@ -85,7 +85,7 @@ describe "TokenAccessController", ->
@req.params['read_and_write_token'] = @readAndWriteToken
@project.owner_ref = @userId
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, @project)
.callsArgWith(1, null, @project, true)
@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
.callsArgWith(2, null)
@ProjectController.loadEditor = sinon.stub()
@@ -123,7 +123,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, @project)
.callsArgWith(1, null, @project, true)
@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
.callsArgWith(2, null)
@ProjectController.loadEditor = sinon.stub()
@@ -159,7 +159,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, @project)
.callsArgWith(1, null, @project, true)
@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
.callsArgWith(2, null)
@ProjectController.loadEditor = sinon.stub()
@@ -244,7 +244,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = '123abc'
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, null)
.callsArgWith(1, null, null, false)
@TokenAccessHandler.findProjectWithHigherAccess =
sinon.stub()
.callsArgWith(2, null, @project, false)
@@ -252,8 +252,10 @@ describe "TokenAccessController", ->
it 'should redirect to v1', (done) ->
expect(@res.redirect.callCount).to.equal 1
expect(@res.redirect.firstCall.args[0])
.to.equal 'http://overleaf.test:5000/123abc'
expect(@res.redirect.calledWith(
302,
'http://overleaf.test:5000/123abc'
)).to.equal true
done()
describe 'when token access is off, but user has higher access anyway', ->
@@ -264,7 +266,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, null)
.callsArgWith(1, null, null, true)
@TokenAccessHandler.findProjectWithHigherAccess =
sinon.stub()
.callsArgWith(2, null, @project, true)
@@ -313,7 +315,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, null)
.callsArgWith(1, null, null, true)
@TokenAccessHandler.findProjectWithHigherAccess =
sinon.stub()
.callsArgWith(2, null, null, true)
@@ -358,7 +360,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, @project)
.callsArgWith(1, null, @project, true)
@TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
.callsArgWith(2, new Error('woops'))
@ProjectController.loadEditor = sinon.stub()
@@ -500,31 +502,7 @@ describe "TokenAccessController", ->
expect(@next.lastCall.args[0]).to.be.instanceof Error
done()
##
describe 'when findProject does not find a project', ->
beforeEach ->
describe 'when project does not exist', ->
beforeEach ->
@req = new MockRequest()
@req.url = '/123abc'
@res = new MockResponse()
@res.redirect = sinon.stub()
@next = sinon.stub()
@req.params['read_and_write_token'] = '123abc'
@TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
.callsArgWith(1, null, null, true)
@TokenAccessHandler.findProjectWithHigherAccess =
sinon.stub()
.callsArgWith(2, null, @project, false)
@TokenAccessController.readOnlyToken @req, @res, @next
it 'should return a ProjectNotTokenAccessError', (done) ->
expect(@res.redirect.callCount).to.equal 1
expect(@res.redirect.firstCall.args[0])
.to.equal 'http://overleaf.test:5000/123abc'
done()
describe 'when token access is off, but user has higher access anyway', ->
beforeEach ->
@req = new MockRequest()
@@ -533,7 +511,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, null)
.callsArgWith(1, null, null, true)
@TokenAccessHandler.findProjectWithHigherAccess =
sinon.stub()
.callsArgWith(2, null, @project, true)
@@ -581,7 +559,7 @@ describe "TokenAccessController", ->
@next = sinon.stub()
@req.params['read_and_write_token'] = @readAndWriteToken
@TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
.callsArgWith(1, null, null)
.callsArgWith(1, null, null, true)
@TokenAccessHandler.findProjectWithHigherAccess =
sinon.stub()
.callsArgWith(2, null, null, true)
@@ -780,7 +758,7 @@ describe "TokenAccessController", ->
.to.equal 0
done()
it 'should call next with a not-found error', (done) ->
it 'should redirect to v1', (done) ->
expect(@res.redirect.callCount).to.equal 1
expect(@res.redirect.calledWith(
302,

View File

@@ -58,7 +58,7 @@ describe "TokenAccessHandler", ->
expect(err).to.be.instanceof Error
done()
describe 'when project is not tokenBased', ->
describe 'when project does not have tokenBased access level', ->
beforeEach ->
@project.publicAccesLevel = 'private'
@Project.findOne = sinon.stub().callsArgWith(2, null, @project, true)
@@ -97,8 +97,7 @@ describe "TokenAccessHandler", ->
@TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project) =>
expect(@Project.findOne.callCount).to.equal 1
expect(@Project.findOne.calledWith({
'tokens.readAndWrite': @token,
'publicAccesLevel': 'tokenBased'
'tokens.readAndWrite': @token
})).to.equal true
done()
@@ -109,6 +108,11 @@ describe "TokenAccessHandler", ->
expect(project).to.deep.equal @project
done()
it 'should return projectExists flag as true', (done) ->
@TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project, projectExists) ->
expect(projectExists).to.equal true
done()
describe 'when Project.findOne produces an error', ->
beforeEach ->
@Project.findOne = sinon.stub().callsArgWith(2, new Error('woops'))
@@ -120,6 +124,22 @@ describe "TokenAccessHandler", ->
expect(err).to.be.instanceof Error
done()
describe 'when project does not have tokenBased access level', ->
beforeEach ->
@project.publicAccesLevel = 'private'
@Project.findOne = sinon.stub().callsArgWith(2, null, @project, true)
it 'should not return a project', (done) ->
@TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project) ->
expect(err).to.not.exist
expect(project).to.not.exist
done()
it 'should return projectExists flag as true', (done) ->
@TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project, projectExists) ->
expect(projectExists).to.equal true
done()
describe 'findProjectWithHigherAccess', ->
describe 'when user does have higher access', ->