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

This commit is contained in:
Shane Kilkelly 2017-10-16 13:20:15 +01:00
parent ee29cb45d2
commit ad999a72b6
4 changed files with 151 additions and 38 deletions

View file

@ -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)

View file

@ -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())

View file

@ -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 ->

View file

@ -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)