| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740 |
- should = require('chai').should()
- SandboxedModule = require('sandboxed-module')
- assert = require('assert')
- path = require('path')
- sinon = require('sinon')
- modulePath = path.join __dirname, "../../../../app/js/Features/TokenAccess/TokenAccessController"
- expect = require("chai").expect
- ObjectId = require("mongojs").ObjectId
- MockRequest = require('../helpers/MockRequest')
- MockResponse = require('../helpers/MockResponse')
- Errors = require "../../../../app/js/Features/Errors/Errors.js"
- describe "TokenAccessController", ->
- beforeEach ->
- @readOnlyToken = 'somereadonlytoken'
- @readAndWriteToken = '42somereadandwritetoken'
- @projectId = ObjectId()
- @ownerId = 'owner'
- @project =
- _id: @projectId
- publicAccesLevel: 'tokenBased'
- tokens:
- readOnly: @readOnlyToken
- readAndWrite: @readAndWriteToken
- owner_ref: @ownerId
- @userId = ObjectId()
- @TokenAccessController = SandboxedModule.require modulePath, requires:
- '../Project/ProjectController': @ProjectController = {}
- '../Authentication/AuthenticationController': @AuthenticationController = {}
- './TokenAccessHandler': @TokenAccessHandler = {}
- 'logger-sharelatex': {log: sinon.stub(), err: sinon.stub()}
- @AuthenticationController.getLoggedInUserId = sinon.stub().returns(@userId.toString())
- describe 'readAndWriteToken', ->
- beforeEach ->
- describe 'when all goes well', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_and_write_token'] = @readAndWriteToken
- @TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @AuthenticationController._setRedirectInSession = 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 add the user to the project with read-write access', (done) ->
- expect(@TokenAccessHandler.addReadAndWriteUserToProject.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.addReadAndWriteUserToProject.calledWith(
- @userId.toString(), @projectId
- ))
- .to.equal true
- done()
- it 'should pass control to loadEditor', (done) ->
- expect(@req.params.Project_id).to.equal @projectId.toString()
- expect(@ProjectController.loadEditor.callCount).to.equal 1
- expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal true
- done()
- describe 'when the user is already the owner', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_and_write_token'] = @readAndWriteToken
- @project.owner_ref = @userId
- @TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @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 pass control to loadEditor', (done) ->
- expect(@req.params.Project_id).to.equal @projectId.toString()
- expect(@ProjectController.loadEditor.callCount).to.equal 1
- expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal true
- done()
- describe 'when there is no user', ->
- beforeEach ->
- @AuthenticationController.getLoggedInUserId =
- sinon.stub().returns(null)
- describe 'when anonymous read-write access is enabled', ->
- beforeEach ->
- @TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED = true
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_and_write_token'] = @readAndWriteToken
- @TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessHandler.grantSessionTokenAccess = 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 give the user session token access', (done) ->
- expect(@TokenAccessHandler.grantSessionTokenAccess.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.grantSessionTokenAccess.calledWith(
- @req, @projectId, @readAndWriteToken
- ))
- .to.equal true
- done()
- it 'should pass control to loadEditor', (done) ->
- expect(@req.params.Project_id).to.equal @projectId.toString()
- expect(@ProjectController.loadEditor.callCount).to.equal 1
- expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal true
- done()
- describe 'when anonymous read-write access is not enabled', ->
- beforeEach ->
- @TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED = false
- @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, @project)
- @TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessHandler.grantSessionTokenAccess = sinon.stub()
- @AuthenticationController._setRedirectInSession = 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 give the user session token access', (done) ->
- expect(@TokenAccessHandler.grantSessionTokenAccess.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 set redirect in session', (done) ->
- expect(@AuthenticationController._setRedirectInSession.callCount).to.equal 1
- expect(@AuthenticationController._setRedirectInSession.calledWith(@req)).to.equal true
- done()
- it 'should redirect to restricted page', (done) ->
- expect(@res.redirect.callCount).to.equal 1
- expect(@res.redirect.calledWith('/restricted')).to.equal true
- done()
- describe 'when findProject produces an error', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_and_write_token'] = @readAndWriteToken
- @TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
- .callsArgWith(1, new Error('woops'))
- @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 an error', (done) ->
- expect(@next.callCount).to.equal 1
- expect(@next.lastCall.args[0]).to.be.instanceof Error
- done()
- describe 'when findProject does not find a project', ->
- beforeEach ->
- describe 'when user is present', ->
- beforeEach ->
- @AuthenticationController.getLoggedInUserId =
- sinon.stub().returns(@userId.toString())
- describe 'when token access is off, but user has higher access anyway', ->
- 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.findProjectWithHigherAccess =
- sinon.stub()
- .callsArgWith(2, null, @project)
- @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 check if user has higher access to the token project', (done) ->
- expect(
- @TokenAccessHandler.findProjectWithHigherAccess.callCount
- ).to.equal 1
- 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 higher access is not available', ->
- 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.findProjectWithHigherAccess =
- sinon.stub()
- .callsArgWith(2, 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 check if user has higher access to the token project', (done) ->
- expect(
- @TokenAccessHandler.findProjectWithHigherAccess.callCount
- ).to.equal 1
- 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 ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_and_write_token'] = @readAndWriteToken
- @TokenAccessHandler.findProjectWithReadAndWriteToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadAndWriteUserToProject = sinon.stub()
- .callsArgWith(2, new Error('woops'))
- @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 add the user to the project with read-write access', (done) ->
- expect(@TokenAccessHandler.addReadAndWriteUserToProject.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.addReadAndWriteUserToProject.calledWith(
- @userId.toString(), @projectId
- ))
- .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 call next with an error', (done) ->
- expect(@next.callCount).to.equal 1
- expect(@next.lastCall.args[0]).to.be.instanceof Error
- done()
- describe 'readOnlyToken', ->
- beforeEach ->
- describe 'with a user', ->
- beforeEach ->
- @AuthenticationController.getLoggedInUserId = sinon.stub().returns(@userId.toString())
- describe 'when all goes well', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.addReadOnlyUserToProject.calledWith(
- @userId.toString(), @projectId
- ))
- .to.equal true
- done()
- it 'should pass control to loadEditor', (done) ->
- expect(@req.params.Project_id).to.equal @projectId.toString()
- expect(@ProjectController.loadEditor.callCount).to.equal 1
- expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal true
- done()
- describe 'when the user is already the owner', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @project.owner_ref = @userId
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should not add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.callCount)
- .to.equal 0
- done()
- it 'should pass control to loadEditor', (done) ->
- expect(@req.params.Project_id).to.equal @projectId.toString()
- expect(@ProjectController.loadEditor.callCount).to.equal 1
- expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal true
- done()
- describe 'when findProject produces an error', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, new Error('woops'))
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should not add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.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 an error', (done) ->
- expect(@next.callCount).to.equal 1
- expect(@next.lastCall.args[0]).to.be.instanceof Error
- done()
- ##
- describe 'when findProject does not find a project', ->
- beforeEach ->
- describe 'when token access is off, but user has higher access anyway', ->
- 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.findProjectWithHigherAccess =
- sinon.stub()
- .callsArgWith(2, null, @project)
- @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 check if user has higher access to the token project', (done) ->
- expect(
- @TokenAccessHandler.findProjectWithHigherAccess.callCount
- ).to.equal 1
- 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 higher access is not available', ->
- 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.findProjectWithHigherAccess =
- sinon.stub()
- .callsArgWith(2, null, null)
- @TokenAccessHandler.addReadOnlyUserToProject = 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 check if user has higher access to the token project', (done) ->
- expect(
- @TokenAccessHandler.findProjectWithHigherAccess.callCount
- ).to.equal 1
- done()
- it 'should not add the user to the project with read-write access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.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 ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, new Error('woops'))
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.addReadOnlyUserToProject.calledWith(
- @userId.toString(), @projectId
- ))
- .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 call next with an error', (done) ->
- expect(@next.callCount).to.equal 1
- expect(@next.lastCall.args[0]).to.be.instanceof Error
- done()
- describe 'anonymous', ->
- beforeEach ->
- @AuthenticationController.getLoggedInUserId = sinon.stub().returns(null)
- @TokenAccessHandler.grantSessionTokenAccess = sinon.stub()
- describe 'when all goes well', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, null, @project)
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should give the user session read-only access', (done) ->
- expect(@TokenAccessHandler.grantSessionTokenAccess.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.grantSessionTokenAccess.calledWith(
- @req, @projectId, @readOnlyToken
- ))
- .to.equal true
- done()
- it 'should not add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.callCount)
- .to.equal 0
- done()
- it 'should pass control to loadEditor', (done) ->
- expect(@req.params.Project_id).to.equal @projectId.toString()
- expect(@req._anonymousAccessToken).to.equal @readOnlyToken
- expect(@ProjectController.loadEditor.callCount).to.equal 1
- expect(@ProjectController.loadEditor.calledWith(@req, @res, @next)).to.equal true
- done()
- describe 'when findProject produces an error', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, new Error('woops'))
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should not give the user session read-only access', (done) ->
- expect(@TokenAccessHandler.grantSessionTokenAccess.callCount)
- .to.equal 0
- done()
- it 'should not add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.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 an error', (done) ->
- expect(@next.callCount).to.equal 1
- expect(@next.lastCall.args[0]).to.be.instanceof Error
- done()
- describe 'when findProject does not find a project', ->
- beforeEach ->
- @req = new MockRequest()
- @res = new MockResponse()
- @next = sinon.stub()
- @req.params['read_only_token'] = @readOnlyToken
- @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
- .callsArgWith(1, null, null)
- @TokenAccessHandler.addReadOnlyUserToProject = sinon.stub()
- .callsArgWith(2, null)
- @ProjectController.loadEditor = sinon.stub()
- @TokenAccessController.readOnlyToken @req, @res, @next
- it 'should try to find a project with this token', (done) ->
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
- .to.equal 1
- expect(@TokenAccessHandler.findProjectWithReadOnlyToken.calledWith(@readOnlyToken))
- .to.equal true
- done()
- it 'should not give the user session read-only access', (done) ->
- expect(@TokenAccessHandler.grantSessionTokenAccess.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 add the user to the project with read-only access', (done) ->
- expect(@TokenAccessHandler.addReadOnlyUserToProject.callCount)
- .to.equal 0
- 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()
|